Generating the parser.
.............
.............
.............
..
...java.lang.NullPointerExceptionnull
at org.sablecc.sablecc.ComputeInlining.computeInlining(Unknown Source)
at org.sablecc.sablecc.GenParser.caseStart(Unknown Source)
at org.sablecc.sablecc.node.Start.apply(Unknown Source)
at org.sablecc.sablecc.SableCC.processGrammar(Unknown Source)
at org.sablecc.sablecc.SableCC.processGrammar(Unknown Source)
at org.sablecc.sablecc.SableCC.main(Unknown Source)
s = {unmatched} u |
{matched} m;
m = e implies [m1]:m else [m2]:m |
{expr} e;
u = {case1} e implies s |
{case2} e implies m else u;
e = s |
{num} number;
Etienne Gagnon, Ph.D. http://sablecc.org
--
-- You received this message because you are subscribed to the SableCC group. To post to this group, send email to sab...@googlegroups.com. To unsubscribe from this group, send email to sablecc+u...@googlegroups.com. For more options, visit this group at https://groups.google.com/d/forum/sablecc?hl=en
Package ca.stevenstewart;
Helpers
digit = ['0'..'9'];
tab = 9;
cr = 13;
lf = 10;
eol = cr lf | cr | lf;
whitespace = (' ' | tab | eol)+;
Tokens
else = 'else';
implies = '=>' | 'implies';
number = digit+;
whitespace = whitespace;
Ignored Tokens
whitespace;
Productions
s = {unmatched} u |
{matched} m;
m = e implies [m1]:m else [m2]:m |
{expr} e;
u = {case1} e implies s |
{case2} e implies m else u;
e = s |
{num} number;
SableCC version 3.3
Copyright (C) 1997-2012 Etienne M. Gagnon <ega...@j-meg.com> and
others. All rights reserved.
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to redistribute it under certain conditions.
Type 'sablecc -license' to view
the complete copyright notice and license.
-- Generating parser for test.grammar in /Users/macbookpro/Documents/A4/test/src
Adding productions and alternative of section AST.
Verifying identifiers.
Verifying ast identifiers.
Adding empty productions and empty alternative transformation if necessary.
Adding productions and alternative transformation if necessary.
computing alternative symbol table identifiers.
Verifying production transform identifiers.
Verifying ast alternatives transform identifiers.
Generating token classes.
Generating production classes.
Generating alternative classes.
Generating analysis classes.
Generating utility classes.
Generating the lexer.
State: INITIAL
- Constructing NFA.
.......................
- Constructing DFA.
..............................................
....................
- resolving ACCEPT states.
Generating the parser.
.............
.............
.............
..
...null
java.lang.NullPointerException
at org.sablecc.sablecc.ComputeInlining.computeInlining(Unknown Source)
at org.sablecc.sablecc.GenParser.caseStart(Unknown Source)
at org.sablecc.sablecc.node.Start.apply(Unknown Source)
at org.sablecc.sablecc.SableCC.processGrammar(Unknown Source)
at org.sablecc.sablecc.SableCC.processGrammar(Unknown Source)
at org.sablecc.sablecc.SableCC.main(Unknown Source)
On Sunday, July 22, 2012 6:07:09 PM UTC-4, Steve Stewart wrote:
[...]I'm working on a 'dangling else' problem, and (for testing) I've restricted the grammar to the relevant productions for handling a version of this problem.
Let me explain. We have expressions of the following form, where E is a non-terminal and '=' separates the left and right side of the following two production rules for E:E = E => EE = E => E else E(The "=>" can be read as "implies.")Obviously, we want to be able to resolve the inherent ambiguity of the dangling else problem; in other words, we want to match each "else" with the closest preceding "=>". I've mocked this up as follows:
[...]
I've more or less copied the solution to the dangling else problem from p.67 of Appel's "Modern Compiler Implementation" text book.
[...]
Hi Steven,Your little grammar combines both of the two common (and famous) ambiguities:
- expression grammar (precedence and associativity)
- dangling else (attached to closest enclosing statement)
<snip>
--
-- You received this message because you are subscribed to the SableCC group. To post to this group, send email to sab...@googlegroups.com. To unsubscribe from this group, send email to sablecc+u...@googlegroups.com. For more options, visit this group at https://groups.google.com/d/forum/sablecc?hl=en
start = {matched} matched |
{unmatched} unmatched
;
matched = expr implies [m1]:matched else [m2]:matched |
{other} expr
;
unmatched = expr implies start |
{else} expr implies matched else unmatched
;
expr = {const} const |
{unary} un_op expr |
;
const = {number} number;
un_op = {not} not;
Etienne Gagnon, Ph.D. http://sablecc.org
Ok, for anyone interested, I think I may have it worked it out now following an example in Andrew Appel's book on compiler implementation:
[...]
term = {const} const | {unary} un_op expr;To solve this, I split the term production into two distinct productions:
left_unary = {unary} un_op left_unary | {simple} term; term = {const} const;Of course, I made left_unary directly right-recursive (as usual, the indirect recursion was the source of the ambiguity). The result was accepted by SableC, as expected.
Etienne Gagnon, Ph.D. http://sablecc.org