TGLexer.cpp revision 56a9fcfd1e19c7adfcc4c948e2f5e471ca8ed241
1a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner//===- TGLexer.cpp - Lexer for TableGen -----------------------------------===//
2a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner//
3a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner//                     The LLVM Compiler Infrastructure
4a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner//
5a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner// This file was developed by Chris Lattner and is distributed under
6a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner// the University of Illinois Open Source License. See LICENSE.TXT for details.
7a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner//
8a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner//===----------------------------------------------------------------------===//
9a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner//
10a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner// Implement the Lexer for TableGen.
11a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner//
12a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner//===----------------------------------------------------------------------===//
13a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
146aaca046d2896d8396314f4b1b6ad7a000034330Chris Lattner#include "TGLexer.h"
15a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner#include "Record.h"
16a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner#include "llvm/Support/Streams.h"
17a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner#include "Record.h"
18a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner#include "llvm/Support/MemoryBuffer.h"
19a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnertypedef std::pair<llvm::Record*, std::vector<llvm::Init*>*> SubClassRefTy;
20a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner#include "FileParser.h"
21a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner#include <cctype>
22a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnerusing namespace llvm;
23a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
24a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner// FIXME: REMOVE THIS.
25a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner#define YYEOF 0
26a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner#define YYERROR -2
27a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
28a8058744229a44e80f90c8530bb7fe47cbab1b70Chris LattnerTGLexer::TGLexer(MemoryBuffer *StartBuf) : CurLineNo(1), CurBuf(StartBuf) {
29a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  CurPtr = CurBuf->getBufferStart();
3056a9fcfd1e19c7adfcc4c948e2f5e471ca8ed241Chris Lattner  TokStart = 0;
31a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner}
32a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
33a8058744229a44e80f90c8530bb7fe47cbab1b70Chris LattnerTGLexer::~TGLexer() {
34a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  while (!IncludeStack.empty()) {
35a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    delete IncludeStack.back().Buffer;
36a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    IncludeStack.pop_back();
37a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  }
38a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  delete CurBuf;
39a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner}
40a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
41c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner/// ReturnError - Set the error to the specified string at the specified
42c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner/// location.  This is defined to always return YYERROR.
43c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattnerint TGLexer::ReturnError(const char *Loc, const std::string &Msg) {
44c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner  PrintError(Loc, Msg);
45c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner  return YYERROR;
46c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner}
47a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
48c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattnerstd::ostream &TGLexer::err() const {
49a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  PrintIncludeStack(*cerr.stream());
50a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  return *cerr.stream();
51a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner}
52a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
53a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
54c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattnervoid TGLexer::PrintIncludeStack(std::ostream &OS) const {
55a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  for (unsigned i = 0, e = IncludeStack.size(); i != e; ++i)
56a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    OS << "Included from " << IncludeStack[i].Buffer->getBufferIdentifier()
57a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner       << ":" << IncludeStack[i].LineNo << ":\n";
58a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  OS << "Parsing " << CurBuf->getBufferIdentifier() << ":"
59a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner     << CurLineNo << ": ";
60a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner}
61a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
62c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner/// PrintError - Print the error at the specified location.
63c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattnervoid TGLexer::PrintError(const char *ErrorLoc,  const std::string &Msg) const {
64c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner  err() << Msg << "\n";
65c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner  assert(ErrorLoc && "Location not specified!");
66c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner
67c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner  // Scan backward to find the start of the line.
68c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner  const char *LineStart = ErrorLoc;
69c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner  while (LineStart != CurBuf->getBufferStart() &&
70c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner         LineStart[-1] != '\n' && LineStart[-1] != '\r')
71c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner    --LineStart;
72c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner  // Get the end of the line.
73c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner  const char *LineEnd = ErrorLoc;
74c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner  while (LineEnd != CurBuf->getBufferEnd() &&
75c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner         LineEnd[0] != '\n' && LineEnd[0] != '\r')
76c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner    ++LineEnd;
77c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner  // Print out the line.
78c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner  cerr << std::string(LineStart, LineEnd) << "\n";
79c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner  // Print out spaces before the carat.
8056a9fcfd1e19c7adfcc4c948e2f5e471ca8ed241Chris Lattner  for (const char *Pos = LineStart; Pos != ErrorLoc; ++Pos)
81c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner    cerr << (*Pos == '\t' ? '\t' : ' ');
82c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner  cerr << "^\n";
83c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner}
84c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner
85a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnerint TGLexer::getNextChar() {
86a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  char CurChar = *CurPtr++;
87a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  switch (CurChar) {
88a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  default:
89c1819188b6c971b91c680a9a3c077b84a110e5fdChris Lattner    return (unsigned char)CurChar;
90a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  case 0:
91a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    // A nul character in the stream is either the end of the current buffer or
92a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    // a random nul in the file.  Disambiguate that here.
93a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    if (CurPtr-1 != CurBuf->getBufferEnd())
94a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      return 0;  // Just whitespace.
95a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
96a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    // If this is the end of an included file, pop the parent file off the
97a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    // include stack.
98a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    if (!IncludeStack.empty()) {
99a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      delete CurBuf;
100a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      CurBuf = IncludeStack.back().Buffer;
101a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      CurLineNo = IncludeStack.back().LineNo;
102a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      CurPtr = IncludeStack.back().CurPtr;
103a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      IncludeStack.pop_back();
104a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      return getNextChar();
105a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    }
106a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
107a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    // Otherwise, return end of file.
108a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    --CurPtr;  // Another call to lex will return EOF again.
109a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    return EOF;
110a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  case '\n':
111a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  case '\r':
112a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    // Handle the newline character by ignoring it and incrementing the line
113a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    // count.  However, be careful about 'dos style' files with \n\r in them.
114a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    // Only treat a \n\r or \r\n as a single line.
115a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    if ((*CurPtr == '\n' || (*CurPtr == '\r')) &&
116a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner        *CurPtr != CurChar)
117c1819188b6c971b91c680a9a3c077b84a110e5fdChris Lattner      ++CurPtr;  // Eat the two char newline sequence.
118a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
119a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    ++CurLineNo;
120a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    return '\n';
121a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  }
122a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner}
123a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
124a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnerint TGLexer::LexToken() {
12556a9fcfd1e19c7adfcc4c948e2f5e471ca8ed241Chris Lattner  TokStart = CurPtr;
126a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  // This always consumes at least one character.
127a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  int CurChar = getNextChar();
128a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
129a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  switch (CurChar) {
130a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  default:
131a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    // Handle letters: [a-zA-Z_]
132a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    if (isalpha(CurChar) || CurChar == '_')
133a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      return LexIdentifier();
134a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
135a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    // Unknown character, return the char itself.
136a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    return (unsigned char)CurChar;
137a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  case EOF: return YYEOF;
138a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  case 0:
139a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  case ' ':
140a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  case '\t':
141a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  case '\n':
142a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  case '\r':
143a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    // Ignore whitespace.
144a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    return LexToken();
145a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  case '/':
146a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    // If this is the start of a // comment, skip until the end of the line or
147a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    // the end of the buffer.
148a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    if (*CurPtr == '/')
149a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      SkipBCPLComment();
150a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    else if (*CurPtr == '*') {
151a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      if (SkipCComment())
152a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner        return YYERROR;
153a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    } else // Otherwise, return this / as a token.
154a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      return CurChar;
155a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    return LexToken();
156a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  case '-': case '+':
157a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  case '0': case '1': case '2': case '3': case '4': case '5': case '6':
158a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  case '7': case '8': case '9':
159a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    return LexNumber();
160a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  case '"': return LexString();
161a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  case '$': return LexVarName();
162a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  case '[': return LexBracket();
163a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  case '!': return LexExclaim();
164a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  }
165a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner}
166a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
167a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// LexString - Lex "[^"]*"
168a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnerint TGLexer::LexString() {
169a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  const char *StrStart = CurPtr;
170a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
171a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  while (*CurPtr != '"') {
172a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    // If we hit the end of the buffer, report an error.
173c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner    if (*CurPtr == 0 && CurPtr == CurBuf->getBufferEnd())
174c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner      return ReturnError(StrStart, "End of file in string literal");
175c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner
176c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner    if (*CurPtr == '\n' || *CurPtr == '\r')
177c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner      return ReturnError(StrStart, "End of line in string literal");
178a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
179a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    ++CurPtr;
180a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  }
181a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
182a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  Filelval.StrVal = new std::string(StrStart, CurPtr);
183a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  ++CurPtr;
184a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  return STRVAL;
185a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner}
186a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
187a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnerint TGLexer::LexVarName() {
188a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  if (!isalpha(CurPtr[0]) && CurPtr[0] != '_')
189a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    return '$'; // Invalid varname.
190a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
191a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  // Otherwise, we're ok, consume the rest of the characters.
192a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  const char *VarNameStart = CurPtr++;
193a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
194a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr == '_')
195a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    ++CurPtr;
196a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
197a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  Filelval.StrVal = new std::string(VarNameStart, CurPtr);
198a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  return VARNAME;
199a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner}
200a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
201a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
202a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnerint TGLexer::LexIdentifier() {
203a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  // The first letter is [a-zA-Z_].
204a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  const char *IdentStart = CurPtr-1;
205a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
206a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  // Match the rest of the identifier regex: [0-9a-zA-Z_]*
207a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr == '_')
208a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    ++CurPtr;
209a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
210a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  // Check to see if this identifier is a keyword.
211a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  unsigned Len = CurPtr-IdentStart;
212a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
213a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  if (Len == 3 && !memcmp(IdentStart, "int", 3)) return INT;
214a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  if (Len == 3 && !memcmp(IdentStart, "bit", 3)) return BIT;
215a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  if (Len == 4 && !memcmp(IdentStart, "bits", 4)) return BITS;
216a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  if (Len == 6 && !memcmp(IdentStart, "string", 6)) return STRING;
217a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  if (Len == 4 && !memcmp(IdentStart, "list", 4)) return LIST;
218a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  if (Len == 4 && !memcmp(IdentStart, "code", 4)) return CODE;
219a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  if (Len == 3 && !memcmp(IdentStart, "dag", 3)) return DAG;
220a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
221a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  if (Len == 5 && !memcmp(IdentStart, "class", 5)) return CLASS;
222a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  if (Len == 3 && !memcmp(IdentStart, "def", 3)) return DEF;
223a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  if (Len == 4 && !memcmp(IdentStart, "defm", 4)) return DEFM;
224a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  if (Len == 10 && !memcmp(IdentStart, "multiclass", 10)) return MULTICLASS;
225a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  if (Len == 5 && !memcmp(IdentStart, "field", 5)) return FIELD;
226a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  if (Len == 3 && !memcmp(IdentStart, "let", 3)) return LET;
227a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  if (Len == 2 && !memcmp(IdentStart, "in", 2)) return IN;
228a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
229a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  if (Len == 7 && !memcmp(IdentStart, "include", 7)) {
230a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    if (LexInclude()) return YYERROR;
231a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    return LexToken();
232a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  }
233a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
234a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  Filelval.StrVal = new std::string(IdentStart, CurPtr);
235a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  return ID;
236a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner}
237a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
238a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// LexInclude - We just read the "include" token.  Get the string token that
239a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// comes next and enter the include.
240a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnerbool TGLexer::LexInclude() {
241a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  // The token after the include must be a string.
242a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  int Tok = LexToken();
243a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  if (Tok == YYERROR) return true;
244a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  if (Tok != STRVAL) {
24556a9fcfd1e19c7adfcc4c948e2f5e471ca8ed241Chris Lattner    PrintError(getTokenStart(), "Expected filename after include");
246a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    return true;
247a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  }
248a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
249a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  // Get the string.
250a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  std::string Filename = *Filelval.StrVal;
251a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  delete Filelval.StrVal;
252a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
253a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  // Try to find the file.
254a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  MemoryBuffer *NewBuf = MemoryBuffer::getFile(&Filename[0], Filename.size());
255a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
256a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  // If the file didn't exist directly, see if it's in an include path.
257a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  for (unsigned i = 0, e = IncludeDirectories.size(); i != e && !NewBuf; ++i) {
258a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    std::string IncFile = IncludeDirectories[i] + "/" + Filename;
259a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    NewBuf = MemoryBuffer::getFile(&IncFile[0], IncFile.size());
260a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  }
261a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
262a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  if (NewBuf == 0) {
26356a9fcfd1e19c7adfcc4c948e2f5e471ca8ed241Chris Lattner    PrintError(getTokenStart(),
26456a9fcfd1e19c7adfcc4c948e2f5e471ca8ed241Chris Lattner               "Could not find include file '" + Filename + "'");
265a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    return true;
266a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  }
267a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
268a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  // Save the line number and lex buffer of the includer.
269a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  IncludeStack.push_back(IncludeRec(CurBuf, CurPtr, CurLineNo));
270a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
271a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  CurLineNo = 1;  // Reset line numbering.
272a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  CurBuf = NewBuf;
273a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  CurPtr = CurBuf->getBufferStart();
274a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  return false;
275a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner}
276a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
277a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnervoid TGLexer::SkipBCPLComment() {
278a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  ++CurPtr;  // skip the second slash.
279a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  while (1) {
280a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    switch (*CurPtr) {
281a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    case '\n':
282a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    case '\r':
283a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      return;  // Newline is end of comment.
284a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    case 0:
285a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      // If this is the end of the buffer, end the comment.
286a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      if (CurPtr == CurBuf->getBufferEnd())
287a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner        return;
288a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      break;
289a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    }
290a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    // Otherwise, skip the character.
291a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    ++CurPtr;
292a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  }
293a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner}
294a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
295a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// SkipCComment - This skips C-style /**/ comments.  The only difference from C
296a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// is that we allow nesting.
297a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnerbool TGLexer::SkipCComment() {
298c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner  const char *CommentStart = CurPtr-1;
299a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  ++CurPtr;  // skip the star.
300a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  unsigned CommentDepth = 1;
301a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
302a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  while (1) {
303a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    int CurChar = getNextChar();
304a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    switch (CurChar) {
305a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    case EOF:
306c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner      PrintError(CommentStart, "Unterminated comment!");
307a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      return true;
308a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    case '*':
309a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      // End of the comment?
310a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      if (CurPtr[0] != '/') break;
311a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
312a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      ++CurPtr;   // End the */.
313a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      if (--CommentDepth == 0)
314a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner        return false;
315a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      break;
316a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    case '/':
317a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      // Start of a nested comment?
318a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      if (CurPtr[0] != '*') break;
319a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      ++CurPtr;
320a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      ++CommentDepth;
321a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      break;
322a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    }
323a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  }
324a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner}
325a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
326a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// LexNumber - Lex:
327a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner///    [-+]?[0-9]+
328a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner///    0x[0-9a-fA-F]+
329a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner///    0b[01]+
330a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnerint TGLexer::LexNumber() {
331a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  const char *NumStart = CurPtr-1;
332a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
333a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  if (CurPtr[-1] == '0') {
334a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    if (CurPtr[0] == 'x') {
335a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      ++CurPtr;
336a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      NumStart = CurPtr;
337a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      while (isxdigit(CurPtr[0]))
338a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner        ++CurPtr;
339a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
340c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner      // Requires at least one hex digit.
341c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner      if (CurPtr == NumStart)
342c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner        return ReturnError(CurPtr-2, "Invalid hexadecimal number");
343c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner
344a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      Filelval.IntVal = strtoll(NumStart, 0, 16);
345a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      return INTVAL;
346a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    } else if (CurPtr[0] == 'b') {
347a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      ++CurPtr;
348a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      NumStart = CurPtr;
349a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      while (CurPtr[0] == '0' || CurPtr[0] == '1')
350a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner        ++CurPtr;
351c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner
352c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner      // Requires at least one binary digit.
353c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner      if (CurPtr == NumStart)
354c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner        return ReturnError(CurPtr-2, "Invalid binary number");
355a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      Filelval.IntVal = strtoll(NumStart, 0, 2);
356a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      return INTVAL;
357a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    }
358a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  }
359a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
360a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  // Check for a sign without a digit.
361a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  if (CurPtr[-1] == '-' || CurPtr[-1] == '+') {
362a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    if (!isdigit(CurPtr[0]))
363a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      return CurPtr[-1];
364a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  }
365a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
366a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  while (isdigit(CurPtr[0]))
367a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    ++CurPtr;
368a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  Filelval.IntVal = strtoll(NumStart, 0, 10);
369a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  return INTVAL;
370a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner}
371a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
372a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// LexBracket - We just read '['.  If this is a code block, return it,
373a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// otherwise return the bracket.  Match: '[' and '[{ ( [^}]+ | }[^]] )* }]'
374a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnerint TGLexer::LexBracket() {
375a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  if (CurPtr[0] != '{')
376a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    return '[';
377a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  ++CurPtr;
378a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  const char *CodeStart = CurPtr;
379a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  while (1) {
380a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    int Char = getNextChar();
381a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    if (Char == EOF) break;
382a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
383a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    if (Char != '}') continue;
384a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
385a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    Char = getNextChar();
386a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    if (Char == EOF) break;
387a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    if (Char == ']') {
388a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      Filelval.StrVal = new std::string(CodeStart, CurPtr-2);
389a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner      return CODEFRAGMENT;
390a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    }
391a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  }
392a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
393c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner  return ReturnError(CodeStart-2, "Unterminated Code Block");
394a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner}
395a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
396a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// LexExclaim - Lex '!' and '![a-zA-Z]+'.
397a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnerint TGLexer::LexExclaim() {
398a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  if (!isalpha(*CurPtr))
399a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    return '!';
400a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
401a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  const char *Start = CurPtr++;
402a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  while (isalpha(*CurPtr))
403a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    ++CurPtr;
404a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
405a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  // Check to see which operator this is.
406a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  unsigned Len = CurPtr-Start;
407a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
408a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  if (Len == 3 && !memcmp(Start, "con", 3)) return CONCATTOK;
409a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  if (Len == 3 && !memcmp(Start, "sra", 3)) return SRATOK;
410a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  if (Len == 3 && !memcmp(Start, "srl", 3)) return SRLTOK;
411a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  if (Len == 3 && !memcmp(Start, "shl", 3)) return SHLTOK;
412a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  if (Len == 9 && !memcmp(Start, "strconcat", 9)) return STRCONCATTOK;
413a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
414c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner  return ReturnError(Start-1, "Unknown operator");
415a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner}
416a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
417a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner//===----------------------------------------------------------------------===//
418a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner//  Interfaces used by the Bison parser.
419a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner//===----------------------------------------------------------------------===//
420a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
421a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnerint Fileparse();
422a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnerstatic TGLexer *TheLexer;
423a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
424a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnernamespace llvm {
425a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
426a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnerstd::ostream &err() {
427a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  return TheLexer->err();
428a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner}
429a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
430a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// ParseFile - this function begins the parsing of the specified tablegen
431a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// file.
432a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner///
433a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnervoid ParseFile(const std::string &Filename,
434a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner               const std::vector<std::string> &IncludeDirs) {
435a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  std::string ErrorStr;
436a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  MemoryBuffer *F = MemoryBuffer::getFileOrSTDIN(&Filename[0], Filename.size(),
437a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner                                                 &ErrorStr);
438a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  if (F == 0) {
439a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    cerr << "Could not open input file '" + Filename + "': " << ErrorStr <<"\n";
440a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    exit(1);
441a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  }
442a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
443a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  assert(!TheLexer && "Lexer isn't reentrant yet!");
444a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  TheLexer = new TGLexer(F);
445a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
446a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  // Record the location of the include directory so that the lexer can find
447a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  // it later.
448a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  TheLexer->setIncludeDirs(IncludeDirs);
449a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
450a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  Fileparse();
451a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
452a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  // Cleanup
453a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  delete TheLexer;
454a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  TheLexer = 0;
455a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner}
456a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} // End llvm namespace
457a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
458a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner
459a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnerint Filelex() {
460a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  assert(TheLexer && "No lexer setup yet!");
461a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  int Tok = TheLexer->LexToken();
462c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner  if (Tok == YYERROR)
463a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner    exit(1);
464a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner  return Tok;
465a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner}
466