最近用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]+;
至此, 问题解决~
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧