Problems with follow sets, epsilon handling, LR0 table
rick-masters opened this issue · comments
There are some problems with follow sets, epsilon handling, and the lr0 action table which I have been able to identify fixes for.
But before that, thank you very much for writing this code. Your code is smaller and simpler than a lot of other projects and it has helped me to learn LR parsing better.
This grammar is not handled correctly:
S -> A B
A -> a
A -> epsilon
B -> b
B -> epsilon
The following test program demonstrates incorrect tables. The proper tables are shown down below further. They can also be computed online at https://mdaines.github.io/grammophone
(just add periods to the end of rules and remove the epsilons).
import util.*;
import lr1.*;
public class TestLR
{
public static void main(String[] args) {
String grammarText = "S -> A B \n" +
"A -> a \n" +
"A -> epsilon \n" +
"B -> b \n" +
"B -> epsilon \n";
LR1Parser lr1Parser = new LR1Parser(new Grammar(grammarText));
if (lr1Parser.parseCLR1()) {
System.out.println(lr1Parser.actionTableStr());
System.out.println(lr1Parser.goToTableStr());
}
else {
System.out.println("parse not ok");
}
}
}
$ java TestLR
Rules:
0 : S' -> S
1 : S -> A B
2 : A -> a
3 : A -> epsilon
4 : B -> b
5 : B -> epsilon
Action Table :
epsilon a b $
----------------------------------------------------
|0 | SHIFT 1| SHIFT 3| | |
----------------------------------------------------
|1 | | | REDUCE 3| REDUCE 3|
----------------------------------------------------
|2 | SHIFT 5| | SHIFT 7| |
----------------------------------------------------
|3 | | | REDUCE 2| REDUCE 2|
----------------------------------------------------
|4 | | | | ACCEPT |
----------------------------------------------------
|5 | | | | REDUCE 5|
----------------------------------------------------
|6 | | | | REDUCE 1|
----------------------------------------------------
|7 | | | | REDUCE 4|
----------------------------------------------------
Go TO Table :
A B S
--------------------------
|0 | 2| | 4|
--------------------------
|1 | | | |
--------------------------
|2 | | 6| |
--------------------------
|3 | | | |
--------------------------
|4 | | | |
--------------------------
|5 | | | |
--------------------------
|6 | | | |
--------------------------
|7 | | | |
--------------------------
Epsilon should not be in the action table. Also, the action table is not correct. For example in state 0 an EOF ($) is valid, and should be a reduce of A to epsilon (rule 3).
This is the correct output:
$ java TestLR
Rules:
0 : S' -> S
1 : S -> A B
2 : A -> a
3 : A -> epsilon
4 : B -> b
5 : B -> epsilon
Action Table :
a b $
------------------------------------------
|0 | SHIFT 2| REDUCE 3| REDUCE 3|
------------------------------------------
|1 | | SHIFT 5| REDUCE 5|
------------------------------------------
|2 | | REDUCE 2| REDUCE 2|
------------------------------------------
|3 | | | ACCEPT |
------------------------------------------
|4 | | | REDUCE 1|
------------------------------------------
|5 | | | REDUCE 4|
------------------------------------------
Go TO Table :
A B S
--------------------------
|0 | 1| | 3|
--------------------------
|1 | | 4| |
--------------------------
|2 | | | |
--------------------------
|3 | | | |
--------------------------
|4 | | | |
--------------------------
|5 | | | |
--------------------------
I have prepared fixes and will send over a pull request.
I want to also let you know that I plan on using this code in a new project soon. It is much appreciated that you offered an MIT license.
Thank you very much for your help.
This is resolved and can be closed.