From e8242b168c7fdce5d5c9f82e8e71397ab3234fdc Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 14 Feb 2006 05:13:13 +0000 Subject: [PATCH] Adjust to new form of handling lexer dependencies, this way shouldn't have the problems the old way did. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26161 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../{FileLexer.cpp => FileLexer.cpp.cvs} | 85 ++++--- utils/TableGen/FileLexer.l | 1 + utils/TableGen/FileLexer.l.cvs | 227 ++++++++++++++++++ 3 files changed, 273 insertions(+), 40 deletions(-) rename utils/TableGen/{FileLexer.cpp => FileLexer.cpp.cvs} (95%) create mode 100644 utils/TableGen/FileLexer.l.cvs diff --git a/utils/TableGen/FileLexer.cpp b/utils/TableGen/FileLexer.cpp.cvs similarity index 95% rename from utils/TableGen/FileLexer.cpp rename to utils/TableGen/FileLexer.cpp.cvs index 7af375c7310..e1f7b5434ff 100644 --- a/utils/TableGen/FileLexer.cpp +++ b/utils/TableGen/FileLexer.cpp.cvs @@ -29,7 +29,6 @@ #define YY_FLEX_MINOR_VERSION 5 #include -#include /* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ @@ -43,6 +42,7 @@ #ifdef __cplusplus #include +#include /* Use prototypes in function declarations. */ #define YY_USE_PROTOS @@ -489,7 +489,7 @@ goto find_rule; \ #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET char *yytext; -#line 1 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 1 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" #define INITIAL 0 /*===-- FileLexer.l - Scanner for TableGen Files ----------------*- C++ -*-===// // @@ -507,7 +507,7 @@ char *yytext; #define YY_NEVER_INTERACTIVE 1 #define comment 1 -#line 30 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 30 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" #include "Record.h" typedef std::pair*> SubClassRefTy; #include "FileParser.h" @@ -792,10 +792,10 @@ YY_MALLOC_DECL YY_DECL { register yy_state_type yy_current_state; - register char *yy_cp = NULL, *yy_bp = NULL; + register char *yy_cp, *yy_bp; register int yy_act; -#line 176 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 176 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" #line 802 "Lexer.cpp" @@ -891,165 +891,165 @@ do_action: /* This label is used only to access EOF actions. */ { /* beginning of action switch */ case 1: YY_RULE_SETUP -#line 178 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 178 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" { /* Ignore comments */ } YY_BREAK case 2: YY_RULE_SETUP -#line 180 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 180 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" { HandleInclude(yytext); } YY_BREAK case 3: YY_RULE_SETUP -#line 181 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 181 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" { Filelval.StrVal = new std::string(yytext+2, yytext+yyleng-2); return CODEFRAGMENT; } YY_BREAK case 4: YY_RULE_SETUP -#line 184 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 184 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" { return INT; } YY_BREAK case 5: YY_RULE_SETUP -#line 185 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 185 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" { return BIT; } YY_BREAK case 6: YY_RULE_SETUP -#line 186 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 186 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" { return BITS; } YY_BREAK case 7: YY_RULE_SETUP -#line 187 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 187 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" { return STRING; } YY_BREAK case 8: YY_RULE_SETUP -#line 188 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 188 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" { return LIST; } YY_BREAK case 9: YY_RULE_SETUP -#line 189 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 189 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" { return CODE; } YY_BREAK case 10: YY_RULE_SETUP -#line 190 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 190 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" { return DAG; } YY_BREAK case 11: YY_RULE_SETUP -#line 192 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 192 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" { return CLASS; } YY_BREAK case 12: YY_RULE_SETUP -#line 193 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 193 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" { return DEF; } YY_BREAK case 13: YY_RULE_SETUP -#line 194 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 194 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" { return FIELD; } YY_BREAK case 14: YY_RULE_SETUP -#line 195 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 195 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" { return LET; } YY_BREAK case 15: YY_RULE_SETUP -#line 196 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 196 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" { return IN; } YY_BREAK case 16: YY_RULE_SETUP -#line 198 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 198 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" { return SRATOK; } YY_BREAK case 17: YY_RULE_SETUP -#line 199 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 199 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" { return SRLTOK; } YY_BREAK case 18: YY_RULE_SETUP -#line 200 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 200 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" { return SHLTOK; } YY_BREAK case 19: YY_RULE_SETUP -#line 203 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 203 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" { Filelval.StrVal = new std::string(yytext, yytext+yyleng); return ID; } YY_BREAK case 20: YY_RULE_SETUP -#line 205 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 205 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" { Filelval.StrVal = new std::string(yytext+1, yytext+yyleng); return VARNAME; } YY_BREAK case 21: YY_RULE_SETUP -#line 208 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 208 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" { Filelval.StrVal = new std::string(yytext+1, yytext+yyleng-1); return STRVAL; } YY_BREAK case 22: YY_RULE_SETUP -#line 211 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 211 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" { Filelval.IntVal = ParseInt(Filetext); return INTVAL; } YY_BREAK case 23: YY_RULE_SETUP -#line 213 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 213 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" { /* Ignore whitespace */ } YY_BREAK case 24: YY_RULE_SETUP -#line 216 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 216 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" { BEGIN(comment); CommentDepth++; } YY_BREAK case 25: YY_RULE_SETUP -#line 217 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 217 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" {} /* eat anything that's not a '*' or '/' */ YY_BREAK case 26: YY_RULE_SETUP -#line 218 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 218 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" {} /* eat up '*'s not followed by '/'s */ YY_BREAK case 27: YY_RULE_SETUP -#line 219 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 219 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" { ++CommentDepth; } YY_BREAK case 28: YY_RULE_SETUP -#line 220 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 220 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" {} /* eat up /'s not followed by *'s */ YY_BREAK case 29: YY_RULE_SETUP -#line 221 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 221 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" { if (!--CommentDepth) { BEGIN(INITIAL); } } YY_BREAK case YY_STATE_EOF(comment): -#line 222 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 222 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" { err() << "Unterminated comment!\n"; exit(1); } YY_BREAK case 30: YY_RULE_SETUP -#line 224 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 224 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" { return Filetext[0]; } YY_BREAK case 31: YY_RULE_SETUP -#line 226 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 226 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK #line 1056 "Lexer.cpp" @@ -1430,7 +1430,6 @@ register char *yy_bp; #endif /* ifndef YY_NO_UNPUT */ -#ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput() #else @@ -1504,7 +1503,7 @@ static int input() return c; } -#endif /* YY_NO_INPUT */ + #ifdef YY_USE_PROTOS void yyrestart( FILE *input_file ) @@ -1615,6 +1614,11 @@ YY_BUFFER_STATE b; } +#ifndef YY_ALWAYS_INTERACTIVE +#ifndef YY_NEVER_INTERACTIVE +extern int isatty YY_PROTO(( int )); +#endif +#endif #ifdef YY_USE_PROTOS void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) @@ -1932,5 +1936,6 @@ int main() return 0; } #endif -#line 226 "/home/vadve/criswell/llvm/utils/TableGen/FileLexer.l" +#line 226 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" + diff --git a/utils/TableGen/FileLexer.l b/utils/TableGen/FileLexer.l index caed04e2eb9..d0457eaa3d4 100644 --- a/utils/TableGen/FileLexer.l +++ b/utils/TableGen/FileLexer.l @@ -224,3 +224,4 @@ ${Identifier} { Filelval.StrVal = new std::string(yytext+1, yytext+yyleng); . { return Filetext[0]; } %% + diff --git a/utils/TableGen/FileLexer.l.cvs b/utils/TableGen/FileLexer.l.cvs new file mode 100644 index 00000000000..d0457eaa3d4 --- /dev/null +++ b/utils/TableGen/FileLexer.l.cvs @@ -0,0 +1,227 @@ +/*===-- 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 +%option nostdinit +%option never-interactive +%option batch +%option nodefault +%option 8bit +%option outfile="Lexer.cpp" +%option ecs +%option noreject +%option noyymore + +%x comment + +%{ +#include "Record.h" +typedef std::pair*> SubClassRefTy; +#include "FileParser.h" + +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); + return strtol(Str, 0, 0); +} + +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 << "Included from " << IncludeStack[i].Filename << ":" + << IncludeStack[i].LineNo << ":\n"; + return std::cerr << "Parsing " << IncludeStack.back().Filename << ":" + << Filelineno << ": "; +} + +/// 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"; + exit (1); + } + IncludeStack.push_back(IncludeRec(Filename, F)); + } else { + IncludeStack.push_back(IncludeRec("", 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... +/// +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) { + // 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... + 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(void) { + 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; +} + +} // End llvm namespace + +using namespace llvm; + +%} + +Comment \/\/.* + +Identifier [a-zA-Z_][0-9a-zA-Z_]* +Integer [-+]?[0-9]+|0x[0-9a-fA-F]+|0b[01]+ +CodeFragment \[\{([^}]+|\}[^\]])*\}\] +StringVal \"[^"]*\" +IncludeStr include[ \t\n]+\"[^"]*\" + +%% + +{Comment} { /* Ignore comments */ } + +{IncludeStr} { HandleInclude(yytext); } +{CodeFragment} { Filelval.StrVal = new std::string(yytext+2, yytext+yyleng-2); + return CODEFRAGMENT; } + +int { return INT; } +bit { return BIT; } +bits { return BITS; } +string { return STRING; } +list { return LIST; } +code { return CODE; } +dag { return DAG; } + +class { return CLASS; } +def { return DEF; } +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); + return VARNAME; } + +{StringVal} { Filelval.StrVal = new std::string(yytext+1, yytext+yyleng-1); + return STRVAL; } + +{Integer} { Filelval.IntVal = ParseInt(Filetext); return INTVAL; } + +[ \t\n\r]+ { /* Ignore whitespace */ } + + +"/*" { BEGIN(comment); CommentDepth++; } +[^*/]* {} /* eat anything that's not a '*' or '/' */ +"*"+[^*/]* {} /* eat up '*'s not followed by '/'s */ +"/*" { ++CommentDepth; } +"/"+[^*/]* {} /* eat up /'s not followed by *'s */ +"*"+"/" { if (!--CommentDepth) { BEGIN(INITIAL); } } +<> { err() << "Unterminated comment!\n"; exit(1); } + +. { return Filetext[0]; } + +%% +