Comments (4)
Hey @csalve,
yeah, looking at the AST that is being produced by the given input, I can definitely see that it tries to generate a Attribute
node instead of continuing with the Struct
rule.
Given that we have limited influence on the error recovery in Langium, I would instead recommend to restructure your grammar a bit. The main issue here is that you have an alternative with a fairly large prefix:
By removing this prefix, we can get a way better completion result:
See the improved grammar below:
entry Model:
(structs+=Struct | attributes+=Attribute)*;
Attribute:
'@' id=INT 'attribute' name=ID;
Struct:
'struct' name=ID '{'
(members+=Member)*
'}';
Member:
'@' id=INT
name=ID ':' ({infer IntegerMember} (type='uint' | type='int') |
{infer StringMember} (type='string' | type='nanoid'));
from langium.
@msujew Thanks for your help.
The improved grammar solves the issue with the parser but opens two new problems.
I tried to implement your suggestion in two different ways and both of them lead to problems/errors with the ast.
Using Interfaces
The documentation tells me, that it is good practice to define interface types.
So I did:
interface IntegerMember {
type:string
}
interface StringMember {
type:string
}
Member:
'@' id=INT
name=ID ':'
(
{IntegerMember} (type='uint' | type='int') |
{StringMember} (type='string' | type='nanoid')
);
But the generated AST does not give me the possibility to access the 'type' variable.
There is no relation between IntegerMember and Member:
export interface IntegerMember extends AstNode {
readonly $type: 'IntegerMember';
type: string
}
export interface Member extends AstNode {
readonly $container: Struct;
readonly $type: 'Member';
id: number
name: string
}
Infer types without interfaces
Using the improved grammar as above creates a good AST:
export interface Member extends AstNode {
readonly $type: 'IntegerMember' | 'Member' | 'StringMember';
id: number
name: string
}
export interface IntegerMember extends Member {
readonly $type: 'IntegerMember';
type: 'int' | 'uint'
}
export interface StringMember extends Member {
readonly $type: 'StringMember';
type: 'nanoid' | 'string'
}
Problem here: The 'name' and 'id' of the Member struct is never set:
In both described cases, langium violates the type system.
from langium.
@csalve Right, I forgot that using the actions syntax removes all previous properties. We kind of inherited that behavior from Xtext and never bothered to change it. You should be good without using it:
Member:
'@' id=INT
name=ID ':'
(
type='uint' | type='int' |
type='string' | type='nanoid'
);
You can write your own isStringMember
function if you need to that checks the value of the type
property on a Member
type.
from langium.
Since this is a known (but unfixable on our side) issue, and it can be worked around by improving the grammar design, I'll close this.
from langium.
Related Issues (20)
- Add features for the Arithmetic example
- Misleading type compatibility validation error
- Add features for the Statemachine example HOT 3
- Enforce isolation of package exports HOT 2
- Parsing EOF leads to invalid CST ranges
- Inconsistent behavior in the completion provider service
- Add service for text document handling HOT 1
- Type hierarchy provider HOT 1
- Testing facilities generated out of the box HOT 1
- Move generator API to separate export HOT 1
- Add read queue to workspace mutex HOT 1
- Non-linear performance during code generation HOT 1
- Add another CompositeGeneratorNode#indent overload HOT 1
- Parse error, but still yields a correct AST HOT 3
- Make the `$container` type more precise in case of guard conditions HOT 2
- Content assist not working at specific grammar element
- Parser rule used as type for cross-reference is marked as "unused" HOT 4
- Consecutive keyword not proposed without space HOT 5
- `yo langium` results in `"initialize" is not exported by "node_modules/vscode/extensions.js"` HOT 9
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from langium.