This project has moved and is read-only. For the latest updates, please go here.

Best way to make optional terms?

Apr 1, 2011 at 10:49 PM
Edited Apr 1, 2011 at 10:50 PM

I am doing something I feel should be rather trivial, as it is very common. I am not happy with any solution I have to deal with it though.

I have a method declaration that looks like this:

method.Rule = identifier + identifier + parameters + block;

I would like to make static methods possible with the keyword. My attempt to do this was:

method.Rule = flags + identifier + identifier + parameters + block
flags.Rule = Empty | "static"

But that causes a shift-reduce conflict, and it does not parse correctly. I am writing my own AST classes, and would like to keep the initialization logic as simple as possible, but I can't find a solution that helps me.

What I ended up doing to make it work is create a Method class and a Static method class that inherits from method and sets a flag for static. I then had to build my grammar like this:

method = new NonTerminal("method",typeof(Method));
staticMethod = new NonTerminal("staticMeth", typeof(StaticMethod));

method.Rule = identifier + identifier + parameters + block;
staticMethod.Rule = ToTerm("static") + identifier + identifier + parameters + block;

classMember.Rule = FieldDecl | method | staticMethod;

This is a lot of redundancy, but doing it this way allowed my method and static method classes to share initialization logic, with the exception of a boolean flag for static. I tried 

staticMethod.Rule = ToTerm("static") + method.Rule
but quickly found out that does all kind of weird things.
Is there a standard way to do this kind of thing with optional parts that doesn't create shift reduce conflicts?
Apr 1, 2011 at 10:52 PM

you could go with original solution if you mark "static" as reserved word:


- if it is in fact a reserved word

Apr 1, 2011 at 11:27 PM

Ok, I think that works pretty well. It looks like I have an additional shift-reduce conflict elsewhere in my grammar that this exposes. I've only ever created LL grammars before, so I'm not too comfortable formatting the rules to remove ambiguity.