2013-10-10 1 views
1

J'ai posé une question il y a quelques semaines à propos de ma grammaire ANTLR (My simple ANTLR grammar is not working as expected). Depuis que j'ai posé cette question, j'ai creusé et débogué davantage et j'ai éliminé la plupart des problèmes. Je reste avec un problème, cependant.Ma simple grammaire ANTLR ignore certains jetons invalides lors de l'analyse

Mon code d'analyse généré ne récupère pas les jetons non valides dans une partie du texte traitée. Le lexer brise correctement les objets en jetons, mais l'analyseur ne supprime pas les jetons invalides dans certains cas. En particulier, lorsque le jeton invalide est à la fin d'une phrase comme « A et « B », l'analyseur ne tient pas compte - c'est comme le jeton est même pas là

Quelques exemples spécifiques:

.
  • "A et B" - parfaitement valable
  • "A @ et B" - analyseur capte correctement le jeton invalide @
  • "A et @B" - analyseur capte correctement le jeton invalide @
  • "A et B @" - voici le mystère - t il lexer trouve le jeton @ et l'analyseur IGNORE il
  • "(A et B @) ou C" (!) - plus mystère - (!) le lexer trouve le jeton @ et l'analyseur IGNORE il

Voici ma grammaire:

grammar QvidianPlaybooks; 
options{ language=CSharp3; output=AST; ASTLabelType = CommonTree; } 

public parse 
    : expression 
    ; 

LPAREN : '(' ; 
RPAREN : ')' ; 
ANDOR : 'AND'|'and'|'OR'|'or'; 
NAME : ('A'..'Z'); 
WS : ' ' { $channel = Hidden; }; 
THEREST : .; 

// ***************** parser rules: 
expression : anexpression EOF!; 
anexpression : atom (ANDOR^ atom)*; 
atom : NAME | LPAREN! anexpression RPAREN!; 

le code qui traite ensuite l'arbre résultant ressemble à ceci:

... from the main program 
QvidianPlaybooksLexer lexer = new QvidianPlaybooksLexer(new ANTLRStringStream(src)); 
QvidianPlaybooksParser parser = new QvidianPlaybooksParser(new CommonTokenStream(lexer)); 
parser.TreeAdaptor = new CommonTreeAdaptor(); 

CommonTree tree = (CommonTree)parser.parse().Tree; 
ValidateTree(tree, 0, iValidIdentifierCount); 

// recursive code that walks the tree 
public static RuleLogicValidationResult ValidateTree(ITree Tree, int depth, int conditionCount) 
{ 
    RuleLogicValidationResult rlvr = null; 

    if (Tree != null) 
    { 
     CommonErrorNode commonErrorNode = Tree as CommonErrorNode; 
     if (null != commonErrorNode) 
     { 
      rlvr = new RuleLogicValidationResult(); 
      rlvr.IsValid = false; 
      rlvr.ErrorType = LogicValidationErrorType.Other; 
      Console.WriteLine(rlvr.ToString()); 
     } 
     else 
     { 
      string strTree = Tree.ToString(); 
      strTree = strTree.Trim(); 
      strTree = strTree.ToUpper(); 
      if ((Tree.ChildCount != 0) && (Tree.ChildCount != 2)) 
      { 
       rlvr = new RuleLogicValidationResult(); 
       rlvr.IsValid = false; 
       rlvr.ErrorType = LogicValidationErrorType.Other; 
       rlvr.InvalidIdentifier = strTree; 
       rlvr.ErrorPosition = 0; 
       Console.WriteLine(String.Format("CHILD COUNT of {0} = {1}", strTree, tree.ChildCount)); 
      } 
      // if the current node is valid, then validate the two child nodes 
      if (null == rlvr || rlvr.IsValid) 
      { 
       // output the tree node 
       for (int i = 0; i < depth; i++) 
       { 
        Console.Write(" "); 
       } 
       Console.WriteLine(Tree); 
       rlvr = ValidateTree(Tree.GetChild(0), depth + 1, conditionCount); 
       if (rlvr.IsValid) 
       { 
        rlvr = ValidateTree(Tree.GetChild(1), depth + 1, conditionCount); 
       } 
      } 
      else 
      { 
       Console.WriteLine(rlvr.ToString()); 
      } 
     } 
    } 
    else 
    { 
     // this tree is null, return a "it's valid" result 
     rlvr = new RuleLogicValidationResult(); 
     rlvr.ErrorType = LogicValidationErrorType.None; 
     rlvr.IsValid = true; 
    } 

    return rlvr; 
} 

Répondre

1

Ajouter EOF à la fin de votre règle de départ. :)

+0

Je ne pense pas que EOF va le faire - et - mes exemples n'étaient pas complets. Comme vous pouvez le voir maintenant, "(A et B @) ou C" entraîne également l'ignorance de "@". – user1193

+0

Aussi, n'ai-je pas déjà une EOF à la fin de ma règle de départ? – user1193

+0

oh. j'ai vu ceci: analyser : expression ; Hmm ... je ne suis pas sûr d'une enquête plus approfondie. pas le temps. –