0

我正在尝试为 IntelliJ IDE 实现自定义语言插件(林登脚本语言)。

该语言具有 XYZ 向量类型,您可以使用以下构造创建向量:

<X, Y, Z>
<1.0, 2.0, 3.0>

但这种结构也是有效的:

<1, 2 < 3 > 4, 5> // same as <1, (2 < 3 > 4), 5>

但我不知道如何使用 GrammarKit 指定这样的语法。这是一个简短的 BNF 文件,例如:

{
  parserClass="org.example.SomeParser"

  extends="com.intellij.extapi.psi.ASTWrapperPsiElement"

  psiClassPrefix="Some"
  psiImplClassSuffix="Impl"
  psiPackage="org.example.psi"
  psiImplPackage="org.example.psi.impl"

  elementTypeHolderClass="org.example.psi.SomeTypes"
  elementTypeClass="org.example.psi.SomeElementType"
  tokenTypeClass="org.example.psi.SomeTokenType"

  generateTokenAccessors=true

  tokens=[
    INTEGER = 'regexp:[+-]?[0-9]+'
    FLOAT = 'regexp:[+-]?([0-9]*\.[0-9]+|[0-9]+\.[0-9]*|[0-9]+)([Ee][+-]?[0-9]+)?[Ff]?'

    IDENTIFIER = 'regexp:[a-zA-Z_][a-zA-Z0-9_]*'

    space='regexp:\s+'
    comment='regexp://.*'
    id='regexp:\p{Alpha}\w*'
  ]
}

SomeFile ::= Statement*

Statement ::= (
    StatementVariableDeclaration
    | StatementIf
    | StatementAssign
)

StatementVariableDeclaration ::= TypeName IDENTIFIER ('=' Expression)? ';' {pin=1 recoverWhile=StatementRecover extends=Statement}
StatementIf ::= 'if' '(' Expression ')' Statement {pin=1 recoverWhile=StatementRecover extends=Statement}
StatementAssign ::= LValue '=' Expression ';' {recoverWhile=StatementRecover extends=Statement}

private StatementRecover ::= !(TypeName | 'if' | IDENTIFIER)

Expression ::= (
    ConstantValue
    | LValue
    | ExpressionPlus
    | ExpressionMinus
    | ExpressionGreater
    | ExpressionLesser
    | ExpressionVector
    | ExpressionParentheses
)

ExpressionVector ::= '<' Expression ',' Expression ',' Expression '>' {pin=1 extends=Expression}
ExpressionPlus ::= Expression '+' Expression {pin=2 extends=Expression}
ExpressionMinus ::= Expression '-' Expression {pin=2 extends=Expression}
ExpressionGreater ::= Expression '>' Expression {pin=2 extends=Expression}
ExpressionLesser ::= Expression '<' Expression {pin=2 extends=Expression}
ExpressionParentheses ::= '(' Expression ')' {pin=1 extends=Expression}

LValue ::= IDENTIFIER ('.' IDENTIFIER)? {extends=Expression}
ConstantValue ::= (INTEGER | FLOAT) {extends=Expression}

TypeName ::= 'vector'

一切都像这样正常工作:

vector a = <1, 2, 3>;
if (a.x > a.y) a.z = a.x;
vector d = <1, (2 > 3 < 4), 5>;

但在这种情况下显示错误,不带括号:

vector a = <1, 2, 3>;
if (a.x > a.y) a.z = a.x;
vector d = <1, 2 > 3 < 4, 5>;

有人可以帮助我并告诉我如何解决这个语法吗?

4

0 回答 0