我试图使用火灾动力学模拟器使用textx为输入文件编写一个解析器。在大多数情况下,忽略空格是完美的,因为大多数参数和值应该用逗号分隔。然而,这是可以接受的忽略参数末尾的逗号和它的程序似乎也将展望过去的值列表中缺少逗号。
我已经删减了这个问题的语法定义,但是下面的代码显示,data中有两个记录,它们以&开头,以/结尾。每个记录都有两个参数。第一个有一些字符串值,而第二个记录有数值。这个代码很好用。
import textx
def test_parse_mesh(model):
expected = {
'XB': [0.0, 5.0, 0.0, 4.0, 0.0, 3.0],
'IJK': [50, 40, 30],
}
parsed = {
param.name: param.value
for param in model.records[1].parameters
}
assert expected == parsed
grammar = """
Model: records*=Record;
Record: /^&/ namelist=ID parameters*=Parameter[','] '/';
Parameter: name=ID '=' value+=Value[','];
Value: (NUMBER | STRING);
"""
data = """
&HEAD CHID='Some Value', TITLE='another string'/
&MESH IJK = 50,40,30,
XB = 0.0,5.0,0.0,4.0,0.0,3.0/
"""
mm = textx.metamodel_from_str(grammar)
model = mm.model_from_str(data)
test_parse_mesh(model)但是,我希望能够修改grammar,以便能够解析以下版本的data
data = """
&HEAD CHID='Some Value', TITLE='another string'/
&MESH IJK = 50 40 30
XB = 0.0 5.0 0.0 4.0 0.0 3.0/
"""我看过重复修饰语,并且能够让下面的内容起作用,但无法使它在更大的语法定义中工作。我还试图修改解析器配置,但无法使其正常工作。
grammar = """
Record[noskipws]: parameters*=Parameter[/,|\s+/];
Parameter[noskipws]: /\s*/ name=ID /\s*=\s*/ value+=NUMBER[/,|\s+/];
"""
data = """
IJK = 50 40 30
XB = 0 5 0 4 0 3
"""
mm = textx.metamodel_from_str(grammar)
model = mm.model_from_str(data)
expected = {'XB': [0.0, 5.0, 0.0, 4.0, 0.0, 3.0], 'IJK': [50, 40, 30]}
assert {param.name: param.value for param in model.parameters} == expected在没有逗号的情况下,如何修改顶部的语法以正确解析第二个版本的data?我将接受一个能让它与每行一个参数一起工作的答案,但理想情况下,它将能够处理两种情况下缺少的逗号。
发布于 2021-04-19 15:02:48
但是,当我看到您的帖子时,解决方案应该是分隔符的一个简单的可选匹配,例如:
Model: records*=Record;
Record: /^&/ namelist=ID parameters*=Parameter[/,?/] '/';
Parameter: name=ID '=' value+=Value[/,?/];
Value: NUMBER | STRING;但是,这不管用。经过一些调试输出调查后,我注意到可选分隔符匹配,?,虽然在没有逗号的地方成功,但会终止重复匹配。窃听器在Arpeggio里。我刚做了个修正。它可以在master分支上使用,所以现在请从GitHub安装。我很快就会发布一个新版本的Arpeggio。通过提供的错误修复,上述语法正确工作。你甚至可以混合和匹配,只在一些地方使用分隔符,例如:
&HEAD CHID='Some Value' TITLE='another string'/
&MESH IJK = 50 40, 30,
XB = 0.0 5.0, 0.0 4.0 0.0 3.0/编辑2021-04-25 Arpeggio 1.10.2与这个答案中提到的补丁一起发布。
https://stackoverflow.com/questions/67154603
复制相似问题