textX规则中数值类型转换异常:如何保留用户输入的原始类型?
解决textX中保留数值原始类型的问题
你遇到的问题根源是textX的规则匹配按顺序执行:
- 当规则写
FLOAT | INT时,整数输入会先被FLOAT规则匹配成功,直接转成浮点数; - 当写
INT | FLOAT时,浮点数的整数部分会先被INT规则匹配,截断小数位转成整数。
要保留用户输入的原始数值类型,可通过「自定义数字规则+语义动作解析」的方案解决,具体步骤如下:
1. 修改textX语法规则
把原来的FLOAT/INT二选一,换成自定义正则规则匹配数字字符串:
IsLessThanOrEqualToRule: 'is <= ' reference_value_input = RawNumber ; # 用正则匹配整数或浮点数的字符串形式 RawNumber: /\d+(\.\d+)?/;
2. 注册语义动作处理类型转换
在加载模型时,为RawNumber规则注册处理器,根据字符串格式判断转成int或float:
from textx import metamodel_from_str # 定义语法 grammar = """ IsLessThanOrEqualToRule: 'is <= ' reference_value_input = RawNumber ; RawNumber: /\\d+(\\.\\d+)?/; """ # 自定义处理器:根据字符串内容决定最终类型 def parse_raw_number(raw_num): num_str = raw_num.value return float(num_str) if '.' in num_str else int(num_str) # 加载元模型并注册处理器 mm = metamodel_from_str(grammar) mm.register_obj_processors({'RawNumber': parse_raw_number}) # 测试验证 test1 = mm.model_from_str('is <= 1000') print(type(test1.reference_value_input), test1.reference_value_input) # <class 'int'> 1000 test2 = mm.model_from_str('is <= 100.025') print(type(test2.reference_value_input), test2.reference_value_input) # <class 'float'> 100.025
通过这种方式,就能精准保留用户输入的原始数值类型,不会出现强制转换的问题。
内容的提问来源于stack exchange,提问作者Anjan
相关产品推荐
相关产品推荐

