如何在文本语法的有序选择表达式中使用 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'
我是 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'