当前位置: 首页 > 知识库问答 >
问题:

Xtext:防止匹配其他规则中的关键字

咸臻
2023-03-14

我正在寻找一种方法,防止在一个不需要关键词的地方匹配关键词。

看看下面的语法。“应用”和“输出”都是关键词。”OUTPUT'有一个包含任何字符的参数。

一切正常,但如果此参数包含单词APPLY,则会引发错误(外部输入APPLY预期规则_END)。

有办法解决这个问题吗?谢谢

示例文本

APPLY, 'an id' $
OUTPUT, A text $
OUTPUT, A text with the word APPLY $

数字用户线

grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals

generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"

Model:
    statement+=Statement*;

Statement:
    ApplyStatement | OutputStatement;

OutputStatement:
    'OUTPUT' ',' out+=EXTENDLABEL* end=END;

ApplyStatement:
    'APPLY' ',' id=LABELIDENTIFIER end=END;

terminal fragment LETTER:
    'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T'
    | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' |
    'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z';

terminal LABELIDENTIFIER:
    "'"->"'";

terminal EXTENDLABEL:
    (LETTER) (LETTER)*;

terminal END:
    '$' !('\n' | '\r')*;

共有2个答案

闻人宏盛
2023-03-14

另一种解决方案是在解析器使用令牌之前更改令牌的ID。标记由lexer提供,解析器将把这些标记作为输入来生成AST。因此,我们的想法是在将令牌传递给解析器之前更改它们。

要做到这一点,您需要声明自己的解析器:

@Override
public Class<? extends IParser> bindIParser() {
    return ModelParser.class;
} 

注意:语法分析器将扩展生成的语法分析器。

然后,您需要重写以下方法来引入您自己的令牌源:

override protected XtextTokenStream createTokenStream(TokenSource tokenSource) {
    return new TokenSource(tokenSource, getTokenDefProvider());
} 

您自己的令牌源需要扩展“XtextTokenStream”。

之后,您需要重写方法'LT'如下:

override LT(int k) {
    var Token token = super.LT(k)
    if(token != null && token.text != null) token.tokenOverride(k);
    token
}

然后你只需要更改ID:

def void tokenOverride(Token token, int index){
    switch (token.text){
        case "APPLY" : {
            overrideType(t_parameter, InternalModelParser.RULE_ID);
        }
    }
 }

def void overrideType(Token token, int i) {
    token.type = i
}

注意:在更改令牌ID之前,不要忘记添加条件,在本例中,所有令牌“APPLY”都将成为一个ID。

当然,在交换机内部,您可以使用令牌“APPLY”的ID,而不是令牌的文本。

张建华
2023-03-14

我认为有几种不同的方法可以解决你的问题。首先,可以转义出现的关键字,例如Xbase语言使用“^”字符作为转义字符;如果出于任何原因,在编写关键字时出现问题,可以在其前面加上“^”,这样就可以了。类似地,如果你把字符串放在特定的符号中,例如撇号,这会很有帮助。当然,这些解决方案需要改变你的语言本身,你可以这样做,也可以不这样做。

还可以用数据类型规则替换EXTENDLABEL终端。这使得在解决冲突方面具有更大的灵活性;最坏的情况下,你可以添加语言关键字作为选项。Eclipse论坛上一个与此相关的案例向我建议了这条路线。

 类似资料:
  • 我不明白关键字的区别("-

  • 基本模式匹配 一切从最基本的开始。模式,是正则表达式最基本的元素,它们是一组描述字符串特征的字符。模式可以很简单,由普通的字符串组成,也可以非常复杂,往往用特殊的字符表示一个范围内的字符、重复出现,或表示上下文。例如: ^once 这个模式包含一个特殊的字符^,表示该模式只匹配那些以once开头的字符串。例如该模式与字符串"once upon a time"匹配,与"There once was

  • 我的第一个标签上有一条编辑文本。当然,当我触摸编辑文本时会出现软键盘。但当我访问第二个选项卡时,这意味着第二个选项卡活动,软键盘始终出现在我的第一个选项卡上,并且不会消失,即使我的第二个选项卡活动上没有EditText。 我想防止软键盘出现,当我访问我的第二个选项卡。 我如何解决这些问题? 这是我的清单文件

  • 语法规则 location [=|~|~*|^~] /uri/ { … } 模式 含义 location = /uri = 表示精确匹配,只有完全匹配上才能生效 location ^~ /uri ^~ 开头对URL路径进行前缀匹配,并且在正则之前。 location ~ pattern 开头表示区分大小写的正则匹配 location ~* pattern 开头表示不区分大小写的正则匹配 locat

  • 用户和首选项由objectProperty链接。 objectProperty断言需要通过SWRL规则从其他用户方面推断。例如,如果用户有听力困难,则需要将设置为,因此: 这很好用。但是,由于我有其他SWRL规则,这些规则也为相同的用户推断,例如: 我需要的是一个规则,不知怎么的,只有在没有更高的级别已经断言的情况下才会断言偏好。在给定的示例中,即使为true,唯一断言的级别也应该是,因为是其他规

  • 本文向大家介绍简介Nginx中的location匹配规则,包括了简介Nginx中的location匹配规则的使用技巧和注意事项,需要的朋友参考一下 location匹配命令 ~      #波浪线表示执行一个正则匹配,区分大小写 ~*    #表示执行一个正则匹配,不区分大小写 ^~    #^~表示普通字符匹配,如果该选项匹配,只匹配该选项,不匹配别的选项,一般用来匹配目录 =      #进行