Matching cross-references and IDs [message #906330] |
Sat, 01 September 2012 06:15 |
Erik Duymelinck Messages: 1 Registered: August 2012 Location: Denver, CO |
Junior Member |
|
|
Hi Everyone,
I am evaluating whether I should use Xtext for a project. In order to do so I wrote a grammar that looks a lot like a subset of C (without pre-processor support). During that exercise I ran into an issue that I could not overcome, even after reading through the documentation several times and reading through some of the relevant blog and forum posts that are available. Therefore I was hoping someone on this forum might be willing to look at this and share their thoughts and suggestions.
Below is a stripped down but functional version of my original grammar, which exhibits my problem. It only has declarations with optional initialisers, and simple expressions.
The problems start occurring as soon as I allow declarations to have a user defined type as defined in a "typedef" statement in addition to the built-in types. The parser will then start matching identifiers (e.g. on the LHS of an assignment) as a TypeSpecifier. This then results in a TypeDef that cannot be found since it doesn't exist. Some code examples below clarify.
grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals
import "http://www.eclipse.org/emf/2002/Ecore" as ecore
generate myDsl "<removed http> www.xtext.org/example/mydsl/MyDsl"
Model: (code+=Statement)*;
AssignmentOperator:
'=' | '+=' | '-='
;
StorageClass:
"extern" | "static" | "auto" | "register"
;
BuiltinType:
"char" | "int" | "long"
;
Statement:
(Declaration | Expression) ";"
;
TypeDef:
'typedef' declSpec=DeclarationSpecifiers? name=ID
;
TypeSpecifier:
type=BuiltinType | name=[TypeDef]
;
DeclarationSpecifiers:
storage=StorageClass typeSpec=TypeSpecifier?
| typeSpec=TypeSpecifier storage=StorageClass?
;
Declaration:
TypeDef | declSpec=DeclarationSpecifiers initDecl=InitDeclarator?
;
InitDeclarator:
name=ID ('=' init=Expression)?
;
Expression:
UnaryExpression ( {Expression.left=current} op=AssignmentOperator => right=Expression)?
;
UnaryExpression:
name=[InitDeclarator] | val=INT | '(' expr=Expression ')'
;
If I try to parse the following statement sequence, I get the results indicated as comments next to the statement:
static int a; // 1. ok
int extern b; // 2. ok
typedef int B; // 3. ok
int c; // 4. ok
B b; // 5. ok
static d; // 6. typedef "d" not found
c = 0; // 7. typedef "c" not found
I am under the impression that there is an issue in my DeclarationSpecifiers parser rule and/or that I am not understanding the cross-referencing mechanism correctly.
It seems that a rule containing a cross-reference will actually match any ID and only check the actual cross-reference at link time. A blog post on the itemis site about this matter (cross-references and scoping - part 1) seems to confirm this and talks about ways to deal with a related case:
Rule2: ... (ref=[Type] | simpleValue=ID)...
Introducing keywords or common supertypes are mentioned as possible solutions. However, I don't want to introduce new keywords and I don't see how I can create a common super type in my case: I have [TypeDef] or BuiltinType (which are essentially keywords).
Before I came to the conclusion that my issue might be in the way I use cross-referencing, I tried various versions of my DeclarationSpecifiers rule. Below is just one of these attempts, which I am mentioning because it caused an IllegalStateException when parsing the statements above with the generated parser. Not sure if this is a bug in ANTLR or Xtext and if so, whether I should file a bugzilla.
DeclarationSpecifiers:
(storage=StorageClass & typeSpec=TypeSpecifier) | storage=StorageClass | typeSpec=TypeSpecifier
;
Please let me know if you have any ideas of how I could work through the cross-reference problems in my grammar, or any pointers to available information that I might have missed.
Thank you,
Erik Duymelinck
|
|
|
Powered by
FUDForum. Page generated in 0.02308 seconds