ANLTR4输入不匹配



我正试图为CAL语言编写一个解析器,但在中出现了这些错误

line 3:12 mismatched input ')' expecting {'(', '+', '-', True, False, Number, ID}
line 8:4 no viable alternative at input 'func'
line 8:10 mismatched input ')' expecting {If, While, Skipp, Begin, ID}
line 8:11 extraneous input ';' expecting End

运行grun cal prog-gui test.cal 时

我的测试.cal:

void func () is
begin
return ();
end
main
begin
func ();
end

我的cal.g4:

grammar cal;
prog: decl_list function_list main Eof;
decl_list: decl SEMI decl_list |;
decl: var_decl | const_decl;
var_decl: Var ID COLON type;
const_decl: Const ID COLON type ASSIGN expression;
function_list: function function_list |;
function: type ID LBR parameter_list RBR Is decl_list Begin statement_block Return LBR expression
| RBR SEMI End;
type: TypeInteger | TypeBoolean | TypeVoid;
parameter_list: nemp_parameter_list |;
nemp_parameter_list: ID COLON type
| ID COLON type COMMA nemp_parameter_list
;
main: Main Begin decl_list statement_block End;
statement_block: LBR statement statement_block RBR |;
statement: ID ASSIGN expression SEMI
| ID LBR arg_list RBR SEMI
| Begin statement_block End
| If condition Begin statement_block End Else Begin statement_block End
| While condition Begin statement_block End
| Skipp SEMI
;
expression: frag binary_arith_op frag
| LBR expression RBR
| ID LBR arg_list RBR
| frag;
binary_arith_op: op=(PLUS | MINUS);
frag: ID | MINUS ID | Number | True | False | binary_arith_op frag
| LBR expression RBR
| ID LBR arg_list RBR;
condition: TILDE condition
| LBR condition RBR
| expression comp_op expression
| condition op=(OR|AND) condition
;
comp_op: EQUAL | NOTEQUAL | LESS | LESSEQUAL | GREATER | GREATEREQUAL;
arg_list: nemp_arg_list |;
nemp_arg_list: ID | ID COMMA nemp_arg_list;
fragment A: 'a' | 'A';
fragment B: 'b' | 'B';
fragment C: 'c' | 'C';
fragment D: 'd' | 'D';
fragment E: 'e' | 'E';
fragment F: 'f' | 'F';
fragment G: 'g' | 'G';
fragment H: 'h' | 'H';
fragment I: 'i' | 'I';
fragment J: 'j' | 'J';
fragment K: 'k' | 'K';
fragment L: 'l' | 'L';
fragment M: 'm' | 'M';
fragment N: 'n' | 'N';
fragment O: 'o' | 'O';
fragment P: 'p' | 'P';
fragment Q: 'q' | 'Q';
fragment R: 'r' | 'R';
fragment S: 's' | 'S';
fragment T: 't' | 'T';
fragment U: 'u' | 'U';
fragment V: 'v' | 'V';
fragment W: 'w' | 'W';
fragment X: 'x' | 'X';
fragment Y: 'y' | 'Y';
fragment Z: 'z' | 'Z';
fragment Digit: [0-9];
fragment Integer: (MINUS? [1-9] Digit*) | '0'+;
COMMA:                  ',';
SEMI:                   ';';
COLON:                  ':';
ASSIGN:                 ':=';
LBR:                    '(';
RBR:                    ')';
PLUS:                   '+';
MINUS:                  '-';
TILDE:                  '~';
OR:                     '|';
AND:                    '&';
EQUAL:                  '=';
NOTEQUAL:               '!=';
LESS:                   '<';
LESSEQUAL:              '<=';
GREATER:                '>';
GREATEREQUAL:           '>=';
Const:                  C O N S T;
Return:                 R E T U R N;
TypeInteger:            I N T E G E R;
TypeBoolean:            B O O L E A N;
TypeVoid:               V O I D;
Main:                   M A I N;
If:                     I F;
Else:                   E L S E;
True:                   T R U E;
False:                  F A L S E;
While:                  W H I L E;
Is:                     I S;
Skipp:                  S K I P;
Var:                    V A R;
Begin:                  B E G I N;
End:                    E N D;

Number: Digit | Integer;
Letter: [a-zA-Z];
ID: Letter (Letter | Digit | '_')*;
WS: [ tnr]+-> skip;

我真的不确定是什么原因导致了这种情况,即使在做了一点挖掘之后,我认为这可能是测试文件本身的问题,但显然是我的语法规则造成的。你知道是什么原因造成了这种情况吗?

有几件事出了问题:

您使用Eof,它应该是EOF:

prog: decl_list function_list main EOF;

function规则看起来很奇怪:

function: type ID LBR parameter_list RBR Is decl_list Begin statement_block Return LBR expression   
| RBR SEMI End;

我认为您应该删除末尾的|| RBR SEMI End;,因为您还想匹配return ();,所以应该将expression设置为可选。这可能就是你想要的:

function
: type ID LBR parameter_list RBR Is decl_list Begin statement_block Return LBR expression? RBR SEMI End
;

最后,在您的statement_block规则中:

statement_block: LBR statement statement_block RBR |;

你说每个块都应该用括号括起来,但看看你的输入,事实并非如此。所以你可能想这样做:

statement_block: statement statement_block |;

也可以这样写:

statement_block: statement*;

相关内容

  • 没有找到相关文章

最新更新