Implement Regression/TableGen/DagDefSubst.ll
[oota-llvm.git] / utils / TableGen / FileLexer.l
index 48070b34a144124027ae9ca1818070eab46d06f5..020a356b0b42d9365664dac2b11d0d5fc21a7143 100644 (file)
@@ -36,9 +36,10 @@ int Fileparse();
 namespace llvm {
 
 // Global variable recording the location of the include directory
-std::string IncludeDirectory;
+std::vector<std::string> IncludeDirectories;
 
-// ParseInt - This has to handle the special case of binary numbers 0b0101
+/// 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);
@@ -60,7 +61,6 @@ struct IncludeRec {
 
 static std::vector<IncludeRec> IncludeStack;
 
-
 std::ostream &err() {
   if (IncludeStack.empty())
     return std::cerr << "At end of input: ";
@@ -72,20 +72,10 @@ std::ostream &err() {
                    << Filelineno << ": ";
 }
 
-
-
-//
-// Function: ParseFile()
-//
-// Description:
-//     This function begins the parsing of the specified tablegen file.
-//
-// Inputs:
-//     Filename - A string containing the name of the file to parse.
-//     IncludeDir - A string containing the directory from which include
-//                  files can be found.
-//
-void ParseFile(const std::string &Filename, const std::string & IncludeDir) {
+/// 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");
@@ -99,11 +89,9 @@ void ParseFile(const std::string &Filename, const std::string & IncludeDir) {
     IncludeStack.push_back(IncludeRec("<stdin>", stdin));
   }
 
-  //
   // Record the location of the include directory so that the lexer can find
   // it later.
-  //
-  IncludeDirectory = IncludeDir;
+  IncludeDirectories = IncludeDirs;
  
   Filein = F;
   Filelineno = 1;
@@ -111,8 +99,9 @@ void ParseFile(const std::string &Filename, const std::string & IncludeDir) {
   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] == '"');
@@ -133,20 +122,21 @@ static void HandleInclude(const char *Buffer) {
   // Open the new input file...
   yyin = fopen(Filename.c_str(), "r");
   if (yyin == 0) {
-    //
     // If we couldn't find the file in the current directory, look for it in
     // the include directories.
     //
-    // NOTE:
-    //  Right now, there is only one directory.  We need to eventually add
-    //  support for more.
-    //
-    Filename = IncludeDirectory + "/" + Filename;
-    yyin = fopen(Filename.c_str(), "r");
+    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";
-      abort();
+      exit(1);
     }
+    Filename = NextFilename;
   }
 
   // Add the file to our include stack...
@@ -157,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();
@@ -210,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);
@@ -220,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]; }
 
 %%
+