2013-02-12 120 views
3

我有一個語法和一切工作正常,直到該部分:ANTLR歧義「 - 」

lexp 
: factor (('+' | '-') factor)* 
; 

factor :('-')? IDENT; 

當然,這帶來了模棱兩可的。

[18:49:39] warning(200): withoutWarningButIncomplete.g:57:31: 
Decision can match input such as "'-' {IDENT, '-'}" using multiple alternatives: 1, 2 

我怎樣才能解決這種不確定性:例如a-a可以通過Factor - FactorFactor -> - IDENT

我得到以下警告,指出此相匹配?我只是沒有看到它的方式。我可以使用某種選擇嗎?

以下是完整的語法:

program 
    : includes decls (procedure)* 
    ; 

/* Check if correct! */ 
includes 
    : ('#include' STRING)* 
    ; 

decls 
    : (typedident ';')* 
    ; 

typedident 
: ('int' | 'char') IDENT  
; 

procedure 
    : ('int' | 'char') IDENT '(' args ')' body 
    ; 

args 
: typedident (',' typedident)* /* Check if correct! */ 
| /* epsilon */ 
; 

body 
: '{' decls stmtlist '}' 
; 

stmtlist 
: (stmt)*; 

stmt 

: '{' stmtlist '}' 
| 'read' '(' IDENT ')' ';' 
| 'output' '(' IDENT ')' ';' 
| 'print' '(' STRING ')' ';' 
| 'return' (lexp)* ';' 
| 'readc' '(' IDENT ')' ';' 
| 'outputc' '(' IDENT ')' ';' 
| IDENT '(' (IDENT (',' IDENT)*)? ')' ';' 
| IDENT '=' lexp ';'; 



lexp 
: term (('+' | '-') term) * /*Add in | '-' to reveal the warning! !*/ 
; 

term 
    : factor (('*' | '/' | '%') factor)* 
; 


factor : '(' lexp ')' 
| ('-')? IDENT 
| NUMBER; 




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

IDENT : ('A' .. 'Z' | 'a' .. 'z') (('A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '_'))* ; 


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

CHARACTER 
: '\'' ('a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '\\n' | '\\t' | '\\\\' | '\\' | 'EOF' |'.' | ',' |':' ) '\'' /* IS THIS COMPLETE? */ 
; 
+0

會發生錯誤只用這個簡單的語法?我對ANTLR不熟悉,我必須在這裏忽略一些明顯的東西,但這對我來說似乎並不明確。緊接着一個因子的減號應該總是在這裏被解釋爲二元運算符。如果存在,則第二個減號將是可選的一元減號。根據語法解析「factor - factor」爲「factor」「-IDENT」將不會是有效的語法,因爲如果不使用+或 - ,則無法從第一個因素轉換。 – 2013-02-12 19:34:39

+0

你是什麼意思*「添加'|'-''」*?將它添加到哪裏?你可以發佈模棱兩可的規則嗎? – 2013-02-12 19:37:55

+0

我已刪除該評論。事實上,這些規則是有意義的。這裏有一個Lexer規則,如果有幫助: IDENT \t:('A'..'Z'|'a'..'z')(('A'..'Z'|'a'..' z'|'0'...'9'|'_'))* \t; – Awoken 2013-02-12 21:48:41

回答

2

正如在評論中提到:這些規則含糊:

lexp 
: factor (('+' | '-') factor)* 
; 

factor : ('-')? IDENT; 

這是含糊不清的原因:

'return' (lexp)* ';' 

它可以解析輸入a-b兩種不同的方式:

  1. a-b作爲一個單一的二進制表示
  2. a作爲一個單一的表達,-b作爲一個一元表達式

你需要改變你的語法。也許在多個返回值中添加逗號?事情是這樣的:

'return' (lexp (',' lexp)*)? ';' 

將匹配:

return; 
return a; 
return a, -b; 
return a-b, c+d+e, f; 
...