Antlr4 将整数定义为标记时匹配单个数字时出现问题
我在语法方面遇到了问题。这是简化版。我尝试解析的语言有如下表达式:Antlr4 将整数定义为标记时匹配单个数字时出现问题,antlr4,Antlr4,我在语法方面遇到了问题。这是简化版。我尝试解析的语言有如下表达式: testing1(2342); testing2(idfor2); testing3(4654); testing4[1..n]; testing5[0..1]; testing6(7); testing7(1); testing8(o); testing9(n); 当我为[1..n]或[0..1]表达式引入规则时,问题就出现了。语法文件(我尝试过的众多变体之一): 当我用这个语法分析样本时,它在testing7(1)上失败和
testing1(2342);
testing2(idfor2);
testing3(4654);
testing4[1..n];
testing5[0..1];
testing6(7);
testing7(1);
testing8(o);
testing9(n);
当我为[1..n]或[0..1]表达式引入规则时,问题就出现了。语法文件(我尝试过的众多变体之一):
当我用这个语法分析样本时,它在testing7(1)上失败代码>和测试(9)代码>。它匹配为decMin
或decMax
,而不是Integer
或Identifier
:
line 8:9 mismatched input '1' expecting {Integer, Identifier}
line 10:9 mismatched input 'n' expecting {Integer, Identifier}
我尝试了许多变体,但无法使其正常工作。我认为您的问题在于没有使用lexer规则明确定义您想要的内容
添加此规则时:
decMin : '0' | '1' ;
实际上,您创建了一个与“0”匹配的未命名词法规则,另一个与“1”匹配:
UNNAMED_0_RULE : '0';
UNNAMED_1_RULE : '1';
您的解析器规则变成:
decMin : UNNAMED_0_RULE | UNNAMED_1_RULE ;
问题:现在,当你的lexer看到
试验7(1);
**它看不见**
callName'('callParameter')“”;'
再也看不到了
调用名“(“未命名规则”)”;“
它不明白这一点
这是因为lexer规则在解析器规则之前是有效的
要解决您的问题,请高效地定义lexer规则,它可能如下所示:
grammar test;
/*---------------- PARSER ----------------*/
tests
: test*
;
test
: call
| declaration
;
call
: callName '(' callParameter ')' ';'
;
callName
: identifier
;
callParameter
: identifier
| integer
;
declaration
: declarationName '[' declarationParams ']' ';'
;
declarationName
: identifier
;
declarationParams
: decMin '..' decMax
;
decMin
: INTEGER_ZERO
| INTEGER_ONE
;
decMax
: INTEGER_ONE
| LETTER_N
;
integer
: (INTEGER_ZERO | INTEGER_ONE | INTEGER_OTHERS)+
;
identifier
: LETTER_N
| IDENTIFIER
;
/*---------------- LEXER ----------------*/
LETTER_N: N;
IDENTIFIER
: [a-zA-Z_][a-zA-Z0-9_]*
;
WS
: [ \t\r\n]+ -> skip
;
INTEGER_ZERO: '0';
INTEGER_ONE: '1';
INTEGER_OTHERS: '2'..'9';
fragment N: [nN];
我刚刚测试了这个语法,它很有效
缺点是,它将在lexer步骤中切割整数(在lexer规则中将1245切割为1 2 4 5,并且将解析器规则视为1 2 4和5的联合)
我认为最好不要太精确,只写:
decMin:整数|标识符
但这取决于你对语法做了什么…是的!现在可以了。我以前尝试过这样的方法,但真正不同的是将标识符
和整数
转换为规则,而不是词素。
grammar test;
/*---------------- PARSER ----------------*/
tests
: test*
;
test
: call
| declaration
;
call
: callName '(' callParameter ')' ';'
;
callName
: identifier
;
callParameter
: identifier
| integer
;
declaration
: declarationName '[' declarationParams ']' ';'
;
declarationName
: identifier
;
declarationParams
: decMin '..' decMax
;
decMin
: INTEGER_ZERO
| INTEGER_ONE
;
decMax
: INTEGER_ONE
| LETTER_N
;
integer
: (INTEGER_ZERO | INTEGER_ONE | INTEGER_OTHERS)+
;
identifier
: LETTER_N
| IDENTIFIER
;
/*---------------- LEXER ----------------*/
LETTER_N: N;
IDENTIFIER
: [a-zA-Z_][a-zA-Z0-9_]*
;
WS
: [ \t\r\n]+ -> skip
;
INTEGER_ZERO: '0';
INTEGER_ONE: '1';
INTEGER_OTHERS: '2'..'9';
fragment N: [nN];