Implement Regression/TableGen/DagDefSubst.ll
[oota-llvm.git] / utils / TableGen / FileLexer.l
index 98370a7fef5d55b860954f027e2902b38ac75e77..020a356b0b42d9365664dac2b11d0d5fc21a7143 100644 (file)
@@ -1,4 +1,11 @@
 /*===-- FileLexer.l - Scanner for TableGen Files ----------------*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
 //
 // This file defines a simple flex scanner for TableGen files.  This is pretty
 // straight-forward, except for the magic to handle file inclusion.
 
 %{
 #include "Record.h"
-typedef std::pair<Record*, std::vector<Init*>*> SubClassRefTy;
+typedef std::pair<llvm::Record*, std::vector<llvm::Init*>*> SubClassRefTy;
 #include "FileParser.h"
 
-// ParseInt - This has to handle the special case of binary numbers 0b0101
+int Fileparse();
+
+namespace llvm {
+
+// Global variable recording the location of the include directory
+std::vector<std::string> IncludeDirectories;
+
+/// ParseInt - This has to handle the special case of binary numbers 0b0101
+///
 static int ParseInt(const char *Str) {
   if (Str[0] == '0' && Str[1] == 'b')
     return strtol(Str+2, 0, 2);
@@ -46,7 +61,6 @@ struct IncludeRec {
 
 static std::vector<IncludeRec> IncludeStack;
 
-
 std::ostream &err() {
   if (IncludeStack.empty())
     return std::cerr << "At end of input: ";
@@ -58,31 +72,36 @@ std::ostream &err() {
                    << Filelineno << ": ";
 }
 
-
-int Fileparse();
-
-void ParseFile(const std::string &Filename) {
+/// ParseFile - this function begins the parsing of the specified tablegen file.
+///
+void ParseFile(const std::string &Filename, 
+               const std::vector<std::string> &IncludeDirs) {
   FILE *F = stdin;
   if (Filename != "-") {
     F = fopen(Filename.c_str(), "r");
 
     if (F == 0) {
       std::cerr << "Could not open input file '" + Filename + "'!\n";
-      abort();
+      exit (1);
     }
     IncludeStack.push_back(IncludeRec(Filename, F));
   } else {
     IncludeStack.push_back(IncludeRec("<stdin>", stdin));
   }
 
+  // Record the location of the include directory so that the lexer can find
+  // it later.
+  IncludeDirectories = IncludeDirs;
   Filein = F;
   Filelineno = 1;
   Fileparse();
   Filein = stdin;
 }
 
-// HandleInclude - This function is called when an include directive is
-// encountered in the input stream...
+/// HandleInclude - This function is called when an include directive is
+/// encountered in the input stream...
+///
 static void HandleInclude(const char *Buffer) {
   unsigned Length = yyleng;
   assert(Buffer[Length-1] == '"');
@@ -103,8 +122,21 @@ static void HandleInclude(const char *Buffer) {
   // Open the new input file...
   yyin = fopen(Filename.c_str(), "r");
   if (yyin == 0) {
-    err() << "Could not find include file '" << Filename << "'!\n";
-    abort();
+    // If we couldn't find the file in the current directory, look for it in
+    // the include directories.
+    //
+    std::string NextFilename;
+    for (unsigned i = 0, e = IncludeDirectories.size(); i != e; ++i) {
+      NextFilename = IncludeDirectories[i] + "/" + Filename;
+      if ((yyin = fopen(NextFilename.c_str(), "r")))
+        break;
+    }
+    
+    if (yyin == 0) {
+      err() << "Could not find include file '" << Filename << "'!\n";
+      exit(1);
+    }
+    Filename = NextFilename;
   }
 
   // Add the file to our include stack...
@@ -115,12 +147,11 @@ static void HandleInclude(const char *Buffer) {
   yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
 }
 
-
-// yywrap - This is called when the lexer runs out of input in one of the files.
-// Switch back to an includer if an includee has run out of input.
-//
+/// yywrap - This is called when the lexer runs out of input in one of the
+/// files. Switch back to an includer if an includee has run out of input.
+///
 extern "C"
-int yywrap() {
+int yywrap(void) {
   if (IncludeStack.back().File != stdin)
     fclose(IncludeStack.back().File);
   IncludeStack.pop_back();
@@ -132,6 +163,10 @@ int yywrap() {
   return 0;
 }
 
+} // End llvm namespace
+
+using namespace llvm;
+
 %}
 
 Comment      \/\/.*
@@ -164,6 +199,11 @@ field          { return FIELD; }
 let            { return LET; }
 in             { return IN; }
 
+!sra           { return SRATOK; }
+!srl           { return SRLTOK; }
+!shl           { return SHLTOK; }
+
+
 {Identifier}   { Filelval.StrVal = new std::string(yytext, yytext+yyleng);
                  return ID; }
 ${Identifier}  { Filelval.StrVal = new std::string(yytext+1, yytext+yyleng);
@@ -174,17 +214,18 @@ ${Identifier}  { Filelval.StrVal = new std::string(yytext+1, yytext+yyleng);
 
 {Integer}      { Filelval.IntVal = ParseInt(Filetext); return INTVAL; }
 
-[ \t\n]+       { /* Ignore whitespace */ }
+[ \t\n\r]+     { /* Ignore whitespace */ }
 
 
 "/*"                    { BEGIN(comment); CommentDepth++; }
-<comment>[^*/]*         /* eat anything that's not a '*' or '/' */
-<comment>"*"+[^*/]*     /* eat up '*'s not followed by '/'s */
+<comment>[^*/]*         {} /* eat anything that's not a '*' or '/' */
+<comment>"*"+[^*/]*     {} /* eat up '*'s not followed by '/'s */
 <comment>"/*"           { ++CommentDepth; }
-<comment>"/"+[^*]*      /* eat up /'s not followed by *'s */
+<comment>"/"+[^*/]*     {} /* eat up /'s not followed by *'s */
 <comment>"*"+"/"        { if (!--CommentDepth) { BEGIN(INITIAL); } }
-<comment><<EOF>>        { err() << "Unterminated comment!\n"; abort(); }
+<comment><<EOF>>        { err() << "Unterminated comment!\n"; exit(1); }
 
 .              { return Filetext[0]; }
 
 %%
+