2013-03-01 40 views
2

我一直在努力解決我的解析器中的「多個替代方案」錯誤,但現在卻沒有成功。我一直在使用Sam Harwell的ANTLR3和VS2010端口將Bart Kiers出色的微型語言(TL)教程代碼轉換爲C#。對這些傢伙的出色工作表示讚賞。我相信我已經準確地跟隨了巴特的教程,但由於我是ANTLR的新手,我無法確定。如何解決「以下替代方案永遠不能匹配」

我確實有TL代碼純數學的基礎上很好地工作,即沒有「功能」或「如果那麼否則」或「而」(見一個小應用程序的截圖)

Simple Maths Parser based on Bart Kiers work

但當我加入了代碼,缺件來完成教程我在「functionCall」,並在「名單」得到了解析錯誤(請參見下面的代碼),我得到

grammar Paralex2; 

options { 
    language=CSharp3; 
    TokenLabelType=CommonToken; 
    output=AST; 
    ASTLabelType=CommonTree; 
} 

tokens { 
    BLOCK; 
    RETURN; 
    STATEMENTS; 
    ASSIGNMENT; 
    FUNC_CALL; 
    EXP; 
    EXP_LIST; 
    ID_LIST; 
    IF; 
    TERNARY; 
    U_SUB; 
    NEGATE; 
    FUNCTION; 
    INDEXES; 
    LIST; 
    LOOKUP; 
} 

@lexer::namespace{Paralex2} 
@parser::namespace{Paralex2} 

/* 
* Parser Rules 
*/ 

@parser::header {using System; using System.Collections.Generic;} 

@parser::members{ 

public SortedList<string, Function> functions = new SortedList<string, Function>(); 

    private void defineFunction(string id, Object idList, Object block) { 

    // `idList` is possibly null! Create an empty tree in that case. 
    CommonTree idListTree = idList == null ? new CommonTree() : (CommonTree)idList; 

    // `block` is never null. 
    CommonTree blockTree = (CommonTree)block; 

    // The function name with the number of parameters after it the unique key 
    string key = id + idListTree.Children.Count(); 
    functions.Add(key, new Function(id, idListTree, blockTree)); 
    } 

} 

public parse 
    : block EOF -> block 
    ; 

block 
    : (statement | functionDecl)* (Return exp ';')? -> ^(BLOCK ^(STATEMENTS statement*) ^(RETURN exp?)) 
    ; 

statement 
    : assignment ';' -> assignment 
    | functionCall ';' -> functionCall 
    | ifStatement 
    | forStatement 
    | whileStatement 
    ; 

assignment 
    : Identifier indexes? '=' exp 
    -> ^(ASSIGNMENT Identifier indexes? exp) 
    ; 

functionCall 
    : Identifier '(' expList? ')' -> ^(FUNC_CALL Identifier expList?) 
    | Assert '(' exp ')' -> ^(FUNC_CALL Assert exp) 
    | Size '(' exp ')'  -> ^(FUNC_CALL Size exp) 
    ; 

ifStatement 
    : ifStat elseIfStat* elseStat? End -> ^(IF ifStat elseIfStat* elseStat?) 
    ; 

ifStat 
    : If exp Do block -> ^(EXP exp block) 
    ; 

elseIfStat 
    : Else If exp Do block -> ^(EXP exp block) 
    ; 

elseStat 
    : Else Do block -> ^(EXP block) 
    ; 

functionDecl 
    : Def Identifier '(' idList? ')' block End 
    {defineFunction($Identifier.text, $idList.tree, $block.tree);} 
    ; 

forStatement 
    : For Identifier '=' exp To exp Do block End 
    -> ^(For Identifier exp exp block) 
    ; 

whileStatement 
    : While exp Do block End -> ^(While exp block) 
    ; 

idList 
    : Identifier (',' Identifier)* -> ^(ID_LIST Identifier+) 
    ; 


expList 
    : exp (',' exp)* -> ^(EXP_LIST exp+) 
    ; 

exp 
    : condExp 
    ; 

condExp 
    : (orExp -> orExp) 
    | ('?' a=exp ':' b=exp -> ^(TERNARY orExp $a $b) 
    | In exp   -> ^(In orExp exp) 
)? 
    ; 

orExp 
    : andExp ('||'^ andExp)* 
    ; 

andExp 
    : equExp ('&&'^ equExp)* 
    ; 

equExp 
    : relExp (('==' | '!=')^ relExp)* 
    ; 

relExp 
    : addExp (('>=' | '<=' | '>' | '<')^ addExp)* 
    ; 

addExp 
    : mulExp ((Add | Sub)^ mulExp)* 
    ; 

mulExp 
    : powExp ((Mul | Div)^ powExp)* 
    ; 

powExp 
    : unaryExp ('^'^ unaryExp)* 
    ; 

unaryExp 
    : Sub atom -> ^(U_SUB atom) 
    | '!' atom -> ^(NEGATE atom) 
    | atom 
    ; 

atom 
    : Nmber 
    | Bool 
    | Null 
    | lookup 
    ; 

list 
    : '[' expList? ']' -> ^(LIST expList?) 
    ; 

lookup 
    : list indexes?    -> ^(LOOKUP list indexes?) 
    | functionCall indexes?  -> ^(LOOKUP functionCall indexes?) 
    | Identifier indexes?  -> ^(LOOKUP Identifier indexes?) 
    | String indexes?   -> ^(LOOKUP String indexes?) 
    | '(' exp ')' indexes?  -> ^(LOOKUP exp indexes?) 
    ; 

indexes 
    : ('[' exp ']')+ -> ^(INDEXES exp+) 
    ; 


/* 
* Lexer Rules 
*/ 

Assert  : 'assert'; 
Size  : 'size'; 
Def   : 'def'; 
If   : 'if'; 
Else  : 'else'; 
Return  : 'return'; 
For   : 'for'; 
While  : 'while'; 
To   : 'to'; 
Do   : 'do'; 
End   : 'end'; 
In   : 'in'; 
Null  : 'null'; 

Or   : '||'; 
And   : '&&'; 
Equals  : '=='; 
NEquals  : '!='; 
GTEquals : '>='; 
LTEquals : '<='; 
Pow   : '^'; 
GT   : '>'; 
LT   : '<'; 
Add   : '+'; 
Sub   : '-'; 
Mul   : '*'; 
Div   : '/'; 
Modulus  : '%'; 
OBrace  : '{'; 
CBrace  : '}'; 
OBracket : '['; 
CBracket : ']'; 
OParen  : '('; 
CParen  : ')'; 
SColon  : ';'; 
Assign  : '='; 
Comma  : ','; 
QMark  : '?'; 
Colon  : ':'; 

Bool 
    : 'true' 
    | 'false' 
    ; 

Nmber 
    : Int ('.' Digit*)? 
    ; 

Identifier 
    : ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_' | Digit)* 
    ; 

String 
@after { 
    setText(getText().substring(1, getText().length()-1).replaceAll("\\\\(.)", "$1")); 
} 
    : '"' (~('"' | '\\') | '\\' ('\\' | '"'))* '"' 
    | '\'' (~('\'' | '\\') | '\\' ('\\' | '\''))* '\'' 
    ; 

Comment 
    : '//' ~('\r' | '\n')* {Skip();} 
    | '/*' .* '*/'   {Skip();} 
    ; 

Space 
    : (' ' | '\t' | '\r' | '\n' | '\u000C') {Skip();} 
    ; 

fragment Int 
    : '1'..'9' Digit* 
    | '0' 
    ; 

fragment Digit 
    : '0'..'9' 
    ; 

的錯誤消息是

決策可以匹配輸入諸如「CParen」使用多個替代:1,2:行79:20

決策可以如「CBracket」使用多個替代輸入匹配:1,2:行176:10

錯誤與functionCall和list規則有關。我在ANTLRWorks 1.5中檢查瞭解析器文件,並確認了相同的錯誤。這兩個規則的語法圖如下所示;

functionCall rule showing parsing error

和這個;

list rule showing parsing error

我嘗試了好幾種變化來嘗試解決這個問題,但我似乎並沒有能夠得到語法正確。我很感謝你們可以提供的任何幫助,並且可以通過電子郵件發送圖片。

在此先感謝 伊恩·卡森

+0

我不知道你試圖發佈的圖片是什麼,但看起來你的規則有點含糊不清,這就是問題出在哪裏。例如,沒有什麼區分「標識符(explist?)」和「Array(exp)」的情況...... – Stobor 2013-03-01 03:50:00

+0

@Stobor感謝我坐在這裏看着ANTLRWorks語法圖的指針(不幸的是,我認爲他們很酷:-))並嘗試了一些東西。到目前爲止沒有運氣,但夜晚很年輕! – 2013-03-01 08:03:33

回答

2

您擁有或運營商在condExp規則制定語法歧義太多。

您有:對應

condExp 
    : (orExp    -> orExp) 
    | ('?' a=exp ':' b=exp -> ^(TERNARY orExp $a $b) 
    | In exp    -> ^(In orExp exp) 
    )? 
    ; 

enter image description here

但它應該是:對應

condExp 
    : (orExp    -> orExp) 
    ('?' a=exp ':' b=exp -> ^(TERNARY orExp $a $b) 
    | In exp    -> ^(In orExp exp) 
    )? 
    ; 

enter image description here

+0

嗨巴特,非常感謝你看看這個小小的我。這是固定的!我想隨着經驗而來的衆多訣竅之一,就是將整個結構作爲一個系統來運作,以超越眼前的問題規則。下次我會記住它。我添加了缺失的圖像來完成我的問題,我試圖投票,但需要15分 - 我會稍後回來 – 2013-03-01 11:36:00

+0

@IanCarson,很高興聽到它,不用客氣。 – 2013-03-01 12:05:48

+0

嗨巴特它的伊恩。按承諾投票。 – 2013-03-20 08:58:37