[llvm-commits] [llvm] r44226 - in /llvm/trunk/utils/TableGen: TGLexer.cpp TGLexer.h

Chris Lattner sabre at nondot.org
Sun Nov 18 23:38:58 PST 2007


Author: lattner
Date: Mon Nov 19 01:38:58 2007
New Revision: 44226

URL: http://llvm.org/viewvc/llvm-project?rev=44226&view=rev
Log:
Add carat diagnostics to tblgen lexer errors.

Modified:
    llvm/trunk/utils/TableGen/TGLexer.cpp
    llvm/trunk/utils/TableGen/TGLexer.h

Modified: llvm/trunk/utils/TableGen/TGLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGLexer.cpp?rev=44226&r1=44225&r2=44226&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/TGLexer.cpp (original)
+++ llvm/trunk/utils/TableGen/TGLexer.cpp Mon Nov 19 01:38:58 2007
@@ -37,14 +37,20 @@
   delete CurBuf;
 }
 
+/// ReturnError - Set the error to the specified string at the specified
+/// location.  This is defined to always return YYERROR.
+int TGLexer::ReturnError(const char *Loc, const std::string &Msg) {
+  PrintError(Loc, Msg);
+  return YYERROR;
+}
 
-std::ostream &TGLexer::err() {
+std::ostream &TGLexer::err() const {
   PrintIncludeStack(*cerr.stream());
   return *cerr.stream();
 }
 
 
-void TGLexer::PrintIncludeStack(std::ostream &OS) {
+void TGLexer::PrintIncludeStack(std::ostream &OS) const {
   for (unsigned i = 0, e = IncludeStack.size(); i != e; ++i)
     OS << "Included from " << IncludeStack[i].Buffer->getBufferIdentifier()
        << ":" << IncludeStack[i].LineNo << ":\n";
@@ -52,6 +58,30 @@
      << CurLineNo << ": ";
 }
 
+/// PrintError - Print the error at the specified location.
+void TGLexer::PrintError(const char *ErrorLoc,  const std::string &Msg) const {
+  err() << Msg << "\n";
+  assert(ErrorLoc && "Location not specified!");
+  
+  // Scan backward to find the start of the line.
+  const char *LineStart = ErrorLoc;
+  while (LineStart != CurBuf->getBufferStart() && 
+         LineStart[-1] != '\n' && LineStart[-1] != '\r')
+    --LineStart;
+  // Get the end of the line.
+  const char *LineEnd = ErrorLoc;
+  while (LineEnd != CurBuf->getBufferEnd() && 
+         LineEnd[0] != '\n' && LineEnd[0] != '\r')
+    ++LineEnd;
+  // Print out the line.
+  cerr << std::string(LineStart, LineEnd) << "\n";
+  // Print out spaces before the carat.
+  const char *Pos = LineStart;
+  while (Pos != ErrorLoc)
+    cerr << (*Pos == '\t' ? '\t' : ' ');
+  cerr << "^\n";
+}
+
 int TGLexer::getNextChar() {
   char CurChar = *CurPtr++;
   switch (CurChar) {
@@ -139,13 +169,11 @@
   
   while (*CurPtr != '"') {
     // If we hit the end of the buffer, report an error.
-    if (*CurPtr == 0 && CurPtr == CurBuf->getBufferEnd()) {
-      TheError = "End of file in string literal";
-      return YYERROR;
-    } else if (*CurPtr == '\n' || *CurPtr == '\r') {
-      TheError = "End of line in string literal";
-      return YYERROR;
-    }
+    if (*CurPtr == 0 && CurPtr == CurBuf->getBufferEnd())
+      return ReturnError(StrStart, "End of file in string literal");
+    
+    if (*CurPtr == '\n' || *CurPtr == '\r')
+      return ReturnError(StrStart, "End of line in string literal");
     
     ++CurPtr;
   }
@@ -210,10 +238,11 @@
 /// comes next and enter the include.
 bool TGLexer::LexInclude() {
   // The token after the include must be a string.
+  const char *TokStart = CurPtr-7;
   int Tok = LexToken();
   if (Tok == YYERROR) return true;
   if (Tok != STRVAL) {
-    TheError = "Expected filename after include";
+    PrintError(TokStart, "Expected filename after include");
     return true;
   }
 
@@ -231,7 +260,7 @@
   }
     
   if (NewBuf == 0) {
-    TheError = "Could not find include file '" + Filename + "'";
+    PrintError(TokStart, "Could not find include file '" + Filename + "'");
     return true;
   }
   
@@ -265,6 +294,7 @@
 /// SkipCComment - This skips C-style /**/ comments.  The only difference from C
 /// is that we allow nesting.
 bool TGLexer::SkipCComment() {
+  const char *CommentStart = CurPtr-1;
   ++CurPtr;  // skip the star.
   unsigned CommentDepth = 1;
   
@@ -272,7 +302,7 @@
     int CurChar = getNextChar();
     switch (CurChar) {
     case EOF:
-      TheError = "Unterminated comment!";
+      PrintError(CommentStart, "Unterminated comment!");
       return true;
     case '*':
       // End of the comment?
@@ -306,10 +336,10 @@
       while (isxdigit(CurPtr[0]))
         ++CurPtr;
       
-      if (CurPtr == NumStart) {
-        TheError = "Invalid hexadecimal number";
-        return YYERROR;
-      }
+      // Requires at least one hex digit.
+      if (CurPtr == NumStart)
+        return ReturnError(CurPtr-2, "Invalid hexadecimal number");
+
       Filelval.IntVal = strtoll(NumStart, 0, 16);
       return INTVAL;
     } else if (CurPtr[0] == 'b') {
@@ -317,11 +347,10 @@
       NumStart = CurPtr;
       while (CurPtr[0] == '0' || CurPtr[0] == '1')
         ++CurPtr;
-      
-      if (CurPtr == NumStart) {
-        TheError = "Invalid binary number";
-        return YYERROR;
-      }
+
+      // Requires at least one binary digit.
+      if (CurPtr == NumStart)
+        return ReturnError(CurPtr-2, "Invalid binary number");
       Filelval.IntVal = strtoll(NumStart, 0, 2);
       return INTVAL;
     }
@@ -360,8 +389,7 @@
     }
   }
   
-  TheError = "Invalid Code Block";
-  return YYERROR;
+  return ReturnError(CodeStart-2, "Unterminated Code Block");
 }
 
 /// LexExclaim - Lex '!' and '![a-zA-Z]+'.
@@ -382,8 +410,7 @@
   if (Len == 3 && !memcmp(Start, "shl", 3)) return SHLTOK;
   if (Len == 9 && !memcmp(Start, "strconcat", 9)) return STRCONCATTOK;
   
-  TheError = "Unknown operator";
-  return YYERROR;
+  return ReturnError(Start-1, "Unknown operator");
 }
 
 //===----------------------------------------------------------------------===//
@@ -431,9 +458,7 @@
 int Filelex() {
   assert(TheLexer && "No lexer setup yet!");
   int Tok = TheLexer->LexToken();
-  if (Tok == YYERROR) {
-    err() << TheLexer->getError() << "\n";
+  if (Tok == YYERROR)
     exit(1);
-  }
   return Tok;
 }

Modified: llvm/trunk/utils/TableGen/TGLexer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGLexer.h?rev=44226&r1=44225&r2=44226&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/TGLexer.h (original)
+++ llvm/trunk/utils/TableGen/TGLexer.h Mon Nov 19 01:38:58 2007
@@ -40,8 +40,6 @@
   // IncludeDirectories - This is the list of directories we should search for
   // include files in.
   std::vector<std::string> IncludeDirectories;
-  
-  std::string TheError;
 public:
   TGLexer(MemoryBuffer *StartBuf);
   ~TGLexer();
@@ -52,11 +50,14 @@
   
   int LexToken();
 
-  const std::string getError() const { return TheError; }
+  void PrintError(const char *Loc, const std::string &Msg) const;
+  
+  std::ostream &err() const;
+  void PrintIncludeStack(std::ostream &OS) const;
   
-  std::ostream &err();
-  void PrintIncludeStack(std::ostream &OS);
 private:
+  int ReturnError(const char *Loc, const std::string &Msg);
+  
   int getNextChar();
   void SkipBCPLComment();
   bool SkipCComment();





More information about the llvm-commits mailing list