匹配某些 xml 标记之间的任何输入的 Xtext 语法
Xtext grammar that matches any input between certain xml tags
我正在尝试为 freemarker 语言编写一个非常简单的 Xtext 语法。我无法匹配已知标签之间的任何文本。
到目前为止我的语法:
grammar org.github.FreemarkerEditor with org.eclipse.xtext.common.Terminals
generate freemarkerEditor "http://www.github.org/FreemarkerEditor"
Freemarker:
elements+=Element*;
Element: Tag|Print|Comment|Text;
Print:value=PRINT_CONTENT;
Tag:open=TAG_OPEN elements+=Element* TAG_CLOSE;
Text: text+=ANY_OTHER+;
Comment: text=COMMENT_CONTENT;
terminal PRINT_START_FRAGMENT:'${';
terminal PRINT_CONTENT:PRINT_START_FRAGMENT->'}';
terminal COMMENT_START:'<#--';
terminal COMMENT_CONTENT:COMMENT_START->'-->';
terminal TAG_START_FRAGMENT:'<#';
terminal TAG_OPEN:TAG_START_FRAGMENT->'>';
terminal TAG_CLOSE_START:'</#';
terminal TAG_CLOSE:TAG_CLOSE_START->'>';
它应该是这样工作的:文档中有 4 种元素可以以任何顺序和编号出现。始终以 <#tag some text and functions called>
</#tag>
开头的 Freemarker 标签可以再次包含任何元素。应包含忽略其中任何内容的所有文本的注释:<#-- Comment -->
。还有一些简单的打印语句,如下所示:${some variable or method call}
。其他一切,甚至是普通的 xml 标签或大括号都应该是未解析的文本。
我的语法问题似乎是无法匹配任何地方的文本。示例输入
${hallo.welt}
mhh
<#list something as somethingElse>${aha haha} some text </#list>
在 mhh
处显示错误,指出缺少 EOF。我必须如何更改语法才能按预期工作?
如果我生成你的语法,我得到
warning(200): ../org.xtext.example.mydsl4/src-gen/org/xtext/example/mydsl4/parser/antlr/internal/InternalMyDsl.g:297:1: Decision can match input such as "RULE_ANY_OTHER" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
warning(200): ../org.xtext.example.mydsl4.ui/src-gen/org/xtext/example/mydsl4/ui/contentassist/antlr/internal/InternalMyDsl.g:194:28: Decision can match input such as "RULE_ANY_OTHER" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
因此你的语法有歧义,你应该修正它,例如通过说 Text 应该尽可能多地吃掉(句法谓词)
Text: => text+=ANY_OTHER+;
然后还有排名更高的其他终端 ANY_OTHER
例如编号
你也必须尊重这一点
Text: => text+=(ID|ANY_OTHER)+;
你为什么要这样写语法?无论如何,这是你的语法。
我花了一段时间才弄清楚你的语法问题,不过我找到了解决你问题的方法。
第一个问题:Text
规则:因为它是一个无限长的输入,可以匹配进去,你必须注意它是不可能的Text
规则后跟 Text
规则。
第二个问题:Text
规则好像是没有引号的字符串
第三个问题:包含->
的terminal
规则:这个太含糊了
我已经完全重建了你的语法,但在我的 workbench 中它有效。也许它会做你想要的:
Freemarker:
elements+=Text?
(elements+=Element
elements+=Text?)*;
Element:
Tag | Print | Comment;
Tag:
'<#' open=ID content=MyString '>' elements=Freemarker '</#' close=ID '>';
MyString:
ID ('.' | ID)*;
Print:
'${' content=MyString '}';
Text returns Element:
text=MyString;
Comment:
{Comment} '<#--' -> '-->';
如您所见,Text
规则无法通过 Element
规则访问,但 Element 是它的超类型。并且任何 Text
元素都必须后跟一个非 Text
.
类型的元素
A Text
元素以 ID
开头,后跟 .
或 ID
,然后是 ... 我认为您可以通过任何方式扩展它其他标志,但你必须尝试。
那么,在我看来,多属性比什么都好。这使得使用模型变得更加容易。
如果您对递归有任何问题或有任何歧义,可以使用一个非常有用的工具,称为 ANTLRWorks。它可以可视化您的语法问题。要使用此工具,有一个可选片段可以包含在 MWE2 工作流中,该工作流构建一个干净的 ANTLR 语法文件:
fragment = parser.antlr.DebugAntlrGeneratorFragment {}
我正在尝试为 freemarker 语言编写一个非常简单的 Xtext 语法。我无法匹配已知标签之间的任何文本。
到目前为止我的语法:
grammar org.github.FreemarkerEditor with org.eclipse.xtext.common.Terminals
generate freemarkerEditor "http://www.github.org/FreemarkerEditor"
Freemarker:
elements+=Element*;
Element: Tag|Print|Comment|Text;
Print:value=PRINT_CONTENT;
Tag:open=TAG_OPEN elements+=Element* TAG_CLOSE;
Text: text+=ANY_OTHER+;
Comment: text=COMMENT_CONTENT;
terminal PRINT_START_FRAGMENT:'${';
terminal PRINT_CONTENT:PRINT_START_FRAGMENT->'}';
terminal COMMENT_START:'<#--';
terminal COMMENT_CONTENT:COMMENT_START->'-->';
terminal TAG_START_FRAGMENT:'<#';
terminal TAG_OPEN:TAG_START_FRAGMENT->'>';
terminal TAG_CLOSE_START:'</#';
terminal TAG_CLOSE:TAG_CLOSE_START->'>';
它应该是这样工作的:文档中有 4 种元素可以以任何顺序和编号出现。始终以 <#tag some text and functions called>
</#tag>
开头的 Freemarker 标签可以再次包含任何元素。应包含忽略其中任何内容的所有文本的注释:<#-- Comment -->
。还有一些简单的打印语句,如下所示:${some variable or method call}
。其他一切,甚至是普通的 xml 标签或大括号都应该是未解析的文本。
我的语法问题似乎是无法匹配任何地方的文本。示例输入
${hallo.welt}
mhh
<#list something as somethingElse>${aha haha} some text </#list>
在 mhh
处显示错误,指出缺少 EOF。我必须如何更改语法才能按预期工作?
如果我生成你的语法,我得到
warning(200): ../org.xtext.example.mydsl4/src-gen/org/xtext/example/mydsl4/parser/antlr/internal/InternalMyDsl.g:297:1: Decision can match input such as "RULE_ANY_OTHER" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
warning(200): ../org.xtext.example.mydsl4.ui/src-gen/org/xtext/example/mydsl4/ui/contentassist/antlr/internal/InternalMyDsl.g:194:28: Decision can match input such as "RULE_ANY_OTHER" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
因此你的语法有歧义,你应该修正它,例如通过说 Text 应该尽可能多地吃掉(句法谓词)
Text: => text+=ANY_OTHER+;
然后还有排名更高的其他终端 ANY_OTHER 例如编号
你也必须尊重这一点
Text: => text+=(ID|ANY_OTHER)+;
你为什么要这样写语法?无论如何,这是你的语法。
我花了一段时间才弄清楚你的语法问题,不过我找到了解决你问题的方法。
第一个问题:Text
规则:因为它是一个无限长的输入,可以匹配进去,你必须注意它是不可能的Text
规则后跟 Text
规则。
第二个问题:Text
规则好像是没有引号的字符串
第三个问题:包含->
的terminal
规则:这个太含糊了
我已经完全重建了你的语法,但在我的 workbench 中它有效。也许它会做你想要的:
Freemarker:
elements+=Text?
(elements+=Element
elements+=Text?)*;
Element:
Tag | Print | Comment;
Tag:
'<#' open=ID content=MyString '>' elements=Freemarker '</#' close=ID '>';
MyString:
ID ('.' | ID)*;
Print:
'${' content=MyString '}';
Text returns Element:
text=MyString;
Comment:
{Comment} '<#--' -> '-->';
如您所见,Text
规则无法通过 Element
规则访问,但 Element 是它的超类型。并且任何 Text
元素都必须后跟一个非 Text
.
A Text
元素以 ID
开头,后跟 .
或 ID
,然后是 ... 我认为您可以通过任何方式扩展它其他标志,但你必须尝试。
那么,在我看来,多属性比什么都好。这使得使用模型变得更加容易。
如果您对递归有任何问题或有任何歧义,可以使用一个非常有用的工具,称为 ANTLRWorks。它可以可视化您的语法问题。要使用此工具,有一个可选片段可以包含在 MWE2 工作流中,该工作流构建一个干净的 ANTLR 语法文件:
fragment = parser.antlr.DebugAntlrGeneratorFragment {}