textx 语法,使用空格作为重复修饰符

问题描述

我正在尝试使用 Fire Dynamics Simulatortextx 使用的输入文件编写解析器。在大多数情况下,忽略空格是完美的,因为大多数参数和值应该用逗号分隔。但是,ignore the comma at the end of a parameter 是可以接受的,而且程序似乎也将查看 missing comma in the value list

我已经精简了这个问题的语法定义,但下面的代码显示 data 中有 2 条记录,它们以 & 开头并以 / 结尾。每个记录有两个参数。第一个有一些字符串值,而第二个记录有数值。此代码运行良好。

import textx

def test_parse_mesh(model):
    expected = {
        'XB': [0.0,5.0,0.0,4.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,30,XB  = 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/
"""

我查看了 repetition modifiers 并能够使以下内容起作用,但无法使其在更大的语法定义中起作用。我还尝试更改 parser configuration,但无法使其正常工作。

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,30]}
assert {param.name: param.value for param in model.parameters} == expected

如何修改顶部的语法以正确解析没有逗号的 data 的第二个版本?我会接受一个可以让它与 one parameter per line 一起工作的答案,但理想情况下,在这两种情况下都能够处理丢失的逗号。

解决方法

当我看到你的帖子时,我认为解决方案应该是一个简单的分隔符可选匹配,例如:

Model: records*=Record;
Record: /^&/ namelist=ID parameters*=Parameter[/,?/] '/';
Parameter: name=ID '=' value+=Value[/,?/];
Value: NUMBER | STRING;

但是,它没有用。经过一些调试输出调查后,我注意到可选的分隔符匹配 ,? 尽管在没有逗号的地方成功会终止重复匹配。错误在于琶音。我刚刚做了一个修复。它在 master 分支上可用,因此请暂时从 GitHub 安装。我将很快发布新版本的琶音。使用提供的错误修正,上述语法可以正常工作。您甚至可以混合搭配,仅在某些地方使用分隔符,例如:

&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 已发布,其中包含此答案中提到的修复。