2013-07-16 34 views
1

我遇到了我的語法問題。antlrworks與多個等於

它說決定可以匹配輸入如"{EQUAL, GREATER..GREATER_EQUAL, LOWER..LOWER_EQUAL, NOT_EQUAL}" using multiple alternatives: 1, 2,雖然規則的所有樹都是正確的。

有人幫忙嗎?!

grammar test; 
//parser : .* EOF; 
program  :T_PROGRAM ID T_LEFTPAR identifier_list T_RIGHTPAR T_SEMICOLON declarations subprogram_declarations compound_statement T_DOT; 
identifier_list :(ID) (',' ID)*; 
declarations :() (T_VAR identifier_list COLON type T_SEMICOLON)* ; 
type  : standard_type| 
     T_ARRAY T_LEFTBRACK NUM T_TO NUM T_RIGHTBRACK T_OF standard_type ; 
standard_type : INT 
     | FLOAT ; 
subprogram_declarations :() (subprogram_declaration T_SEMICOLON)* ; 
subprogram_declaration : subprogram_head declarations compound_statement; 
subprogram_head :T_FUNCTION ID arguments COLON standard_type | 
     T_PROCEDURE ID arguments ; 
arguments :T_LEFTPAR parameter_list T_RIGHTPAR | ; 
parameter_list :(identifier_list COLON type) (T_SEMICOLON identifier_list COLON type)*; 
compound_statement : T_BEGIN optional_statements T_END; 
optional_statements :statement_list | ; 
statement_list :(statement) (T_SEMICOLON statement)*; 

statement : 
variable ASSIGN expression 
| procedure_statement 
| compound_statement 
| T_IF expression T_THEN statement T_ELSE statement 
| T_WHILE expression T_DO statement 
; 
procedure_statement :ID 
     | ID T_LEFTPAR expression_list T_RIGHTPAR; 

expression_list : (expression) (',' expression)*; 
variable : ID T_LEFTBRACK expression T_RIGHTBRACK | ; 

expression :(() |simple_expression) ((LOWER | LOWER_EQUAL | GREATER | GREATER_EQUAL | EQUAL | NOT_EQUAL) simple_expression)* ; 

simple_expression : 
(() | sign) term ((PLUS | MINUS | T_OR) term)*; 

term : 
(factor) ((CROSS | DIVIDE | MOD | T_AND) factor)*; 

factor : 
variable 
|ID T_LEFTPAR expression_list T_RIGHTPAR 
| NUM 
| T_LEFTPAR expression T_RIGHTPAR 
| T_NOT factor; 

sign : 
'+' 
    | '-'; 

/********/ 


T_PROGRAM : 'program'; 
T_FUNCTION : 'function'; 
T_PROCEDURE : 'procedure';  
T_READ : 'read'; 
T_WRITE : 'write'; 
T_OF : 'of'; 
T_ARRAY : 'array'; 
T_VAR : 'var'; 
T_FLOAT : 'float'; 
T_INT : 'int'; 
T_CHAR : 'char'; 
T_STRING : 'string'; 
T_BEGIN :  'begin'; 
T_END : 'end'; 
T_IF : 'if'; 
T_THEN : 'then'; 
T_ELSE : 'else'; 
T_WHILE : 'while'; 
T_DO : 'do'; 
T_NOT : 'not'; 


NUM : INT 
    | FLOAT; 
STRING 
    : '"' (ESC_SEQ | ~('\\'|'"'))* '"' 
    ; 

CHAR: '\'' (ESC_SEQ | ~('\''|'\\')) '\'' 
    ; 
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')* 
    ; 



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



LOWER    : '<'; 
LOWER_EQUAL   : '<='; 
GREATER    : '>'; 
GREATER_EQUAL   : '>='; 
EQUAL    : '='; 
NOT_EQUAL   : '<>'; 

ASSIGN : 
    ':='; 
COLON : 
    ':'; 

PLUS : '+'; 
MINUS : '-'; 
T_OR : 'OR'; 


CROSS : '*'; 
DIVIDE : '/'; 
MOD  : 'MOD'; 
T_AND : 'AND'; 


T_LEFTPAR 
    : '('; 
T_RIGHTPAR 
    : ')'; 
T_LEFTBRACK 
     : '['; 
T_RIGHTBRACK 
    : ']'; 
T_TO 
    : '..'; 
T_DOT : '.'; 
T_SEMICOLON 
    : ';'; 
T_COMMA 
    : ','; 
T_BADNUM 
    : (NUM)(CHAR)*; 
T_BADSTRING 
    : '"' (ESC_SEQ | ~('\\'|'"'))*WS; 




WS : (' ' 
     | '\t' 
     | '\r' 
     | '\n' 
     ) {$channel=HIDDEN;} 
    ; 

fragment 
EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ; 

fragment 
HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ; 

fragment 
ESC_SEQ 
    : '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\') 
    | UNICODE_ESC 
    | OCTAL_ESC 
    ; 

fragment 
OCTAL_ESC 
    : '\\' ('0'..'3') ('0'..'7') ('0'..'7') 
    | '\\' ('0'..'7') ('0'..'7') 
    | '\\' ('0'..'7') 
    ; 

fragment 
UNICODE_ESC 
    : '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT 
    ; 

fragment 
INT : '0'..'9'+ 
    ; 
fragment 
FLOAT 
    : ('0'..'9')+ '.' ('0'..'9')* EXPONENT? 
    | '.' ('0'..'9')+ EXPONENT? 
    | ('0'..'9')+ EXPONENT 
    ; 

回答

0

問題1

歧義(錯誤/警告某些輸入可以超過1分的方式進行匹配)主要來源於這樣的事實,無論你variableexpression規則可以匹配空的輸入:

variable 
: ID T_LEFTBRACK expression T_RIGHTBRACK 
| /* nothing */ 
; 

expression 
: (
     (/* nothing */) 
    | simple_expression 
    ) 
    (
    (LOWER | LOWER_EQUAL | GREATER | GREATER_EQUAL | EQUAL | NOT_EQUAL) simple_expression 
    )* /* because of the `*`, this can also match nothing */ 
; 

(我加的是/* ... */意見並重新格式化的規則,使他們更具可讀性)

修復1

你可能要像這樣做,而不是:

variable 
: ID T_LEFTBRACK expression T_RIGHTBRACK 
; 

expression 
: simple_expression ((LOWER | LOWER_EQUAL | GREATER | GREATER_EQUAL | EQUAL | NOT_EQUAL) simple_expression)* 
; 

問題2

另一個問題(一個將出現一次,你會得到解決的歧義,是您定義的標記MODT_ANDT_OR後您的ID規則:

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

... 

MOD  : 'MOD'; 
T_AND : 'AND'; 
T_OR : 'OR'; 

這將導致MOD,T_ANDT_OR永遠不會被創建,因爲ID也與這些字符匹配。

修復2

廣場MODT_ANDT_OR之前ID規則:

MOD  : 'MOD'; 
T_AND : 'AND'; 
T_OR : 'OR'; 

... 

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

哇,我真的很感謝你們......這下完了!感謝您爲我的整個項目提供的幫助!我學到了很多! – cmin

+0

@ user2584661,不客氣。與昨天發佈的語法相比,您取得了很大的進步。祝你好運! –