我是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
}我希望将字段的类型链接到已经声明的数据类型,或者链接到一些简单的字符串。但是,在用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'.。
有什么办法能实现我想要的吗?我尝试过将类型声明放在一个单独的块中,如注释中所示,但这并没有帮助。如有任何建议或暗示,将不胜感激。
发布于 2021-09-01 16:31:51
一种标准方法是为用户自己创建的所有类型使用自定义类和创建内置程序。最好使用您的示例在代码中演示它是如何完成的。请注意注册的使用,以便可以将已注册的内置语言提供给textx命令。另外,请参见实体示例,因为这里使用了相同的技术。
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'https://stackoverflow.com/questions/69016508
复制相似问题