如何在文本语法的有序选择表达式中使用 link 规则引用?

How to use a link rule reference in an ordered choice expression in a TextX grammar?

我是 TextX 新手。我正在尝试创建一个语法来定义数据类型,这些数据类型的字段可以是简单类型或其他数据类型的类型。语法说明为:

Library: 
    data_types *= DataType
;

DataType: name=ID "{" 
fields*=Field
"}" ;

Field: type=([DataType] | ID) name=ID;
//Type: [DataType] | ID;

遵循此语法的模型示例是

vec { 
int64 a
int64 b
int64 c
}

matrix {
    vec a
    vec b
}

我想 link 将字段的类型设置为已声明的数据类型或一些简单的字符串。但是,当用 textx generate dummy.tx --target dot 编译上述语法时,我得到错误 Error: None:9:13: error: Expected ''((\')|[^'])*'' or '"((\")|[^"])*"' or re_match or rule_ref or '[' at position dummy.tx:(9, 13) => 'eld: type=*([DataType'..

有什么方法可以实现我想要的吗?我曾尝试将类型声明放在一个单独的块中,如评论中所示,但这没有帮助。任何建议或提示将不胜感激。

标准方法是使用自定义 类 并为所有非用户自己创建的类型创建内置函数。最好使用您的示例在代码中展示它是如何完成的。请注意 registration so that the language with registered builtins can be available to textx CLI command. Also, see the entity example 的使用,因为那里使用了相同的技术。

from textx import metamodel_from_str
from textx.registration import (language, register_language,
                                metamodel_for_language)

# We use registration support to register language
# This way it will be available to textx CLI command
@language('library', '.lib')
def library_lang():
    "Library language."

    grammar = r'''
    Library:
        data_types *= DataType
    ;

    DataType: name=ID "{"
        fields*=Field
    "}" ;

    Field: type=[Type] name=ID;
    Type: DataType | BuiltInType;
    BuiltInType: name=ID;
    '''

    # Here we use our class for builtin types so we can
    # make our own instances for builtin types.
    # See textX Entity example for more.
    class BuiltInType:
        def __init__(self, parent, name):
            self.parent = parent
            self.name = name

    # Create all builtin instances.
    builtins = {
        'int64': BuiltInType(None, 'int64'),
    }

    return metamodel_from_str(grammar,
                              # Register custom classes and builtins.
                              classes=[BuiltInType],
                              builtins=builtins)


# This should really be done through setup.{cfg,py}
# Here it is done through registration API for an example to
# be self-contained.
register_language(library_lang)

model_str = r'''
vec {
int64 a
int64 b
int64 c
}

matrix {
    vec a
    vec b
}

'''

# Now we can get registered language metamodel by name and
# parse our model.
model = metamodel_for_language('library').model_from_str(model_str)
# ... do something with the model
assert len(model.data_types) == 2
assert model.data_types[0].name == 'vec'
assert model.data_types[0].fields[0].name == 'a'
assert model.data_types[0].fields[0].type.name == 'int64'