From 7dff053540024b8483d715ed39494d08515621fe Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 30 Jul 2003 20:56:47 +0000 Subject: [PATCH] Move err() to the lexer, implement file inclusion capabilities directly in tblgen git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@7436 91177308-0d34-0410-b5e6-96231b3b80d8 --- support/tools/TableGen/FileLexer.l | 93 +++++++++++++++++++++++++++-- support/tools/TableGen/FileParser.y | 4 +- utils/TableGen/FileLexer.l | 93 +++++++++++++++++++++++++++-- utils/TableGen/FileParser.y | 4 +- 4 files changed, 176 insertions(+), 18 deletions(-) diff --git a/support/tools/TableGen/FileLexer.l b/support/tools/TableGen/FileLexer.l index c61e9ded3f7..d3264da91a0 100644 --- a/support/tools/TableGen/FileLexer.l +++ b/support/tools/TableGen/FileLexer.l @@ -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 ParseInt(const char *Str) { 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 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 @@ void ParseFile(const std::string &Filename) { std::cerr << "Could not open input file '" + Filename + "'!\n"; abort(); } + IncludeStack.push_back(IncludeRec(Filename, F)); + } else { + IncludeStack.push_back(IncludeRec("", 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 @@ Comment \/\/.* 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 @@ in { return IN; } {Integer} { Filelval.IntVal = ParseInt(Filetext); return INTVAL; } [ \t\n]+ { /* Ignore whitespace */ } -. { return Filetext[0]; } "/*" { BEGIN(comment); CommentDepth++; } @@ -96,6 +175,8 @@ in { return IN; } "/*" { ++CommentDepth; } "/"+[^*]* /* eat up /'s not followed by *'s */ "*"+"/" { if (!--CommentDepth) { BEGIN(INITIAL); } } -<> { fprintf(stderr, "Unterminated comment!\n"); abort(); } +<> { err() << "Unterminated comment!\n"; abort(); } + +. { return Filetext[0]; } %% diff --git a/support/tools/TableGen/FileParser.y b/support/tools/TableGen/FileParser.y index d1f8308ce47..431fcfcc624 100644 --- a/support/tools/TableGen/FileParser.y +++ b/support/tools/TableGen/FileParser.y @@ -21,9 +21,7 @@ typedef std::pair*> SubClassRefTy; static std::vector*>, 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())) { diff --git a/utils/TableGen/FileLexer.l b/utils/TableGen/FileLexer.l index c61e9ded3f7..d3264da91a0 100644 --- a/utils/TableGen/FileLexer.l +++ b/utils/TableGen/FileLexer.l @@ -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 ParseInt(const char *Str) { 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 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 @@ void ParseFile(const std::string &Filename) { std::cerr << "Could not open input file '" + Filename + "'!\n"; abort(); } + IncludeStack.push_back(IncludeRec(Filename, F)); + } else { + IncludeStack.push_back(IncludeRec("", 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 @@ Comment \/\/.* 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 @@ in { return IN; } {Integer} { Filelval.IntVal = ParseInt(Filetext); return INTVAL; } [ \t\n]+ { /* Ignore whitespace */ } -. { return Filetext[0]; } "/*" { BEGIN(comment); CommentDepth++; } @@ -96,6 +175,8 @@ in { return IN; } "/*" { ++CommentDepth; } "/"+[^*]* /* eat up /'s not followed by *'s */ "*"+"/" { if (!--CommentDepth) { BEGIN(INITIAL); } } -<> { fprintf(stderr, "Unterminated comment!\n"); abort(); } +<> { err() << "Unterminated comment!\n"; abort(); } + +. { return Filetext[0]; } %% diff --git a/utils/TableGen/FileParser.y b/utils/TableGen/FileParser.y index d1f8308ce47..431fcfcc624 100644 --- a/utils/TableGen/FileParser.y +++ b/utils/TableGen/FileParser.y @@ -21,9 +21,7 @@ typedef std::pair*> SubClassRefTy; static std::vector*>, 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())) {