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

Xtext:关键字作为标识符

万俟光临
2023-03-14

我有以下问题:我正在为GLSL着色语言创建一个编辑器。我希望在某些情况下允许关键字作为标识符,因为内置函数的名称可以用作标识符。

例如:vec3纹理=vec3(1,2,3) 是有效的,即使纹理是一个内置函数。

这是内置函数的规则:

BuiltInFunction:
'abs' |
'acos' |
'acosh' |
'all' |
'any' |
'asin' |
'asinh' |
'atan' |
'atanh' |
'atomicAdd' |
'atomicAnd' |
//etc...

这是标识符终端规则:

terminal IDENTIFIER: (('a'..'z')|('A'..'Z')|'_') (('a'..'z')|('A'..'Z')|'_'|('0'..'9'))*;

这是编辑器中的结果<代码>纹理abs不被识别为标识符。

完整语法供参考:http://paste2.org/YwDNkBYW

解决方案:

我创建了一个包含所有内置函数的源文件:

common void abs(); 
common void acos(); 
common void acosh(); 
common void all(); 
common void any(); 
common void asin(); 
common void asinh(); 
common void atan(); 
common void atanh(); 
common void atomicAdd(); 
common void atomicAnd(); 
common void atomicCompSwap(); 
//etc...

我使用保留的关键字common来区分内置函数和本地创建的函数:

BuiltInFunctionDeclaration returns FunctionDeclaration:
    'common' qualifier=TypeQualifier? type=Type name=BuiltInFunction LEFT_PAREN (args+=Parameter (COMMA args+=Parameter)*)? RIGHT_PAREN (functionBlock=BlockStatement|SEMICOLON)
;

BuiltInFunction returns Function:
    ({BuiltInFunction}name=IDENTIFIER)
;

FunctionDeclaration:
    qualifier=TypeQualifier? type=Type name=Function LEFT_PAREN (args+=Parameter (COMMA args+=Parameter)*)? RIGHT_PAREN (functionBlock=BlockStatement|SEMICOLON)
;

Function:
    ({Function}name=IDENTIFIER)
;

...在ScopeProvider中添加了以下内容:

public IScope scope_CallFunction_name(CallFunction context,EReference reference){
    ... add local functions to list ...
    if(builtInFunctions==null){
        ResourceSet set=file.eResource().getResourceSet();
        Resource r=set.createResource(URI.createURI("internal:/builtin.glsl"));
        try {
            //Internals.builtInFunctions is a String of the source file.
            r.load(new ByteArrayInputStream(Internals.builtInFunctions.getBytes()), set.getLoadOptions());
        } catch (IOException e) {
            e.printStackTrace();
        }
        builtInFunctions=((GLSLFile) r.getContents().get(0)).getFunctions().stream()
                .map(FunctionDeclaration::getName)
                .collect(Collectors.toList());
    }
    functions.addAll(builtInFunctions);
    return Scopes.scopeFor(functions);
}

ISemanticHighlight ing计算器中,我在迭代器循环中添加了这个检查:

        if(current instanceof CallFunction){
            if(((CallFunction) current).getName() instanceof BuiltInFunction){
                acceptor.addPosition(node.getOffset(), node.getLength(), "CallBuiltInFunction");
                continue;
            }
        }

共有1个答案

薛烈
2023-03-14

在xtext中,关键字覆盖标识符规则。当您在规则中使用标识符时,它将永远不会与关键字匹配。

无论如何,如果你想这么做,你必须把这些规则合并成一个新的规则:

keywordOrIdentifier:
    BuiltInFunction | IDENTIFIER
;

然后您必须使用此规则而不是IDENTIFIER规则:

Function:
    {Function} name=keywordOrIdentifier
;

通过此修改,您的语法将解析所需内容,如本例所示:

vec3 texture(float x, float y) {
    return vec(1,2,3)
}

这个解决方案的唯一问题是,单词texture将作为关键字着色,而在这种情况下,它不是关键字。我想你可以用一个自定义的语义计算程序来覆盖这个行为。

 类似资料:
  • 问题内容: 我在OCJP for Java6的书中读到了带有断言的部分。我到达了那一部分,它概述了如果将“ assert”一词用作关键字或标识符时编译器的反应。 a 和an有什么区别?谁能给我一个简单的解释,并同时给我一个或多个例子? 问题答案: 术语“关键字”和“标识符”不是Java特定的。 关键字是Java关键字列表中的保留字,可为编译器提供指令。由于保留了关键字,因此程序员不能将其用于变量或

  • 主要内容:标识符,关键字任何一种计算机语言都离不开标识符和关键字,因此下面将详细介绍 Java 的标识符、关键字和保留字。 标识符 Java 中标识符是为方法、变量或其他用户定义项所定义的名称。标识符可以有一个或多个字符。在 Java 语言中,标识符的构成规则如下。 标识符由数字(0~9)和字母(A~Z 和 a~z)、美元符号($)、下划线(_)以及 Unicode 字符集中符号大于 0xC0 的所有符号组合构成(各符号

  • 我不明白关键字的区别("-

  • 我试图让一些sql关键字作为标识符被接受,当用作标识符时。Antlr的书p210提出了这个技巧: 我也有类似的东西,但它不起作用,我想这是我的误解。是标识符的解析规则,因此: 是ident的主要lex规则。大致是这样的(这里简化了),它起作用了: 如果我给它作为输入('aaa'不是关键字),它将解析: 但是如果我给它,它就会失败--'sparse'是一个关键字: 也许我很笨,但我不明白为什么,因为

  • 主要内容:关键字,标识符Go语言的词法元素包括 5 种,分别是标识符(identifier)、关键字(keyword)、操作符(operator)、分隔符(delimiter)、字面量(literal),它们是组成Go语言代码和程序的最基本单位。 本节我们主要来介绍一下Go语言中的关键字和标识符。 关键字 关键字即是被Go语言赋予了特殊含义的单词,也可以称为保留字。 Go语言中的关键字一共有 25 个: break de

  • 本文向大家介绍Java的关键字与标识符小结,包括了Java的关键字与标识符小结的使用技巧和注意事项,需要的朋友参考一下 本文总结了Java的关键字与标识符。分享给大家供大家参考,具体如下: 关键字: 定义 特点 用于定义数据类型的关键字 用于定义流程控制的关键字 用于定义访问权限修饰符的关键字 用于定义类,函数,变量修饰符的关键字 用于定义类,函数,变量修饰符的关键字 用于定义类与类之间的关系的关