Antlr4 区分“减号”运算符和负号

最近用Antlr4开发解释器,在识别带减号“-”的表达式遭遇语法错误,例如

a = 2-1

原因是将“2-1”识别为了2和-1两个token,而我的预期是2、-、1三个token
当然,我也知道之所以这样识别,是因为我定义数字字面量的规则时,支持负号

LiteralInt: '-'?[0-9]+;

当然,我也可以通过如下语法规避此问题,即负号和1之间加个空格,但这样毕竟不易用

a = 2 - 1

我在token规则层面上想了好久都没有解决办法,后来我想到了查看一下python解释器是如何区分的,这也让我找到了答案

import ast

root = ast.parse("a=2-1")
root1 = ast.parse("a=1")
root2 = ast.parse("a=-1")
print(ast.dump(root))
print(ast.dump(root1))
print(ast.dump(root2))

结果如下:

Module(body=[Assign(targets=[Name(id='a', ctx=Store())], value=BinOp(left=Constant(value=2), op=Sub(), right=Constant(value=1)))], type_ignores=[])
Module(body=[Assign(targets=[Name(id='a', ctx=Store())], value=Constant(value=1))], type_ignores=[])
Module(body=[Assign(targets=[Name(id='a', ctx=Store())], value=UnaryOp(op=USub(), operand=Constant(value=1)))], type_ignores=[])

通过三个表达式的解析结果,我发现表达式a=-1中,-1并不是与1一样识别为constant,而是UnaryOp(op=USub(), operand=Constant(value=1)),即一元运算符“-”和常量1

这让我茅塞顿开,马上开始修改我定义的语法

unaryOp: ('+'|'-') expr;
expr
	: constant
	| ...
	;
constant
	: LiteralInt
	| LiteralFloat
	;
// 定义数字字面量,没有负号
LiteralInt: [0-9]+;

至此, 问题解决~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值