2016-03-26 14 views
0

Ich habe eine ziemlich einfache Sprache in ANTLR geschrieben. Bevor ich den von einem Benutzer geschriebenen Code tatsächlich interpretiere, möchte ich den Code analysieren und auf Syntaxfehler prüfen. Wenn gefunden, möchte ich die Ursache für den Fehler ausgeben und beenden. Wie kann ich den Code auf Syntaxfehler prüfen und den entsprechenden Fehler ausgeben. Bitte nicht, dass für meine Zwecke die Fehlermeldungen, die denen des ANTLR-Tools ähnlich sind, mehr als ausreichend sind. Zum BeispielWie gehen Sie den Parse-Baum, um nach Syntaxfehlern in ANTLR zu suchen

line 3:0 missing ';' 
+0

Nun, führen Sie einfach die Abfrage durch Sie generiert Parser und erhalten Sie die Fehlermeldung von ihm. –

Antwort

0

Es gibt ErrorListener, die Sie verwenden können, um weitere Informationen zu erhalten.

Zum Beispiel:

... 
FormulaParser parser = new FormulaParser(tokens); 
parser.IsCompletion = options.IsForCompletion; 
ErrorListener errListener = new ErrorListener(); 
parser.AddErrorListener(errListener); 
IParseTree tree = parser.formula(); 

Das Einzige, was Sie tun müssen, ist ErrorListener an den Parser zu befestigen. Hier ist der Code von ErrorListener.

/// <summary> 
    /// Error listener recording all errors that Antlr parser raises during parsing. 
    /// </summary> 
    internal class ErrorListener : BaseErrorListener 
    { 
     private const string Eof = "the end of formula"; 

     public ErrorListener() 
     { 
      ErrorMessages = new List<ErrorInfo>(); 
     } 

     public bool ErrorOccured { get; private set; } 
     public List<ErrorInfo> ErrorMessages { get; private set; } 

     public override void SyntaxError(IRecognizer recognizer, IToken offendingSymbol, int line, int charPositionInLine, string msg, RecognitionException e) 
     { 
      ErrorOccured = true; 

      if (e == null || e.GetType() != typeof(NoViableAltException)) 
      { 
       ErrorMessages.Add(new ErrorInfo() 
       { 
        Message = ConvertMessage(msg), 
        StartIndex = offendingSymbol.StartIndex, 
        Column = offendingSymbol.Column + 1, 
        Line = offendingSymbol.Line, 
        Length = offendingSymbol.Text.Length 
       }); 
       return; 
      } 

      ErrorMessages.Add(new ErrorInfo() 
      { 
       Message = string.Format("{0}{1}", ConvertToken(offendingSymbol.Text), " unexpected"), 
       StartIndex = offendingSymbol.StartIndex, 
       Column = offendingSymbol.Column + 1, 
       Line = offendingSymbol.Line, 
       Length = offendingSymbol.Text.Length 
      }); 
     } 

     public override void ReportAmbiguity(Antlr4.Runtime.Parser recognizer, DFA dfa, int startIndex, int stopIndex, bool exact, BitSet ambigAlts, ATNConfigSet configs) 
     { 
      ErrorOccured = true; 
      ErrorMessages.Add(new ErrorInfo() 
           { 
            Message = "Ambiguity", Column = startIndex, StartIndex = startIndex 
           }); 
      base.ReportAmbiguity(recognizer, dfa, startIndex, stopIndex, exact, ambigAlts, configs); 
     } 

     private string ConvertToken(string token) 
     { 
      return string.Equals(token, "<EOF>", StringComparison.InvariantCultureIgnoreCase) 
       ? Eof 
       : token; 
     } 

     private string ConvertMessage(string message) 
     { 
      StringBuilder builder = new StringBuilder(message); 
      builder.Replace("<EOF>", Eof); 
      return builder.ToString(); 
     } 
    } 

Es ist ein Dummy-Listener, aber Sie können sehen, was es tut. Und Sie können feststellen, ob der Fehler ein Syntaxfehler oder ein Mehrdeutigkeitsfehler ist. Nach dem Parsen können Sie direkt den errorListener fragen, wenn ein Fehler aufgetreten ist.

+0

Können Sie bitte näher erläutern. Ich bin ein Anfänger und es wäre sehr hilfreich, wenn Sie mir ein paar Beispiele geben oder mir zeigen könnten, wo ich anfangen soll. – Ray