Error while parsing with an optional reference #1303
-
Hello,
It works well when I run the extension on the following code:
but if I remove 'myImport.' in my firstAttr declaration, I get the following error message: Could not resolve reference to Import named 'SecondClass'. It looks like Langium is not looking for a Class ID at all, but in my understanding my Attribute grammar should allow Langium to search for either an Import or a Class ID. But what I find most confusing is that the error disappears once I change the "." by "->" in either my Attribute or ClassCall grammar. Then I am able to call myImport before SecondClass or not. I also found that I can make it work with "." appearing twice by removing the ClassCall parser rule and rewrite my attributes like this:
but I don't understand what changed for Langium once I do that. Can somebody explain to me why the error occurs if I try to do the same thing with "." in both my Attribute and my ClassCall grammar? I'm sure there is something I misunderstand. Thank you for your help. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
Hey @antoinelilly, thanks for trying out Langium :) When trying to parse the What you've just created is called a parser ambiguity since the part after the optional element looks exactly like the optional element itself - the parser cannot differentiate between those options. In order to support such a grammar, you will need to refactor it into multiple steps of member references. See our guide here. We have a very similar issue in our Langium implementation of SQL. For example, how to decide whether the name |
Beta Was this translation helpful? Give feedback.
-
OK I think I understand the problem now and how to fix it for next times. Thank you so much for this quick answer! |
Beta Was this translation helpful? Give feedback.
Hey @antoinelilly, thanks for trying out Langium :)
When trying to parse the
(import=[Import:ID] ".")? refclass=[Class:ID])
part of your grammar, the underlying parser of Langium doesn't know about the semantic meaning of those references. All it sees are:(ID '.')? ID
. When trying to decide whether it should parse the(ID '.')?
part, the parser will need to look at the next few tokens to see whether that's a valid option. It sees[ID, '.']
in the stack and decides to parse the optional part, even though there isn't enough left afterwards to parse the rest of the parser rule successfully.What you've just created is called a parser ambiguity since the part after the optional element looks…