捕获可以在Xtext中使用Parser关键字开头的内容

时间:2015-09-30 14:33:39

标签: grammar xtext

以下是我实际语法的简化版本: -

grammar org.hello.World 

import "http://www.eclipse.org/emf/2002/Ecore" as ecore

generate world "http://www.hello.org/World"

Model:
    content=AnyContent greetings+=Greeting*;

AnyContent:
    (ID | ANY_OTHER)*
;

Greeting:
    '<hello>' name=ID '</hello>';

terminal ID:
    ('a'..'z'|'A'..'Z')+
;

terminal ANY_OTHER:
    .
;

如果输入如下,则使用上面的语法: -

&LT;喜&GT;&LT;你好&GT;世界&LT; /你好&GT;

然后我收到一个语法错误,指出不匹配的字符&#39; i&#39;期待第2栏的“

我的要求是AnyContent应匹配&#34;&lt; hi&gt;&#34; ,任何人都可以指导我如何实现这一目标吗?

2 个答案:

答案 0 :(得分:1)

如果你想用Xtext制作它。我建议你解决你的问题。你的第一个问题是语法,你需要解析你的文件。第二个问题是语义问题,你想给出一个&#34; sense&#34;到你的objets并告诉谁是容器。定义容器,XML的包含不能在你的语法中完成。

  1. 制作自定义Ecore,并使用开始和结束标记制作简单的语法。您并不真正关心标签的名称。 示例:

    Model returns XmlFile: (StartTag|EndTag|Text)+;
    
    Text returns Text: text=STRING;
    
    StartTag returns StartTag: '<' name=ID '>';
    
    EndTag returns EndTag: '</' name=ID '>';
    
  2. 更改TokenSource。令牌源将令牌提供给您的Parser。您可以覆盖令牌的性质,合并或拆分它们。 这里的想法是将所有令牌合并到">""</"之间。 此标记表示文本,因此您可以为包含此元素之间的所有元素创建单个标记。示例:

    class CustomTokenSource extends XtextTokenStream{
    
    
    new(TokenSource tokenSource, ITokenDefProvider tokenDefProvider) {  
        super(tokenSource,tokenDefProvider)
    }
    
    override LT(int k) {
        var Token token = super.LT(k)
        if(token != null && token.text != null) token.tokenOverride(k);
        token
    }
    
  3. 在此示例中,您需要在方法&#34; tokenOverride&#34;上添加自定义代码。

    在解析器上添加自定义令牌源:

    class XDSLParser extends DSLParser{
    
    override protected XtextTokenStream createTokenStream(TokenSource tokenSource) {
       return new CustomTokenSource(tokenSource, getTokenDefProvider());
    }
    
    }
    
    1. 计算容器:解析后可以计算元素的包含。在它之后,您可以获得您的模型并随意更改它。要做到这一点,你需要覆盖方法&#34; doParse&#34;你的Parser&#34; XDSLParser&#34;如下:

      override protected IParseResult doParse(String ruleName, CharStream in,         NodeModelBuilder nodeModelBuilder, int initialLookAhead) {      
      var IParseResult result = super.doParse( ruleName,  in,  nodeModelBuilder,  initialLookAhead)
      
      //Give you model        
      result.rootASTElement;
      
          return result
      

      }

    2. 注意:解析后获得的模型将是平坦的。 xmlFile对象将包含良好顺序中的所有元素。您需要编写一个算法来在AST模型上构建容器。

答案 1 :(得分:0)

由于Xtext使用的antlr词法分析器的性质,这将需要在语法中进行大量调整。词法分析器不会回滚关键字<hello>:只要它看到<后跟h,它就会尝试使用hello-token。这些方面的东西可以起作用:

Model:
    content=AnyContent greetings+=Greeting*;

AnyContent:
    (ID | ANY_OTHER | '<' (ID | ANY_OTHER | '/' | '>') | '/' | '>' | 'hello')*
;

Greeting:
    '<' 'hello '>' name=ID '<' '/' 'hello' '>';

terminal ID:
    ('a'..'z'|'A'..'Z')+
;

terminal ANY_OTHER:
    .
;

这种方法不会扩展到现实世界的语法,但也许有助于走上一些工作轨道。