[llvm-commits] CVS: llvm/utils/TableGen/FileLexer.l FileParser.y

Chris Lattner lattner at cs.uiuc.edu
Wed Jul 30 15:57:01 PDT 2003


Changes in directory llvm/utils/TableGen:

FileLexer.l updated: 1.3 -> 1.4
FileParser.y updated: 1.12 -> 1.13

---
Log message:

Move err() to the lexer, implement file inclusion capabilities directly in tblgen


---
Diffs of the changes:

Index: llvm/utils/TableGen/FileLexer.l
diff -u llvm/utils/TableGen/FileLexer.l:1.3 llvm/utils/TableGen/FileLexer.l:1.4
--- llvm/utils/TableGen/FileLexer.l:1.3	Wed Jul 30 14:55:10 2003
+++ llvm/utils/TableGen/FileLexer.l	Wed Jul 30 15:56:47 2003
@@ -8,7 +8,6 @@
 %option nostdinit
 %option never-interactive
 %option batch
-%option noyywrap
 %option nodefault
 %option 8bit
 %option outfile="Lexer.cpp"
@@ -32,6 +31,32 @@
 
 static int CommentDepth = 0;
 
+struct IncludeRec {
+  std::string Filename;
+  FILE *File;
+  unsigned LineNo;
+  YY_BUFFER_STATE Buffer;
+
+  IncludeRec(const std::string &FN, FILE *F)
+    : Filename(FN), File(F), LineNo(0){
+  }
+};
+
+static std::vector<IncludeRec> IncludeStack;
+
+
+std::ostream &err() {
+  if (IncludeStack.empty())
+    return std::cerr << "At end of input: ";
+
+  for (unsigned i = 0, e = IncludeStack.size()-1; i != e; ++i)
+    std::cerr << "IncFrom " << IncludeStack[i].Filename << ":"
+              << IncludeStack[i].LineNo << ":\n";
+  return std::cerr << "Parsing " << IncludeStack.back().Filename << ":"
+                   << Filelineno << ": ";
+}
+
+
 int Fileparse();
 
 void ParseFile(const std::string &Filename) {
@@ -43,17 +68,68 @@
       std::cerr << "Could not open input file '" + Filename + "'!\n";
       abort();
     }
+    IncludeStack.push_back(IncludeRec(Filename, F));
+  } else {
+    IncludeStack.push_back(IncludeRec("<stdin>", stdin));
   }
 
   Filein = F;
   Filelineno = 1;
   Fileparse();
-
-  if (F != stdin)
-    fclose(F);
   Filein = stdin;
 }
 
+// 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] == '"');
+  Buffer += strlen("include ");
+  Length -= strlen("include ");
+  while (*Buffer != '"') {
+    ++Buffer;
+    --Length;
+  }
+  assert(Length >= 2 && "Double quotes not found?");
+  std::string Filename(Buffer+1, Buffer+Length-1);
+  //std::cerr << "Filename = '" << Filename << "'\n";
+
+  // Save the line number and lex buffer of the includer...
+  IncludeStack.back().LineNo = Filelineno;
+  IncludeStack.back().Buffer = YY_CURRENT_BUFFER;
+
+  // Open the new input file...
+  yyin = fopen(Filename.c_str(), "r");
+  if (yyin == 0) {
+    err() << "Could not find include file '" << Filename << "'!\n";
+    abort();
+  }
+
+  // Add the file to our include stack...
+  IncludeStack.push_back(IncludeRec(Filename, yyin));
+  Filelineno = 1;  // Reset line numbering...
+  //yyrestart(yyin);    // Start lexing the new file...
+
+  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.
+//
+extern "C"
+int yywrap() {
+  if (IncludeStack.back().File != stdin)
+    fclose(IncludeStack.back().File);
+  IncludeStack.pop_back();
+  if (IncludeStack.empty()) return 1;  // Top-level file is done.
+
+  // Otherwise, we need to switch back to a file which included the current one.
+  Filelineno = IncludeStack.back().LineNo;  // Restore current line number
+  yy_switch_to_buffer(IncludeStack.back().Buffer);
+  return 0;
+}
+
 %}
 
 Comment     \/\/.*
@@ -61,11 +137,15 @@
 Identifier  [a-zA-Z_][0-9a-zA-Z_]*
 Integer     [-+]?[0-9]+|0x[0-9a-fA-F]+|0b[01]+
 StringVal   \"[^"]*\"
+IncludeStr  include[ \t\n]+\"[^"]*\"
 
 %%
 
 {Comment}      { /* Ignore comments */ }
 
+{IncludeStr}   { HandleInclude(yytext); }
+
+
 int            { return INT; }
 bit            { return BIT; }
 bits           { return BITS; }
@@ -87,7 +167,6 @@
 {Integer}      { Filelval.IntVal = ParseInt(Filetext); return INTVAL; }
 
 [ \t\n]+       { /* Ignore whitespace */ }
-.              { return Filetext[0]; }
 
 
 "/*"                    { BEGIN(comment); CommentDepth++; }
@@ -96,6 +175,8 @@
 <comment>"/*"           { ++CommentDepth; }
 <comment>"/"+[^*]*      /* eat up /'s not followed by *'s */
 <comment>"*"+"/"        { if (!--CommentDepth) { BEGIN(INITIAL); } }
-<comment><<EOF>>        { fprintf(stderr, "Unterminated comment!\n"); abort(); }
+<comment><<EOF>>        { err() << "Unterminated comment!\n"; abort(); }
+
+.              { return Filetext[0]; }
 
 %%


Index: llvm/utils/TableGen/FileParser.y
diff -u llvm/utils/TableGen/FileParser.y:1.12 llvm/utils/TableGen/FileParser.y:1.13
--- llvm/utils/TableGen/FileParser.y:1.12	Wed Jul 30 14:55:10 2003
+++ llvm/utils/TableGen/FileParser.y	Wed Jul 30 15:56:47 2003
@@ -21,9 +21,7 @@
 static std::vector<std::pair<std::pair<std::string, std::vector<unsigned>*>,
                              Init*> > SetStack;
 
-static std::ostream &err() {
-  return std::cerr << "Parsing Line #" << Filelineno << ": ";
-}
+extern std::ostream &err();
 
 static void addValue(const RecordVal &RV) {
   if (CurRec->getValue(RV.getName())) {





More information about the llvm-commits mailing list