2012-10-11 72 views
1

我有點困惑。我的語法運行良好,符合我的語言,就像我想要的一樣。最近,我在語法上添加了一些規則,並且在將新語法規則轉換爲樹語法的過程中,我收到了一些奇怪的錯誤。我得到的第一個錯誤是樹語法不明確。爲什麼我的樹語法不明確?

我收到的錯誤是:

[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,subjunctDeclNodeProd,subjunctDecl和subjunctSelector規則之前,這很好。

我的語法是:

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' 
    ; 

我的樹語法的部分看起來像:

tree grammar ShiroDefinitionPass; 

options{ 
    tokenVocab=Shiro; 
    ASTLabelType=CommonTree; 
} 

shiro 
    : statement+ 

    ; 

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

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

collection 
    : ^('collection' IDENT orderingFunc path collItem+) 
    ; 

collItem: IDENT 
    ; 

orderingFunc 
    : IDENT 
    ; 

statestmt 
    : ^(STATE_DECL stateHeader) 
    ; 

stateHeader 
    : (stateTimeStmt | stateCommentStmt | stateParentStmt| stateGraphStmt | activation)+  
    ; 

stateTimeStmt 
    : ^('Time' time) 
    ; 

stateCommentStmt 
    : ^('Comment' comment)  
    ; 

stateParentStmt 
    : ^('Parent' stateParent) 
    ; 

stateGraphStmt 
    : ^('Graph' stateGraph) 
    ; 

stateName 
    : IDENT 
    ; 

time : STRING_LITERAL 
    ; 

comment : STRING_LITERAL 
    ; 

stateParent 
    : IDENT 
    ; 

stateGraph 
    : IDENT 
    ; 

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

activationList 
    : ^(ACTIVATION_LIST activation+) 
    ; 

activation 
    : ^(ACTIVATION IDENT IDENT?) 
    ; 

// Graph Declarations 
graphDecl 
    : ^('graph' IDENT graphLine+) 
    ; 

graphLine 
    : nodeProduction 
    | portAssignmen 
    ; 
// End Graph declaration 

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

nodestmt 
    : ^('node' IDENT activeSelector? nodeInternal)  
    ; 

sNode 
    : ^('subjunctive node' IDENT subjunctSelector (subjunctDeclNodeProd | subjunctDecl)*) 
    ; 

subjunctDeclNodeProd 
    : ^(SUBJ_NODE_PROD IDENT IDENT nodeInternal+) 
    ; 

subjunctDecl 
    : ^('subjunct' IDENT activeSelector? nodeInternal) 
    ; 

subjunctSelector 
    : ^(SUBJ_SELECT IDENT) 
    ; 

activeSelector returns 
    : ^(EVAL_SELECT IDENT) 
    ; 

nodeProduction 
    : ^('->' nodeProduction) 
    | path 
    ; 

portAssignment 
    : ^(PORT_ASSIGNMENT path) 
    ; 

// Port Statement 
portDecl 
    : ^(PORT_DECL ^(PORT_TAG portType) portName mfName) 
    ; 

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

portstmt  
    : (portDecl | portDeclInit) 
    ; 

portName 
    : IDENT 
    ; 

portType returns 
    : 'port' | 'eval' 
    ; 


mfCall 
    : ^(mfName mfparams) 
    ; 

mfName 
    : IDENT 
    ; 

mfparams 
    : (exps=expression)+ 
    ; 

// Path 
path 
    : ^(PATH (id=IDENT)+ (pathIndex)?) 
    ; 

pathIndex 
    : ^(PORT_INDEX portIndex) 
    ; 

portIndex 
    : (NUMBER 
     |STRING_LITERAL 
     ) 
    ; 

// Expressions 
expression 
    : ^('+' op1=expression op2=expression) 
    | ^('-' op1=expression op2=expression) 
    | ^('*' op1=expression op2=expression) 
    | ^('/' op1=expression op2=expression) 
    | ^('%' op1=expression op2=expression) 
    | ^('|' op1=expression op2=expression) 
    | NUMBER 
    | path 
    ; 
+0

海事組織,有太多的代碼/語法去通過。我可能會考慮給你的語法通過ANTLRWorks,但是你需要發佈2個clean(無自定義代碼!)語法文件,我可以簡單地複製和粘貼並查看你看到的錯誤。你的語法片段缺少太多的東西來測試。 –

+0

是的你是對的。對於那個很抱歉。對我而言,這是sl iness不馴的。我已經刪除了自定義代碼。 –

+0

沒問題,但它不是*只是*嵌入式代碼,如果這是唯一的東西(我很懶,但不* *表示懶惰:)),我會自己刪除它。我看到'token' {...}塊丟失,'activationPath'規則丟失(也許更多?)。我問你的是發佈2個語法(組合和樹),根本不需要編輯:所以從語法定義開始。這不僅有利於像我這樣的(懶惰)人,還能確保我看到你所看到的。 –

回答

2

樹中的語法,這裏是規則nodeInternal聲明:

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

這裏是你的規則subjunctDeclNodeProd的聲明:

subjunctDeclNodeProd 
    : ^(SUBJ_NODE_PROD IDENT IDENT nodeInternal+) 
    ; 

subjunctDeclNodeProd正在處理,ANTLR不知道如何處理輸入像這樣,有兩個孩子PATH

^(SUBJ_NODE_PROD IDENT IDENT ^(PATH IDENT) ^(PATH IDENT)) 

它應該遵循的規則nodeInternal一次和工藝nodeProduction, nodeProduction或應它每次跟隨nodeInternal兩次並且處理nodeProduction

考慮重寫subjunctDeclNodeProd沒有+

subjunctDeclNodeProd 
    : ^(SUBJ_NODE_PROD IDENT IDENT nodeInternal) 
    ; 

我認爲,將採取照顧的問題。