eclipse-langium / langium

Next-gen language engineering / DSL framework
https://langium.org/
MIT License
754 stars 68 forks source link

Error: Maximum call stack size exceeded #635

Closed luan-xiaokun closed 2 years ago

luan-xiaokun commented 2 years ago

When run the vscode extension, get the following error

[Error - 19:51:45] Request textDocument/semanticTokens/range failed.
  Message: Request textDocument/semanticTokens/range failed with message: Maximum call stack size exceeded
  Code: -32603 

Langium version: 0.4.0

Steps To Reproduce

  1. The semantic token provider is implemented as follows
export class MediatorGrammarSemanticTokenProvider extends AbstractSemanticTokenProvider {
    protected highlightElement(node: AstNode, acceptor: SemanticTokenAcceptor): void {
        if (isTypeDefinition(node)) {
            acceptor({
                node,
                feature: 'alias',
                type: SemanticTokenTypes.type
            });
        }
    }
}
  1. A minimal grammar to reproduce
entry Program:
    TypeDefinition*;

TypeDefinition infers TypeDefinition:
    'typedef' name=TypeSpecifier 'as' alias=ID ';';

TypeSpecifier:
    (
        'int' | 'real' | 'char' | 'bool' | UnionCompositeTypeSpecifier
    )
    ('[' Expression? ']')?
    ('init' init=Expression)?
;

UnionCompositeTypeSpecifier:
    'union' '(' TypeSpecifier (',' TypeSpecifier)* ')';

Expression:
    Addition;

Addition infers Expression:
    Multiplication ({infer BinaryExpression.left=current} operator=('+' | '-') right=Multiplication)*;

Multiplication infers Expression:
    PrimaryExpression ({infer BinaryExpression.left=current} operator=('*' | '/') right=PrimaryExpression)*;

PrimaryExpression infers Expression:
    '(' Expression ')' |
    {infer NumberLiteral} value=(INT | FLOAT);

terminal ID returns string: /[a-zA-Z_]\w*/;
terminal FLOAT returns number: /\d+\.\d*/;
terminal INT returns number: /[1-9]\d*|0/;

hidden terminal WS: /\s+/;
hidden terminal ML_COMMENT: /\/\*[\s\S]*?\*\//;
hidden terminal SL_COMMENT: /\/\/[^\n\r]*/;

NOTE: the error disappears when the UnionCompositeTypeSpecifier rule is removed.

The current behavior

When running the plugin, open the file and write:

typedef int as myint;

then the error shows up, and myint is not correctly colored.

The expected behavior

When the UnionCompositeTypeSpecifier rule is removed, myint gets correctly colored, and the error disappears.

msujew commented 2 years ago

Hey @luan-xiaokun,

When the UnionCompositeTypeSpecifier rule is removed

That kind of makes perfect sense, since it's not a legal rule. Our validations don't catch it (yet), but having multiple unassigned rule calls after another don't work as expected (as in: undefined behavior). Something like the following should resolve the issue:

UnionCompositeTypeSpecifier:
    'union' '(' specifiers+=TypeSpecifier (',' specificers+=TypeSpecifier)* ')';

Can you try that and see whether that resolves the issue?

luan-xiaokun commented 2 years ago

It works, thanks for you help!

My complete grammar seems to have many such errors, so it seems that I should spend more time learning the langium grammar.