Antlr 为什么我的树语法模棱两可?

Antlr 为什么我的树语法模棱两可?,antlr,antlrworks,Antlr,Antlrworks,我有点困惑。我的语法很好用,而且和我的语言完全匹配。最近,我在语法中添加了一些规则,在将新语法规则转换为树语法的过程中,我发现了一些奇怪的错误。我遇到的第一个错误是树语法不明确 我收到的错误是: [10:53:16] warning(200): ShiroDefinitionPass.g:129:17: Decision can match input such as "'subjunctive node'" using multiple alternatives: 5, 6 As a re

我有点困惑。我的语法很好用,而且和我的语言完全匹配。最近,我在语法中添加了一些规则,在将新语法规则转换为树语法的过程中,我发现了一些奇怪的错误。我遇到的第一个错误是树语法不明确

我收到的错误是:

[10:53:16] warning(200): ShiroDefinitionPass.g:129:17: 
Decision can match input such as "'subjunctive node'" using multiple alternatives: 5, 6

As a result, alternative(s) 6 were disabled for that input
[10:53:16] warning(200): ShiroDefinitionPass.g:129:17: 
Decision can match input such as "PORT_ASSIGNMENT" using multiple alternatives: 2, 6
还有大约10个类似的错误

我说不出为什么树语法是模棱两可的。在我添加sNode、subsunctdeclnodeprod、subsunctdecl和subsunctdeclector规则之前,一切都很好

我的语法是:

grammar Shiro;

options{
    language = Java;
    ASTLabelType=CommonTree;
    output=AST;
}

tokens{
    NEGATION;
    STATE_DECL;
    PORT_DECL;
    PORT_INIT;
    PORT_ASSIGNMENT;
    PORT_TAG;
    PATH;
    PORT_INDEX;
    EVAL_SELECT;
    SUBJ_SELECT;
    SUBJ_NODE_PROD;
    ACTIVATION;
    ACTIVATION_LIST;
    PRODUCES;
}

shiro   :   statement+
    ;   

statement
    :   nodestmt
    |   sNode 
    |   graphDecl
    |   statestmt
    |   collection
    |   view
    |   NEWLINE!
    ;

view    :   'view' IDENT mfName IDENT -> ^('view' IDENT mfName IDENT)
    ;

collection
    :   'collection' IDENT orderingFunc path 'begin' NEWLINE
            (collItem)+ NEWLINE?
        'end'
        -> ^('collection' IDENT orderingFunc path collItem+)
    ;

collItem:   IDENT -> IDENT
    ;

orderingFunc
    :   IDENT -> IDENT
    ;

statestmt
    :   'state' stateName 'begin' NEWLINE
        stateHeader
        'end' -> ^(STATE_DECL stateName stateHeader)
    ;

stateHeader
    :   (stateTimeStmt | stateCommentStmt | stateParentStmt | stateGraphStmt | activationPath | NEWLINE!)+  
    ;

stateTimeStmt
    :   'Time' time -> ^('Time' time)
    ;

stateCommentStmt
    :   'Comment' comment -> ^('Comment' comment)   
    ;

stateParentStmt
    :   'Parent' stateParent -> ^('Parent' stateParent)
    ;

stateGraphStmt
    :   'Graph' stateGraph -> ^('Graph' stateGraph)
    ;

stateName
    :   IDENT
    ;

time    :   STRING_LITERAL  
    ;

comment :   STRING_LITERAL
    ;

stateParent
    :   IDENT
    ;

stateGraph
    :   IDENT
    ;

activationPath
    :   l=activation ('.'^ (r=activation | activationList))*
    ;

activationList
    :   '<' activation (',' activation)* '>' -> ^(ACTIVATION_LIST activation+)
    ;

activation
    :   c=IDENT ('[' v=IDENT ']')? -> ^(ACTIVATION $c ($v)?)
    ;

graphDecl
    :   'graph' IDENT 'begin' NEWLINE
        graphLine+
        'end'
        -> ^('graph' IDENT graphLine+)
    ;

graphLine
    :   nodeProduction | portAssignment | NEWLINE!
    ;

nodeInternal
    :   (nodeProduction 
        | portAssignment 
        | portstmt 
        | nodestmt 
        | sNode 
        | NEWLINE!)+
    ;

nodestmt 
    :   'node'^ IDENT ('['! activeSelector ']'!)? 'begin'! NEWLINE!
        nodeInternal
        'end'!
    ;

sNode
:   'subjunctive node'^ IDENT '['! subjunctSelector ']'! 'begin'! NEWLINE!
        (subjunctDeclNodeProd | subjunctDecl | NEWLINE!)+
        'end'!
    ;

subjunctDeclNodeProd
    :   l=IDENT '->' r=IDENT 'begin' NEWLINE
        nodeInternal
        'end' -> ^(SUBJ_NODE_PROD $l $r nodeInternal )
    ;

subjunctDecl
    :   'subjunct'^ IDENT ('['! activeSelector ']'!)? 'begin'! NEWLINE!
        nodeInternal
        'end'!
    ;

subjunctSelector
    :   IDENT -> ^(SUBJ_SELECT IDENT)
    ;

activeSelector  
    :   IDENT -> ^(EVAL_SELECT IDENT)
    ;

nodeProduction
    :   path ('->'^ activationPath )+ NEWLINE!
    ;

portAssignment
    :   path '(' mfparams ')' NEWLINE -> ^(PORT_ASSIGNMENT path mfparams)
    ;   

portDecl
    :   portType portName mfName -> ^(PORT_DECL ^(PORT_TAG portType) portName mfName)
    ;

portDeclInit
    :   portType portName mfCall -> ^(PORT_INIT ^(PORT_TAG portType) portName mfCall)
    ;

portstmt    
    :   (portDecl | portDeclInit ) NEWLINE!
    ;   

portName 
    :   IDENT
    ;

portType:   'port'
    |   'eval'
    ;

mfCall  :   mfName '(' mfparams ')' -> ^(mfName mfparams)
    ;

mfName  :   IDENT
    ;

mfparams:   expression(',' expression)* -> expression+
    ;

// Path
path    :   (IDENT)('.' IDENT)*('[' pathIndex ']')? -> ^(PATH IDENT+ pathIndex?)
    ;

pathIndex
    :   portIndex -> ^(PORT_INDEX portIndex)
    ;

portIndex
    :   ( NUMBER |STRING_LITERAL )
    ;

// Expressions
term    :   path
    |   '(' expression ')' -> expression
    |   NUMBER
    |   STRING_LITERAL
    ;

unary   :   ('+'^ | '-'^)* term

    ;

mult    :   unary (('*'^ | '/'^ | '%'^) unary)*
    ;

add     
    :   mult (( '+'^ | '-'^ ) mult)*
    ;

expression
    :   add (( '|'^ ) add)*
    ;

// LEXEMES
STRING_LITERAL
    :   '"' .* '"'
    ;

NUMBER  :   DIGIT+ ('.'DIGIT+)?
    ;

IDENT   :   (LCLETTER | UCLETTER | DIGIT)(LCLETTER | UCLETTER | DIGIT|'_')*
    ;

COMMENT
        :       '//' ~('\n'|'\r')*  {$channel=HIDDEN;}
    |   '/*' ( options {greedy=false;} : . )* '*/' NEWLINE?{$channel=HIDDEN;}
        ;

WS
    :   (' ' | '\t' | '\f')+ {$channel = HIDDEN;}
    ;

NEWLINE :   '\r'? '\n'
    ;

fragment
LCLETTER 
    :   'a'..'z'
    ;

fragment
UCLETTER:   'A'..'Z'
    ;   

fragment
DIGIT   :   '0'..'9'
    ;

在树语法中,以下是规则
nodeInternal
的声明:

  nodeInternal
    :  (nodeProduction
       |portAssignment
       |portstmt
       |nodestmt
       |sNode)+
    ;
这是您的规则声明
subsunctdeclnodeprod

   subjunctDeclNodeProd
    :   ^(SUBJ_NODE_PROD IDENT IDENT nodeInternal+ )
    ;
当处理
subsunctdeclnodeprod
时,ANTLR不知道如何处理这样一个具有两个子
PATH
的输入:

^(SUBJ_NODE_PROD IDENT IDENT ^(PATH IDENT) ^(PATH IDENT))
它应该遵循规则
nodeInternal
一次并处理
nodeProduction,nodeProduction
还是应该遵循
nodeInternal
两次并每次处理
nodeProduction

考虑在不使用
+
的情况下重写
subsunctdeclnodeprod

   subjunctDeclNodeProd
    :   ^(SUBJ_NODE_PROD IDENT IDENT nodeInternal)
    ;

我想这会解决问题。

在我看来,代码/语法太多了。我可能会考虑给你的语法通过ANTLRWork,但你需要发布2干净(没有自定义代码!)语法文件,我可以简单地复制和粘贴,看到你看到的错误。你的语法片段太少了,我无法测试。是的,你是对的。很抱歉。这是我的疏忽。我已经删除了自定义代码。没问题,但这不仅仅是嵌入的代码,如果这是唯一的事情,我会自己删除它(我很懒,但不是那么懒:)。我看到
tokens{…}
块丢失,
activationPath
规则丢失(可能更多?)。我要求你们发布两个根本不需要编辑的语法(组合和树):从语法定义开始。这不仅对像我这样的(懒惰的)人很有帮助,而且可以确保我能准确地看到你所看到的。好的,让我知道这是否对你有效。你现在有了我完整的语法。你有机会看看我贴的答案吗?如果这不是你想要的(或者如果你自己解决了问题),请告诉我。我讨厌“无用”的答案(没有评论,没有赞成票或反对票,没有其他答案,…)四处飘荡,特别是当问题是关于破碎的东西而不是理论的东西时。谢谢。
   subjunctDeclNodeProd
    :   ^(SUBJ_NODE_PROD IDENT IDENT nodeInternal)
    ;