Antlr4 解析器未正确解析重新分配语句
Antlr4 parser not parsing reassignment statement correctly
我一直在使用 Antlr4 创建语法分析器,并希望添加变量重新分配(无需声明新变量)
我试过将重新赋值语句更改为表达式,但这并没有改变任何东西
这是我的语法的简化版本:
grammar MyLanguage;
program: statement* EOF;
statement
: expression EOC
| variable EOC
| IDENTIFIER ASSIGNMENT expression EOC
;
variable: type IDENTIFIER (ASSIGNMENT expression)?;
expression
: STRING
| INTEGER
| IDENTIFIER
| expression MATH expression
| ('+' | '-') expression
;
MATH: '+' | '-' | '*' | '/' | '%' | '//' | '**';
ASSIGNMENT: MATH? '=';
EOC: ';';
WHITESPACE: [ \t\r\n]+ -> skip;
STRING: '"' (~[\u0000-\u0008\u0010-\u001F"] | [\t])* '"' | '\'' (~[\u0000-\u0008\u0010-\u001F'] | [\t])* '\'';
INTEGER: '0' | ('+' | '-')? [1-9][0-9]*;
IDENTIFIER: [a-zA-Z_][a-zA-Z0-9_]*;
type: 'str';
如果还有其他相关问题,请询问
所以我尝试解析
str test = "empty";
test = "not empty";
这有效,但是当我尝试时(fibbionaci 函数的一部分)
temp = n1;
n1 = n1 + n2;
n2 = temp;
出现错误并将其解析为
temp = n1; //statement
n1 = n1 //statement - <missing ';'>
+n2; //statement
n2 = temp; //statement
您的问题与赋值语句无关。添加根本不起作用 - 无论它们是否是作业的一部分。因此,获得错误的最简单输入是 x+y;
。如果您打印该输入的令牌流(例如使用 grun
和 -tokens
选项),您将获得以下输出:
[@0,0:0='x',<IDENTIFIER>,1:0]
[@1,1:1='+',<'+'>,1:1]
[@2,2:2='y',<IDENTIFIER>,1:2]
[@3,3:3=';',<';'>,1:3]
[@4,4:3='<EOF>',<EOF>,1:4]
line 1:1 no viable alternative at input 'x+'
现在将其与 x*y;
进行比较,效果很好:
[@0,0:0='x',<IDENTIFIER>,1:0]
[@1,1:1='*',<MATH>,1:1]
[@2,2:2='y',<IDENTIFIER>,1:2]
[@3,3:3=';',<';'>,1:3]
[@4,4:3='<EOF>',<EOF>,1:4]
这里的重要区别是 *
被识别为 MATH
标记,但 +
不是。它被识别为 '+'
令牌。
发生这种情况是因为您在备选 | ('+' | '-') expression
中引入了单独的 '+'
(和 '-'
)令牌类型。因此,每当词法分析器看到 +
时,它都会生成一个 '+'
标记,而不是 MATH
标记,因为解析器规则中的字符串文字优先于命名的词法分析器规则。
如果您将 MATH
改为解析器规则 math
(或者 mathOperator
),所有运算符都将是文字,问题就会消失。也就是说,您可能不希望所有数学运算符都使用单一规则,因为这不会为您提供您想要的优先级,但这是一个不同的问题。
PS:x+1
之类的东西仍然不起作用,因为它会将 +1
视为单个 INTEGER
标记。您可以通过从 INTEGER
规则中删除前导 +
和 -
来解决这个问题(这样 x = -2
将被解析为应用于整数 2
而不仅仅是整数 -2
,但这不是问题)。
我一直在使用 Antlr4 创建语法分析器,并希望添加变量重新分配(无需声明新变量)
我试过将重新赋值语句更改为表达式,但这并没有改变任何东西
这是我的语法的简化版本:
grammar MyLanguage;
program: statement* EOF;
statement
: expression EOC
| variable EOC
| IDENTIFIER ASSIGNMENT expression EOC
;
variable: type IDENTIFIER (ASSIGNMENT expression)?;
expression
: STRING
| INTEGER
| IDENTIFIER
| expression MATH expression
| ('+' | '-') expression
;
MATH: '+' | '-' | '*' | '/' | '%' | '//' | '**';
ASSIGNMENT: MATH? '=';
EOC: ';';
WHITESPACE: [ \t\r\n]+ -> skip;
STRING: '"' (~[\u0000-\u0008\u0010-\u001F"] | [\t])* '"' | '\'' (~[\u0000-\u0008\u0010-\u001F'] | [\t])* '\'';
INTEGER: '0' | ('+' | '-')? [1-9][0-9]*;
IDENTIFIER: [a-zA-Z_][a-zA-Z0-9_]*;
type: 'str';
如果还有其他相关问题,请询问
所以我尝试解析
str test = "empty";
test = "not empty";
这有效,但是当我尝试时(fibbionaci 函数的一部分)
temp = n1;
n1 = n1 + n2;
n2 = temp;
出现错误并将其解析为
temp = n1; //statement
n1 = n1 //statement - <missing ';'>
+n2; //statement
n2 = temp; //statement
您的问题与赋值语句无关。添加根本不起作用 - 无论它们是否是作业的一部分。因此,获得错误的最简单输入是 x+y;
。如果您打印该输入的令牌流(例如使用 grun
和 -tokens
选项),您将获得以下输出:
[@0,0:0='x',<IDENTIFIER>,1:0]
[@1,1:1='+',<'+'>,1:1]
[@2,2:2='y',<IDENTIFIER>,1:2]
[@3,3:3=';',<';'>,1:3]
[@4,4:3='<EOF>',<EOF>,1:4]
line 1:1 no viable alternative at input 'x+'
现在将其与 x*y;
进行比较,效果很好:
[@0,0:0='x',<IDENTIFIER>,1:0]
[@1,1:1='*',<MATH>,1:1]
[@2,2:2='y',<IDENTIFIER>,1:2]
[@3,3:3=';',<';'>,1:3]
[@4,4:3='<EOF>',<EOF>,1:4]
这里的重要区别是 *
被识别为 MATH
标记,但 +
不是。它被识别为 '+'
令牌。
发生这种情况是因为您在备选 | ('+' | '-') expression
中引入了单独的 '+'
(和 '-'
)令牌类型。因此,每当词法分析器看到 +
时,它都会生成一个 '+'
标记,而不是 MATH
标记,因为解析器规则中的字符串文字优先于命名的词法分析器规则。
如果您将 MATH
改为解析器规则 math
(或者 mathOperator
),所有运算符都将是文字,问题就会消失。也就是说,您可能不希望所有数学运算符都使用单一规则,因为这不会为您提供您想要的优先级,但这是一个不同的问题。
PS:x+1
之类的东西仍然不起作用,因为它会将 +1
视为单个 INTEGER
标记。您可以通过从 INTEGER
规则中删除前导 +
和 -
来解决这个问题(这样 x = -2
将被解析为应用于整数 2
而不仅仅是整数 -2
,但这不是问题)。