Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use same token in multiple expressions? #295

Open
riej opened this issue Jan 21, 2022 · 0 comments
Open

How to use same token in multiple expressions? #295

riej opened this issue Jan 21, 2022 · 0 comments

Comments

@riej
Copy link

riej commented Jan 21, 2022

I'm trying to implement custom language plugin (Linden Script Language) for IntelliJ IDE. I already implemented parsing using YACC before, but have a problem while trying to do the same using GrammarKit.

The language has XYZ vector type, you can create vector using such construction:

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

But this construction is also valid:

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

But I don't know how to specify such syntax using GrammarKit. Here's short BNF file for example:

{
  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'

Everything works fine like that:

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

But shows errors in such case, without parentheses:

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

Can someone help me please and tell how to make it work?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant