我觉得我错过了一些非常简单的东西。我正在尝试创建一个textX语法,使我的解析器能够识别普通文本标记和特殊关键字。在下面的语法中,我无法让textX识别由SpecialKeyword规则表示的[LINK ...]关键字,因为它会被更通用的NormalString规则吸收。
我得到的输入如下:
['\n', 'Text part before [LINK: REQ-001] Text part after.', '\n', 'Text part before [LINK: REQ-002] Text part after.', '\n']虽然我希望它是:
['\n', 'Text part before ', My Link object with 'REQ-001', 'Text part after.', '\n', 'Text part before ', My Link object with 'REQ-002', 'Text part after.', '\n']一个相关的问题是:如何使NormalString规则支持多行字符串?
from textx import metamodel_from_str
mm = metamodel_from_str('''
Text:
parts+=TextPart;
TextPart[noskipws]:
(NormalString | SpecialKeyword | '\n')
;
NormalString[noskipws]:
!SpecialKeyword /(.*)?/ // this is too greedy
;
SpecialKeyword[noskipws]:
Link // more keywords are coming later
;
Link[noskipws]:
'[LINK: ' value = /[^\\]]*/ ']'
;
''')
textx_input = '''
Text part before [LINK: REQ-001] Text part after.
Text part before [LINK: REQ-002] Text part after.
'''
model = mm.model_from_str(textx_input, debug=False)
print(model.parts)发布于 2021-08-23 11:19:18
你们已经很接近了。解决方案是在NormalString中的每个否定断言之后匹配单个字符,然后重复。此外,跨多行的匹配是通过(?ms)正则表达式参数实现的。
可以在the textX docs中阅读更多内容。
Link规则很常见,它会产生Python对象,所以你需要提取actual关键字,它应该是一个匹配规则,从而产生Python字符串。
以下是完整的解决方案:
from textx import metamodel_from_str
mm = metamodel_from_str('''
Text:
parts+=TextPart;
TextPart[noskipws]:
Link | NormalString
;
NormalString[noskipws]:
(!SpecialKeyword /(?ms)./)*
;
SpecialKeyword:
LinkKW // more keywords are coming later
;
LinkKW: '[LINK: ';
Link[noskipws]:
LinkKW value = /[^\\]]*/ ']'
;
''')
textx_input = '''
Text part before [LINK: REQ-001] Text part after.
Text part before [LINK: REQ-002] Text part after.
'''
model = mm.model_from_str(textx_input, debug=True)
print(model.parts)https://stackoverflow.com/questions/68884718
复制相似问题