parsing - 如何在 xtext 语法中处理 xml 标签之间的类似字符串的值
问题描述
我正在尝试创建一种强定义的 xml 语言,但在元素标记之间的元素值上遇到了麻烦。我希望它们被视为一个字符串,除非它们没有用引号括起来。这是我为演示这个想法而创建的基本语法:
grammar org.xtext.example.myxml.MyXml hidden(WS)
generate myXml "http://www.xtext.org/example/myxml/MyXml"
import "http://www.eclipse.org/emf/2002/Ecore" as ecore
Element:
{Element}
'<Element' attributes+=ElementAttribute* ('/>' | '>'
subElement+=SubElement*
'</Element' '>')
;
SubElement:
{SubElement}
'<SubElement' attributes+=SubElementAttribute* ('/>' | '>'
value=ElementValue
'</SubElement' '>')
;
ElementAttribute:
NameAttribute | TypeAttribute
;
SubElementAttribute:
NameAttribute
;
TypeAttribute:
'type' '=' type=STRING
;
NameAttribute:
'name' '=' name=STRING
;
ElementValue hidden():
value=ID
;
terminal STRING:
'"' ( '\\' . /* 'b'|'t'|'n'|'f'|'r'|'u'|'"'|"'"|'\\' */ | !('\\'|'"') )* '"' |
"'" ( '\\' . /* 'b'|'t'|'n'|'f'|'r'|'u'|'"'|"'"|'\\' */ | !('\\'|"'") )* "'"
;
terminal WS: (' '|'\t'|'\r'|'\n')+;
terminal ID: '^'?('a'..'z'|'A'..'Z'|'_'|'0'..'9'|':'|'-'|'('|')')*;
这是一个演示其用法的测试:
@Test
def void parseXML() {
val result = parseHelper.parse('''
<Element type="myType" name="myName">
<SubElement>some string:like-stuff here </SubElement>
</Element>
''')
Assert.assertNotNull(result)
val errors = result.eResource.errors
for (error : errors) {
println(error.message)
}
}
我从这个确切的代码中得到的错误是mismatched input 'string:like-stuff' expecting '</SubElement'
显然这不起作用,因为ID
不允许空格,添加空格来ID
修复上述错误,但会导致解析其他问题。所以我的问题是如何将元素值解析为类似字符串的表示形式,而不会导致其他领域的解析器产生歧义。我能够让它以我的完整语言以任何形式工作的唯一方法是将转换为由空格分隔ElementValue
的列表。ID's
(但是我无法让它在这个最小的例子上工作,不确定有什么不同)
解决方案
我不会真正推荐它,因为 Xtext 通常不是最适合 XML 解析的,但是通过将 ElementValue 转换为允许所有不会产生歧义的数据类型规则,这可能是可能的。
类似于以下内容:
ElementValue returns ecore::EString hidden(): (ID|WS|STRING|UNMATCHED)+ ;
在语法的最后:
terminal UNMATCHED: .;
您可能希望将 SubElement.value 设为可选以允许空元素。
value=ElementValue?
推荐阅读
- ios - UITableview 粘性标题未在 iPhone X 上正确呈现
- variables - 如何在clojure宏中绑定var的名称和值?
- azure - 如何使用 AzureADGraph 或 Microsoft Graph 为 AZURE AD B2C 中的用户生成访问令牌?
- lotus-notes - 如何通过点击 Lotus Notes 邮件主题打开网站链接?
- ajax - 如何在 laravel 5.2 中控制多个 ajax 请求
- android - app:compileDebugJavaWithJavac 删除包后
- r - 将因子更改为 R 中的日期时间
- javascript - 滚动页面时如何在屏幕上显示固定的引导模式?
- firebase - Firestore 安全规则:仅允许用户创建文档
- javascript - Redux - 如何对更改做出反应