1
幾周前我問了一個關於我的ANTLR語法的問題(My simple ANTLR grammar is not working as expected)。自從提出這個問題以來,我已經做了更多的挖掘和調試,並且獲得了大部分的結果。不過,我留下了一個問題。我的簡單ANTLR語法在解析時忽略了某些無效標記
我生成的解析器代碼沒有在處理的文本的特定部分中拾取無效令牌。詞法分析器正確地將事物分解爲令牌,但在某些情況下解析器不會排除無效令牌。 特別是,當無效令牌是在像「A和‘B’一語結束,解析器會忽略它 - 就像令牌甚至不存在
一些具體的例子:
。- 「A和B」 - 完全有效的
- 「@和B」 - 解析正確拿起無效@令牌
- 「A和@B」 - 解析正確拿起無效@令牌
- 「A和B @」 - 這是神祕 - t他詞法分析器發現@令牌和分析器忽略它
- 「(A和B @)或C」(!) - 進一步謎 - (!)詞法分析器找到@令牌和分析器忽略它
這裏是我的語法:
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!;
是再處理得到的樹看起來像這樣的代碼:
... 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;
}
我不認爲EOF會這樣做 - 而且 - 我的例子並不完整。正如您現在所看到的,「(A和B @)或C」也會導致忽略「@」。 – user1193
另外,我的啓動規則結束時是否已經有EOF? – user1193
哦。我看到這個:解析 :表達式 ;嗯......不確定沒有深入調查。沒時間。 –