implement new method
[oota-llvm.git] / utils / TableGen / FileLexer.l
index 8ab400610d02152804f9d868da15330219b85413..9b7973c6dc302538ed3d3c50b8a5bbf41e661d07 100644 (file)
@@ -1,7 +1,16 @@
 /*===-- 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.
+//
+//===----------------------------------------------------------------------===*/
 
 %option prefix="File"
 %option yylineno
 
 %{
 #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::string IncludeDirectory;
+
+/// 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);
@@ -44,7 +61,6 @@ struct IncludeRec {
 
 static std::vector<IncludeRec> IncludeStack;
 
-
 std::ostream &err() {
   if (IncludeStack.empty())
     return std::cerr << "At end of input: ";
@@ -56,31 +72,35 @@ 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::string & IncludeDir) {
   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.
+  IncludeDirectory = IncludeDir;
   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] == '"');
@@ -101,8 +121,18 @@ 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.
+    //
+    // NOTE: Right now, there is only one directory.  We need to eventually add
+    // support for more.
+    std::string NextFilename = IncludeDirectory + "/" + Filename;
+    yyin = fopen(NextFilename.c_str(), "r");
+    if (yyin == 0) {
+      err() << "Could not find include file '" << Filename << "'!\n";
+      exit(1);
+    }
+    Filename = NextFilename;
   }
 
   // Add the file to our include stack...
@@ -113,10 +143,9 @@ 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() {
   if (IncludeStack.back().File != stdin)
@@ -130,6 +159,10 @@ int yywrap() {
   return 0;
 }
 
+} // End llvm namespace
+
+using namespace llvm;
+
 %}
 
 Comment      \/\/.*
@@ -159,11 +192,13 @@ dag            { return DAG; }
 class          { return CLASS; }
 def            { return DEF; }
 field          { return FIELD; }
-set            { return SET; }
+let            { return LET; }
 in             { return IN; }
 
 {Identifier}   { Filelval.StrVal = new std::string(yytext, yytext+yyleng);
                  return ID; }
+${Identifier}  { Filelval.StrVal = new std::string(yytext+1, yytext+yyleng);
+                 return VARNAME; } 
 
 {StringVal}    { Filelval.StrVal = new std::string(yytext+1, yytext+yyleng-1);
                  return STRVAL; }
@@ -179,7 +214,7 @@ in             { return IN; }
 <comment>"/*"           { ++CommentDepth; }
 <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]; }