Antlr4 ANLTR4输入不匹配

Antlr4 ANLTR4输入不匹配,antlr4,Antlr4,我正试图为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 in

我正试图为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时

my test.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: [ \t\n\r]+-> skip;

grammarcal;
prog:decl_list function_list main Eof;
decl_列表:decl半decl_列表|;
decl:var_decl | const_decl;
var_decl:var ID冒号类型;
const_decl:const ID冒号类型赋值表达式;
函数列表:函数列表;
函数:type ID LBR参数\u list RBR是decl\u list Begin语句\u块返回LBR表达式
|RBR半末端;
类型:TypeInteger | TypeBoolean | TypeVoid;
参数列表:nemp参数列表;
nemp_参数_列表:ID冒号类型
|ID冒号类型逗号nemp_参数_列表
;
主:主开始-结束列表语句-块结束;
语句块:LBR语句块RBR;
语句:ID赋值表达式
|ID LBR参数列表RBR半
|Begin语句\u块结束
|如果条件开始语句\u块结束,否则开始语句\u块结束
|While条件开始语句\u块结束
|跳投半决赛
;
表达式:frag二进制算术运算frag
|LBR表达
|ID LBR参数列表RBR
|弗拉格;
二进制算术运算:运算=(加减);
frag:ID |减去ID | Number |真|假|二进制|算术| op frag
|LBR表达
|ID LBR参数列表RBR;
条件:平铺条件
|LBR条件RBR
|表达式复合表达式
|条件op=(或|和)条件
;
比较:相等|不相等|较小|较小|较小|较大|较大相等;
arg_列表:nemp_arg_列表|;
nemp_参数列表:ID | ID逗号nemp_参数列表;
片段A:‘A’|‘A’;
片段B:“B”|“B”;
片段C:‘C’|‘C’;
片段D:‘D’|‘D’;
片段E:‘E’|‘E’;
片段F:'F'|'F';
片段G:'G'|'G';
片段H:'H'|'H';
片段一:“我”|“我”;
片段J:'J'|'J';
片段K:'K'|'K';
片段L:‘L’|‘L’;
片段M:'M'|'M';
片段N:'N'|'N';
片段O:‘O’|‘O’;
片段P:'P'|'P';
片段Q:'Q'|'Q';
片段R:'R'|'R';
片段S:S'|'S';
片段T:'T'|'T';
片段U:‘U’|‘U’;
片段V:“V”|“V”;
碎片W:‘W’|‘W’;
片段X:'X'|'X';
片段Y:'Y'|'Y';
片段Z:'Z'|'Z';
碎片数字:[0-9];
片段整数:(减?[1-9]位*)|“0”+;
逗号:',';
半:';';
冒号:':';
分配:':=';
LBR:'(';
RBR:')';
加:“+”;
减:'-';
瓷砖:“~”;
或:“|”;
及:"及",;
相等:'=';
NOTEQUAL:“!=”;
减:“=”;
常数:C O N S T;
返回:R E T U R N;
TypeInteger:I N T E G E R;
类型布尔:B O L E A N;
TypeVoid:void;
主营业务:M A I N ;;
如果:I F ;;
其他:E L S E ;;
正确:T R U E;
错误:F A L S E;
而:W H I L E;
Is:I S;
跳过:S K I P;
Var:va-R;
开始:B E G I N;
完:E N D ;;
数字:数字|整数;
信:[a-zA-Z];
ID:字母(字母|数字|'|')*;
WS:[\t\n\r]+->跳过;

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

有两件事出了问题:

您使用的是
Eof
,它应该是
Eof

prog: decl_list function_list main EOF;
函数
规则看起来很奇怪:

function: type ID LBR parameter_list RBR Is decl_list Begin statement_block Return LBR expression   
        | RBR SEMI End;
我认为您应该删除结尾处的
| RBR SEMI-endreturn()
,则应将
表达式设置为可选。这可能是您想要的:

function
 : type ID LBR parameter_list RBR Is decl_list Begin statement_block Return LBR expression? RBR SEMI End
 ;
最后,在您的语句中,使用块规则:

statement_block: LBR statement statement_block RBR |;
您是说每个块都应该用括号括起来,但从您的输入来看,情况并非如此。所以你可能想这样做:

statement_block: statement statement_block |;
statement_block: statement*;
也可以这样写:

statement_block: statement statement_block |;
statement_block: statement*;