summaryrefslogtreecommitdiffstats
path: root/src/syntaxParser
diff options
context:
space:
mode:
authorConstantin Jucovschi <cj@ubuntu.localdomain>2009-03-31 06:18:54 -0400
committerConstantin Jucovschi <cj@ubuntu.localdomain>2009-03-31 06:18:54 -0400
commit0f1055b8d7f97d86c66fa602c17666bc2ff9c437 (patch)
tree9c68fa99a97063bbe4a4231e04fc09329541ac71 /src/syntaxParser
Initial commit
Diffstat (limited to 'src/syntaxParser')
-rw-r--r--src/syntaxParser/AtomicLit.java56
-rw-r--r--src/syntaxParser/AxisCrsElement.java19
-rw-r--r--src/syntaxParser/AxisCrsList.java7
-rw-r--r--src/syntaxParser/AxisIntervalElement.java32
-rw-r--r--src/syntaxParser/AxisIntervalList.java6
-rw-r--r--src/syntaxParser/AxisPointElement.java30
-rw-r--r--src/syntaxParser/AxisPointList.java8
-rw-r--r--src/syntaxParser/BinaryInducedExpr.java38
-rw-r--r--src/syntaxParser/BooleanExpr.java33
-rw-r--r--src/syntaxParser/BooleanScalarExpr.java38
-rw-r--r--src/syntaxParser/CastExpr.java24
-rw-r--r--src/syntaxParser/ComplexLit.java33
-rw-r--r--src/syntaxParser/CondenseExpr.java22
-rw-r--r--src/syntaxParser/CoverageConstructorExpr.java21
-rw-r--r--src/syntaxParser/CoverageExpr.java61
-rw-r--r--src/syntaxParser/CoverageList.java33
-rw-r--r--src/syntaxParser/CrsList.java33
-rw-r--r--src/syntaxParser/CrsTransformExpr.java23
-rw-r--r--src/syntaxParser/EncodedCoverageExpr.java42
-rw-r--r--src/syntaxParser/ExponentialExpr.java22
-rw-r--r--src/syntaxParser/ExtendExpr.java20
-rw-r--r--src/syntaxParser/FieldInterpolationElement.java18
-rw-r--r--src/syntaxParser/FieldInterpolationList.java9
-rw-r--r--src/syntaxParser/FieldInterpolationMethod.java20
-rw-r--r--src/syntaxParser/ForClause.java17
-rw-r--r--src/syntaxParser/ForClauseElements.java39
-rw-r--r--src/syntaxParser/GeneralCondenseExpr.java37
-rw-r--r--src/syntaxParser/GetMetaDataExpr.java50
-rw-r--r--src/syntaxParser/IParseTreeNode.java9
-rw-r--r--src/syntaxParser/InducedExpr.java21
-rw-r--r--src/syntaxParser/InterpolationMethodList.java6
-rw-r--r--src/syntaxParser/JLex/CAccept.classbin0 -> 641 bytes
-rw-r--r--src/syntaxParser/JLex/CAcceptAnchor.classbin0 -> 297 bytes
-rw-r--r--src/syntaxParser/JLex/CAlloc.classbin0 -> 1377 bytes
-rw-r--r--src/syntaxParser/JLex/CBunch.classbin0 -> 455 bytes
-rw-r--r--src/syntaxParser/JLex/CDTrans.classbin0 -> 479 bytes
-rw-r--r--src/syntaxParser/JLex/CDfa.classbin0 -> 530 bytes
-rw-r--r--src/syntaxParser/JLex/CEmit.classbin0 -> 19867 bytes
-rw-r--r--src/syntaxParser/JLex/CError.classbin0 -> 2694 bytes
-rw-r--r--src/syntaxParser/JLex/CInput.classbin0 -> 1366 bytes
-rw-r--r--src/syntaxParser/JLex/CLexGen.classbin0 -> 25971 bytes
-rw-r--r--src/syntaxParser/JLex/CMakeNfa.classbin0 -> 6169 bytes
-rw-r--r--src/syntaxParser/JLex/CMinimize.classbin0 -> 5862 bytes
-rw-r--r--src/syntaxParser/JLex/CNfa.classbin0 -> 1031 bytes
-rw-r--r--src/syntaxParser/JLex/CNfa2Dfa.classbin0 -> 5215 bytes
-rw-r--r--src/syntaxParser/JLex/CNfaPair.classbin0 -> 281 bytes
-rw-r--r--src/syntaxParser/JLex/CSet.classbin0 -> 1297 bytes
-rw-r--r--src/syntaxParser/JLex/CSimplifyNfa.classbin0 -> 2472 bytes
-rw-r--r--src/syntaxParser/JLex/CSpec.classbin0 -> 2939 bytes
-rw-r--r--src/syntaxParser/JLex/CUtility.classbin0 -> 2681 bytes
-rw-r--r--src/syntaxParser/JLex/Main.classbin0 -> 670 bytes
-rw-r--r--src/syntaxParser/JLex/Main.java7841
-rw-r--r--src/syntaxParser/JLex/SparseBitSet$1.classbin0 -> 384 bytes
-rw-r--r--src/syntaxParser/JLex/SparseBitSet$2.classbin0 -> 384 bytes
-rw-r--r--src/syntaxParser/JLex/SparseBitSet$3.classbin0 -> 384 bytes
-rw-r--r--src/syntaxParser/JLex/SparseBitSet$4.classbin0 -> 961 bytes
-rw-r--r--src/syntaxParser/JLex/SparseBitSet$BinOp.classbin0 -> 191 bytes
-rw-r--r--src/syntaxParser/JLex/SparseBitSet.classbin0 -> 5958 bytes
-rw-r--r--src/syntaxParser/List.java42
-rw-r--r--src/syntaxParser/Makefile34
-rw-r--r--src/syntaxParser/NumericScalarExpr.java51
-rw-r--r--src/syntaxParser/ProcessingExpr.java18
-rw-r--r--src/syntaxParser/README97
-rw-r--r--src/syntaxParser/RangeValue.java17
-rw-r--r--src/syntaxParser/RangeValueList.java10
-rw-r--r--src/syntaxParser/ReduceExpr.java19
-rw-r--r--src/syntaxParser/ReturnClause.java16
-rw-r--r--src/syntaxParser/SAMPLE_REQUESTS.txt52
-rw-r--r--src/syntaxParser/ScalarExpr.java18
-rw-r--r--src/syntaxParser/ScalarLit.java42
-rw-r--r--src/syntaxParser/ScalarLitList.java52
-rw-r--r--src/syntaxParser/ScaleExpr.java24
-rw-r--r--src/syntaxParser/SelectExpr.java22
-rw-r--r--src/syntaxParser/SetMetaDataExpr.java54
-rw-r--r--src/syntaxParser/SliceExpr.java20
-rw-r--r--src/syntaxParser/StoreExpr.java15
-rw-r--r--src/syntaxParser/StructuredLiteral.java15
-rw-r--r--src/syntaxParser/SubsetExpr.java21
-rw-r--r--src/syntaxParser/SyntaxErrorException.java26
-rw-r--r--src/syntaxParser/TrigonometricExpr.java23
-rw-r--r--src/syntaxParser/TrimExpr.java21
-rw-r--r--src/syntaxParser/UnaryArithMeticExpr.java31
-rw-r--r--src/syntaxParser/UnaryInducedExpr.java23
-rw-r--r--src/syntaxParser/VariableList.java37
-rw-r--r--src/syntaxParser/WCPSRequest.java42
-rw-r--r--src/syntaxParser/WCPSRequestProcessor.java46
-rw-r--r--src/syntaxParser/WhereClause.java14
-rw-r--r--src/syntaxParser/java-cup-11a.jarbin0 -> 96121 bytes
-rw-r--r--src/syntaxParser/java_cup/CUP$parser$actions.classbin0 -> 15551 bytes
-rw-r--r--src/syntaxParser/java_cup/Main.classbin0 -> 14726 bytes
-rw-r--r--src/syntaxParser/java_cup/Main.java854
-rw-r--r--src/syntaxParser/java_cup/SAVE/Main.java854
-rw-r--r--src/syntaxParser/java_cup/SAVE/action_part.java93
-rw-r--r--src/syntaxParser/java_cup/SAVE/action_production.java39
-rw-r--r--src/syntaxParser/java_cup/SAVE/assoc.java16
-rw-r--r--src/syntaxParser/java_cup/SAVE/emit.java897
-rw-r--r--src/syntaxParser/java_cup/SAVE/internal_error.java22
-rw-r--r--src/syntaxParser/java_cup/SAVE/lalr_item.java330
-rw-r--r--src/syntaxParser/java_cup/SAVE/lalr_item_set.java371
-rw-r--r--src/syntaxParser/java_cup/SAVE/lalr_state.java884
-rw-r--r--src/syntaxParser/java_cup/SAVE/lalr_transition.java93
-rw-r--r--src/syntaxParser/java_cup/SAVE/lexer.java543
-rw-r--r--src/syntaxParser/java_cup/SAVE/lr_item_core.java280
-rw-r--r--src/syntaxParser/java_cup/SAVE/non_terminal.java301
-rw-r--r--src/syntaxParser/java_cup/SAVE/nonassoc_action.java71
-rw-r--r--src/syntaxParser/java_cup/SAVE/parse_action.java92
-rw-r--r--src/syntaxParser/java_cup/SAVE/parse_action_row.java106
-rw-r--r--src/syntaxParser/java_cup/SAVE/parse_action_table.java143
-rw-r--r--src/syntaxParser/java_cup/SAVE/parse_reduce_row.java41
-rw-r--r--src/syntaxParser/java_cup/SAVE/parse_reduce_table.java99
-rw-r--r--src/syntaxParser/java_cup/SAVE/parser.cup863
-rw-r--r--src/syntaxParser/java_cup/SAVE/parser.java1849
-rw-r--r--src/syntaxParser/java_cup/SAVE/production.java756
-rw-r--r--src/syntaxParser/java_cup/SAVE/production_part.java94
-rw-r--r--src/syntaxParser/java_cup/SAVE/reduce_action.java84
-rw-r--r--src/syntaxParser/java_cup/SAVE/shift_action.java82
-rw-r--r--src/syntaxParser/java_cup/SAVE/sym.java43
-rw-r--r--src/syntaxParser/java_cup/SAVE/symbol.java107
-rw-r--r--src/syntaxParser/java_cup/SAVE/symbol_part.java100
-rw-r--r--src/syntaxParser/java_cup/SAVE/symbol_set.java231
-rw-r--r--src/syntaxParser/java_cup/SAVE/terminal.java169
-rw-r--r--src/syntaxParser/java_cup/SAVE/terminal_set.java253
-rw-r--r--src/syntaxParser/java_cup/SAVE/version.java55
-rw-r--r--src/syntaxParser/java_cup/action_part.classbin0 -> 1107 bytes
-rw-r--r--src/syntaxParser/java_cup/action_part.java93
-rw-r--r--src/syntaxParser/java_cup/action_production.classbin0 -> 604 bytes
-rw-r--r--src/syntaxParser/java_cup/action_production.java39
-rw-r--r--src/syntaxParser/java_cup/assoc.classbin0 -> 333 bytes
-rw-r--r--src/syntaxParser/java_cup/assoc.java16
-rw-r--r--src/syntaxParser/java_cup/emit.classbin0 -> 13969 bytes
-rw-r--r--src/syntaxParser/java_cup/emit.java897
-rw-r--r--src/syntaxParser/java_cup/internal_error.classbin0 -> 580 bytes
-rw-r--r--src/syntaxParser/java_cup/internal_error.java22
-rw-r--r--src/syntaxParser/java_cup/lalr_item.classbin0 -> 3741 bytes
-rw-r--r--src/syntaxParser/java_cup/lalr_item.java330
-rw-r--r--src/syntaxParser/java_cup/lalr_item_set.classbin0 -> 3937 bytes
-rw-r--r--src/syntaxParser/java_cup/lalr_item_set.java371
-rw-r--r--src/syntaxParser/java_cup/lalr_state.classbin0 -> 9664 bytes
-rw-r--r--src/syntaxParser/java_cup/lalr_state.java884
-rw-r--r--src/syntaxParser/java_cup/lalr_transition.classbin0 -> 1508 bytes
-rw-r--r--src/syntaxParser/java_cup/lalr_transition.java93
-rw-r--r--src/syntaxParser/java_cup/lexer.classbin0 -> 5258 bytes
-rw-r--r--src/syntaxParser/java_cup/lexer.java543
-rw-r--r--src/syntaxParser/java_cup/lr_item_core.classbin0 -> 3158 bytes
-rw-r--r--src/syntaxParser/java_cup/lr_item_core.java280
-rw-r--r--src/syntaxParser/java_cup/non_terminal.classbin0 -> 3759 bytes
-rw-r--r--src/syntaxParser/java_cup/non_terminal.java301
-rw-r--r--src/syntaxParser/java_cup/nonassoc_action.classbin0 -> 675 bytes
-rw-r--r--src/syntaxParser/java_cup/nonassoc_action.java71
-rw-r--r--src/syntaxParser/java_cup/parse_action.classbin0 -> 740 bytes
-rw-r--r--src/syntaxParser/java_cup/parse_action.java92
-rw-r--r--src/syntaxParser/java_cup/parse_action_row.classbin0 -> 1035 bytes
-rw-r--r--src/syntaxParser/java_cup/parse_action_row.java106
-rw-r--r--src/syntaxParser/java_cup/parse_action_table.classbin0 -> 2258 bytes
-rw-r--r--src/syntaxParser/java_cup/parse_action_table.java143
-rw-r--r--src/syntaxParser/java_cup/parse_reduce_row.classbin0 -> 529 bytes
-rw-r--r--src/syntaxParser/java_cup/parse_reduce_row.java41
-rw-r--r--src/syntaxParser/java_cup/parse_reduce_table.classbin0 -> 1295 bytes
-rw-r--r--src/syntaxParser/java_cup/parse_reduce_table.java99
-rw-r--r--src/syntaxParser/java_cup/parser.classbin0 -> 7471 bytes
-rw-r--r--src/syntaxParser/java_cup/parser.cup863
-rw-r--r--src/syntaxParser/java_cup/parser.java1849
-rw-r--r--src/syntaxParser/java_cup/production.classbin0 -> 8084 bytes
-rw-r--r--src/syntaxParser/java_cup/production.java756
-rw-r--r--src/syntaxParser/java_cup/production_part.classbin0 -> 966 bytes
-rw-r--r--src/syntaxParser/java_cup/production_part.java94
-rw-r--r--src/syntaxParser/java_cup/reduce_action.classbin0 -> 1218 bytes
-rw-r--r--src/syntaxParser/java_cup/reduce_action.java84
-rw-r--r--src/syntaxParser/java_cup/runtime/Scanner.classbin0 -> 211 bytes
-rw-r--r--src/syntaxParser/java_cup/runtime/Scanner.java25
-rw-r--r--src/syntaxParser/java_cup/runtime/Symbol.classbin0 -> 1045 bytes
-rw-r--r--src/syntaxParser/java_cup/runtime/Symbol.java105
-rw-r--r--src/syntaxParser/java_cup/runtime/lr_parser.classbin0 -> 9907 bytes
-rw-r--r--src/syntaxParser/java_cup/runtime/lr_parser.java1238
-rw-r--r--src/syntaxParser/java_cup/runtime/virtual_parse_stack.classbin0 -> 1508 bytes
-rw-r--r--src/syntaxParser/java_cup/runtime/virtual_parse_stack.java145
-rw-r--r--src/syntaxParser/java_cup/shift_action.classbin0 -> 1199 bytes
-rw-r--r--src/syntaxParser/java_cup/shift_action.java82
-rw-r--r--src/syntaxParser/java_cup/simple_calc/Main.java32
-rw-r--r--src/syntaxParser/java_cup/simple_calc/parser.cup55
-rw-r--r--src/syntaxParser/java_cup/simple_calc/parser.java318
-rw-r--r--src/syntaxParser/java_cup/simple_calc/scanner.java63
-rw-r--r--src/syntaxParser/java_cup/simple_calc/sym.java25
-rw-r--r--src/syntaxParser/java_cup/sym.classbin0 -> 1111 bytes
-rw-r--r--src/syntaxParser/java_cup/sym.java43
-rw-r--r--src/syntaxParser/java_cup/symbol.classbin0 -> 925 bytes
-rw-r--r--src/syntaxParser/java_cup/symbol.java107
-rw-r--r--src/syntaxParser/java_cup/symbol_part.classbin0 -> 1431 bytes
-rw-r--r--src/syntaxParser/java_cup/symbol_part.java100
-rw-r--r--src/syntaxParser/java_cup/symbol_set.classbin0 -> 2608 bytes
-rw-r--r--src/syntaxParser/java_cup/symbol_set.java231
-rw-r--r--src/syntaxParser/java_cup/terminal.classbin0 -> 2196 bytes
-rw-r--r--src/syntaxParser/java_cup/terminal.java169
-rw-r--r--src/syntaxParser/java_cup/terminal_set.classbin0 -> 2459 bytes
-rw-r--r--src/syntaxParser/java_cup/terminal_set.java253
-rw-r--r--src/syntaxParser/java_cup/version.classbin0 -> 549 bytes
-rw-r--r--src/syntaxParser/java_cup/version.java55
-rw-r--r--src/syntaxParser/processcoverage.xsd189
-rw-r--r--src/syntaxParser/request.wcps1
-rw-r--r--src/syntaxParser/run.bat8
-rw-r--r--src/syntaxParser/test_requests.txt101
-rw-r--r--src/syntaxParser/tmp/META-INF/MANIFEST.MF6
-rw-r--r--src/syntaxParser/wcps.cup415
-rw-r--r--src/syntaxParser/wcps.lex157
-rw-r--r--src/syntaxParser/wcps.lex_ORIG141
-rw-r--r--src/syntaxParser/wcpsRequest.xml11
206 files changed, 32527 insertions, 0 deletions
diff --git a/src/syntaxParser/AtomicLit.java b/src/syntaxParser/AtomicLit.java
new file mode 100644
index 0000000..b4b8409
--- /dev/null
+++ b/src/syntaxParser/AtomicLit.java
@@ -0,0 +1,56 @@
+package syntaxParser;
+/**
+ * AtomicLit
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani
+ */
+class AtomicLit {
+
+
+ BooleanExpr booleanExpr;
+ int integerExpr;
+ float floatExpr;
+ String stringExpr;
+
+ String flag;
+
+ /**
+ * AtomicLit constructor comment.
+ */
+ public AtomicLit() {
+ super();
+ }
+ public AtomicLit( BooleanExpr be){
+ booleanExpr = be;
+ flag = "boolean";
+ }
+
+ public AtomicLit( int ie){
+ stringExpr = ie.toString();
+ flag = "int";
+ }
+
+ public AtomicLit( float fe){
+ stringExpr = fe.toString();
+ flag = "float";
+ }
+
+ public AtomicLit( String se){
+ stringExpr = se;
+ flag = "string";
+ }
+
+ String toXML(){
+ String result="" ;
+ try {
+ if (flag.equals("boolean")) {
+ result += "<boolean>" + booleanExpr.toXML() + "</boolean>";
+ } else if (flag.equals("int") || flag.equals("float") || flag.equals("string")) {
+ result += "<scalar>" + stringExpr + "</scalar>
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return result;
+ }
+}
diff --git a/src/syntaxParser/AxisCrsElement.java b/src/syntaxParser/AxisCrsElement.java
new file mode 100644
index 0000000..152bea1
--- /dev/null
+++ b/src/syntaxParser/AxisCrsElement.java
@@ -0,0 +1,19 @@
+package syntaxParser;
+/* Author: Sorin Stancu-Mara
+ * Date: 8 Feb 2008
+ */
+
+class AxisCrsElement implements IParseTreeNode {
+ String axis;
+ String crs;
+
+ public AxisCrsElement(String name, String crs) {
+ axis = name;
+ this.crs = crs;
+ }
+
+ public String toXML() {
+ return "<axis>" + axis + "</axis><crs>" + crs + "</crs>";
+ }
+
+}
diff --git a/src/syntaxParser/AxisCrsList.java b/src/syntaxParser/AxisCrsList.java
new file mode 100644
index 0000000..2bcfdc9
--- /dev/null
+++ b/src/syntaxParser/AxisCrsList.java
@@ -0,0 +1,7 @@
+package syntaxParser;
+
+class AxisCrsList extends List {
+ public AxisCrsList(AxisCrsElement elem) { super((IParseTreeNode)elem); }
+ public AxisCrsList(AxisCrsElement elem, AxisCrsList next) { super((IParseTreeNode)elem, (List)next); }
+}
+
diff --git a/src/syntaxParser/AxisIntervalElement.java b/src/syntaxParser/AxisIntervalElement.java
new file mode 100644
index 0000000..4c0b4e7
--- /dev/null
+++ b/src/syntaxParser/AxisIntervalElement.java
@@ -0,0 +1,32 @@
+package syntaxParser;
+/* Author: Sorin Stancu-Mara
+ * Date: 8 Feb 2008
+ */
+
+class AxisIntervalElement implements IParseTreeNode {
+ String axisName;
+ String lo, hi;
+ String crs;
+
+ public AxisIntervalElement(String name, String lo, String hi) {
+ axisName = name;
+ this.lo = lo;
+ this.hi = hi;
+ }
+
+ public AxisIntervalElement(String name,String crs, String lo, String hi) {
+ axisName = name;
+ this.crs = crs;
+ this.lo = lo;
+ this.hi = hi;
+ }
+
+ public String toXML() {
+ String result = "<axis>" + axisName + "</axis>";
+ if (crs != null)
+ result += "<crs>" + crs + "</crs>";
+ result += "<coord>" + lo + "</coord><coord>" + hi +
+ "</coord>";
+ return result;
+ }
+}
diff --git a/src/syntaxParser/AxisIntervalList.java b/src/syntaxParser/AxisIntervalList.java
new file mode 100644
index 0000000..d610c53
--- /dev/null
+++ b/src/syntaxParser/AxisIntervalList.java
@@ -0,0 +1,6 @@
+package syntaxParser;
+
+class AxisIntervalList extends List {
+ public AxisIntervalList(AxisIntervalElement elem) { super((IParseTreeNode)elem); }
+ public AxisIntervalList(AxisIntervalElement elem, AxisIntervalList next) { super((IParseTreeNode)elem, (List)next); }
+} \ No newline at end of file
diff --git a/src/syntaxParser/AxisPointElement.java b/src/syntaxParser/AxisPointElement.java
new file mode 100644
index 0000000..37e4911
--- /dev/null
+++ b/src/syntaxParser/AxisPointElement.java
@@ -0,0 +1,30 @@
+package syntaxParser;
+/* Author: Sorin Stancu-Mara
+ * Date: 8 Feb 2008
+ */
+
+class AxisPointElement implements IParseTreeNode {
+ String axis;
+ String crs;
+ String point;
+
+ public AxisPointElement(String name, String p) {
+ axis = name;
+ point = p;
+ }
+
+ public AxisPointElement(String name, String crs, String p) {
+ axis = name;
+ point = p;
+ this.crs = crs;
+ }
+
+ public String toXML() {
+ String result = "<axis>" + axis + "</axis>";
+ if (crs != null)
+ result += "<crs>" + crs + "</crs>";
+ result += "<coord>" + point + "</coord>";
+ return result;
+ }
+
+}
diff --git a/src/syntaxParser/AxisPointList.java b/src/syntaxParser/AxisPointList.java
new file mode 100644
index 0000000..84d5c23
--- /dev/null
+++ b/src/syntaxParser/AxisPointList.java
@@ -0,0 +1,8 @@
+package syntaxParser;
+
+class AxisPointList extends List {
+ public AxisPointList(AxisPointElement elem) { super((IParseTreeNode)elem); }
+ public AxisPointList(AxisPointElement elem, AxisPointList next) { super((IParseTreeNode)elem, (List)next); }
+}
+
+
diff --git a/src/syntaxParser/BinaryInducedExpr.java b/src/syntaxParser/BinaryInducedExpr.java
new file mode 100644
index 0000000..fd34bda
--- /dev/null
+++ b/src/syntaxParser/BinaryInducedExpr.java
@@ -0,0 +1,38 @@
+package syntaxParser;
+/**
+ * BinaryInducedExpr
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani, Sorin Stancu-Mara
+ */
+class BinaryInducedExpr implements IParseTreeNode {
+
+ IParseTreeNode leftCoverageExpr;
+ IParseTreeNode rightCoverageExpr;
+ int wrapInScalar;
+ String operator;
+
+ public BinaryInducedExpr( String o, IParseTreeNode le, IParseTreeNode re ){
+ leftCoverageExpr = le;
+ rightCoverageExpr = re;
+ wrapInScalar = 0;
+ operator = o;
+ }
+ public BinaryInducedExpr( String o, IParseTreeNode le, IParseTreeNode re, int wis ){
+ leftCoverageExpr = le;
+ rightCoverageExpr = re;
+ wrapInScalar = wis;
+ operator = o;
+ }
+ public String toXML(){
+ String result="";
+ result = "<" + operator + ">";
+ if (wrapInScalar == -1) result += "<scalar>";
+ result += leftCoverageExpr.toXML();
+ if (wrapInScalar == -1) result += "</scalar>";
+ if (wrapInScalar == 1) result += "<scalar>";
+ result += rightCoverageExpr.toXML();
+ if (wrapInScalar == 1) result += "</scalar>";
+ result += "</" + operator + ">";
+ return result;
+ }
+}
diff --git a/src/syntaxParser/BooleanExpr.java b/src/syntaxParser/BooleanExpr.java
new file mode 100644
index 0000000..5d013f4
--- /dev/null
+++ b/src/syntaxParser/BooleanExpr.java
@@ -0,0 +1,33 @@
+package syntaxParser;
+/**
+ * BooleanExpr
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani, Sorin Stancu-Mara
+ */
+class BooleanExpr implements IParseTreeNode {
+ CoverageExpr coverageExpr;
+ String operator;
+ int integerExpr;
+
+ public BooleanExpr( CoverageExpr ce, String op ){
+ coverageExpr = ce;
+ operator = op;
+ }
+
+ public BooleanExpr( CoverageExpr ce, int ie, String op ){
+ coverageExpr = ce;
+ integerExpr = ie;
+ operator = op;
+ }
+
+ public String toXML(){
+ String result="";
+ result += "<"+operator+">";
+ if (operator.equals("bit")) {
+ result += "<position>" + integerExpr +"<position>";
+ }
+ result += coverageExpr.toXML();
+ result += "</"+operator+">";
+ return result;
+ }
+}
diff --git a/src/syntaxParser/BooleanScalarExpr.java b/src/syntaxParser/BooleanScalarExpr.java
new file mode 100644
index 0000000..6b2278d
--- /dev/null
+++ b/src/syntaxParser/BooleanScalarExpr.java
@@ -0,0 +1,38 @@
+package syntaxParser;
+/**
+ * BooleanScalarExpr
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani, Sorin Stancu-Mara
+ */
+class BooleanScalarExpr implements IParseTreeNode {
+ BooleanScalarExpr leftBooleanScalarExpr, rightBooleanScalarExpr;
+ String booleanConstant;
+ String op;
+ public BooleanScalarExpr(String bc) {
+ booleanConstant = bc;
+ }
+
+ public BooleanScalarExpr(String op, BooleanScalarExpr be){
+ this.op = op;
+ leftBooleanScalarExpr = be ;
+ }
+
+ public BooleanScalarExpr(String op, BooleanScalarExpr lbe, BooleanScalarExpr rbe){
+ this.op = op;
+ leftBooleanScalarExpr = lbe ;
+ rightBooleanScalarExpr = rbe ;
+ }
+
+ public String toXML(){
+ if (op == null) return "<boolean>" + booleanConstant + "</boolean>";
+ else if (op.equals("not")) return "<scalarNot>" + leftBooleanScalarExpr.toXML() + "</scalarNot>";
+ else {
+ if (op.equals("and")) op = "scalarAnd";
+ else if (op.equals("or")) op = "scalarOr";
+ else if (op.equals("xor")) op = "scalarXor";
+ return "<" + op + ">" + leftBooleanScalarExpr.toXML() + rightBooleanScalarExpr.toXML() + "</" + op + ">";
+ }
+
+ }
+
+}
diff --git a/src/syntaxParser/CastExpr.java b/src/syntaxParser/CastExpr.java
new file mode 100644
index 0000000..dddaa0e
--- /dev/null
+++ b/src/syntaxParser/CastExpr.java
@@ -0,0 +1,24 @@
+package syntaxParser;
+/**
+ * CastExpr
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani, Sorin Stancu-Mara
+ */
+class CastExpr implements IParseTreeNode {
+ String castType;
+ CoverageExpr coverageExpr;
+
+ public CastExpr( CoverageExpr ce, String ct){
+ castType = ct;
+ coverageExpr = ce;
+ }
+
+ public String toXML(){
+ String result= "" ;
+ result += "<cast>";
+ result += "<type>" + castType + "</type>";
+ result += coverageExpr.toXML();
+ result += "</cast>";
+ return result;
+ }
+}
diff --git a/src/syntaxParser/ComplexLit.java b/src/syntaxParser/ComplexLit.java
new file mode 100644
index 0000000..a75b495
--- /dev/null
+++ b/src/syntaxParser/ComplexLit.java
@@ -0,0 +1,33 @@
+package syntaxParser;
+/**
+ * ComplexLit
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani
+ */
+class ComplexLit {
+
+ ScalarLitList scalarLitList;
+
+ /**
+ * ComplexLit constructor comment.
+ */
+
+ public ComplexLit() {
+ super();
+ }
+ public ComplexLit( ScalarLitList l ){
+ scalarLitList = l;
+ }
+
+
+ String toXML(){
+ String result="" ;
+ try {
+ result += "complex literal not defined XSD";
+ } catch (Exception e ) {
+ e.printStackTrace();
+ }
+ return result;
+ }
+
+}
diff --git a/src/syntaxParser/CondenseExpr.java b/src/syntaxParser/CondenseExpr.java
new file mode 100644
index 0000000..a5fdb3f
--- /dev/null
+++ b/src/syntaxParser/CondenseExpr.java
@@ -0,0 +1,22 @@
+package syntaxParser;
+/**
+ * CondenseExpr
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani, Sorin Stancu-Mara
+ */
+class CondenseExpr implements IParseTreeNode{
+
+
+ IParseTreeNode expr;
+
+ public CondenseExpr( IParseTreeNode re ){
+ expr = re;
+ }
+
+ public String toXML() {
+ return expr.toXML();
+ }
+
+
+
+}
diff --git a/src/syntaxParser/CoverageConstructorExpr.java b/src/syntaxParser/CoverageConstructorExpr.java
new file mode 100644
index 0000000..2f6d89e
--- /dev/null
+++ b/src/syntaxParser/CoverageConstructorExpr.java
@@ -0,0 +1,21 @@
+package syntaxParser;
+/* Author: Sorin Stancu-Mara
+ * Date: 8 Feb 2008
+ */
+
+class CoverageConstructorExpr implements IParseTreeNode {
+ String name;
+ VariableList variables;
+ ScalarExpr expr;
+
+ public CoverageConstructorExpr(String name, VariableList vl, ScalarExpr expr) {
+ this.name = name;
+ this.variables = vl;
+ this.expr = expr;
+ }
+
+ public String toXML() {
+ return "<construct><coverage>" + name + "</coverage>" + variables.toXML() + expr.toXML() + "</construct>";
+ }
+
+}
diff --git a/src/syntaxParser/CoverageExpr.java b/src/syntaxParser/CoverageExpr.java
new file mode 100644
index 0000000..516c061
--- /dev/null
+++ b/src/syntaxParser/CoverageExpr.java
@@ -0,0 +1,61 @@
+package syntaxParser;
+/**
+ * CoverageExpr
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani, Sorin Stancu-Mara
+ */
+class CoverageExpr implements IParseTreeNode {
+
+ String coverageName;
+ IParseTreeNode expr;
+ String function;
+
+ public CoverageExpr( String n ){
+ coverageName = n;
+ function = "name";
+ }
+
+ public CoverageExpr( SetMetaDataExpr smde ){
+ expr = smde;
+ function = "setMetaDataExpr";
+ }
+
+ public CoverageExpr( InducedExpr ie ){
+ expr = ie;
+ function = "inducedExpr";
+ }
+
+ public CoverageExpr( SubsetExpr se ){
+ expr = se;
+ function = "subsetExpr";
+ }
+
+ public CoverageExpr( CrsTransformExpr cte ){
+ expr = cte;
+ function = "crsTransformExpr";
+ }
+
+ public CoverageExpr( ScaleExpr se ){
+ expr = se;
+ function = "scaleExpr";
+ }
+
+ public CoverageExpr( CoverageExpr ce ){
+ expr = ce;
+ function = "coverageExpr";
+ }
+
+ public CoverageExpr( CoverageConstructorExpr ce ){
+ expr = ce;
+ function = "coverageConstructorExpr";
+ }
+
+ public String toXML(){
+ String result= "" ;
+ if (function.equals("name")) {
+ result = "<coverage>" + coverageName + "</coverage>";
+ } else
+ result = expr.toXML();
+ return result;
+ }
+}
diff --git a/src/syntaxParser/CoverageList.java b/src/syntaxParser/CoverageList.java
new file mode 100644
index 0000000..9ee476d
--- /dev/null
+++ b/src/syntaxParser/CoverageList.java
@@ -0,0 +1,33 @@
+package syntaxParser;
+/**
+ * CoverageList class represents a CoverageList.
+ * Creation date: (3/3/2003 2:52:55 AM)
+ * @author: mattia parigiani, Sorin Stancu-Mara
+ */
+import java.util.*;
+public class CoverageList implements IParseTreeNode {
+ private String coverageName;
+ private CoverageList next;
+
+ public CoverageList(String c) {
+ coverageName = c;
+ next = null;
+ }
+
+ public CoverageList(String c, CoverageList l) {
+ coverageName = c;
+ next = l;
+ }
+
+
+ public String toXML(){
+ String result = "<coverageName>" + coverageName + "</coverageName>";
+ if (next != null) {
+ result += next.toXML();
+ }
+ return result;
+ }
+
+
+
+}
diff --git a/src/syntaxParser/CrsList.java b/src/syntaxParser/CrsList.java
new file mode 100644
index 0000000..d10834e
--- /dev/null
+++ b/src/syntaxParser/CrsList.java
@@ -0,0 +1,33 @@
+package syntaxParser;
+/* Author: Sorin Stancu-Mara
+ * Date: 9 Feb 2008
+ * Outside the other Lists becasuse this one works with strings.
+ */
+
+class CrsList implements IParseTreeNode {
+ String elem;
+ String tag;
+ CrsList next;
+ public CrsList(String e) {
+ elem = e;
+ }
+ public CrsList(String e, CrsList n) {
+ elem = e;
+ next = n;
+ }
+ public void setTag(String newTag) {
+ tag =newTag;
+ if (next != null) {
+ next.setTag(tag);
+ }
+ }
+ public String toXML() {
+ String result = "";
+ if (tag != null) result += "<" + tag + ">" + elem + "</" + tag + ">";
+ else result += elem;
+ if (next != null)
+ result += next.toXML();
+ return result;
+
+ }
+}
diff --git a/src/syntaxParser/CrsTransformExpr.java b/src/syntaxParser/CrsTransformExpr.java
new file mode 100644
index 0000000..ea214bc
--- /dev/null
+++ b/src/syntaxParser/CrsTransformExpr.java
@@ -0,0 +1,23 @@
+package syntaxParser;
+/**
+ * CrsTransformExpr
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani, Sorin Stancu-Mara
+ */
+class CrsTransformExpr implements IParseTreeNode {
+ CoverageExpr coverageExpr;
+ AxisCrsList axisCrsList;
+ FieldInterpolationList interpList;
+
+ public CrsTransformExpr( CoverageExpr ce, AxisCrsList axisList, FieldInterpolationList fil ){
+ coverageExpr = ce;
+ axisCrsList = axisList;
+ axisCrsList.setTag("crsTransformAxisSpec");
+ interpList = fil;
+ interpList.setTag("crsTransformFieldSpec");
+ }
+ public String toXML(){
+ return "<crsTransform>" + axisCrsList.toXML() + interpList.toXML() +
+ coverageExpr.toXML() + "</crsTransform>";
+ }
+}
diff --git a/src/syntaxParser/EncodedCoverageExpr.java b/src/syntaxParser/EncodedCoverageExpr.java
new file mode 100644
index 0000000..3f5f283
--- /dev/null
+++ b/src/syntaxParser/EncodedCoverageExpr.java
@@ -0,0 +1,42 @@
+package syntaxParser;
+/**
+ * EncodedCoverageExpr
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani, Sorin Stancu-Mara
+ */
+class EncodedCoverageExpr implements IParseTreeNode {
+ CoverageExpr coverageExpr;
+ String formatName;
+ String extraParams;
+ boolean store;
+ public EncodedCoverageExpr( CoverageExpr ce , String fn ){
+ coverageExpr = ce;
+ formatName = fn;
+ extraParams = null;
+ store = false;
+ }
+
+ public EncodedCoverageExpr( CoverageExpr ce , String fn, String ep ){
+ coverageExpr = ce;
+ formatName = fn;
+ extraParams = ep;
+ store = false;
+ }
+
+ public void setStoreFlag() {
+ store = true;
+ }
+
+ public String toXML(){
+ String result= "<encode>" ;
+ if (store) result = "<encode store=\"true\">";
+
+ result += "<format>" + formatName + "</format>" ;
+ if (extraParams != null ) {
+ result += "<extraParams>" + extraParams + "</extraParams>" ;
+ }
+ result += coverageExpr.toXML() ;
+ result+= "</encode>" ;
+ return result;
+ }
+}
diff --git a/src/syntaxParser/ExponentialExpr.java b/src/syntaxParser/ExponentialExpr.java
new file mode 100644
index 0000000..469657e
--- /dev/null
+++ b/src/syntaxParser/ExponentialExpr.java
@@ -0,0 +1,22 @@
+package syntaxParser;
+/**
+ * ExponentialExpr
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani, Sorin Stancu-Mara
+ */
+class ExponentialExpr implements IParseTreeNode {
+ String expOperator;
+ CoverageExpr coverageExpr;
+
+ public ExponentialExpr( CoverageExpr ce, String op){
+ expOperator = op;
+ coverageExpr = ce;
+ }
+ public String toXML(){
+ String result= "" ;
+ result += "<" + expOperator + ">";
+ result += coverageExpr.toXML() ;
+ result += "</" + expOperator + ">";
+ return result;
+ }
+}
diff --git a/src/syntaxParser/ExtendExpr.java b/src/syntaxParser/ExtendExpr.java
new file mode 100644
index 0000000..8a43b48
--- /dev/null
+++ b/src/syntaxParser/ExtendExpr.java
@@ -0,0 +1,20 @@
+package syntaxParser;
+/**
+ * ExtendExpr
+ * Creation date: (8/2/2008)
+ * @author: Sorin Stancu-Mara
+ */
+class ExtendExpr implements IParseTreeNode {
+
+ CoverageExpr coverageExpr;
+ AxisIntervalList intervalList;
+ public ExtendExpr( CoverageExpr ce, AxisIntervalList apl){
+ coverageExpr = ce;
+ intervalList = apl;
+ intervalList.setTag("extendAxisSpec");
+ }
+
+ public String toXML(){
+ return "<extend>" + intervalList.toXML() + coverageExpr.toXML() + "</extend>";
+ }
+}
diff --git a/src/syntaxParser/FieldInterpolationElement.java b/src/syntaxParser/FieldInterpolationElement.java
new file mode 100644
index 0000000..28ab51f
--- /dev/null
+++ b/src/syntaxParser/FieldInterpolationElement.java
@@ -0,0 +1,18 @@
+package syntaxParser;
+/* Authod: Sorin Stancu-Mara
+ * Date: 8 Feb 2008
+ */
+
+class FieldInterpolationElement implements IParseTreeNode {
+ String field;
+ FieldInterpolationMethod method;
+
+ public FieldInterpolationElement(String field, FieldInterpolationMethod m) {
+ this.field = field;
+ this.method = m;
+ }
+
+ public String toXML() {
+ return "<field>" + field + "</field>" + method.toXML();
+ }
+}
diff --git a/src/syntaxParser/FieldInterpolationList.java b/src/syntaxParser/FieldInterpolationList.java
new file mode 100644
index 0000000..12d81e2
--- /dev/null
+++ b/src/syntaxParser/FieldInterpolationList.java
@@ -0,0 +1,9 @@
+package syntaxParser;
+
+class FieldInterpolationList extends List {
+ public FieldInterpolationList(FieldInterpolationElement elem) { super((IParseTreeNode)elem); }
+ public FieldInterpolationList(FieldInterpolationElement elem, FieldInterpolationList next) { super((IParseTreeNode)elem, (List)next); }
+}
+
+
+
diff --git a/src/syntaxParser/FieldInterpolationMethod.java b/src/syntaxParser/FieldInterpolationMethod.java
new file mode 100644
index 0000000..da54fea
--- /dev/null
+++ b/src/syntaxParser/FieldInterpolationMethod.java
@@ -0,0 +1,20 @@
+package syntaxParser;
+/**
+ * InterpMethod
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani, Sorin Stancu-Mara
+ */
+class FieldInterpolationMethod implements IParseTreeNode {
+ String type;
+ String nullresistence;
+
+ public FieldInterpolationMethod(String type, String nr ) {
+ this.type = type;
+ nullresistence = nr;
+ }
+
+ public String toXML(){
+ return "<interpolationMethod>" + type + "</interpolationMethod>" +
+ "<nullResistence>" + nullresistence + "</nullResistence>";
+ }
+}
diff --git a/src/syntaxParser/ForClause.java b/src/syntaxParser/ForClause.java
new file mode 100644
index 0000000..f0203f5
--- /dev/null
+++ b/src/syntaxParser/ForClause.java
@@ -0,0 +1,17 @@
+package syntaxParser;
+/**
+ * ForClause
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani, Sorin Stancu-Mara
+ */
+class ForClause implements IParseTreeNode {
+ ForClauseElements forClauseElements;
+ public ForClause( ForClauseElements fce ){
+
+ forClauseElements = fce;
+ }
+
+ public String toXML(){
+ return forClauseElements.toXML();
+ }
+}
diff --git a/src/syntaxParser/ForClauseElements.java b/src/syntaxParser/ForClauseElements.java
new file mode 100644
index 0000000..ffb48d0
--- /dev/null
+++ b/src/syntaxParser/ForClauseElements.java
@@ -0,0 +1,39 @@
+package syntaxParser;
+/**
+ * ForClauseElements
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani, Sorin Stancu-Mara
+ */
+
+import java.util.*;
+
+class ForClauseElements implements IParseTreeNode{
+ String var;
+ CoverageList coverageList;
+ ForClauseElements next;
+
+
+ public ForClauseElements( String v, CoverageList c ){
+ var = v;
+ coverageList = c;
+ }
+
+ public ForClauseElements( String v, CoverageList c, ForClauseElements next ){
+ var = v;
+ coverageList = c;
+ this.next = next;
+ }
+
+ public String toXML(){
+
+ String result="";
+ result += "<coverageIterator>";
+ result +="<iteratorVar>" + var + "</iteratorVar>" ;
+ result += coverageList.toXML() ;
+ result += "</coverageIterator>";
+ if (next != null) {
+ result += next.toXML();
+ }
+ return result;
+ }
+}
diff --git a/src/syntaxParser/GeneralCondenseExpr.java b/src/syntaxParser/GeneralCondenseExpr.java
new file mode 100644
index 0000000..397e36a
--- /dev/null
+++ b/src/syntaxParser/GeneralCondenseExpr.java
@@ -0,0 +1,37 @@
+package syntaxParser;
+/**
+ * GeneralCondenseExpr
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani, Sorin stancu-Mara
+ */
+class GeneralCondenseExpr implements IParseTreeNode {
+
+ String condenseOpType;
+ ScalarExpr scalarExpr;
+ VariableList variables;
+ BooleanScalarExpr condition;
+
+ public GeneralCondenseExpr(String op, VariableList vars, ScalarExpr val) {
+ condenseOpType = op;
+ variables = vars;
+ scalarExpr = val;
+ }
+
+ public GeneralCondenseExpr(String op, VariableList vars, BooleanScalarExpr cond, ScalarExpr val) {
+ condenseOpType = op;
+ variables = vars;
+ scalarExpr = val;
+ condition = cond;
+ }
+
+ public String toXML(){
+ String result = "<condense>" + variables.toXML();
+ if (condition != null)
+ result += "<where>" + condition.toXML() + "</where>";
+ result += scalarExpr.toXML() + "</condense>";
+ return result;
+ }
+
+
+
+}
diff --git a/src/syntaxParser/GetMetaDataExpr.java b/src/syntaxParser/GetMetaDataExpr.java
new file mode 100644
index 0000000..a3f5c33
--- /dev/null
+++ b/src/syntaxParser/GetMetaDataExpr.java
@@ -0,0 +1,50 @@
+package syntaxParser;
+/**
+ * GetMetaDataExpr
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani
+ */
+class GetMetaDataExpr implements IParseTreeNode {
+ CoverageExpr coverageExpr;
+ String function;
+ String field;
+
+ /**
+ * GetMetaDataExpr constructor comment.
+ */
+ public GetMetaDataExpr() {
+ super();
+ }
+
+ public GetMetaDataExpr( String f, CoverageExpr ce){
+ coverageExpr = ce ;
+ function =f;
+ field = null;
+ }
+ public GetMetaDataExpr( String f, CoverageExpr exp, String field) {
+ coverageExpr = exp;
+ function = f;
+ this.field = field;
+ }
+
+ public String toXML() {
+ String op = "operationNotSet";
+ if (function.equals("identifier")) op = "getIdentifier";
+ if (function.equals("imageCrs")) op = "getImageCrs";
+ if (function.equals("imageCrsDomain")) op = "getImageCrsDomain"; //TODO(smsorin): The schema requires an extra parameter axis not documented in the protocol specfication
+ if (function.equals("crsSet")) op = "crsSet";
+ if (function.equals("generalDomain")) op = "getGeneralDomain"; //TODO(smsorin): The schema requires an extra parameter axis and optional* parameter crs
+ if (function.equals("nullDefault")) op = "getNullDefault";
+ if (function.equals("nullSet")) op = "getNullSet";
+ if (function.equals("interpolationDefault")) op = "getInterpolationDefault";
+ if (function.equals("interpolationSet")) op = "getInterpolationSet";
+ String result = "<" + op + ">";
+ result += coverageExpr.toXML();
+ if (field != null) {
+ result += "<field>" + field + "</field>";
+ }
+ result += "</" + op + ">";
+ return result;
+ }
+
+}
diff --git a/src/syntaxParser/IParseTreeNode.java b/src/syntaxParser/IParseTreeNode.java
new file mode 100644
index 0000000..4f59d37
--- /dev/null
+++ b/src/syntaxParser/IParseTreeNode.java
@@ -0,0 +1,9 @@
+package syntaxParser;
+/* Author: Sorin Stancu-Mara
+Date: 7 FEB 2007
+Interface that all nodes implement to simply some of the complex nodes
+*/
+
+interface IParseTreeNode {
+ public String toXML();
+}
diff --git a/src/syntaxParser/InducedExpr.java b/src/syntaxParser/InducedExpr.java
new file mode 100644
index 0000000..84c8967
--- /dev/null
+++ b/src/syntaxParser/InducedExpr.java
@@ -0,0 +1,21 @@
+package syntaxParser;
+/**
+ * InducedExpr
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani, Sorin Stancu-Mara
+ */
+class InducedExpr implements IParseTreeNode {
+
+ IParseTreeNode expr;
+
+ public InducedExpr( IParseTreeNode e ){
+ expr =e;
+ }
+
+ public String toXML(){
+ return expr.toXML();
+ }
+
+
+
+}
diff --git a/src/syntaxParser/InterpolationMethodList.java b/src/syntaxParser/InterpolationMethodList.java
new file mode 100644
index 0000000..bfec142
--- /dev/null
+++ b/src/syntaxParser/InterpolationMethodList.java
@@ -0,0 +1,6 @@
+package syntaxParser;
+
+class InterpolationMethodList extends List {
+ public InterpolationMethodList(FieldInterpolationMethod elem) { super((IParseTreeNode)elem); }
+ public InterpolationMethodList(FieldInterpolationMethod elem, InterpolationMethodList next) { super((IParseTreeNode)elem, (List)next); }
+}
diff --git a/src/syntaxParser/JLex/CAccept.class b/src/syntaxParser/JLex/CAccept.class
new file mode 100644
index 0000000..2516677
--- /dev/null
+++ b/src/syntaxParser/JLex/CAccept.class
Binary files differ
diff --git a/src/syntaxParser/JLex/CAcceptAnchor.class b/src/syntaxParser/JLex/CAcceptAnchor.class
new file mode 100644
index 0000000..394e070
--- /dev/null
+++ b/src/syntaxParser/JLex/CAcceptAnchor.class
Binary files differ
diff --git a/src/syntaxParser/JLex/CAlloc.class b/src/syntaxParser/JLex/CAlloc.class
new file mode 100644
index 0000000..127dae9
--- /dev/null
+++ b/src/syntaxParser/JLex/CAlloc.class
Binary files differ
diff --git a/src/syntaxParser/JLex/CBunch.class b/src/syntaxParser/JLex/CBunch.class
new file mode 100644
index 0000000..f63af6f
--- /dev/null
+++ b/src/syntaxParser/JLex/CBunch.class
Binary files differ
diff --git a/src/syntaxParser/JLex/CDTrans.class b/src/syntaxParser/JLex/CDTrans.class
new file mode 100644
index 0000000..e1a8fba
--- /dev/null
+++ b/src/syntaxParser/JLex/CDTrans.class
Binary files differ
diff --git a/src/syntaxParser/JLex/CDfa.class b/src/syntaxParser/JLex/CDfa.class
new file mode 100644
index 0000000..22eb5bf
--- /dev/null
+++ b/src/syntaxParser/JLex/CDfa.class
Binary files differ
diff --git a/src/syntaxParser/JLex/CEmit.class b/src/syntaxParser/JLex/CEmit.class
new file mode 100644
index 0000000..3d0d93c
--- /dev/null
+++ b/src/syntaxParser/JLex/CEmit.class
Binary files differ
diff --git a/src/syntaxParser/JLex/CError.class b/src/syntaxParser/JLex/CError.class
new file mode 100644
index 0000000..f2f8f9d
--- /dev/null
+++ b/src/syntaxParser/JLex/CError.class
Binary files differ
diff --git a/src/syntaxParser/JLex/CInput.class b/src/syntaxParser/JLex/CInput.class
new file mode 100644
index 0000000..f83ce01
--- /dev/null
+++ b/src/syntaxParser/JLex/CInput.class
Binary files differ
diff --git a/src/syntaxParser/JLex/CLexGen.class b/src/syntaxParser/JLex/CLexGen.class
new file mode 100644
index 0000000..c26935d
--- /dev/null
+++ b/src/syntaxParser/JLex/CLexGen.class
Binary files differ
diff --git a/src/syntaxParser/JLex/CMakeNfa.class b/src/syntaxParser/JLex/CMakeNfa.class
new file mode 100644
index 0000000..7d1a6b0
--- /dev/null
+++ b/src/syntaxParser/JLex/CMakeNfa.class
Binary files differ
diff --git a/src/syntaxParser/JLex/CMinimize.class b/src/syntaxParser/JLex/CMinimize.class
new file mode 100644
index 0000000..73e0a30
--- /dev/null
+++ b/src/syntaxParser/JLex/CMinimize.class
Binary files differ
diff --git a/src/syntaxParser/JLex/CNfa.class b/src/syntaxParser/JLex/CNfa.class
new file mode 100644
index 0000000..1cdac1f
--- /dev/null
+++ b/src/syntaxParser/JLex/CNfa.class
Binary files differ
diff --git a/src/syntaxParser/JLex/CNfa2Dfa.class b/src/syntaxParser/JLex/CNfa2Dfa.class
new file mode 100644
index 0000000..691fcaf
--- /dev/null
+++ b/src/syntaxParser/JLex/CNfa2Dfa.class
Binary files differ
diff --git a/src/syntaxParser/JLex/CNfaPair.class b/src/syntaxParser/JLex/CNfaPair.class
new file mode 100644
index 0000000..b51d958
--- /dev/null
+++ b/src/syntaxParser/JLex/CNfaPair.class
Binary files differ
diff --git a/src/syntaxParser/JLex/CSet.class b/src/syntaxParser/JLex/CSet.class
new file mode 100644
index 0000000..747e900
--- /dev/null
+++ b/src/syntaxParser/JLex/CSet.class
Binary files differ
diff --git a/src/syntaxParser/JLex/CSimplifyNfa.class b/src/syntaxParser/JLex/CSimplifyNfa.class
new file mode 100644
index 0000000..67110fa
--- /dev/null
+++ b/src/syntaxParser/JLex/CSimplifyNfa.class
Binary files differ
diff --git a/src/syntaxParser/JLex/CSpec.class b/src/syntaxParser/JLex/CSpec.class
new file mode 100644
index 0000000..279418a
--- /dev/null
+++ b/src/syntaxParser/JLex/CSpec.class
Binary files differ
diff --git a/src/syntaxParser/JLex/CUtility.class b/src/syntaxParser/JLex/CUtility.class
new file mode 100644
index 0000000..a48a826
--- /dev/null
+++ b/src/syntaxParser/JLex/CUtility.class
Binary files differ
diff --git a/src/syntaxParser/JLex/Main.class b/src/syntaxParser/JLex/Main.class
new file mode 100644
index 0000000..c6fb41a
--- /dev/null
+++ b/src/syntaxParser/JLex/Main.class
Binary files differ
diff --git a/src/syntaxParser/JLex/Main.java b/src/syntaxParser/JLex/Main.java
new file mode 100644
index 0000000..89ba5bb
--- /dev/null
+++ b/src/syntaxParser/JLex/Main.java
@@ -0,0 +1,7841 @@
+/**************************************************************
+ JLex: A Lexical Analyzer Generator for Java(TM)
+ Written by Elliot Berk <ejberk@cs.princeton.edu>. Copyright 1996.
+ Maintained by C. Scott Ananian <cananian@alumni.princeton.edu>.
+ See below for copyright notice, license, and disclaimer.
+ New releases from http://www.cs.princeton.edu/~appel/modern/java/JLex/
+
+ Version 1.2.6, 2/7/03, [C. Scott Ananian]
+ Renamed 'assert' function 'ASSERT' to accomodate Java 1.4's new keyword.
+ Fixed a bug which certain forms of comment in the JLex directives section
+ (which are not allowed) to be incorrectly parsed as macro definitions.
+ Version 1.2.5, 7/25/99-5/16/00, [C. Scott Ananian]
+ Stomped on one more 8-bit character bug. Should work now (really!).
+ Added unicode support, including unicode escape sequences.
+ Rewrote internal JavaLexBitSet class as SparseBitSet for efficient
+ unicoding.
+ Added an NFA character class simplification pass for unicode efficiency.
+ Changed byte- and stream-oriented I/O routines to use characters and
+ java.io.Reader and java.io.Writer instead --- which means we read in
+ unicode specifications correctly and write out a proper unicode java
+ source file. As a happy side-effect, the output java file is written
+ with your platform's preferred newline character(s).
+ Rewrote CInput to fix bugs with line-counting in the specification file
+ and "unusual behaviour" when the last line of the specification wasn't
+ terminated with a newline. Thanks to Matt Hanna <mhanna@cs.caltech.edu>
+ for pointing out the bug.
+ Fixed a bug that would cause JLex not to terminate given certain input
+ specifications. Thanks to Mark Greenstreet <mrg@cs.ubc.ca> and
+ Frank B. Brokken <frank@suffix.icce.rug.nl> for reporting this.
+ CUP parser integration improved according to suggestions made by
+ David MacMahon <davidm@smartsc.com>. The %cup directive now tells
+ JLex to generate a parser conforming to the java_cup.runtime.Scanner
+ interface; see manual for more details.
+ Fixed bug with null string literals ("") in regexps. Reported by
+ Charles Fischer <fischer@cs.wisc.edu>.
+ Rewrote start-of-line and end-of-line handling, closing active bug #5.
+ Also fixed line-counting code, closing active bug #12. All
+ new-line handling is now platform-independent.
+ Used unpackFromString more extensively to allow larger cmap, etc,
+ tables. This helps unicode support work reliably. It's also
+ prettier now if you happen to read the source to the generated
+ lexer.
+ Generated lexer now accepts unicode LS (U+2028) and PS (U+2029) as
+ line separators for strict unicode compliance; see
+ http://www.unicode.org/unicode/reports/tr18/
+ Fixed bug with character constants in action strings. Reported by
+ Andrew Appel against 1.2.5b3.
+ Fixed bug with illegal \^C-style escape sequences. Reported by
+ Toshiya Iwai <iwai@isdnet.co.jp> against 1.2.5b4.
+ Fixed "newline in quoted string" error when unpaired single- or
+ double-quotes were present in comments in the action phrase.
+ Reported by Stephen Ostermiller <1010JLex@ostermiller.com>
+ against 1.2.5b4. Reported by Eric Esposito <eric.esposito@unh.edu>
+ against 1.2.4 and 1.2.5b2.
+ Fixed "newline in quoted string" error when /* or // appeared
+ in quoted strings in the action phrase. Reported by
+ David Eichmann <david-eichmann@uiowa.edu> against 1.2.5b5.
+ Fixed 'illegal constant' errors in case statements caused by
+ Sun's JDK 1.3 more closely adhering to the Java Language
+ Specification. Reported by a number of people, but
+ Harold Grovesteen <hgrovesteen@home.com> was the first to direct me to
+ a Sun bug report (4119776) which quoted the relevant section of the
+ JLS (15.27) to convince me that the JLex construction actually was
+ illegal. Reported against 1.2.5b6, but this bit of code has been
+ present since the very first version of JLex (1.1.1).
+
+ Version 1.2.4, 7/24/99, [C. Scott Ananian]
+ Correct the parsing of '-' in character classes, closing active
+ bug #1. Behaviour follows egrep: leading and trailing dashes in
+ a character class lose their special meaning, so [-+] and [+-] do
+ what you would expect them to.
+ New %ignorecase directive for generating case-insensitive lexers by
+ expanding matched character classes in a unicode-friendly way.
+ Handle unmatched braces in quoted strings or comments within
+ action code blocks.
+ Fixed input lexer to allow whitespace in character classes, closing
+ active bug #9. Whitespace in quotes had been previously fixed.
+ Made Yylex.YYEOF and %yyeof work like the manual says they should.
+
+ Version 1.2.3, 6/26/97, [Raimondas Lencevicius]
+ Fixed the yy_nxt[][] assignment that has generated huge code
+ exceeding 64K method size limit. Now the assignment
+ is handled by unpacking a string encoding of integer array.
+ To achieve that, added
+ "private int [][] unpackFromString(int size1, int size2, String st)"
+ function and coded the yy_nxt[][] values into a string
+ by printing integers into a string and representing
+ integer sequences as "value:length" pairs.
+ Improvement: generated .java file reduced 2 times, .class file
+ reduced 6 times for sample grammar. No 64K errors.
+ Possible negatives: Some editors and OSs may not be able to handle
+ the huge one-line generated string. String unpacking may be slower
+ than direct array initialization.
+
+ Version 1.2.2, 10/24/97, [Martin Dirichs]
+ Notes:
+ Changed yy_instream to yy_reader of type BufferedReader. This reflects
+ the improvements in the JDK 1.1 concerning InputStreams. As a
+ consequence, changed yy_buffer from byte[] to char[].
+ The lexer can now be initialized with either an InputStream
+ or a Reader. A third, private constructor is called by the other
+ two to execute user specified constructor code.
+
+ Version 1.2.1, 9/15/97 [A. Appel]
+ Fixed bugs 6 (character codes > 127) and 10 (deprecated String constructor).
+
+ Version 1.2, 5/5/97, [Elliot Berk]
+ Notes:
+ Simply changed the name from JavaLex to JLex. No other changes.
+
+ Version 1.1.5, 2/25/97, [Elliot Berk]
+ Notes:
+ Simple optimization to the creation of the source files.
+ Added a BufferedOutputStream in the creation of the DataOutputStream
+ field m_outstream of the class CLexGen. This helps performance by
+ doing some buffering, and was suggested by Max Hailperin,
+ Associate Professor of Computer Science, Gustavus Adolphus College.
+
+ Version 1.1.4, 12/12/96, [Elliot Berk]
+ Notes:
+ Added %public directive to make generated class public.
+
+ Version 1.1.3, 12/11/96, [Elliot Berk]
+ Notes:
+ Converted assertion failure on invalid character class
+ when a dash '-' is not preceded with a start-of-range character.
+ Converted this into parse error E_DASH.
+
+ Version 1.1.2, October 30, 1996 [Elliot Berk]
+ Fixed BitSet bugs by installing a BitSet class of my own,
+ called JavaLexBitSet. Fixed support for '\r', non-UNIX
+ sequences. Added try/catch block around lexer generation
+ in main routine to moderate error information presented
+ to user. Fixed macro expansion, so that macros following
+ quotes are expanded correctly in regular expressions.
+ Fixed dynamic reallocation of accept action buffers.
+
+ Version 1.1.1, September 3, 1996 [Andrew Appel]
+ Made the class "Main" instead of "JavaLex",
+ improved the installation instructions to reflect this.
+
+ Version 1.1, August 15, 1996 [Andrew Appel]
+ Made yychar, yyline, yytext global to the lexer so that
+ auxiliary functions can access them.
+ **************************************************************/
+
+/***************************************************************
+ JLEX COPYRIGHT NOTICE, LICENSE, AND DISCLAIMER
+ Copyright 1996-2000 by Elliot Joel Berk and C. Scott Ananian
+
+ Permission to use, copy, modify, and distribute this software and its
+ documentation for any purpose and without fee is hereby granted,
+ provided that the above copyright notice appear in all copies and that
+ both the copyright notice and this permission notice and warranty
+ disclaimer appear in supporting documentation, and that the name of
+ the authors or their employers not be used in advertising or publicity
+ pertaining to distribution of the software without specific, written
+ prior permission.
+
+ The authors and their employers disclaim all warranties with regard to
+ this software, including all implied warranties of merchantability and
+ fitness. In no event shall the authors or their employers be liable
+ for any special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether in an
+ action of contract, negligence or other tortious action, arising out
+ of or in connection with the use or performance of this software.
+ **************************************************************/
+
+/***************************************************************
+ Package Declaration
+ **************************************************************/
+package JLex;
+
+/***************************************************************
+ Imported Packages
+ **************************************************************/
+import java.lang.System;
+import java.lang.Integer;
+import java.lang.Character;
+
+import java.util.Enumeration;
+import java.util.Stack;
+import java.util.Hashtable;
+import java.util.Vector;
+
+/******************************
+ Questions:
+ 2) How should I use the Java package system
+ to make my tool more modularized and
+ coherent?
+
+ Unimplemented:
+ !) Fix BitSet issues -- expand only when necessary.
+ 2) Repeated accept rules.
+ 6) Clean up the CAlloc class and use buffered
+ allocation.
+ 9) Add to spec about extending character set.
+ 11) m_verbose -- what should be done with it?
+ 12) turn lexical analyzer into a coherent
+ Java package
+ 13) turn lexical analyzer generator into a
+ coherent Java package
+ 16) pretty up generated code
+ 17) make it possible to have white space in
+ regular expressions
+ 18) clean up all of the class files the lexer
+ generator produces when it is compiled,
+ and reduce this number in some way.
+ 24) character format to and from file: writeup
+ and implementation
+ 25) Debug by testing all arcane regular expression cases.
+ 26) Look for and fix all UNDONE comments below.
+ 27) Fix package system.
+ 28) Clean up unnecessary classes.
+ *****************************/
+
+/***************************************************************
+ Class: CSpec
+ **************************************************************/
+class CSpec
+{
+ /***************************************************************
+ Member Variables
+ **************************************************************/
+
+ /* Lexical States. */
+ Hashtable m_states; /* Hashtable taking state indices (Integer)
+ to state name (String). */
+
+ /* Regular Expression Macros. */
+ Hashtable m_macros; /* Hashtable taking macro name (String)
+ to corresponding char buffer that
+ holds macro definition. */
+
+ /* NFA Machine. */
+ CNfa m_nfa_start; /* Start state of NFA machine. */
+ Vector m_nfa_states; /* Vector of states, with index
+ corresponding to label. */
+
+ Vector m_state_rules[]; /* An array of Vectors of Integers.
+ The ith Vector represents the lexical state
+ with index i. The contents of the ith
+ Vector are the indices of the NFA start
+ states that can be matched while in
+ the ith lexical state. */
+
+
+ int m_state_dtrans[];
+
+ /* DFA Machine. */
+ Vector m_dfa_states; /* Vector of states, with index
+ corresponding to label. */
+ Hashtable m_dfa_sets; /* Hashtable taking set of NFA states
+ to corresponding DFA state,
+ if the latter exists. */
+
+ /* Accept States and Corresponding Anchors. */
+ Vector m_accept_vector;
+ int m_anchor_array[];
+
+ /* Transition Table. */
+ Vector m_dtrans_vector;
+ int m_dtrans_ncols;
+ int m_row_map[];
+ int m_col_map[];
+
+ /* Special pseudo-characters for beginning-of-line and end-of-file. */
+ static final int NUM_PSEUDO=2;
+ int BOL; // beginning-of-line
+ int EOF; // end-of-line
+
+ /** NFA character class minimization map. */
+ int m_ccls_map[];
+
+ /* Regular expression token variables. */
+ int m_current_token;
+ char m_lexeme;
+ boolean m_in_quote;
+ boolean m_in_ccl;
+
+ /* Verbose execution flag. */
+ boolean m_verbose;
+
+ /* JLex directives flags. */
+ boolean m_integer_type;
+ boolean m_intwrap_type;
+ boolean m_yyeof;
+ boolean m_count_chars;
+ boolean m_count_lines;
+ boolean m_cup_compatible;
+ boolean m_unix;
+ boolean m_public;
+ boolean m_ignorecase;
+
+ char m_init_code[];
+ int m_init_read;
+
+ char m_init_throw_code[];
+ int m_init_throw_read;
+
+ char m_class_code[];
+ int m_class_read;
+
+ char m_eof_code[];
+ int m_eof_read;
+
+ char m_eof_value_code[];
+ int m_eof_value_read;
+
+ char m_eof_throw_code[];
+ int m_eof_throw_read;
+
+ char m_yylex_throw_code[];
+ int m_yylex_throw_read;
+
+ /* Class, function, type names. */
+ char m_class_name[] = {
+ 'Y', 'y', 'l',
+ 'e', 'x'
+ };
+ char m_implements_name[] = {};
+ char m_function_name[] = {
+ 'y', 'y', 'l',
+ 'e', 'x'
+ };
+ char m_type_name[] = {
+ 'Y', 'y', 't',
+ 'o', 'k', 'e',
+ 'n'
+ };
+
+ /* Lexical Generator. */
+ private CLexGen m_lexGen;
+
+ /***************************************************************
+ Constants
+ ***********************************************************/
+ static final int NONE = 0;
+ static final int START = 1;
+ static final int END = 2;
+
+ /***************************************************************
+ Function: CSpec
+ Description: Constructor.
+ **************************************************************/
+ CSpec
+ (
+ CLexGen lexGen
+ )
+ {
+ m_lexGen = lexGen;
+
+ /* Initialize regular expression token variables. */
+ m_current_token = m_lexGen.EOS;
+ m_lexeme = '\0';
+ m_in_quote = false;
+ m_in_ccl = false;
+
+ /* Initialize hashtable for lexer states. */
+ m_states = new Hashtable();
+ m_states.put(new String("YYINITIAL"),new Integer(m_states.size()));
+
+ /* Initialize hashtable for lexical macros. */
+ m_macros = new Hashtable();
+
+ /* Initialize variables for lexer options. */
+ m_integer_type = false;
+ m_intwrap_type = false;
+ m_count_lines = false;
+ m_count_chars = false;
+ m_cup_compatible = false;
+ m_unix = true;
+ m_public = false;
+ m_yyeof = false;
+ m_ignorecase = false;
+
+ /* Initialize variables for JLex runtime options. */
+ m_verbose = true;
+
+ m_nfa_start = null;
+ m_nfa_states = new Vector();
+
+ m_dfa_states = new Vector();
+ m_dfa_sets = new Hashtable();
+
+ m_dtrans_vector = new Vector();
+ m_dtrans_ncols = CUtility.MAX_SEVEN_BIT + 1;
+ m_row_map = null;
+ m_col_map = null;
+
+ m_accept_vector = null;
+ m_anchor_array = null;
+
+ m_init_code = null;
+ m_init_read = 0;
+
+ m_init_throw_code = null;
+ m_init_throw_read = 0;
+
+ m_yylex_throw_code = null;
+ m_yylex_throw_read = 0;
+
+ m_class_code = null;
+ m_class_read = 0;
+
+ m_eof_code = null;
+ m_eof_read = 0;
+
+ m_eof_value_code = null;
+ m_eof_value_read = 0;
+
+ m_eof_throw_code = null;
+ m_eof_throw_read = 0;
+
+ m_state_dtrans = null;
+
+ m_state_rules = null;
+ }
+}
+
+/***************************************************************
+ Class: CEmit
+ **************************************************************/
+class CEmit
+{
+ /***************************************************************
+ Member Variables
+ **************************************************************/
+ private CSpec m_spec;
+ private java.io.PrintWriter m_outstream;
+
+ /***************************************************************
+ Constants: Anchor Types
+ **************************************************************/
+ private final int START = 1;
+ private final int END = 2;
+ private final int NONE = 4;
+
+ /***************************************************************
+ Constants
+ **************************************************************/
+ private final boolean EDBG = true;
+ private final boolean NOT_EDBG = false;
+
+ /***************************************************************
+ Function: CEmit
+ Description: Constructor.
+ **************************************************************/
+ CEmit
+ (
+ )
+ {
+ reset();
+ }
+
+ /***************************************************************
+ Function: reset
+ Description: Clears member variables.
+ **************************************************************/
+ private void reset
+ (
+ )
+ {
+ m_spec = null;
+ m_outstream = null;
+ }
+
+ /***************************************************************
+ Function: set
+ Description: Initializes member variables.
+ **************************************************************/
+ private void set
+ (
+ CSpec spec,
+ java.io.PrintWriter outstream
+ )
+ {
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != spec);
+ CUtility.ASSERT(null != outstream);
+ }
+
+ m_spec = spec;
+ m_outstream = outstream;
+ }
+
+ /***************************************************************
+ Function: emit_imports
+ Description: Emits import packages at top of
+ generated source file.
+ **************************************************************/
+ /*void emit_imports
+ (
+ CSpec spec,
+ OutputStream outstream
+ )
+ throws java.io.IOException
+ {
+ set(spec,outstream);
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != m_spec);
+ CUtility.ASSERT(null != m_outstream);
+ }*/
+
+ /*m_outstream.println("import java.lang.String;");
+ m_outstream.println("import java.lang.System;");
+ m_outstream.println("import java.io.BufferedReader;");
+ m_outstream.println("import java.io.InputStream;");*/
+ /*
+ reset();
+ }*/
+
+ /***************************************************************
+ Function: print_details
+ Description: Debugging output.
+ **************************************************************/
+ private void print_details
+ (
+ )
+ {
+ int i;
+ int j;
+ int next;
+ int state;
+ CDTrans dtrans;
+ CAccept accept;
+ boolean tr;
+
+ System.out.println("---------------------- Transition Table "
+ + "----------------------");
+
+ for (i = 0; i < m_spec.m_row_map.length; ++i)
+ {
+ System.out.print("State " + i);
+
+ accept = (CAccept) m_spec.m_accept_vector.elementAt(i);
+ if (null == accept)
+ {
+ System.out.println(" [nonaccepting]");
+ }
+ else
+ {
+ System.out.println(" [accepting, line "
+ + accept.m_line_number
+ + " <"
+ + (new java.lang.String(accept.m_action,0,
+ accept.m_action_read))
+ + ">]");
+ }
+ dtrans = (CDTrans) m_spec.m_dtrans_vector.elementAt(m_spec.m_row_map[i]);
+
+ tr = false;
+ state = dtrans.m_dtrans[m_spec.m_col_map[0]];
+ if (CDTrans.F != state)
+ {
+ tr = true;
+ System.out.print("\tgoto " + state + " on [" + ((char) 0));
+ }
+ for (j = 1; j < m_spec.m_dtrans_ncols; ++j)
+ {
+ next = dtrans.m_dtrans[m_spec.m_col_map[j]];
+ if (state == next)
+ {
+ if (CDTrans.F != state)
+ {
+ System.out.print((char) j);
+ }
+ }
+ else
+ {
+ state = next;
+ if (tr)
+ {
+ System.out.println("]");
+ tr = false;
+ }
+ if (CDTrans.F != state)
+ {
+ tr = true;
+ System.out.print("\tgoto " + state + " on [" + ((char) j));
+ }
+ }
+ }
+ if (tr)
+ {
+ System.out.println("]");
+ }
+ }
+
+ System.out.println("---------------------- Transition Table "
+ + "----------------------");
+ }
+
+ /***************************************************************
+ Function: emit
+ Description: High-level access function to module.
+ **************************************************************/
+ void emit
+ (
+ CSpec spec,
+ java.io.PrintWriter outstream
+ )
+ throws java.io.IOException
+ {
+ set(spec,outstream);
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != m_spec);
+ CUtility.ASSERT(null != m_outstream);
+ }
+
+ if (CUtility.OLD_DEBUG) {
+ print_details();
+ }
+
+ emit_header();
+ emit_construct();
+ emit_helpers();
+ emit_driver();
+ emit_footer();
+
+ reset();
+ }
+
+ /***************************************************************
+ Function: emit_construct
+ Description: Emits constructor, member variables,
+ and constants.
+ **************************************************************/
+ private void emit_construct
+ (
+ )
+ throws java.io.IOException
+ {
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != m_spec);
+ CUtility.ASSERT(null != m_outstream);
+ }
+
+ /* Constants */
+ m_outstream.println("\tprivate final int YY_BUFFER_SIZE = 512;");
+
+ m_outstream.println("\tprivate final int YY_F = -1;");
+ m_outstream.println("\tprivate final int YY_NO_STATE = -1;");
+
+ m_outstream.println("\tprivate final int YY_NOT_ACCEPT = 0;");
+ m_outstream.println("\tprivate final int YY_START = 1;");
+ m_outstream.println("\tprivate final int YY_END = 2;");
+ m_outstream.println("\tprivate final int YY_NO_ANCHOR = 4;");
+
+ // internal
+ m_outstream.println("\tprivate final int YY_BOL = "+m_spec.BOL+";");
+ m_outstream.println("\tprivate final int YY_EOF = "+m_spec.EOF+";");
+ // external
+ if (m_spec.m_integer_type || true == m_spec.m_yyeof)
+ m_outstream.println("\tpublic final int YYEOF = -1;");
+
+ /* User specified class code. */
+ if (null != m_spec.m_class_code)
+ {
+ m_outstream.print(new String(m_spec.m_class_code,0,
+ m_spec.m_class_read));
+ }
+
+ /* Member Variables */
+ m_outstream.println("\tprivate java.io.BufferedReader yy_reader;");
+ m_outstream.println("\tprivate int yy_buffer_index;");
+ m_outstream.println("\tprivate int yy_buffer_read;");
+ m_outstream.println("\tprivate int yy_buffer_start;");
+ m_outstream.println("\tprivate int yy_buffer_end;");
+ m_outstream.println("\tprivate char yy_buffer[];");
+ if (m_spec.m_count_chars)
+ {
+ m_outstream.println("\tprivate int yychar;");
+ }
+ if (m_spec.m_count_lines)
+ {
+ m_outstream.println("\tprivate int yyline;");
+ }
+ m_outstream.println("\tprivate boolean yy_at_bol;");
+ m_outstream.println("\tprivate int yy_lexical_state;");
+ /*if (m_spec.m_count_lines || true == m_spec.m_count_chars)
+ {
+ m_outstream.println("\tprivate int yy_buffer_prev_start;");
+ }*/
+ m_outstream.println();
+
+
+ /* Function: first constructor (Reader) */
+ m_outstream.print("\t");
+ if (true == m_spec.m_public) {
+ m_outstream.print("public ");
+ }
+ m_outstream.print(new String(m_spec.m_class_name));
+ m_outstream.print(" (java.io.Reader reader)");
+
+ if (null != m_spec.m_init_throw_code)
+ {
+ m_outstream.println();
+ m_outstream.print("\t\tthrows ");
+ m_outstream.print(new String(m_spec.m_init_throw_code,0,
+ m_spec.m_init_throw_read));
+ m_outstream.println();
+ m_outstream.println("\t\t{");
+ }
+ else
+ {
+ m_outstream.println(" {");
+ }
+
+ m_outstream.println("\t\tthis ();");
+ m_outstream.println("\t\tif (null == reader) {");
+ m_outstream.println("\t\t\tthrow (new Error(\"Error: Bad input "
+ + "stream initializer.\"));");
+ m_outstream.println("\t\t}");
+ m_outstream.println("\t\tyy_reader = new java.io.BufferedReader(reader);");
+ m_outstream.println("\t}");
+ m_outstream.println();
+
+
+ /* Function: second constructor (InputStream) */
+ m_outstream.print("\t");
+ if (true == m_spec.m_public) {
+ m_outstream.print("public ");
+ }
+ m_outstream.print(new String(m_spec.m_class_name));
+ m_outstream.print(" (java.io.InputStream instream)");
+
+ if (null != m_spec.m_init_throw_code)
+ {
+ m_outstream.println();
+ m_outstream.print("\t\tthrows ");
+ m_outstream.println(new String(m_spec.m_init_throw_code,0,
+ m_spec.m_init_throw_read));
+ m_outstream.println("\t\t{");
+ }
+ else
+ {
+ m_outstream.println(" {");
+ }
+
+ m_outstream.println("\t\tthis ();");
+ m_outstream.println("\t\tif (null == instream) {");
+ m_outstream.println("\t\t\tthrow (new Error(\"Error: Bad input "
+ + "stream initializer.\"));");
+ m_outstream.println("\t\t}");
+ m_outstream.println("\t\tyy_reader = new java.io.BufferedReader(new java.io.InputStreamReader(instream));");
+ m_outstream.println("\t}");
+ m_outstream.println();
+
+
+ /* Function: third, private constructor - only for internal use */
+ m_outstream.print("\tprivate ");
+ m_outstream.print(new String(m_spec.m_class_name));
+ m_outstream.print(" ()");
+
+ if (null != m_spec.m_init_throw_code)
+ {
+ m_outstream.println();
+ m_outstream.print("\t\tthrows ");
+ m_outstream.println(new String(m_spec.m_init_throw_code,0,
+ m_spec.m_init_throw_read));
+ m_outstream.println("\t\t{");
+ }
+ else
+ {
+ m_outstream.println(" {");
+ }
+
+ m_outstream.println("\t\tyy_buffer = new char[YY_BUFFER_SIZE];");
+ m_outstream.println("\t\tyy_buffer_read = 0;");
+ m_outstream.println("\t\tyy_buffer_index = 0;");
+ m_outstream.println("\t\tyy_buffer_start = 0;");
+ m_outstream.println("\t\tyy_buffer_end = 0;");
+ if (m_spec.m_count_chars)
+ {
+ m_outstream.println("\t\tyychar = 0;");
+ }
+ if (m_spec.m_count_lines)
+ {
+ m_outstream.println("\t\tyyline = 0;");
+ }
+ m_outstream.println("\t\tyy_at_bol = true;");
+ m_outstream.println("\t\tyy_lexical_state = YYINITIAL;");
+ /*if (m_spec.m_count_lines || true == m_spec.m_count_chars)
+ {
+ m_outstream.println("\t\tyy_buffer_prev_start = 0;");
+ }*/
+
+ /* User specified constructor code. */
+ if (null != m_spec.m_init_code)
+ {
+ m_outstream.print(new String(m_spec.m_init_code,0,
+ m_spec.m_init_read));
+ }
+
+ m_outstream.println("\t}");
+ m_outstream.println();
+
+ }
+
+ /***************************************************************
+ Function: emit_states
+ Description: Emits constants that serve as lexical states,
+ including YYINITIAL.
+ **************************************************************/
+ private void emit_states
+ (
+ )
+ throws java.io.IOException
+ {
+ Enumeration states;
+ String state;
+ int index;
+
+ states = m_spec.m_states.keys();
+ /*index = 0;*/
+ while (states.hasMoreElements())
+ {
+ state = (String) states.nextElement();
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != state);
+ }
+
+ m_outstream.println("\tprivate final int "
+ + state
+ + " = "
+ + (m_spec.m_states.get(state)).toString()
+ + ";");
+ /*++index;*/
+ }
+
+ m_outstream.println("\tprivate final int yy_state_dtrans[] = {");
+ for (index = 0; index < m_spec.m_state_dtrans.length; ++index)
+ {
+ m_outstream.print("\t\t" + m_spec.m_state_dtrans[index]);
+ if (index < m_spec.m_state_dtrans.length - 1)
+ {
+ m_outstream.println(",");
+ }
+ else
+ {
+ m_outstream.println();
+ }
+ }
+ m_outstream.println("\t};");
+ }
+
+ /***************************************************************
+ Function: emit_helpers
+ Description: Emits helper functions, particularly
+ error handling and input buffering.
+ **************************************************************/
+ private void emit_helpers
+ (
+ )
+ throws java.io.IOException
+ {
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != m_spec);
+ CUtility.ASSERT(null != m_outstream);
+ }
+
+ /* Function: yy_do_eof */
+ m_outstream.println("\tprivate boolean yy_eof_done = false;");
+ if (null != m_spec.m_eof_code)
+ {
+ m_outstream.print("\tprivate void yy_do_eof ()");
+
+ if (null != m_spec.m_eof_throw_code)
+ {
+ m_outstream.println();
+ m_outstream.print("\t\tthrows ");
+ m_outstream.println(new String(m_spec.m_eof_throw_code,0,
+ m_spec.m_eof_throw_read));
+ m_outstream.println("\t\t{");
+ }
+ else
+ {
+ m_outstream.println(" {");
+ }
+
+ m_outstream.println("\t\tif (false == yy_eof_done) {");
+ m_outstream.print(new String(m_spec.m_eof_code,0,
+ m_spec.m_eof_read));
+ m_outstream.println("\t\t}");
+ m_outstream.println("\t\tyy_eof_done = true;");
+ m_outstream.println("\t}");
+ }
+
+ emit_states();
+
+ /* Function: yybegin */
+ m_outstream.println("\tprivate void yybegin (int state) {");
+ m_outstream.println("\t\tyy_lexical_state = state;");
+ m_outstream.println("\t}");
+
+ /* Function: yy_initial_dtrans */
+ /*m_outstream.println("\tprivate int yy_initial_dtrans (int state) {");
+ m_outstream.println("\t\treturn yy_state_dtrans[state];");
+ m_outstream.println("\t}");*/
+
+ /* Function: yy_advance */
+ m_outstream.println("\tprivate int yy_advance ()");
+ m_outstream.println("\t\tthrows java.io.IOException {");
+ /*m_outstream.println("\t\t{");*/
+ m_outstream.println("\t\tint next_read;");
+ m_outstream.println("\t\tint i;");
+ m_outstream.println("\t\tint j;");
+ m_outstream.println();
+
+ m_outstream.println("\t\tif (yy_buffer_index < yy_buffer_read) {");
+ m_outstream.println("\t\t\treturn yy_buffer[yy_buffer_index++];");
+ /*m_outstream.println("\t\t\t++yy_buffer_index;");*/
+ m_outstream.println("\t\t}");
+ m_outstream.println();
+
+ m_outstream.println("\t\tif (0 != yy_buffer_start) {");
+ m_outstream.println("\t\t\ti = yy_buffer_start;");
+ m_outstream.println("\t\t\tj = 0;");
+ m_outstream.println("\t\t\twhile (i < yy_buffer_read) {");
+ m_outstream.println("\t\t\t\tyy_buffer[j] = yy_buffer[i];");
+ m_outstream.println("\t\t\t\t++i;");
+ m_outstream.println("\t\t\t\t++j;");
+ m_outstream.println("\t\t\t}");
+ m_outstream.println("\t\t\tyy_buffer_end = yy_buffer_end - yy_buffer_start;");
+ m_outstream.println("\t\t\tyy_buffer_start = 0;");
+ m_outstream.println("\t\t\tyy_buffer_read = j;");
+ m_outstream.println("\t\t\tyy_buffer_index = j;");
+ m_outstream.println("\t\t\tnext_read = yy_reader.read(yy_buffer,");
+ m_outstream.println("\t\t\t\t\tyy_buffer_read,");
+ m_outstream.println("\t\t\t\t\tyy_buffer.length - yy_buffer_read);");
+ m_outstream.println("\t\t\tif (-1 == next_read) {");
+ m_outstream.println("\t\t\t\treturn YY_EOF;");
+ m_outstream.println("\t\t\t}");
+ m_outstream.println("\t\t\tyy_buffer_read = yy_buffer_read + next_read;");
+ m_outstream.println("\t\t}");
+ m_outstream.println();
+
+ m_outstream.println("\t\twhile (yy_buffer_index >= yy_buffer_read) {");
+ m_outstream.println("\t\t\tif (yy_buffer_index >= yy_buffer.length) {");
+ m_outstream.println("\t\t\t\tyy_buffer = yy_double(yy_buffer);");
+ m_outstream.println("\t\t\t}");
+ m_outstream.println("\t\t\tnext_read = yy_reader.read(yy_buffer,");
+ m_outstream.println("\t\t\t\t\tyy_buffer_read,");
+ m_outstream.println("\t\t\t\t\tyy_buffer.length - yy_buffer_read);");
+ m_outstream.println("\t\t\tif (-1 == next_read) {");
+ m_outstream.println("\t\t\t\treturn YY_EOF;");
+ m_outstream.println("\t\t\t}");
+ m_outstream.println("\t\t\tyy_buffer_read = yy_buffer_read + next_read;");
+ m_outstream.println("\t\t}");
+
+ m_outstream.println("\t\treturn yy_buffer[yy_buffer_index++];");
+ m_outstream.println("\t}");
+
+ /* Function: yy_move_end */
+ m_outstream.println("\tprivate void yy_move_end () {");
+ m_outstream.println("\t\tif (yy_buffer_end > yy_buffer_start &&");
+ m_outstream.println("\t\t '\\n' == yy_buffer[yy_buffer_end-1])");
+ m_outstream.println("\t\t\tyy_buffer_end--;");
+ m_outstream.println("\t\tif (yy_buffer_end > yy_buffer_start &&");
+ m_outstream.println("\t\t '\\r' == yy_buffer[yy_buffer_end-1])");
+ m_outstream.println("\t\t\tyy_buffer_end--;");
+ m_outstream.println("\t}");
+
+ /* Function: yy_mark_start */
+ m_outstream.println("\tprivate boolean yy_last_was_cr=false;");
+ m_outstream.println("\tprivate void yy_mark_start () {");
+ if (m_spec.m_count_lines || true == m_spec.m_count_chars)
+ {
+ if (m_spec.m_count_lines)
+ {
+ m_outstream.println("\t\tint i;");
+ m_outstream.println("\t\tfor (i = yy_buffer_start; "
+ + "i < yy_buffer_index; ++i) {");
+ m_outstream.println("\t\t\tif ('\\n' == yy_buffer[i] && !yy_last_was_cr) {");
+ m_outstream.println("\t\t\t\t++yyline;");
+ m_outstream.println("\t\t\t}");
+ m_outstream.println("\t\t\tif ('\\r' == yy_buffer[i]) {");
+ m_outstream.println("\t\t\t\t++yyline;");
+ m_outstream.println("\t\t\t\tyy_last_was_cr=true;");
+ m_outstream.println("\t\t\t} else yy_last_was_cr=false;");
+ m_outstream.println("\t\t}");
+ }
+ if (m_spec.m_count_chars)
+ {
+ m_outstream.println("\t\tyychar = yychar");
+ m_outstream.println("\t\t\t+ yy_buffer_index - yy_buffer_start;");
+ }
+ }
+ m_outstream.println("\t\tyy_buffer_start = yy_buffer_index;");
+ m_outstream.println("\t}");
+
+ /* Function: yy_mark_end */
+ m_outstream.println("\tprivate void yy_mark_end () {");
+ m_outstream.println("\t\tyy_buffer_end = yy_buffer_index;");
+ m_outstream.println("\t}");
+
+ /* Function: yy_to_mark */
+ m_outstream.println("\tprivate void yy_to_mark () {");
+ m_outstream.println("\t\tyy_buffer_index = yy_buffer_end;");
+ m_outstream.println("\t\tyy_at_bol = "+
+ "(yy_buffer_end > yy_buffer_start) &&");
+ m_outstream.println("\t\t "+
+ "('\\r' == yy_buffer[yy_buffer_end-1] ||");
+ m_outstream.println("\t\t "+
+ " '\\n' == yy_buffer[yy_buffer_end-1] ||");
+ m_outstream.println("\t\t "+ /* unicode LS */
+ " 2028/*LS*/ == yy_buffer[yy_buffer_end-1] ||");
+ m_outstream.println("\t\t "+ /* unicode PS */
+ " 2029/*PS*/ == yy_buffer[yy_buffer_end-1]);");
+ m_outstream.println("\t}");
+
+ /* Function: yytext */
+ m_outstream.println("\tprivate java.lang.String yytext () {");
+ m_outstream.println("\t\treturn (new java.lang.String(yy_buffer,");
+ m_outstream.println("\t\t\tyy_buffer_start,");
+ m_outstream.println("\t\t\tyy_buffer_end - yy_buffer_start));");
+ m_outstream.println("\t}");
+
+ /* Function: yylength */
+ m_outstream.println("\tprivate int yylength () {");
+ m_outstream.println("\t\treturn yy_buffer_end - yy_buffer_start;");
+ m_outstream.println("\t}");
+
+ /* Function: yy_double */
+ m_outstream.println("\tprivate char[] yy_double (char buf[]) {");
+ m_outstream.println("\t\tint i;");
+ m_outstream.println("\t\tchar newbuf[];");
+ m_outstream.println("\t\tnewbuf = new char[2*buf.length];");
+ m_outstream.println("\t\tfor (i = 0; i < buf.length; ++i) {");
+ m_outstream.println("\t\t\tnewbuf[i] = buf[i];");
+ m_outstream.println("\t\t}");
+ m_outstream.println("\t\treturn newbuf;");
+ m_outstream.println("\t}");
+
+ /* Function: yy_error */
+ m_outstream.println("\tprivate final int YY_E_INTERNAL = 0;");
+ m_outstream.println("\tprivate final int YY_E_MATCH = 1;");
+ m_outstream.println("\tprivate java.lang.String yy_error_string[] = {");
+ m_outstream.println("\t\t\"Error: Internal error.\\n\",");
+ m_outstream.println("\t\t\"Error: Unmatched input.\\n\"");
+ m_outstream.println("\t};");
+ m_outstream.println("\tprivate void yy_error (int code,boolean fatal) {");
+ m_outstream.println("\t\tjava.lang.System.out.print(yy_error_string[code]);");
+ m_outstream.println("\t\tjava.lang.System.out.flush();");
+ m_outstream.println("\t\tif (fatal) {");
+ m_outstream.println("\t\t\tthrow new Error(\"Fatal Error.\\n\");");
+ m_outstream.println("\t\t}");
+ m_outstream.println("\t}");
+
+ /* Function: yy_next */
+ /*m_outstream.println("\tprivate int yy_next (int current,char lookahead) {");
+ m_outstream.println("\t\treturn yy_nxt[yy_rmap[current]][yy_cmap[lookahead]];");
+ m_outstream.println("\t}");*/
+
+ /* Function: yy_accept */
+ /*m_outstream.println("\tprivate int yy_accept (int current) {");
+ m_outstream.println("\t\treturn yy_acpt[current];");
+ m_outstream.println("\t}");*/
+
+
+ // Function: private int [][] unpackFromString(int size1, int size2, String st)
+ // Added 6/24/98 Raimondas Lencevicius
+ // May be made more efficient by replacing String operations
+ // Assumes correctly formed input String. Performs no error checking
+ m_outstream.println("\tprivate int[][] unpackFromString"+
+ "(int size1, int size2, String st) {");
+ m_outstream.println("\t\tint colonIndex = -1;");
+ m_outstream.println("\t\tString lengthString;");
+ m_outstream.println("\t\tint sequenceLength = 0;");
+ m_outstream.println("\t\tint sequenceInteger = 0;");
+ m_outstream.println();
+ m_outstream.println("\t\tint commaIndex;");
+ m_outstream.println("\t\tString workString;");
+ m_outstream.println();
+ m_outstream.println("\t\tint res[][] = new int[size1][size2];");
+ m_outstream.println("\t\tfor (int i= 0; i < size1; i++) {");
+ m_outstream.println("\t\t\tfor (int j= 0; j < size2; j++) {");
+ m_outstream.println("\t\t\t\tif (sequenceLength != 0) {");
+ m_outstream.println("\t\t\t\t\tres[i][j] = sequenceInteger;");
+ m_outstream.println("\t\t\t\t\tsequenceLength--;");
+ m_outstream.println("\t\t\t\t\tcontinue;");
+ m_outstream.println("\t\t\t\t}");
+ m_outstream.println("\t\t\t\tcommaIndex = st.indexOf(',');");
+ m_outstream.println("\t\t\t\tworkString = (commaIndex==-1) ? st :");
+ m_outstream.println("\t\t\t\t\tst.substring(0, commaIndex);");
+ m_outstream.println("\t\t\t\tst = st.substring(commaIndex+1);");
+ m_outstream.println("\t\t\t\tcolonIndex = workString.indexOf(':');");
+ m_outstream.println("\t\t\t\tif (colonIndex == -1) {");
+ m_outstream.println("\t\t\t\t\tres[i][j]=Integer.parseInt(workString);");
+ m_outstream.println("\t\t\t\t\tcontinue;");
+ m_outstream.println("\t\t\t\t}");
+ m_outstream.println("\t\t\t\tlengthString =");
+ m_outstream.println("\t\t\t\t\tworkString.substring(colonIndex+1);");
+ m_outstream.println("\t\t\t\tsequenceLength="+
+ "Integer.parseInt(lengthString);");
+ m_outstream.println("\t\t\t\tworkString="+
+ "workString.substring(0,colonIndex);");
+ m_outstream.println("\t\t\t\tsequenceInteger="+
+ "Integer.parseInt(workString);");
+ m_outstream.println("\t\t\t\tres[i][j] = sequenceInteger;");
+ m_outstream.println("\t\t\t\tsequenceLength--;");
+ m_outstream.println("\t\t\t}");
+ m_outstream.println("\t\t}");
+ m_outstream.println("\t\treturn res;");
+ m_outstream.println("\t}");
+ }
+
+ /***************************************************************
+ Function: emit_header
+ Description: Emits class header.
+ **************************************************************/
+ private void emit_header
+ (
+ )
+ throws java.io.IOException
+ {
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != m_spec);
+ CUtility.ASSERT(null != m_outstream);
+ }
+
+ m_outstream.println();
+ m_outstream.println();
+ if (true == m_spec.m_public) {
+ m_outstream.print("public ");
+ }
+ m_outstream.print("class ");
+ m_outstream.print(new String(m_spec.m_class_name,0,
+ m_spec.m_class_name.length));
+ if (m_spec.m_implements_name.length > 0) {
+ m_outstream.print(" implements ");
+ m_outstream.print(new String(m_spec.m_implements_name,0,
+ m_spec.m_implements_name.length));
+ }
+ m_outstream.println(" {");
+ }
+
+ /***************************************************************
+ Function: emit_table
+ Description: Emits transition table.
+ **************************************************************/
+ private void emit_table
+ (
+ )
+ throws java.io.IOException
+ {
+ int i;
+ int elem;
+ int size;
+ CDTrans dtrans;
+ boolean is_start;
+ boolean is_end;
+ CAccept accept;
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != m_spec);
+ CUtility.ASSERT(null != m_outstream);
+ }
+
+ m_outstream.println("\tprivate int yy_acpt[] = {");
+ size = m_spec.m_accept_vector.size();
+ for (elem = 0; elem < size; ++elem)
+ {
+ accept = (CAccept) m_spec.m_accept_vector.elementAt(elem);
+
+ m_outstream.print("\t\t/* "+elem+" */ ");
+ if (null != accept)
+ {
+ is_start = (0 != (m_spec.m_anchor_array[elem] & CSpec.START));
+ is_end = (0 != (m_spec.m_anchor_array[elem] & CSpec.END));
+
+ if (is_start && true == is_end)
+ {
+ m_outstream.print("YY_START | YY_END");
+ }
+ else if (is_start)
+ {
+ m_outstream.print("YY_START");
+ }
+ else if (is_end)
+ {
+ m_outstream.print("YY_END");
+ }
+ else
+ {
+ m_outstream.print("YY_NO_ANCHOR");
+ }
+ }
+ else
+ {
+ m_outstream.print("YY_NOT_ACCEPT");
+ }
+
+ if (elem < size - 1)
+ {
+ m_outstream.print(",");
+ }
+
+ m_outstream.println();
+ }
+ m_outstream.println("\t};");
+
+ // CSA: modified yy_cmap to use string packing 9-Aug-1999
+ int[] yy_cmap = new int[m_spec.m_ccls_map.length];
+ for (i = 0; i < m_spec.m_ccls_map.length; ++i)
+ yy_cmap[i] = m_spec.m_col_map[m_spec.m_ccls_map[i]];
+ m_outstream.print("\tprivate int yy_cmap[] = unpackFromString(");
+ emit_table_as_string(new int[][] { yy_cmap });
+ m_outstream.println(")[0];");
+ m_outstream.println();
+
+ // CSA: modified yy_rmap to use string packing 9-Aug-1999
+ m_outstream.print("\tprivate int yy_rmap[] = unpackFromString(");
+ emit_table_as_string(new int[][] { m_spec.m_row_map });
+ m_outstream.println(")[0];");
+ m_outstream.println();
+
+ // 6/24/98 Raimondas Lencevicius
+ // modified to use
+ // int[][] unpackFromString(int size1, int size2, String st)
+ size = m_spec.m_dtrans_vector.size();
+ int[][] yy_nxt = new int[size][];
+ for (elem=0; elem<size; elem++) {
+ dtrans = (CDTrans) m_spec.m_dtrans_vector.elementAt(elem);
+ CUtility.ASSERT(dtrans.m_dtrans.length==m_spec.m_dtrans_ncols);
+ yy_nxt[elem] = dtrans.m_dtrans;
+ }
+ m_outstream.print
+ ("\tprivate int yy_nxt[][] = unpackFromString(");
+ emit_table_as_string(yy_nxt);
+ m_outstream.println(");");
+ m_outstream.println();
+ }
+
+ /***************************************************************
+ Function: emit_driver
+ Description: Output an integer table as a string. Written by
+ Raimondas Lencevicius 6/24/98; reorganized by CSA 9-Aug-1999.
+ From his original comments:
+ yy_nxt[][] values are coded into a string
+ by printing integers and representing
+ integer sequences as "value:length" pairs.
+ **************************************************************/
+ private void emit_table_as_string(int[][] ia) {
+ int sequenceLength = 0; // RL - length of the number sequence
+ boolean sequenceStarted = false; // RL - has number sequence started?
+ int previousInt = -20; // RL - Bogus -20 state.
+
+ // RL - Output matrix size
+ m_outstream.print(ia.length);
+ m_outstream.print(",");
+ m_outstream.print(ia.length>0?ia[0].length:0);
+ m_outstream.println(",");
+
+ StringBuffer outstr = new StringBuffer();
+
+ // RL - Output matrix
+ for (int elem = 0; elem < ia.length; ++elem)
+ {
+ for (int i = 0; i < ia[elem].length; ++i)
+ {
+ int writeInt = ia[elem][i];
+ if (writeInt == previousInt) // RL - sequence?
+ {
+ if (sequenceStarted)
+ {
+ sequenceLength++;
+ }
+ else
+ {
+ outstr.append(writeInt);
+ outstr.append(":");
+ sequenceLength = 2;
+ sequenceStarted = true;
+ }
+ }
+ else // RL - no sequence or end sequence
+ {
+ if (sequenceStarted)
+ {
+ outstr.append(sequenceLength);
+ outstr.append(",");
+ sequenceLength = 0;
+ sequenceStarted = false;
+ }
+ else
+ {
+ if (previousInt != -20)
+ {
+ outstr.append(previousInt);
+ outstr.append(",");
+ }
+ }
+ }
+ previousInt = writeInt;
+ // CSA: output in 75 character chunks.
+ if (outstr.length() > 75) {
+ String s = outstr.toString();
+ m_outstream.println("\""+s.substring(0,75)+"\" +");
+ outstr = new StringBuffer(s.substring(75));
+ }
+ }
+ }
+ if (sequenceStarted)
+ {
+ outstr.append(sequenceLength);
+ }
+ else
+ {
+ outstr.append(previousInt);
+ }
+ // CSA: output in 75 character chunks.
+ if (outstr.length() > 75) {
+ String s = outstr.toString();
+ m_outstream.println("\""+s.substring(0,75)+"\" +");
+ outstr = new StringBuffer(s.substring(75));
+ }
+ m_outstream.print("\""+outstr+"\"");
+ }
+
+ /***************************************************************
+ Function: emit_driver
+ Description:
+ **************************************************************/
+ private void emit_driver
+ (
+ )
+ throws java.io.IOException
+ {
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != m_spec);
+ CUtility.ASSERT(null != m_outstream);
+ }
+
+ emit_table();
+
+ if (m_spec.m_integer_type)
+ {
+ m_outstream.print("\tpublic int ");
+ m_outstream.print(new String(m_spec.m_function_name));
+ m_outstream.println(" ()");
+ }
+ else if (m_spec.m_intwrap_type)
+ {
+ m_outstream.print("\tpublic java.lang.Integer ");
+ m_outstream.print(new String(m_spec.m_function_name));
+ m_outstream.println(" ()");
+ }
+ else
+ {
+ m_outstream.print("\tpublic ");
+ m_outstream.print(new String(m_spec.m_type_name));
+ m_outstream.print(" ");
+ m_outstream.print(new String(m_spec.m_function_name));
+ m_outstream.println(" ()");
+ }
+
+ /*m_outstream.println("\t\tthrows java.io.IOException {");*/
+ m_outstream.print("\t\tthrows java.io.IOException");
+ if (null != m_spec.m_yylex_throw_code)
+ {
+ m_outstream.print(", ");
+ m_outstream.print(new String(m_spec.m_yylex_throw_code,0,
+ m_spec.m_yylex_throw_read));
+ m_outstream.println();
+ m_outstream.println("\t\t{");
+ }
+ else
+ {
+ m_outstream.println(" {");
+ }
+
+ m_outstream.println("\t\tint yy_lookahead;");
+ m_outstream.println("\t\tint yy_anchor = YY_NO_ANCHOR;");
+ /*m_outstream.println("\t\tint yy_state "
+ + "= yy_initial_dtrans(yy_lexical_state);");*/
+ m_outstream.println("\t\tint yy_state "
+ + "= yy_state_dtrans[yy_lexical_state];");
+ m_outstream.println("\t\tint yy_next_state = YY_NO_STATE;");
+ /*m_outstream.println("\t\tint yy_prev_stave = YY_NO_STATE;");*/
+ m_outstream.println("\t\tint yy_last_accept_state = YY_NO_STATE;");
+ m_outstream.println("\t\tboolean yy_initial = true;");
+ m_outstream.println("\t\tint yy_this_accept;");
+ m_outstream.println();
+
+ m_outstream.println("\t\tyy_mark_start();");
+ /*m_outstream.println("\t\tyy_this_accept = yy_accept(yy_state);");*/
+ m_outstream.println("\t\tyy_this_accept = yy_acpt[yy_state];");
+ m_outstream.println("\t\tif (YY_NOT_ACCEPT != yy_this_accept) {");
+ m_outstream.println("\t\t\tyy_last_accept_state = yy_state;");
+ m_outstream.println("\t\t\tyy_mark_end();");
+ m_outstream.println("\t\t}");
+
+ if (NOT_EDBG)
+ {
+ m_outstream.println("\t\tjava.lang.System.out.println(\"Begin\");");
+ }
+
+ m_outstream.println("\t\twhile (true) {");
+
+ m_outstream.println("\t\t\tif (yy_initial && yy_at_bol) "+
+ "yy_lookahead = YY_BOL;");
+ m_outstream.println("\t\t\telse yy_lookahead = yy_advance();");
+ m_outstream.println("\t\t\tyy_next_state = YY_F;");
+ /*m_outstream.println("\t\t\t\tyy_next_state = "
+ + "yy_next(yy_state,yy_lookahead);");*/
+ m_outstream.println("\t\t\tyy_next_state = "
+ + "yy_nxt[yy_rmap[yy_state]][yy_cmap[yy_lookahead]];");
+
+ if (NOT_EDBG)
+ {
+ m_outstream.println("java.lang.System.out.println(\"Current state: \""
+ + " + yy_state");
+ m_outstream.println("+ \"\tCurrent input: \"");
+ m_outstream.println(" + ((char) yy_lookahead));");
+ }
+ if (NOT_EDBG)
+ {
+ m_outstream.println("\t\t\tjava.lang.System.out.println(\"State = \""
+ + "+ yy_state);");
+ m_outstream.println("\t\t\tjava.lang.System.out.println(\"Accepting status = \""
+ + "+ yy_this_accept);");
+ m_outstream.println("\t\t\tjava.lang.System.out.println(\"Last accepting state = \""
+ + "+ yy_last_accept_state);");
+ m_outstream.println("\t\t\tjava.lang.System.out.println(\"Next state = \""
+ + "+ yy_next_state);");
+ m_outstream.println("\t\t\tjava.lang.System.out.println(\"Lookahead input = \""
+ + "+ ((char) yy_lookahead));");
+ }
+
+ // handle bare EOF.
+ m_outstream.println("\t\t\tif (YY_EOF == yy_lookahead "
+ + "&& true == yy_initial) {");
+ if (null != m_spec.m_eof_code)
+ {
+ m_outstream.println("\t\t\t\tyy_do_eof();");
+ }
+ if (true == m_spec.m_integer_type)
+ {
+ m_outstream.println("\t\t\t\treturn YYEOF;");
+ }
+ else if (null != m_spec.m_eof_value_code)
+ {
+ m_outstream.print(new String(m_spec.m_eof_value_code,0,
+ m_spec.m_eof_value_read));
+ }
+ else
+ {
+ m_outstream.println("\t\t\t\treturn null;");
+ }
+ m_outstream.println("\t\t\t}");
+
+ m_outstream.println("\t\t\tif (YY_F != yy_next_state) {");
+ m_outstream.println("\t\t\t\tyy_state = yy_next_state;");
+ m_outstream.println("\t\t\t\tyy_initial = false;");
+ /*m_outstream.println("\t\t\t\tyy_this_accept = yy_accept(yy_state);");*/
+ m_outstream.println("\t\t\t\tyy_this_accept = yy_acpt[yy_state];");
+ m_outstream.println("\t\t\t\tif (YY_NOT_ACCEPT != yy_this_accept) {");
+ m_outstream.println("\t\t\t\t\tyy_last_accept_state = yy_state;");
+ m_outstream.println("\t\t\t\t\tyy_mark_end();");
+ m_outstream.println("\t\t\t\t}");
+ /*m_outstream.println("\t\t\t\tyy_prev_state = yy_state;");*/
+ /*m_outstream.println("\t\t\t\tyy_state = yy_next_state;");*/
+ m_outstream.println("\t\t\t}");
+
+ m_outstream.println("\t\t\telse {");
+
+ m_outstream.println("\t\t\t\tif (YY_NO_STATE == yy_last_accept_state) {");
+
+
+ /*m_outstream.println("\t\t\t\t\tyy_error(YY_E_MATCH,false);");
+ m_outstream.println("\t\t\t\t\tyy_initial = true;");
+ m_outstream.println("\t\t\t\t\tyy_state "
+ + "= yy_state_dtrans[yy_lexical_state];");
+ m_outstream.println("\t\t\t\t\tyy_next_state = YY_NO_STATE;");*/
+ /*m_outstream.println("\t\t\t\t\tyy_prev_state = YY_NO_STATE;");*/
+ /*m_outstream.println("\t\t\t\t\tyy_last_accept_state = YY_NO_STATE;");
+ m_outstream.println("\t\t\t\t\tyy_mark_start();");*/
+ /*m_outstream.println("\t\t\t\t\tyy_this_accept = yy_accept(yy_state);");*/
+ /*m_outstream.println("\t\t\t\t\tyy_this_accept = yy_acpt[yy_state];");
+ m_outstream.println("\t\t\t\t\tif (YY_NOT_ACCEPT != yy_this_accept) {");
+ m_outstream.println("\t\t\t\t\t\tyy_last_accept_state = yy_state;");
+ m_outstream.println("\t\t\t\t\t}");*/
+
+ m_outstream.println("\t\t\t\t\tthrow (new Error(\"Lexical Error: Unmatched Input.\"));");
+ m_outstream.println("\t\t\t\t}");
+
+ m_outstream.println("\t\t\t\telse {");
+
+ m_outstream.println("\t\t\t\t\tyy_anchor = yy_acpt[yy_last_accept_state];");
+ /*m_outstream.println("\t\t\t\t\tyy_anchor "
+ + "= yy_accept(yy_last_accept_state);");*/
+ m_outstream.println("\t\t\t\t\tif (0 != (YY_END & yy_anchor)) {");
+ m_outstream.println("\t\t\t\t\t\tyy_move_end();");
+ m_outstream.println("\t\t\t\t\t}");
+ m_outstream.println("\t\t\t\t\tyy_to_mark();");
+
+ m_outstream.println("\t\t\t\t\tswitch (yy_last_accept_state) {");
+
+ emit_actions("\t\t\t\t\t");
+
+ m_outstream.println("\t\t\t\t\tdefault:");
+ m_outstream.println("\t\t\t\t\t\tyy_error(YY_E_INTERNAL,false);");
+ /*m_outstream.println("\t\t\t\t\t\treturn null;");*/
+ m_outstream.println("\t\t\t\t\tcase -1:");
+ m_outstream.println("\t\t\t\t\t}");
+
+ m_outstream.println("\t\t\t\t\tyy_initial = true;");
+ m_outstream.println("\t\t\t\t\tyy_state "
+ + "= yy_state_dtrans[yy_lexical_state];");
+ m_outstream.println("\t\t\t\t\tyy_next_state = YY_NO_STATE;");
+ /*m_outstream.println("\t\t\t\t\tyy_prev_state = YY_NO_STATE;");*/
+ m_outstream.println("\t\t\t\t\tyy_last_accept_state = YY_NO_STATE;");
+
+ m_outstream.println("\t\t\t\t\tyy_mark_start();");
+
+ /*m_outstream.println("\t\t\t\t\tyy_this_accept = yy_accept(yy_state);");*/
+ m_outstream.println("\t\t\t\t\tyy_this_accept = yy_acpt[yy_state];");
+ m_outstream.println("\t\t\t\t\tif (YY_NOT_ACCEPT != yy_this_accept) {");
+ m_outstream.println("\t\t\t\t\t\tyy_last_accept_state = yy_state;");
+ m_outstream.println("\t\t\t\t\t\tyy_mark_end();");
+ m_outstream.println("\t\t\t\t\t}");
+
+ m_outstream.println("\t\t\t\t}");
+ m_outstream.println("\t\t\t}");
+ m_outstream.println("\t\t}");
+ m_outstream.println("\t}");
+
+ /*m_outstream.println("\t\t\t\t");
+ m_outstream.println("\t\t\t");
+ m_outstream.println("\t\t\t");
+ m_outstream.println("\t\t\t");
+ m_outstream.println("\t\t\t");
+ m_outstream.println("\t\t}");*/
+ }
+
+ /***************************************************************
+ Function: emit_actions
+ Description:
+ **************************************************************/
+ private void emit_actions
+ (
+ String tabs
+ )
+ throws java.io.IOException
+ {
+ int elem;
+ int size;
+ int bogus_index;
+ CAccept accept;
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(m_spec.m_accept_vector.size()
+ == m_spec.m_anchor_array.length);
+ }
+
+ bogus_index = -2;
+ size = m_spec.m_accept_vector.size();
+ for (elem = 0; elem < size; ++elem)
+ {
+ accept = (CAccept) m_spec.m_accept_vector.elementAt(elem);
+ if (null != accept)
+ {
+ m_outstream.println(tabs + "case " + elem
+ + ":");
+ m_outstream.print(tabs + "\t");
+ m_outstream.print(new String(accept.m_action,0,
+ accept.m_action_read));
+ m_outstream.println();
+ m_outstream.println(tabs + "case " + bogus_index + ":");
+ m_outstream.println(tabs + "\tbreak;");
+ --bogus_index;
+ }
+ }
+ }
+
+ /***************************************************************
+ Function: emit_footer
+ Description:
+ **************************************************************/
+ private void emit_footer
+ (
+ )
+ throws java.io.IOException
+ {
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != m_spec);
+ CUtility.ASSERT(null != m_outstream);
+ }
+
+ m_outstream.println("}");
+ }
+}
+
+/***************************************************************
+ Class: CBunch
+ **************************************************************/
+class CBunch
+{
+ /***************************************************************
+ Member Variables
+ **************************************************************/
+ Vector m_nfa_set; /* Vector of CNfa states in dfa state. */
+ SparseBitSet m_nfa_bit; /* BitSet representation of CNfa labels. */
+ CAccept m_accept; /* Accepting actions, or null if nonaccepting state. */
+ int m_anchor; /* Anchors on regular expression. */
+ int m_accept_index; /* CNfa index corresponding to accepting actions. */
+
+ /***************************************************************
+ Function: CBunch
+ Description: Constructor.
+ **************************************************************/
+ CBunch
+ (
+ )
+ {
+ m_nfa_set = null;
+ m_nfa_bit = null;
+ m_accept = null;
+ m_anchor = CSpec.NONE;
+ m_accept_index = -1;
+ }
+}
+
+/***************************************************************
+ Class: CMakeNfa
+ **************************************************************/
+class CMakeNfa
+{
+ /***************************************************************
+ Member Variables
+ **************************************************************/
+ private CSpec m_spec;
+ private CLexGen m_lexGen;
+ private CInput m_input;
+
+ /***************************************************************
+ Function: CMakeNfa
+ Description: Constructor.
+ **************************************************************/
+ CMakeNfa
+ (
+ )
+ {
+ reset();
+ }
+
+ /***************************************************************
+ Function: reset
+ Description: Resets CMakeNfa member variables.
+ **************************************************************/
+ private void reset
+ (
+ )
+ {
+ m_input = null;
+ m_lexGen = null;
+ m_spec = null;
+ }
+
+ /***************************************************************
+ Function: set
+ Description: Sets CMakeNfa member variables.
+ **************************************************************/
+ private void set
+ (
+ CLexGen lexGen,
+ CSpec spec,
+ CInput input
+ )
+ {
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != input);
+ CUtility.ASSERT(null != lexGen);
+ CUtility.ASSERT(null != spec);
+ }
+
+ m_input = input;
+ m_lexGen = lexGen;
+ m_spec = spec;
+ }
+
+ /***************************************************************
+ Function: allocate_BOL_EOF
+ Description: Expands character class to include special BOL and
+ EOF characters. Puts numeric index of these characters in
+ input CSpec.
+ **************************************************************/
+ void allocate_BOL_EOF
+ (
+ CSpec spec
+ )
+ {
+ CUtility.ASSERT(CSpec.NUM_PSEUDO==2);
+ spec.BOL = spec.m_dtrans_ncols++;
+ spec.EOF = spec.m_dtrans_ncols++;
+ }
+
+ /***************************************************************
+ Function: thompson
+ Description: High level access function to module.
+ Deposits result in input CSpec.
+ **************************************************************/
+ void thompson
+ (
+ CLexGen lexGen,
+ CSpec spec,
+ CInput input
+ )
+ throws java.io.IOException
+ {
+ int i;
+ CNfa elem;
+ int size;
+
+ /* Set member variables. */
+ reset();
+ set(lexGen,spec,input);
+
+ size = m_spec.m_states.size();
+ m_spec.m_state_rules = new Vector[size];
+ for (i = 0; i < size; ++i)
+ {
+ m_spec.m_state_rules[i] = new Vector();
+ }
+
+ /* Initialize current token variable
+ and create nfa. */
+ /*m_spec.m_current_token = m_lexGen.EOS;
+ m_lexGen.advance();*/
+
+ m_spec.m_nfa_start = machine();
+
+ /* Set labels in created nfa machine. */
+ size = m_spec.m_nfa_states.size();
+ for (i = 0; i < size; ++i)
+ {
+ elem = (CNfa) m_spec.m_nfa_states.elementAt(i);
+ elem.m_label = i;
+ }
+
+ /* Debugging output. */
+ if (CUtility.DO_DEBUG)
+ {
+ m_lexGen.print_nfa();
+ }
+
+ if (m_spec.m_verbose)
+ {
+ System.out.println("NFA comprised of "
+ + (m_spec.m_nfa_states.size() + 1)
+ + " states.");
+ }
+
+ reset();
+ }
+
+ /***************************************************************
+ Function: discardCNfa
+ Description:
+ **************************************************************/
+ private void discardCNfa
+ (
+ CNfa nfa
+ )
+ {
+ m_spec.m_nfa_states.removeElement(nfa);
+ }
+
+ /***************************************************************
+ Function: processStates
+ Description:
+ **************************************************************/
+ private void processStates
+ (
+ SparseBitSet states,
+ CNfa current
+ )
+ {
+ int size;
+ int i;
+
+ size = m_spec.m_states.size();
+ for (i = 0; i < size; ++i)
+ {
+ if (states.get(i))
+ {
+ m_spec.m_state_rules[i].addElement(current);
+ }
+ }
+ }
+
+ /***************************************************************
+ Function: machine
+ Description: Recursive descent regular expression parser.
+ **************************************************************/
+ private CNfa machine
+ (
+ )
+ throws java.io.IOException
+ {
+ CNfa start;
+ CNfa p;
+ SparseBitSet states;
+
+ if (CUtility.DESCENT_DEBUG)
+ {
+ CUtility.enter("machine",m_spec.m_lexeme,m_spec.m_current_token);
+ }
+
+ start = CAlloc.newCNfa(m_spec);
+ p = start;
+
+ states = m_lexGen.getStates();
+
+ /* Begin: Added for states. */
+ m_spec.m_current_token = m_lexGen.EOS;
+ m_lexGen.advance();
+ /* End: Added for states. */
+
+ if (m_lexGen.END_OF_INPUT != m_spec.m_current_token) // CSA fix.
+ {
+ p.m_next = rule();
+
+ processStates(states,p.m_next);
+ }
+
+ while (m_lexGen.END_OF_INPUT != m_spec.m_current_token)
+ {
+ /* Make state changes HERE. */
+ states = m_lexGen.getStates();
+
+ /* Begin: Added for states. */
+ m_lexGen.advance();
+ if (m_lexGen.END_OF_INPUT == m_spec.m_current_token)
+ {
+ break;
+ }
+ /* End: Added for states. */
+
+ p.m_next2 = CAlloc.newCNfa(m_spec);
+ p = p.m_next2;
+ p.m_next = rule();
+
+ processStates(states,p.m_next);
+ }
+
+ // CSA: add pseudo-rules for BOL and EOF
+ SparseBitSet all_states = new SparseBitSet();
+ for (int i = 0; i < m_spec.m_states.size(); ++i)
+ all_states.set(i);
+ p.m_next2 = CAlloc.newCNfa(m_spec);
+ p = p.m_next2;
+ p.m_next = CAlloc.newCNfa(m_spec);
+ p.m_next.m_edge = CNfa.CCL;
+ p.m_next.m_next = CAlloc.newCNfa(m_spec);
+ p.m_next.m_set = new CSet();
+ p.m_next.m_set.add(m_spec.BOL);
+ p.m_next.m_set.add(m_spec.EOF);
+ p.m_next.m_next.m_accept = // do-nothing accept rule
+ new CAccept(new char[0], 0, m_input.m_line_number+1);
+ processStates(all_states,p.m_next);
+ // CSA: done.
+
+ if (CUtility.DESCENT_DEBUG)
+ {
+ CUtility.leave("machine",m_spec.m_lexeme,m_spec.m_current_token);
+ }
+
+ return start;
+ }
+
+ /***************************************************************
+ Function: rule
+ Description: Recursive descent regular expression parser.
+ **************************************************************/
+ private CNfa rule
+ (
+ )
+ throws java.io.IOException
+ {
+ CNfaPair pair;
+ CNfa p;
+ CNfa start = null;
+ CNfa end = null;
+ int anchor = CSpec.NONE;
+
+ if (CUtility.DESCENT_DEBUG)
+ {
+ CUtility.enter("rule",m_spec.m_lexeme,m_spec.m_current_token);
+ }
+
+ pair = CAlloc.newCNfaPair();
+
+ if (m_lexGen.AT_BOL == m_spec.m_current_token)
+ {
+ anchor = anchor | CSpec.START;
+ m_lexGen.advance();
+ expr(pair);
+
+ // CSA: fixed beginning-of-line operator. 8-aug-1999
+ start = CAlloc.newCNfa(m_spec);
+ start.m_edge = m_spec.BOL;
+ start.m_next = pair.m_start;
+ end = pair.m_end;
+ }
+ else
+ {
+ expr(pair);
+ start = pair.m_start;
+ end = pair.m_end;
+ }
+
+ if (m_lexGen.AT_EOL == m_spec.m_current_token)
+ {
+ m_lexGen.advance();
+ // CSA: fixed end-of-line operator. 8-aug-1999
+ CNfaPair nlpair = CAlloc.newNLPair(m_spec);
+ end.m_next = CAlloc.newCNfa(m_spec);
+ end.m_next.m_next = nlpair.m_start;
+ end.m_next.m_next2 = CAlloc.newCNfa(m_spec);
+ end.m_next.m_next2.m_edge = m_spec.EOF;
+ end.m_next.m_next2.m_next = nlpair.m_end;
+ end = nlpair.m_end;
+ anchor = anchor | CSpec.END;
+ }
+
+ /* Check for null rules. Charles Fischer found this bug. [CSA] */
+ if (end==null)
+ CError.parse_error(CError.E_ZERO, m_input.m_line_number);
+
+ /* Handle end of regular expression. See page 103. */
+ end.m_accept = m_lexGen.packAccept();
+ end.m_anchor = anchor;
+
+ /* Begin: Removed for states. */
+ /*m_lexGen.advance();*/
+ /* End: Removed for states. */
+
+ if (CUtility.DESCENT_DEBUG)
+ {
+ CUtility.leave("rule",m_spec.m_lexeme,m_spec.m_current_token);
+ }
+
+ return start;
+ }
+
+ /***************************************************************
+ Function: expr
+ Description: Recursive descent regular expression parser.
+ **************************************************************/
+ private void expr
+ (
+ CNfaPair pair
+ )
+ throws java.io.IOException
+ {
+ CNfaPair e2_pair;
+ CNfa p;
+
+ if (CUtility.DESCENT_DEBUG)
+ {
+ CUtility.enter("expr",m_spec.m_lexeme,m_spec.m_current_token);
+ }
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != pair);
+ }
+
+ e2_pair = CAlloc.newCNfaPair();
+
+ cat_expr(pair);
+
+ while (m_lexGen.OR == m_spec.m_current_token)
+ {
+ m_lexGen.advance();
+ cat_expr(e2_pair);
+
+ p = CAlloc.newCNfa(m_spec);
+ p.m_next2 = e2_pair.m_start;
+ p.m_next = pair.m_start;
+ pair.m_start = p;
+
+ p = CAlloc.newCNfa(m_spec);
+ pair.m_end.m_next = p;
+ e2_pair.m_end.m_next = p;
+ pair.m_end = p;
+ }
+
+ if (CUtility.DESCENT_DEBUG)
+ {
+ CUtility.leave("expr",m_spec.m_lexeme,m_spec.m_current_token);
+ }
+ }
+
+ /***************************************************************
+ Function: cat_expr
+ Description: Recursive descent regular expression parser.
+ **************************************************************/
+ private void cat_expr
+ (
+ CNfaPair pair
+ )
+ throws java.io.IOException
+ {
+ CNfaPair e2_pair;
+
+ if (CUtility.DESCENT_DEBUG)
+ {
+ CUtility.enter("cat_expr",m_spec.m_lexeme,m_spec.m_current_token);
+ }
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != pair);
+ }
+
+ e2_pair = CAlloc.newCNfaPair();
+
+ if (first_in_cat(m_spec.m_current_token))
+ {
+ factor(pair);
+ }
+
+ while (first_in_cat(m_spec.m_current_token))
+ {
+ factor(e2_pair);
+
+ /* Destroy */
+ pair.m_end.mimic(e2_pair.m_start);
+ discardCNfa(e2_pair.m_start);
+
+ pair.m_end = e2_pair.m_end;
+ }
+
+ if (CUtility.DESCENT_DEBUG)
+ {
+ CUtility.leave("cat_expr",m_spec.m_lexeme,m_spec.m_current_token);
+ }
+ }
+
+ /***************************************************************
+ Function: first_in_cat
+ Description: Recursive descent regular expression parser.
+ **************************************************************/
+ private boolean first_in_cat
+ (
+ int token
+ )
+ {
+ switch (token)
+ {
+ case CLexGen.CLOSE_PAREN:
+ case CLexGen.AT_EOL:
+ case CLexGen.OR:
+ case CLexGen.EOS:
+ return false;
+
+ case CLexGen.CLOSURE:
+ case CLexGen.PLUS_CLOSE:
+ case CLexGen.OPTIONAL:
+ CError.parse_error(CError.E_CLOSE,m_input.m_line_number);
+ return false;
+
+ case CLexGen.CCL_END:
+ CError.parse_error(CError.E_BRACKET,m_input.m_line_number);
+ return false;
+
+ case CLexGen.AT_BOL:
+ CError.parse_error(CError.E_BOL,m_input.m_line_number);
+ return false;
+
+ default:
+ break;
+ }
+
+ return true;
+ }
+
+ /***************************************************************
+ Function: factor
+ Description: Recursive descent regular expression parser.
+ **************************************************************/
+ private void factor
+ (
+ CNfaPair pair
+ )
+ throws java.io.IOException
+ {
+ CNfa start = null;
+ CNfa end = null;
+
+ if (CUtility.DESCENT_DEBUG)
+ {
+ CUtility.enter("factor",m_spec.m_lexeme,m_spec.m_current_token);
+ }
+
+ term(pair);
+
+ if (m_lexGen.CLOSURE == m_spec.m_current_token
+ || m_lexGen.PLUS_CLOSE == m_spec.m_current_token
+ || m_lexGen.OPTIONAL == m_spec.m_current_token)
+ {
+ start = CAlloc.newCNfa(m_spec);
+ end = CAlloc.newCNfa(m_spec);
+
+ start.m_next = pair.m_start;
+ pair.m_end.m_next = end;
+
+ if (m_lexGen.CLOSURE == m_spec.m_current_token
+ || m_lexGen.OPTIONAL == m_spec.m_current_token)
+ {
+ start.m_next2 = end;
+ }
+
+ if (m_lexGen.CLOSURE == m_spec.m_current_token
+ || m_lexGen.PLUS_CLOSE == m_spec.m_current_token)
+ {
+ pair.m_end.m_next2 = pair.m_start;
+ }
+
+ pair.m_start = start;
+ pair.m_end = end;
+ m_lexGen.advance();
+ }
+
+ if (CUtility.DESCENT_DEBUG)
+ {
+ CUtility.leave("factor",m_spec.m_lexeme,m_spec.m_current_token);
+ }
+ }
+
+ /***************************************************************
+ Function: term
+ Description: Recursive descent regular expression parser.
+ **************************************************************/
+ private void term
+ (
+ CNfaPair pair
+ )
+ throws java.io.IOException
+ {
+ CNfa start;
+ boolean isAlphaL;
+ int c;
+
+ if (CUtility.DESCENT_DEBUG)
+ {
+ CUtility.enter("term",m_spec.m_lexeme,m_spec.m_current_token);
+ }
+
+ if (m_lexGen.OPEN_PAREN == m_spec.m_current_token)
+ {
+ m_lexGen.advance();
+ expr(pair);
+
+ if (m_lexGen.CLOSE_PAREN == m_spec.m_current_token)
+ {
+ m_lexGen.advance();
+ }
+ else
+ {
+ CError.parse_error(CError.E_SYNTAX,m_input.m_line_number);
+ }
+ }
+ else
+ {
+ start = CAlloc.newCNfa(m_spec);
+ pair.m_start = start;
+
+ start.m_next = CAlloc.newCNfa(m_spec);
+ pair.m_end = start.m_next;
+
+ if (m_lexGen.L == m_spec.m_current_token &&
+ Character.isLetter(m_spec.m_lexeme))
+ {
+ isAlphaL = true;
+ }
+ else
+ {
+ isAlphaL = false;
+ }
+ if (false == (m_lexGen.ANY == m_spec.m_current_token
+ || m_lexGen.CCL_START == m_spec.m_current_token
+ || (m_spec.m_ignorecase && isAlphaL)))
+ {
+ start.m_edge = m_spec.m_lexeme;
+ m_lexGen.advance();
+ }
+ else
+ {
+ start.m_edge = CNfa.CCL;
+
+ start.m_set = new CSet();
+
+ /* Match case-insensitive letters using character class. */
+ if (m_spec.m_ignorecase && isAlphaL)
+ {
+ start.m_set.addncase(m_spec.m_lexeme);
+ }
+ /* Match dot (.) using character class. */
+ else if (m_lexGen.ANY == m_spec.m_current_token)
+ {
+ start.m_set.add('\n');
+ start.m_set.add('\r');
+ // CSA: exclude BOL and EOF from character classes
+ start.m_set.add(m_spec.BOL);
+ start.m_set.add(m_spec.EOF);
+ start.m_set.complement();
+ }
+ else
+ {
+ m_lexGen.advance();
+ if (m_lexGen.AT_BOL == m_spec.m_current_token)
+ {
+ m_lexGen.advance();
+
+ // CSA: exclude BOL and EOF from character classes
+ start.m_set.add(m_spec.BOL);
+ start.m_set.add(m_spec.EOF);
+ start.m_set.complement();
+ }
+ if (false == (m_lexGen.CCL_END == m_spec.m_current_token))
+ {
+ dodash(start.m_set);
+ }
+ /*else
+ {
+ for (c = 0; c <= ' '; ++c)
+ {
+ start.m_set.add((byte) c);
+ }
+ }*/
+ }
+ m_lexGen.advance();
+ }
+ }
+
+ if (CUtility.DESCENT_DEBUG)
+ {
+ CUtility.leave("term",m_spec.m_lexeme,m_spec.m_current_token);
+ }
+ }
+
+ /***************************************************************
+ Function: dodash
+ Description: Recursive descent regular expression parser.
+ **************************************************************/
+ private void dodash
+ (
+ CSet set
+ )
+ throws java.io.IOException
+ {
+ int first = -1;
+
+ if (CUtility.DESCENT_DEBUG)
+ {
+ CUtility.enter("dodash",m_spec.m_lexeme,m_spec.m_current_token);
+ }
+
+ while (m_lexGen.EOS != m_spec.m_current_token
+ && m_lexGen.CCL_END != m_spec.m_current_token)
+ {
+ // DASH loses its special meaning if it is first in class.
+ if (m_lexGen.DASH == m_spec.m_current_token && -1 != first)
+ {
+ m_lexGen.advance();
+ // DASH loses its special meaning if it is last in class.
+ if (m_spec.m_current_token == m_lexGen.CCL_END)
+ {
+ // 'first' already in set.
+ set.add('-');
+ break;
+ }
+ for ( ; first <= m_spec.m_lexeme; ++first)
+ {
+ if (m_spec.m_ignorecase)
+ set.addncase((char)first);
+ else
+ set.add(first);
+ }
+ }
+ else
+ {
+ first = m_spec.m_lexeme;
+ if (m_spec.m_ignorecase)
+ set.addncase(m_spec.m_lexeme);
+ else
+ set.add(m_spec.m_lexeme);
+ }
+
+ m_lexGen.advance();
+ }
+
+ if (CUtility.DESCENT_DEBUG)
+ {
+ CUtility.leave("dodash",m_spec.m_lexeme,m_spec.m_current_token);
+ }
+ }
+}
+
+/**
+ * Extract character classes from NFA and simplify.
+ * @author C. Scott Ananian 25-Jul-1999
+ */
+class CSimplifyNfa
+{
+ private int[] ccls; // character class mapping.
+ private int original_charset_size; // original charset size
+ private int mapped_charset_size; // reduced charset size
+
+ void simplify(CSpec m_spec) {
+ computeClasses(m_spec); // initialize fields.
+
+ // now rewrite the NFA using our character class mapping.
+ for (Enumeration e=m_spec.m_nfa_states.elements(); e.hasMoreElements(); ) {
+ CNfa nfa = (CNfa) e.nextElement();
+ if (nfa.m_edge==CNfa.EMPTY || nfa.m_edge==CNfa.EPSILON)
+ continue; // no change.
+ if (nfa.m_edge==CNfa.CCL) {
+ CSet ncset = new CSet();
+ ncset.map(nfa.m_set, ccls); // map it.
+ nfa.m_set = ncset;
+ } else { // single character
+ nfa.m_edge = ccls[nfa.m_edge]; // map it.
+ }
+ }
+
+ // now update m_spec with the mapping.
+ m_spec.m_ccls_map = ccls;
+ m_spec.m_dtrans_ncols = mapped_charset_size;
+ }
+ /** Compute minimum set of character classes needed to disambiguate
+ * edges. We optimistically assume that every character belongs to
+ * a single character class, and then incrementally split classes
+ * as we see edges that require discrimination between characters in
+ * the class. [CSA, 25-Jul-1999] */
+ private void computeClasses(CSpec m_spec) {
+ this.original_charset_size = m_spec.m_dtrans_ncols;
+ this.ccls = new int[original_charset_size]; // initially all zero.
+
+ int nextcls = 1;
+ SparseBitSet clsA = new SparseBitSet(), clsB = new SparseBitSet();
+ Hashtable h = new Hashtable();
+
+ System.out.print("Working on character classes.");
+ for (Enumeration e=m_spec.m_nfa_states.elements(); e.hasMoreElements(); ) {
+ CNfa nfa = (CNfa) e.nextElement();
+ if (nfa.m_edge==CNfa.EMPTY || nfa.m_edge==CNfa.EPSILON)
+ continue; // no discriminatory information.
+ clsA.clearAll(); clsB.clearAll();
+ for (int i=0; i<ccls.length; i++)
+ if (nfa.m_edge==i || // edge labeled with a character
+ nfa.m_edge==CNfa.CCL && nfa.m_set.contains(i)) // set of characters
+ clsA.set(ccls[i]);
+ else
+ clsB.set(ccls[i]);
+ // now figure out which character classes we need to split.
+ clsA.and(clsB); // split the classes which show up on both sides of edge
+ System.out.print(clsA.size()==0?".":":");
+ if (clsA.size()==0) continue; // nothing to do.
+ // and split them.
+ h.clear(); // h will map old to new class name
+ for (int i=0; i<ccls.length; i++)
+ if (clsA.get(ccls[i])) // a split class
+ if (nfa.m_edge==i ||
+ nfa.m_edge==CNfa.CCL && nfa.m_set.contains(i)) { // on A side
+ Integer split = new Integer(ccls[i]);
+ if (!h.containsKey(split))
+ h.put(split, new Integer(nextcls++)); // make new class
+ ccls[i] = ((Integer)h.get(split)).intValue();
+ }
+ }
+ System.out.println();
+ System.out.println("NFA has "+nextcls+" distinct character classes.");
+
+ this.mapped_charset_size = nextcls;
+ }
+}
+
+/***************************************************************
+ Class: CMinimize
+ **************************************************************/
+class CMinimize
+{
+ /***************************************************************
+ Member Variables
+ **************************************************************/
+ CSpec m_spec;
+ Vector m_group;
+ int m_ingroup[];
+
+ /***************************************************************
+ Function: CMinimize
+ Description: Constructor.
+ **************************************************************/
+ CMinimize
+ (
+ )
+ {
+ reset();
+ }
+
+ /***************************************************************
+ Function: reset
+ Description: Resets member variables.
+ **************************************************************/
+ private void reset
+ (
+ )
+ {
+ m_spec = null;
+ m_group = null;
+ m_ingroup = null;
+ }
+
+ /***************************************************************
+ Function: set
+ Description: Sets member variables.
+ **************************************************************/
+ private void set
+ (
+ CSpec spec
+ )
+ {
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != spec);
+ }
+
+ m_spec = spec;
+ m_group = null;
+ m_ingroup = null;
+ }
+
+ /***************************************************************
+ Function: min_dfa
+ Description: High-level access function to module.
+ **************************************************************/
+ void min_dfa
+ (
+ CSpec spec
+ )
+ {
+ set(spec);
+
+ /* Remove redundant states. */
+ minimize();
+
+ /* Column and row compression.
+ Save accept states in auxilary vector. */
+ reduce();
+
+ reset();
+ }
+
+ /***************************************************************
+ Function: col_copy
+ Description: Copies source column into destination column.
+ **************************************************************/
+ private void col_copy
+ (
+ int dest,
+ int src
+ )
+ {
+ int n;
+ int i;
+ CDTrans dtrans;
+
+ n = m_spec.m_dtrans_vector.size();
+ for (i = 0; i < n; ++i)
+ {
+ dtrans = (CDTrans) m_spec.m_dtrans_vector.elementAt(i);
+ dtrans.m_dtrans[dest] = dtrans.m_dtrans[src];
+ }
+ }
+
+ /***************************************************************
+ Function: trunc_col
+ Description: Truncates each column to the 'correct' length.
+ **************************************************************/
+ private void trunc_col
+ (
+ )
+ {
+ int n;
+ int i;
+ CDTrans dtrans;
+
+ n = m_spec.m_dtrans_vector.size();
+ for (i = 0; i < n; ++i)
+ {
+ int[] ndtrans = new int[m_spec.m_dtrans_ncols];
+ dtrans = (CDTrans) m_spec.m_dtrans_vector.elementAt(i);
+ System.arraycopy(dtrans.m_dtrans, 0, ndtrans, 0, ndtrans.length);
+ dtrans.m_dtrans = ndtrans;
+ }
+ }
+ /***************************************************************
+ Function: row_copy
+ Description: Copies source row into destination row.
+ **************************************************************/
+ private void row_copy
+ (
+ int dest,
+ int src
+ )
+ {
+ CDTrans dtrans;
+
+ dtrans = (CDTrans) m_spec.m_dtrans_vector.elementAt(src);
+ m_spec.m_dtrans_vector.setElementAt(dtrans,dest);
+ }
+
+ /***************************************************************
+ Function: col_equiv
+ Description:
+ **************************************************************/
+ private boolean col_equiv
+ (
+ int col1,
+ int col2
+ )
+ {
+ int n;
+ int i;
+ CDTrans dtrans;
+
+ n = m_spec.m_dtrans_vector.size();
+ for (i = 0; i < n; ++i)
+ {
+ dtrans = (CDTrans) m_spec.m_dtrans_vector.elementAt(i);
+ if (dtrans.m_dtrans[col1] != dtrans.m_dtrans[col2])
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /***************************************************************
+ Function: row_equiv
+ Description:
+ **************************************************************/
+ private boolean row_equiv
+ (
+ int row1,
+ int row2
+ )
+ {
+ int i;
+ CDTrans dtrans1;
+ CDTrans dtrans2;
+
+ dtrans1 = (CDTrans) m_spec.m_dtrans_vector.elementAt(row1);
+ dtrans2 = (CDTrans) m_spec.m_dtrans_vector.elementAt(row2);
+
+ for (i = 0; i < m_spec.m_dtrans_ncols; ++i)
+ {
+ if (dtrans1.m_dtrans[i] != dtrans2.m_dtrans[i])
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /***************************************************************
+ Function: reduce
+ Description:
+ **************************************************************/
+ private void reduce
+ (
+ )
+ {
+ int i;
+ int j;
+ int k;
+ int nrows;
+ int reduced_ncols;
+ int reduced_nrows;
+ SparseBitSet set;
+ CDTrans dtrans;
+ int size;
+
+ set = new SparseBitSet();
+
+ /* Save accept nodes and anchor entries. */
+ size = m_spec.m_dtrans_vector.size();
+ m_spec.m_anchor_array = new int[size];
+ m_spec.m_accept_vector = new Vector();
+ for (i = 0; i < size; ++i)
+ {
+ dtrans = (CDTrans) m_spec.m_dtrans_vector.elementAt(i);
+ m_spec.m_accept_vector.addElement(dtrans.m_accept);
+ m_spec.m_anchor_array[i] = dtrans.m_anchor;
+ dtrans.m_accept = null;
+ }
+
+ /* Allocate column map. */
+ m_spec.m_col_map = new int[m_spec.m_dtrans_ncols];
+ for (i = 0; i < m_spec.m_dtrans_ncols; ++i)
+ {
+ m_spec.m_col_map[i] = -1;
+ }
+
+ /* Process columns for reduction. */
+ for (reduced_ncols = 0; ; ++reduced_ncols)
+ {
+ if (CUtility.DEBUG)
+ {
+ for (i = 0; i < reduced_ncols; ++i)
+ {
+ CUtility.ASSERT(-1 != m_spec.m_col_map[i]);
+ }
+ }
+
+ for (i = reduced_ncols; i < m_spec.m_dtrans_ncols; ++i)
+ {
+ if (-1 == m_spec.m_col_map[i])
+ {
+ break;
+ }
+ }
+
+ if (i >= m_spec.m_dtrans_ncols)
+ {
+ break;
+ }
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(false == set.get(i));
+ CUtility.ASSERT(-1 == m_spec.m_col_map[i]);
+ }
+
+ set.set(i);
+
+ m_spec.m_col_map[i] = reduced_ncols;
+
+ /* UNDONE: Optimize by doing all comparisons in one batch. */
+ for (j = i + 1; j < m_spec.m_dtrans_ncols; ++j)
+ {
+ if (-1 == m_spec.m_col_map[j] && true == col_equiv(i,j))
+ {
+ m_spec.m_col_map[j] = reduced_ncols;
+ }
+ }
+ }
+
+ /* Reduce columns. */
+ k = 0;
+ for (i = 0; i < m_spec.m_dtrans_ncols; ++i)
+ {
+ if (set.get(i))
+ {
+ ++k;
+
+ set.clear(i);
+
+ j = m_spec.m_col_map[i];
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(j <= i);
+ }
+
+ if (j == i)
+ {
+ continue;
+ }
+
+ col_copy(j,i);
+ }
+ }
+ m_spec.m_dtrans_ncols = reduced_ncols;
+ /* truncate m_dtrans at proper length (freeing extra) */
+ trunc_col();
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(k == reduced_ncols);
+ }
+
+ /* Allocate row map. */
+ nrows = m_spec.m_dtrans_vector.size();
+ m_spec.m_row_map = new int[nrows];
+ for (i = 0; i < nrows; ++i)
+ {
+ m_spec.m_row_map[i] = -1;
+ }
+
+ /* Process rows to reduce. */
+ for (reduced_nrows = 0; ; ++reduced_nrows)
+ {
+ if (CUtility.DEBUG)
+ {
+ for (i = 0; i < reduced_nrows; ++i)
+ {
+ CUtility.ASSERT(-1 != m_spec.m_row_map[i]);
+ }
+ }
+
+ for (i = reduced_nrows; i < nrows; ++i)
+ {
+ if (-1 == m_spec.m_row_map[i])
+ {
+ break;
+ }
+ }
+
+ if (i >= nrows)
+ {
+ break;
+ }
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(false == set.get(i));
+ CUtility.ASSERT(-1 == m_spec.m_row_map[i]);
+ }
+
+ set.set(i);
+
+ m_spec.m_row_map[i] = reduced_nrows;
+
+ /* UNDONE: Optimize by doing all comparisons in one batch. */
+ for (j = i + 1; j < nrows; ++j)
+ {
+ if (-1 == m_spec.m_row_map[j] && true == row_equiv(i,j))
+ {
+ m_spec.m_row_map[j] = reduced_nrows;
+ }
+ }
+ }
+
+ /* Reduce rows. */
+ k = 0;
+ for (i = 0; i < nrows; ++i)
+ {
+ if (set.get(i))
+ {
+ ++k;
+
+ set.clear(i);
+
+ j = m_spec.m_row_map[i];
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(j <= i);
+ }
+
+ if (j == i)
+ {
+ continue;
+ }
+
+ row_copy(j,i);
+ }
+ }
+ m_spec.m_dtrans_vector.setSize(reduced_nrows);
+
+ if (CUtility.DEBUG)
+ {
+ /*System.out.println("k = " + k + "\nreduced_nrows = " + reduced_nrows + "");*/
+ CUtility.ASSERT(k == reduced_nrows);
+ }
+ }
+
+ /***************************************************************
+ Function: fix_dtrans
+ Description: Updates CDTrans table after minimization
+ using groups, removing redundant transition table states.
+ **************************************************************/
+ private void fix_dtrans
+ (
+ )
+ {
+ Vector new_vector;
+ int i;
+ int size;
+ Vector dtrans_group;
+ CDTrans first;
+ int c;
+
+ new_vector = new Vector();
+
+ size = m_spec.m_state_dtrans.length;
+ for (i = 0; i < size; ++i)
+ {
+ if (CDTrans.F != m_spec.m_state_dtrans[i])
+ {
+ m_spec.m_state_dtrans[i] = m_ingroup[m_spec.m_state_dtrans[i]];
+ }
+ }
+
+ size = m_group.size();
+ for (i = 0; i < size; ++i)
+ {
+ dtrans_group = (Vector) m_group.elementAt(i);
+ first = (CDTrans) dtrans_group.elementAt(0);
+ new_vector.addElement(first);
+
+ for (c = 0; c < m_spec.m_dtrans_ncols; ++c)
+ {
+ if (CDTrans.F != first.m_dtrans[c])
+ {
+ first.m_dtrans[c] = m_ingroup[first.m_dtrans[c]];
+ }
+ }
+ }
+
+ m_group = null;
+ m_spec.m_dtrans_vector = new_vector;
+ }
+
+ /***************************************************************
+ Function: minimize
+ Description: Removes redundant transition table states.
+ **************************************************************/
+ private void minimize
+ (
+ )
+ {
+ Vector dtrans_group;
+ Vector new_group;
+ int i;
+ int j;
+ int old_group_count;
+ int group_count;
+ CDTrans next;
+ CDTrans first;
+ int goto_first;
+ int goto_next;
+ int c;
+ int group_size;
+ boolean added;
+
+ init_groups();
+
+ group_count = m_group.size();
+ old_group_count = group_count - 1;
+
+ while (old_group_count != group_count)
+ {
+ old_group_count = group_count;
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(m_group.size() == group_count);
+ }
+
+ for (i = 0; i < group_count; ++i)
+ {
+ dtrans_group = (Vector) m_group.elementAt(i);
+
+ group_size = dtrans_group.size();
+ if (group_size <= 1)
+ {
+ continue;
+ }
+
+ new_group = new Vector();
+ added = false;
+
+ first = (CDTrans) dtrans_group.elementAt(0);
+ for (j = 1; j < group_size; ++j)
+ {
+ next = (CDTrans) dtrans_group.elementAt(j);
+
+ for (c = 0; c < m_spec.m_dtrans_ncols; ++c)
+ {
+ goto_first = first.m_dtrans[c];
+ goto_next = next.m_dtrans[c];
+
+ if (goto_first != goto_next
+ && (goto_first == CDTrans.F
+ || goto_next == CDTrans.F
+ || m_ingroup[goto_next] != m_ingroup[goto_first]))
+ {
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(dtrans_group.elementAt(j) == next);
+ }
+
+ dtrans_group.removeElementAt(j);
+ --j;
+ --group_size;
+ new_group.addElement(next);
+ if (false == added)
+ {
+ added = true;
+ ++group_count;
+ m_group.addElement(new_group);
+ }
+ m_ingroup[next.m_label] = m_group.size() - 1;
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(m_group.contains(new_group)
+ == true);
+ CUtility.ASSERT(m_group.contains(dtrans_group)
+ == true);
+ CUtility.ASSERT(dtrans_group.contains(first)
+ == true);
+ CUtility.ASSERT(dtrans_group.contains(next)
+ == false);
+ CUtility.ASSERT(new_group.contains(first)
+ == false);
+ CUtility.ASSERT(new_group.contains(next)
+ == true);
+ CUtility.ASSERT(dtrans_group.size() == group_size);
+ CUtility.ASSERT(i == m_ingroup[first.m_label]);
+ CUtility.ASSERT((m_group.size() - 1)
+ == m_ingroup[next.m_label]);
+ }
+
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ System.out.println(m_group.size() + " states after removal of redundant states.");
+
+ if (m_spec.m_verbose
+ && true == CUtility.OLD_DUMP_DEBUG)
+ {
+ System.out.println();
+ System.out.println("States grouped as follows after minimization");
+ pgroups();
+ }
+
+ fix_dtrans();
+ }
+
+ /***************************************************************
+ Function: init_groups
+ Description:
+ **************************************************************/
+ private void init_groups
+ (
+ )
+ {
+ int i;
+ int j;
+ int group_count;
+ int size;
+ CAccept accept;
+ CDTrans dtrans;
+ Vector dtrans_group;
+ CDTrans first;
+ boolean group_found;
+
+ m_group = new Vector();
+ group_count = 0;
+
+ size = m_spec.m_dtrans_vector.size();
+ m_ingroup = new int[size];
+
+ for (i = 0; i < size; ++i)
+ {
+ group_found = false;
+ dtrans = (CDTrans) m_spec.m_dtrans_vector.elementAt(i);
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(i == dtrans.m_label);
+ CUtility.ASSERT(false == group_found);
+ CUtility.ASSERT(group_count == m_group.size());
+ }
+
+ for (j = 0; j < group_count; ++j)
+ {
+ dtrans_group = (Vector) m_group.elementAt(j);
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(false == group_found);
+ CUtility.ASSERT(0 < dtrans_group.size());
+ }
+
+ first = (CDTrans) dtrans_group.elementAt(0);
+
+ if (CUtility.SLOW_DEBUG)
+ {
+ CDTrans check;
+ int k;
+ int s;
+
+ s = dtrans_group.size();
+ CUtility.ASSERT(0 < s);
+
+ for (k = 1; k < s; ++k)
+ {
+ check = (CDTrans) dtrans_group.elementAt(k);
+ CUtility.ASSERT(check.m_accept == first.m_accept);
+ }
+ }
+
+ if (first.m_accept == dtrans.m_accept)
+ {
+ dtrans_group.addElement(dtrans);
+ m_ingroup[i] = j;
+ group_found = true;
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(j == m_ingroup[dtrans.m_label]);
+ }
+
+ break;
+ }
+ }
+
+ if (false == group_found)
+ {
+ dtrans_group = new Vector();
+ dtrans_group.addElement(dtrans);
+ m_ingroup[i] = m_group.size();
+ m_group.addElement(dtrans_group);
+ ++group_count;
+ }
+ }
+
+ if (m_spec.m_verbose
+ && true == CUtility.OLD_DUMP_DEBUG)
+ {
+ System.out.println("Initial grouping:");
+ pgroups();
+ System.out.println();
+ }
+ }
+
+ /***************************************************************
+ Function: pset
+ **************************************************************/
+ private void pset
+ (
+ Vector dtrans_group
+ )
+ {
+ int i;
+ int size;
+ CDTrans dtrans;
+
+ size = dtrans_group.size();
+ for (i = 0; i < size; ++i)
+ {
+ dtrans = (CDTrans) dtrans_group.elementAt(i);
+ System.out.print(dtrans.m_label + " ");
+ }
+ }
+
+ /***************************************************************
+ Function: pgroups
+ **************************************************************/
+ private void pgroups
+ (
+ )
+ {
+ int i;
+ int dtrans_size;
+ int group_size;
+
+ group_size = m_group.size();
+ for (i = 0; i < group_size; ++i)
+ {
+ System.out.print("\tGroup " + i + " {");
+ pset((Vector) m_group.elementAt(i));
+ System.out.println("}");
+ System.out.println();
+ }
+
+ System.out.println();
+ dtrans_size = m_spec.m_dtrans_vector.size();
+ for (i = 0; i < dtrans_size; ++i)
+ {
+ System.out.println("\tstate " + i
+ + " is in group "
+ + m_ingroup[i]);
+ }
+ }
+}
+
+/***************************************************************
+ Class: CNfa2Dfa
+ **************************************************************/
+class CNfa2Dfa
+{
+ /***************************************************************
+ Member Variables
+ **************************************************************/
+ private CSpec m_spec;
+ private int m_unmarked_dfa;
+ private CLexGen m_lexGen;
+
+ /***************************************************************
+ Constants
+ **************************************************************/
+ private static final int NOT_IN_DSTATES = -1;
+
+ /***************************************************************
+ Function: CNfa2Dfa
+ **************************************************************/
+ CNfa2Dfa
+ (
+ )
+ {
+ reset();
+ }
+
+ /***************************************************************
+ Function: set
+ Description:
+ **************************************************************/
+ private void set
+ (
+ CLexGen lexGen,
+ CSpec spec
+ )
+ {
+ m_lexGen = lexGen;
+ m_spec = spec;
+ m_unmarked_dfa = 0;
+ }
+
+ /***************************************************************
+ Function: reset
+ Description:
+ **************************************************************/
+ private void reset
+ (
+ )
+ {
+ m_lexGen = null;
+ m_spec = null;
+ m_unmarked_dfa = 0;
+ }
+
+ /***************************************************************
+ Function: make_dfa
+ Description: High-level access function to module.
+ **************************************************************/
+ void make_dfa
+ (
+ CLexGen lexGen,
+ CSpec spec
+ )
+ {
+ int i;
+
+ reset();
+ set(lexGen,spec);
+
+ make_dtrans();
+ free_nfa_states();
+
+ if (m_spec.m_verbose && true == CUtility.OLD_DUMP_DEBUG)
+ {
+ System.out.println(m_spec.m_dfa_states.size()
+ + " DFA states in original machine.");
+ }
+
+ free_dfa_states();
+ }
+
+ /***************************************************************
+ Function: make_dtrans
+ Description: Creates uncompressed CDTrans transition table.
+ **************************************************************/
+ private void make_dtrans
+ (
+ )
+ /* throws java.lang.CloneNotSupportedException*/
+ {
+ CDfa next;
+ CDfa dfa;
+ CBunch bunch;
+ int i;
+ int nextstate;
+ int size;
+ CDTrans dtrans;
+ CNfa nfa;
+ int istate;
+ int nstates;
+
+ System.out.print("Working on DFA states.");
+
+ /* Reference passing type and initializations. */
+ bunch = new CBunch();
+ m_unmarked_dfa = 0;
+
+ /* Allocate mapping array. */
+ nstates = m_spec.m_state_rules.length;
+ m_spec.m_state_dtrans = new int[nstates];
+
+ for (istate = 0; nstates > istate; ++istate)
+ {
+ /* CSA bugfix: if we skip all zero size rules, then
+ an specification with no rules produces an illegal
+ lexer (0 states) instead of a lexer that rejects
+ everything (1 nonaccepting state). [27-Jul-1999]
+ if (0 == m_spec.m_state_rules[istate].size())
+ {
+ m_spec.m_state_dtrans[istate] = CDTrans.F;
+ continue;
+ }
+ */
+
+ /* Create start state and initialize fields. */
+ bunch.m_nfa_set = (Vector) m_spec.m_state_rules[istate].clone();
+ sortStates(bunch.m_nfa_set);
+
+ bunch.m_nfa_bit = new SparseBitSet();
+
+ /* Initialize bit set. */
+ size = bunch.m_nfa_set.size();
+ for (i = 0; size > i; ++i)
+ {
+ nfa = (CNfa) bunch.m_nfa_set.elementAt(i);
+ bunch.m_nfa_bit.set(nfa.m_label);
+ }
+
+ bunch.m_accept = null;
+ bunch.m_anchor = CSpec.NONE;
+ bunch.m_accept_index = CUtility.INT_MAX;
+
+ e_closure(bunch);
+ add_to_dstates(bunch);
+
+ m_spec.m_state_dtrans[istate] = m_spec.m_dtrans_vector.size();
+
+ /* Main loop of CDTrans creation. */
+ while (null != (dfa = get_unmarked()))
+ {
+ System.out.print(".");
+ System.out.flush();
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(false == dfa.m_mark);
+ }
+
+ /* Get first unmarked node, then mark it. */
+ dfa.m_mark = true;
+
+ /* Allocate new CDTrans, then initialize fields. */
+ dtrans = new CDTrans(m_spec.m_dtrans_vector.size(),m_spec);
+ dtrans.m_accept = dfa.m_accept;
+ dtrans.m_anchor = dfa.m_anchor;
+
+ /* Set CDTrans array for each character transition. */
+ for (i = 0; i < m_spec.m_dtrans_ncols; ++i)
+ {
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(0 <= i);
+ CUtility.ASSERT(m_spec.m_dtrans_ncols > i);
+ }
+
+ /* Create new dfa set by attempting character transition. */
+ move(dfa.m_nfa_set,dfa.m_nfa_bit,i,bunch);
+ if (null != bunch.m_nfa_set)
+ {
+ e_closure(bunch);
+ }
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT((null == bunch.m_nfa_set
+ && null == bunch.m_nfa_bit)
+ || (null != bunch.m_nfa_set
+ && null != bunch.m_nfa_bit));
+ }
+
+ /* Create new state or set state to empty. */
+ if (null == bunch.m_nfa_set)
+ {
+ nextstate = CDTrans.F;
+ }
+ else
+ {
+ nextstate = in_dstates(bunch);
+
+ if (NOT_IN_DSTATES == nextstate)
+ {
+ nextstate = add_to_dstates(bunch);
+ }
+ }
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(nextstate < m_spec.m_dfa_states.size());
+ }
+
+ dtrans.m_dtrans[i] = nextstate;
+ }
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(m_spec.m_dtrans_vector.size() == dfa.m_label);
+ }
+
+ m_spec.m_dtrans_vector.addElement(dtrans);
+ }
+ }
+
+ System.out.println();
+ }
+
+ /***************************************************************
+ Function: free_dfa_states
+ **************************************************************/
+ private void free_dfa_states
+ (
+ )
+ {
+ m_spec.m_dfa_states = null;
+ m_spec.m_dfa_sets = null;
+ }
+
+ /***************************************************************
+ Function: free_nfa_states
+ **************************************************************/
+ private void free_nfa_states
+ (
+ )
+ {
+ /* UNDONE: Remove references to nfas from within dfas. */
+ /* UNDONE: Don't free CAccepts. */
+
+ m_spec.m_nfa_states = null;
+ m_spec.m_nfa_start = null;
+ m_spec.m_state_rules = null;
+ }
+
+ /***************************************************************
+ Function: e_closure
+ Description: Alters and returns input set.
+ **************************************************************/
+ private void e_closure
+ (
+ CBunch bunch
+ )
+ {
+ Stack nfa_stack;
+ int size;
+ int i;
+ CNfa state;
+
+ /* Debug checks. */
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != bunch);
+ CUtility.ASSERT(null != bunch.m_nfa_set);
+ CUtility.ASSERT(null != bunch.m_nfa_bit);
+ }
+
+ bunch.m_accept = null;
+ bunch.m_anchor = CSpec.NONE;
+ bunch.m_accept_index = CUtility.INT_MAX;
+
+ /* Create initial stack. */
+ nfa_stack = new Stack();
+ size = bunch.m_nfa_set.size();
+ for (i = 0; i < size; ++i)
+ {
+ state = (CNfa) bunch.m_nfa_set.elementAt(i);
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(bunch.m_nfa_bit.get(state.m_label));
+ }
+
+ nfa_stack.push(state);
+ }
+
+ /* Main loop. */
+ while (false == nfa_stack.empty())
+ {
+ state = (CNfa) nfa_stack.pop();
+
+ if (CUtility.OLD_DUMP_DEBUG)
+ {
+ if (null != state.m_accept)
+ {
+ System.out.println("Looking at accepting state " + state.m_label
+ + " with <"
+ + (new String(state.m_accept.m_action,0,
+ state.m_accept.m_action_read))
+ + ">");
+ }
+ }
+
+ if (null != state.m_accept
+ && state.m_label < bunch.m_accept_index)
+ {
+ bunch.m_accept_index = state.m_label;
+ bunch.m_accept = state.m_accept;
+ bunch.m_anchor = state.m_anchor;
+
+ if (CUtility.OLD_DUMP_DEBUG)
+ {
+ System.out.println("Found accepting state " + state.m_label
+ + " with <"
+ + (new String(state.m_accept.m_action,0,
+ state.m_accept.m_action_read))
+ + ">");
+ }
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != bunch.m_accept);
+ CUtility.ASSERT(CSpec.NONE == bunch.m_anchor
+ || 0 != (bunch.m_anchor & CSpec.END)
+ || 0 != (bunch.m_anchor & CSpec.START));
+ }
+ }
+
+ if (CNfa.EPSILON == state.m_edge)
+ {
+ if (null != state.m_next)
+ {
+ if (false == bunch.m_nfa_set.contains(state.m_next))
+ {
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(false == bunch.m_nfa_bit.get(state.m_next.m_label));
+ }
+
+ bunch.m_nfa_bit.set(state.m_next.m_label);
+ bunch.m_nfa_set.addElement(state.m_next);
+ nfa_stack.push(state.m_next);
+ }
+ }
+
+ if (null != state.m_next2)
+ {
+ if (false == bunch.m_nfa_set.contains(state.m_next2))
+ {
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(false == bunch.m_nfa_bit.get(state.m_next2.m_label));
+ }
+
+ bunch.m_nfa_bit.set(state.m_next2.m_label);
+ bunch.m_nfa_set.addElement(state.m_next2);
+ nfa_stack.push(state.m_next2);
+ }
+ }
+ }
+ }
+
+ if (null != bunch.m_nfa_set)
+ {
+ sortStates(bunch.m_nfa_set);
+ }
+
+ return;
+ }
+
+ /***************************************************************
+ Function: move
+ Description: Returns null if resulting NFA set is empty.
+ **************************************************************/
+ void move
+ (
+ Vector nfa_set,
+ SparseBitSet nfa_bit,
+ int b,
+ CBunch bunch
+ )
+ {
+ int size;
+ int index;
+ CNfa state;
+
+ bunch.m_nfa_set = null;
+ bunch.m_nfa_bit = null;
+
+ size = nfa_set.size();
+ for (index = 0; index < size; ++index)
+ {
+ state = (CNfa) nfa_set.elementAt(index);
+
+ if (b == state.m_edge
+ || (CNfa.CCL == state.m_edge
+ && true == state.m_set.contains(b)))
+ {
+ if (null == bunch.m_nfa_set)
+ {
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null == bunch.m_nfa_bit);
+ }
+
+ bunch.m_nfa_set = new Vector();
+ /*bunch.m_nfa_bit
+ = new SparseBitSet(m_spec.m_nfa_states.size());*/
+ bunch.m_nfa_bit = new SparseBitSet();
+ }
+
+ bunch.m_nfa_set.addElement(state.m_next);
+ /*System.out.println("Size of bitset: " + bunch.m_nfa_bit.size());
+ System.out.println("Reference index: " + state.m_next.m_label);
+ System.out.flush();*/
+ bunch.m_nfa_bit.set(state.m_next.m_label);
+ }
+ }
+
+ if (null != bunch.m_nfa_set)
+ {
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != bunch.m_nfa_bit);
+ }
+
+ sortStates(bunch.m_nfa_set);
+ }
+
+ return;
+ }
+
+ /***************************************************************
+ Function: sortStates
+ **************************************************************/
+ private void sortStates
+ (
+ Vector nfa_set
+ )
+ {
+ CNfa elem;
+ int begin;
+ int size;
+ int index;
+ int value;
+ int smallest_index;
+ int smallest_value;
+ CNfa begin_elem;
+
+ size = nfa_set.size();
+ for (begin = 0; begin < size; ++begin)
+ {
+ elem = (CNfa) nfa_set.elementAt(begin);
+ smallest_value = elem.m_label;
+ smallest_index = begin;
+
+ for (index = begin + 1; index < size; ++index)
+ {
+ elem = (CNfa) nfa_set.elementAt(index);
+ value = elem.m_label;
+
+ if (value < smallest_value)
+ {
+ smallest_index = index;
+ smallest_value = value;
+ }
+ }
+
+ begin_elem = (CNfa) nfa_set.elementAt(begin);
+ elem = (CNfa) nfa_set.elementAt(smallest_index);
+ nfa_set.setElementAt(elem,begin);
+ nfa_set.setElementAt(begin_elem,smallest_index);
+ }
+
+ if (CUtility.OLD_DEBUG)
+ {
+ System.out.print("NFA vector indices: ");
+
+ for (index = 0; index < size; ++index)
+ {
+ elem = (CNfa) nfa_set.elementAt(index);
+ System.out.print(elem.m_label + " ");
+ }
+ System.out.println();
+ }
+
+ return;
+ }
+
+ /***************************************************************
+ Function: get_unmarked
+ Description: Returns next unmarked DFA state.
+ **************************************************************/
+ private CDfa get_unmarked
+ (
+ )
+ {
+ int size;
+ CDfa dfa;
+
+ size = m_spec.m_dfa_states.size();
+ while (m_unmarked_dfa < size)
+ {
+ dfa = (CDfa) m_spec.m_dfa_states.elementAt(m_unmarked_dfa);
+
+ if (false == dfa.m_mark)
+ {
+ if (CUtility.OLD_DUMP_DEBUG)
+ {
+ System.out.print("*");
+ System.out.flush();
+ }
+
+ if (m_spec.m_verbose && true == CUtility.OLD_DUMP_DEBUG)
+ {
+ System.out.println("---------------");
+ System.out.print("working on DFA state "
+ + m_unmarked_dfa
+ + " = NFA states: ");
+ m_lexGen.print_set(dfa.m_nfa_set);
+ System.out.println();
+ }
+
+ return dfa;
+ }
+
+ ++m_unmarked_dfa;
+ }
+
+ return null;
+ }
+
+ /***************************************************************
+ function: add_to_dstates
+ Description: Takes as input a CBunch with details of
+ a dfa state that needs to be created.
+ 1) Allocates a new dfa state and saves it in
+ the appropriate CSpec vector.
+ 2) Initializes the fields of the dfa state
+ with the information in the CBunch.
+ 3) Returns index of new dfa.
+ **************************************************************/
+ private int add_to_dstates
+ (
+ CBunch bunch
+ )
+ {
+ CDfa dfa;
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != bunch.m_nfa_set);
+ CUtility.ASSERT(null != bunch.m_nfa_bit);
+ CUtility.ASSERT(null != bunch.m_accept
+ || CSpec.NONE == bunch.m_anchor);
+ }
+
+ /* Allocate, passing CSpec so dfa label can be set. */
+ dfa = CAlloc.newCDfa(m_spec);
+
+ /* Initialize fields, including the mark field. */
+ dfa.m_nfa_set = (Vector) bunch.m_nfa_set.clone();
+ dfa.m_nfa_bit = (SparseBitSet) bunch.m_nfa_bit.clone();
+ dfa.m_accept = bunch.m_accept;
+ dfa.m_anchor = bunch.m_anchor;
+ dfa.m_mark = false;
+
+ /* Register dfa state using BitSet in CSpec Hashtable. */
+ m_spec.m_dfa_sets.put(dfa.m_nfa_bit,dfa);
+ /*registerCDfa(dfa);*/
+
+ if (CUtility.OLD_DUMP_DEBUG)
+ {
+ System.out.print("Registering set : ");
+ m_lexGen.print_set(dfa.m_nfa_set);
+ System.out.println();
+ }
+
+ return dfa.m_label;
+ }
+
+ /***************************************************************
+ Function: in_dstates
+ **************************************************************/
+ private int in_dstates
+ (
+ CBunch bunch
+ )
+ {
+ CDfa dfa;
+
+ if (CUtility.OLD_DEBUG)
+ {
+ System.out.print("Looking for set : ");
+ m_lexGen.print_set(bunch.m_nfa_set);
+ }
+
+ dfa = (CDfa) m_spec.m_dfa_sets.get(bunch.m_nfa_bit);
+
+ if (null != dfa)
+ {
+ if (CUtility.OLD_DUMP_DEBUG)
+ {
+ System.out.println(" FOUND!");
+ }
+
+ return dfa.m_label;
+ }
+
+ if (CUtility.OLD_DUMP_DEBUG)
+ {
+ System.out.println(" NOT FOUND!");
+ }
+ return NOT_IN_DSTATES;
+ }
+
+}
+
+/***************************************************************
+ Class: CAlloc
+ **************************************************************/
+class CAlloc
+{
+ /***************************************************************
+ Function: newCDfa
+ **************************************************************/
+ static CDfa newCDfa
+ (
+ CSpec spec
+ )
+ {
+ CDfa dfa;
+
+ dfa = new CDfa(spec.m_dfa_states.size());
+ spec.m_dfa_states.addElement(dfa);
+
+ return dfa;
+ }
+
+ /***************************************************************
+ Function: newCNfaPair
+ Description:
+ **************************************************************/
+ static CNfaPair newCNfaPair
+ (
+ )
+ {
+ CNfaPair pair = new CNfaPair();
+
+ return pair;
+ }
+ /***************************************************************
+ Function: newNLPair
+ Description: return a new CNfaPair that matches a new
+ line: (\r\n?|[\n\uu2028\uu2029])
+ Added by CSA 8-Aug-1999, updated 10-Aug-1999
+ **************************************************************/
+ static CNfaPair newNLPair(CSpec spec) {
+ CNfaPair pair = newCNfaPair();
+ pair.m_end=newCNfa(spec); // newline accepting state
+ pair.m_start=newCNfa(spec); // new state with two epsilon edges
+ pair.m_start.m_next = newCNfa(spec);
+ pair.m_start.m_next.m_edge = CNfa.CCL;
+ pair.m_start.m_next.m_set = new CSet();
+ pair.m_start.m_next.m_set.add('\n');
+ if (spec.m_dtrans_ncols-CSpec.NUM_PSEUDO > 2029) {
+ pair.m_start.m_next.m_set.add(2028); /*U+2028 is LS, the line separator*/
+ pair.m_start.m_next.m_set.add(2029); /*U+2029 is PS, the paragraph sep.*/
+ }
+ pair.m_start.m_next.m_next = pair.m_end; // accept '\n', U+2028, or U+2029
+ pair.m_start.m_next2 = newCNfa(spec);
+ pair.m_start.m_next2.m_edge = '\r';
+ pair.m_start.m_next2.m_next = newCNfa(spec);
+ pair.m_start.m_next2.m_next.m_next = pair.m_end; // accept '\r';
+ pair.m_start.m_next2.m_next.m_next2 = newCNfa(spec);
+ pair.m_start.m_next2.m_next.m_next2.m_edge = '\n';
+ pair.m_start.m_next2.m_next.m_next2.m_next = pair.m_end; // accept '\r\n';
+ return pair;
+ }
+
+ /***************************************************************
+ Function: newCNfa
+ Description:
+ **************************************************************/
+ static CNfa newCNfa
+ (
+ CSpec spec
+ )
+ {
+ CNfa p;
+
+ /* UNDONE: Buffer this? */
+
+ p = new CNfa();
+
+ /*p.m_label = spec.m_nfa_states.size();*/
+ spec.m_nfa_states.addElement(p);
+ p.m_edge = CNfa.EPSILON;
+
+ return p;
+ }
+}
+
+/***************************************************************
+ Class: Main
+ Description: Top-level lexical analyzer generator function.
+ **************************************************************/
+public class Main
+{
+ /***************************************************************
+ Function: main
+ **************************************************************/
+ public static void main
+ (
+ String arg[]
+ )
+ throws java.io.IOException
+ {
+ CLexGen lg;
+
+ if (arg.length < 1)
+ {
+ System.out.println("Usage: JLex.Main <filename>");
+ return;
+ }
+
+ /* Note: For debuging, it may be helpful to remove the try/catch
+ block and permit the Exception to propagate to the top level.
+ This gives more information. */
+ try
+ {
+ lg = new CLexGen(arg[0]);
+ lg.generate();
+ }
+ catch (Error e)
+ {
+ System.out.println(e.getMessage());
+ }
+ }
+}
+
+/***************************************************************
+ Class: CDTrans
+ **************************************************************/
+class CDTrans
+{
+ /*************************************************************
+ Member Variables
+ ***********************************************************/
+ int m_dtrans[];
+ CAccept m_accept;
+ int m_anchor;
+ int m_label;
+
+ /*************************************************************
+ Constants
+ ***********************************************************/
+ static final int F = -1;
+
+ /*************************************************************
+ Function: CTrans
+ ***********************************************************/
+ CDTrans
+ (
+ int label,
+ CSpec spec
+ )
+ {
+ m_dtrans = new int[spec.m_dtrans_ncols];
+ m_accept = null;
+ m_anchor = CSpec.NONE;
+ m_label = label;
+ }
+}
+
+/***************************************************************
+ Class: CDfa
+ **************************************************************/
+class CDfa
+{
+ /***************************************************************
+ Member Variables
+ ***********************************************************/
+ int m_group;
+ boolean m_mark;
+ CAccept m_accept;
+ int m_anchor;
+ Vector m_nfa_set;
+ SparseBitSet m_nfa_bit;
+ int m_label;
+
+ /***************************************************************
+ Function: CDfa
+ **************************************************************/
+ CDfa
+ (
+ int label
+ )
+ {
+ m_group = 0;
+ m_mark = false;
+
+ m_accept = null;
+ m_anchor = CSpec.NONE;
+
+ m_nfa_set = null;
+ m_nfa_bit = null;
+
+ m_label = label;
+ }
+}
+
+/***************************************************************
+ Class: CAccept
+ **************************************************************/
+class CAccept
+{
+ /***************************************************************
+ Member Variables
+ **************************************************************/
+ char m_action[];
+ int m_action_read;
+ int m_line_number;
+
+ /***************************************************************
+ Function: CAccept
+ **************************************************************/
+ CAccept
+ (
+ char action[],
+ int action_read,
+ int line_number
+ )
+ {
+ int elem;
+
+ m_action_read = action_read;
+
+ m_action = new char[m_action_read];
+ for (elem = 0; elem < m_action_read; ++elem)
+ {
+ m_action[elem] = action[elem];
+ }
+
+ m_line_number = line_number;
+ }
+
+ /***************************************************************
+ Function: CAccept
+ **************************************************************/
+ CAccept
+ (
+ CAccept accept
+ )
+ {
+ int elem;
+
+ m_action_read = accept.m_action_read;
+
+ m_action = new char[m_action_read];
+ for (elem = 0; elem < m_action_read; ++elem)
+ {
+ m_action[elem] = accept.m_action[elem];
+ }
+
+ m_line_number = accept.m_line_number;
+ }
+
+ /***************************************************************
+ Function: mimic
+ **************************************************************/
+ void mimic
+ (
+ CAccept accept
+ )
+ {
+ int elem;
+
+ m_action_read = accept.m_action_read;
+
+ m_action = new char[m_action_read];
+ for (elem = 0; elem < m_action_read; ++elem)
+ {
+ m_action[elem] = accept.m_action[elem];
+ }
+ }
+}
+
+/***************************************************************
+ Class: CAcceptAnchor
+ **************************************************************/
+class CAcceptAnchor
+{
+ /***************************************************************
+ Member Variables
+ **************************************************************/
+ CAccept m_accept;
+ int m_anchor;
+
+ /***************************************************************
+ Function: CAcceptAnchor
+ **************************************************************/
+ CAcceptAnchor
+ (
+ )
+ {
+ m_accept = null;
+ m_anchor = CSpec.NONE;
+ }
+}
+
+/***************************************************************
+ Class: CNfaPair
+ **************************************************************/
+class CNfaPair
+{
+ /***************************************************************
+ Member Variables
+ **************************************************************/
+ CNfa m_start;
+ CNfa m_end;
+
+ /***************************************************************
+ Function: CNfaPair
+ **************************************************************/
+ CNfaPair
+ (
+ )
+ {
+ m_start = null;
+ m_end = null;
+ }
+}
+
+/***************************************************************
+ Class: CInput
+ Description:
+ **************************************************************/
+class CInput
+{
+ /***************************************************************
+ Member Variables
+ **************************************************************/
+ private java.io.BufferedReader m_input; /* JLex specification file. */
+
+ boolean m_eof_reached; /* Whether EOF has been encountered. */
+ boolean m_pushback_line;
+
+ char m_line[]; /* Line buffer. */
+ int m_line_read; /* Number of bytes read into line buffer. */
+ int m_line_index; /* Current index into line buffer. */
+
+ int m_line_number; /* Current line number. */
+
+ /***************************************************************
+ Constants
+ **************************************************************/
+ static final boolean EOF = true;
+ static final boolean NOT_EOF = false;
+
+ /***************************************************************
+ Function: CInput
+ Description:
+ **************************************************************/
+ CInput
+ (
+ java.io.Reader input
+ )
+ {
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != input);
+ }
+
+ /* Initialize input stream. */
+ m_input = new java.io.BufferedReader(input);
+
+ /* Initialize buffers and index counters. */
+ m_line = null;
+ m_line_read = 0;
+ m_line_index = 0;
+
+ /* Initialize state variables. */
+ m_eof_reached = false;
+ m_line_number = 0;
+ m_pushback_line = false;
+ }
+
+ /***************************************************************
+ Function: getLine
+ Description: Returns true on EOF, false otherwise.
+ Guarantees not to return a blank line, or a line
+ of zero length.
+ **************************************************************/
+ boolean getLine
+ (
+ )
+ throws java.io.IOException
+ {
+ String lineStr;
+ int elem;
+
+ /* Has EOF already been reached? */
+ if (m_eof_reached)
+ {
+ return EOF;
+ }
+
+ /* Pushback current line? */
+ if (m_pushback_line)
+ {
+ m_pushback_line = false;
+
+ /* Check for empty line. */
+ for (elem = 0; elem < m_line_read; ++elem)
+ {
+ if (false == CUtility.isspace(m_line[elem]))
+ {
+ break;
+ }
+ }
+
+ /* Nonempty? */
+ if (elem < m_line_read)
+ {
+ m_line_index = 0;
+ return NOT_EOF;
+ }
+ }
+
+ while (true)
+ {
+ if (null == (lineStr = m_input.readLine()))
+ {
+ m_eof_reached = true;
+ m_line_index = 0;
+ return EOF;
+ }
+ m_line = (lineStr + "\n").toCharArray();
+ m_line_read=m_line.length;
+ ++m_line_number;
+
+ /* Check for empty lines and discard them. */
+ elem = 0;
+ while (CUtility.isspace(m_line[elem]))
+ {
+ ++elem;
+ if (elem == m_line_read)
+ {
+ break;
+ }
+ }
+
+ if (elem < m_line_read)
+ {
+ break;
+ }
+ }
+
+ m_line_index = 0;
+ return NOT_EOF;
+ }
+}
+
+/********************************************************
+ Class: Utility
+ *******************************************************/
+class CUtility
+{
+ /********************************************************
+ Constants
+ *******************************************************/
+ static final boolean DEBUG = true;
+ static final boolean SLOW_DEBUG = true;
+ static final boolean DUMP_DEBUG = true;
+ /*static final boolean DEBUG = false;
+ static final boolean SLOW_DEBUG = false;
+ static final boolean DUMP_DEBUG = false;*/
+ static final boolean DESCENT_DEBUG = false;
+ static final boolean OLD_DEBUG = false;
+ static final boolean OLD_DUMP_DEBUG = false;
+ static final boolean FOODEBUG = false;
+ static final boolean DO_DEBUG = false;
+
+ /********************************************************
+ Constants: Integer Bounds
+ *******************************************************/
+ static final int INT_MAX = 2147483647;
+
+ static final int MAX_SEVEN_BIT = 127;
+ static final int MAX_EIGHT_BIT = 255;
+ static final int MAX_SIXTEEN_BIT=65535;
+
+ /********************************************************
+ Function: enter
+ Description: Debugging routine.
+ *******************************************************/
+ static void enter
+ (
+ String descent,
+ char lexeme,
+ int token
+ )
+ {
+ System.out.println("Entering " + descent
+ + " [lexeme: " + lexeme
+ + "] [token: " + token + "]");
+ }
+
+ /********************************************************
+ Function: leave
+ Description: Debugging routine.
+ *******************************************************/
+ static void leave
+ (
+ String descent,
+ char lexeme,
+ int token
+ )
+ {
+ System.out.println("Leaving " + descent
+ + " [lexeme:" + lexeme
+ + "] [token:" + token + "]");
+ }
+
+ /********************************************************
+ Function: ASSERT
+ Description: Debugging routine.
+ *******************************************************/
+ static void ASSERT
+ (
+ boolean expr
+ )
+ {
+ if (DEBUG && false == expr)
+ {
+ System.out.println("Assertion Failed");
+ throw new Error("Assertion Failed.");
+ }
+ }
+
+ /***************************************************************
+ Function: doubleSize
+ **************************************************************/
+ static char[] doubleSize
+ (
+ char oldBuffer[]
+ )
+ {
+ char newBuffer[] = new char[2 * oldBuffer.length];
+ int elem;
+
+ for (elem = 0; elem < oldBuffer.length; ++elem)
+ {
+ newBuffer[elem] = oldBuffer[elem];
+ }
+
+ return newBuffer;
+ }
+
+ /***************************************************************
+ Function: doubleSize
+ **************************************************************/
+ static byte[] doubleSize
+ (
+ byte oldBuffer[]
+ )
+ {
+ byte newBuffer[] = new byte[2 * oldBuffer.length];
+ int elem;
+
+ for (elem = 0; elem < oldBuffer.length; ++elem)
+ {
+ newBuffer[elem] = oldBuffer[elem];
+ }
+
+ return newBuffer;
+ }
+
+ /********************************************************
+ Function: hex2bin
+ *******************************************************/
+ static char hex2bin
+ (
+ char c
+ )
+ {
+ if ('0' <= c && '9' >= c)
+ {
+ return (char) (c - '0');
+ }
+ else if ('a' <= c && 'f' >= c)
+ {
+ return (char) (c - 'a' + 10);
+ }
+ else if ('A' <= c && 'F' >= c)
+ {
+ return (char) (c - 'A' + 10);
+ }
+
+ CError.impos("Bad hexidecimal digit" + c);
+ return 0;
+ }
+
+ /********************************************************
+ Function: ishexdigit
+ *******************************************************/
+ static boolean ishexdigit
+ (
+ char c
+ )
+ {
+ if (('0' <= c && '9' >= c)
+ || ('a' <= c && 'f' >= c)
+ || ('A' <= c && 'F' >= c))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ /********************************************************
+ Function: oct2bin
+ *******************************************************/
+ static char oct2bin
+ (
+ char c
+ )
+ {
+ if ('0' <= c && '7' >= c)
+ {
+ return (char) (c - '0');
+ }
+
+ CError.impos("Bad octal digit " + c);
+ return 0;
+ }
+
+ /********************************************************
+ Function: isoctdigit
+ *******************************************************/
+ static boolean isoctdigit
+ (
+ char c
+ )
+ {
+ if ('0' <= c && '7' >= c)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ /********************************************************
+ Function: isspace
+ *******************************************************/
+ static boolean isspace
+ (
+ char c
+ )
+ {
+ if ('\b' == c
+ || '\t' == c
+ || '\n' == c
+ || '\f' == c
+ || '\r' == c
+ || ' ' == c)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ /********************************************************
+ Function: isnewline
+ *******************************************************/
+ static boolean isnewline
+ (
+ char c
+ )
+ {
+ if ('\n' == c
+ || '\r' == c)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ /********************************************************
+ Function: bytencmp
+ Description: Compares up to n elements of
+ byte array a[] against byte array b[].
+ The first byte comparison is made between
+ a[a_first] and b[b_first]. Comparisons continue
+ until the null terminating byte '\0' is reached
+ or until n bytes are compared.
+ Return Value: Returns 0 if arrays are the
+ same up to and including the null terminating byte
+ or up to and including the first n bytes,
+ whichever comes first.
+ *******************************************************/
+ static int bytencmp
+ (
+ byte a[],
+ int a_first,
+ byte b[],
+ int b_first,
+ int n
+ )
+ {
+ int elem;
+
+ for (elem = 0; elem < n; ++elem)
+ {
+ /*System.out.print((char) a[a_first + elem]);
+ System.out.print((char) b[b_first + elem]);*/
+
+ if ('\0' == a[a_first + elem] && '\0' == b[b_first + elem])
+ {
+ /*System.out.println("return 0");*/
+ return 0;
+ }
+ if (a[a_first + elem] < b[b_first + elem])
+ {
+ /*System.out.println("return 1");*/
+ return 1;
+ }
+ else if (a[a_first + elem] > b[b_first + elem])
+ {
+ /*System.out.println("return -1");*/
+ return -1;
+ }
+ }
+
+ /*System.out.println("return 0");*/
+ return 0;
+ }
+
+ /********************************************************
+ Function: charncmp
+ *******************************************************/
+ static int charncmp
+ (
+ char a[],
+ int a_first,
+ char b[],
+ int b_first,
+ int n
+ )
+ {
+ int elem;
+
+ for (elem = 0; elem < n; ++elem)
+ {
+ if ('\0' == a[a_first + elem] && '\0' == b[b_first + elem])
+ {
+ return 0;
+ }
+ if (a[a_first + elem] < b[b_first + elem])
+ {
+ return 1;
+ }
+ else if (a[a_first + elem] > b[b_first + elem])
+ {
+ return -1;
+ }
+ }
+
+ return 0;
+ }
+}
+
+/********************************************************
+ Class: CError
+ *******************************************************/
+class CError
+{
+ /********************************************************
+ Function: impos
+ Description:
+ *******************************************************/
+ static void impos
+ (
+ String message
+ )
+ {
+ System.out.println("JLex Error: " + message);
+ }
+
+ /********************************************************
+ Constants
+ Description: Error codes for parse_error().
+ *******************************************************/
+ static final int E_BADEXPR = 0;
+ static final int E_PAREN = 1;
+ static final int E_LENGTH = 2;
+ static final int E_BRACKET = 3;
+ static final int E_BOL = 4;
+ static final int E_CLOSE = 5;
+ static final int E_NEWLINE = 6;
+ static final int E_BADMAC = 7;
+ static final int E_NOMAC = 8;
+ static final int E_MACDEPTH = 9;
+ static final int E_INIT = 10;
+ static final int E_EOF = 11;
+ static final int E_DIRECT = 12;
+ static final int E_INTERNAL = 13;
+ static final int E_STATE = 14;
+ static final int E_MACDEF = 15;
+ static final int E_SYNTAX = 16;
+ static final int E_BRACE = 17;
+ static final int E_DASH = 18;
+ static final int E_ZERO = 19;
+ static final int E_BADCTRL = 20;
+
+ /********************************************************
+ Constants
+ Description: String messages for parse_error();
+ *******************************************************/
+ static final String errmsg[] =
+ {
+ "Malformed regular expression.",
+ "Missing close parenthesis.",
+ "Too many regular expressions or expression too long.",
+ "Missing [ in character class.",
+ "^ must be at start of expression or after [.",
+ "+ ? or * must follow an expression or subexpression.",
+ "Newline in quoted string.",
+ "Missing } in macro expansion.",
+ "Macro does not exist.",
+ "Macro expansions nested too deeply.",
+ "JLex has not been successfully initialized.",
+ "Unexpected end-of-file found.",
+ "Undefined or badly-formed JLex directive.",
+ "Internal JLex error.",
+ "Unitialized state name.",
+ "Badly formed macro definition.",
+ "Syntax error.",
+ "Missing brace at start of lexical action.",
+ "Special character dash - in character class [...] must\n"
+ + "\tbe preceded by start-of-range character.",
+ "Zero-length regular expression.",
+ "Illegal \\^C-style escape sequence (character following caret must\n"
+ + "\tbe alphabetic).",
+ };
+
+ /********************************************************
+ Function: parse_error
+ Description:
+ *******************************************************/
+ static void parse_error
+ (
+ int error_code,
+ int line_number
+ )
+ {
+ System.out.println("Error: Parse error at line "
+ + line_number + ".");
+ System.out.println("Description: " + errmsg[error_code]);
+ throw new Error("Parse error.");
+ }
+}
+
+/********************************************************
+ Class: CSet
+ *******************************************************/
+class CSet
+{
+ /********************************************************
+ Member Variables
+ *******************************************************/
+ private SparseBitSet m_set;
+ private boolean m_complement;
+
+ /********************************************************
+ Function: CSet
+ *******************************************************/
+ CSet
+ (
+ )
+ {
+ m_set = new SparseBitSet();
+ m_complement = false;
+ }
+
+ /********************************************************
+ Function: complement
+ *******************************************************/
+ void complement
+ (
+ )
+ {
+ m_complement = true;
+ }
+
+ /********************************************************
+ Function: add
+ *******************************************************/
+ void add
+ (
+ int i
+ )
+ {
+ m_set.set(i);
+ }
+
+ /********************************************************
+ Function: addncase
+ *******************************************************/
+ void addncase // add, ignoring case.
+ (
+ char c
+ )
+ {
+ /* Do this in a Unicode-friendly way. */
+ /* (note that duplicate adds have no effect) */
+ add(c);
+ add(Character.toLowerCase(c));
+ add(Character.toTitleCase(c));
+ add(Character.toUpperCase(c));
+ }
+
+ /********************************************************
+ Function: contains
+ *******************************************************/
+ boolean contains
+ (
+ int i
+ )
+ {
+ boolean result;
+
+ result = m_set.get(i);
+
+ if (m_complement)
+ {
+ return (false == result);
+ }
+
+ return result;
+ }
+
+ /********************************************************
+ Function: mimic
+ *******************************************************/
+ void mimic
+ (
+ CSet set
+ )
+ {
+ m_complement = set.m_complement;
+ m_set = (SparseBitSet) set.m_set.clone();
+ }
+
+ /** Map set using character classes [CSA] */
+ void map(CSet set, int[] mapping) {
+ m_complement = set.m_complement;
+ m_set.clearAll();
+ for (Enumeration e=set.m_set.elements(); e.hasMoreElements(); ) {
+ int old_value =((Integer)e.nextElement()).intValue();
+ if (old_value<mapping.length) // skip unmapped characters
+ m_set.set(mapping[old_value]);
+ }
+ }
+}
+
+/********************************************************
+ Class: CNfa
+ *******************************************************/
+class CNfa
+{
+ /********************************************************
+ Member Variables
+ *******************************************************/
+ int m_edge; /* Label for edge type:
+ character code,
+ CCL (character class),
+ [STATE,
+ SCL (state class),]
+ EMPTY,
+ EPSILON. */
+
+ CSet m_set; /* Set to store character classes. */
+ CNfa m_next; /* Next state (or null if none). */
+
+ CNfa m_next2; /* Another state with type == EPSILON
+ and null if not used.
+ The NFA construction should result in two
+ outgoing edges only if both are EPSILON edges. */
+
+ CAccept m_accept; /* Set to null if nonaccepting state. */
+ int m_anchor; /* Says if and where pattern is anchored. */
+
+ int m_label;
+
+ SparseBitSet m_states;
+
+ /********************************************************
+ Constants
+ *******************************************************/
+ static final int NO_LABEL = -1;
+
+ /********************************************************
+ Constants: Edge Types
+ Note: Edge transitions on one specific character
+ are labelled with the character Ascii (Unicode)
+ codes. So none of the constants below should
+ overlap with the natural character codes.
+ *******************************************************/
+ static final int CCL = -1;
+ static final int EMPTY = -2;
+ static final int EPSILON = -3;
+
+ /********************************************************
+ Function: CNfa
+ *******************************************************/
+ CNfa
+ (
+ )
+ {
+ m_edge = EMPTY;
+ m_set = null;
+ m_next = null;
+ m_next2 = null;
+ m_accept = null;
+ m_anchor = CSpec.NONE;
+ m_label = NO_LABEL;
+ m_states = null;
+ }
+
+ /********************************************************
+ Function: mimic
+ Description: Converts this NFA state into a copy of
+ the input one.
+ *******************************************************/
+ void mimic
+ (
+ CNfa nfa
+ )
+ {
+ m_edge = nfa.m_edge;
+
+ if (null != nfa.m_set)
+ {
+ if (null == m_set)
+ {
+ m_set = new CSet();
+ }
+ m_set.mimic(nfa.m_set);
+ }
+ else
+ {
+ m_set = null;
+ }
+
+ m_next = nfa.m_next;
+ m_next2 = nfa.m_next2;
+ m_accept = nfa.m_accept;
+ m_anchor = nfa.m_anchor;
+
+ if (null != nfa.m_states)
+ {
+ m_states = (SparseBitSet) nfa.m_states.clone();
+ }
+ else
+ {
+ m_states = null;
+ }
+ }
+}
+
+/***************************************************************
+ Class: CLexGen
+ **************************************************************/
+class CLexGen
+{
+ /***************************************************************
+ Member Variables
+ **************************************************************/
+ private java.io.Reader m_instream; /* JLex specification file. */
+ private java.io.PrintWriter m_outstream; /* Lexical analyzer source file. */
+
+ private CInput m_input; /* Input buffer class. */
+
+ private Hashtable m_tokens; /* Hashtable that maps characters to their
+ corresponding lexical code for
+ the internal lexical analyzer. */
+ private CSpec m_spec; /* Spec class holds information
+ about the generated lexer. */
+ private boolean m_init_flag; /* Flag set to true only upon
+ successful initialization. */
+
+ private CMakeNfa m_makeNfa; /* NFA machine generator module. */
+ private CNfa2Dfa m_nfa2dfa; /* NFA to DFA machine (transition table)
+ conversion module. */
+ private CMinimize m_minimize; /* Transition table compressor. */
+ private CSimplifyNfa m_simplifyNfa; /* NFA simplifier using char classes */
+ private CEmit m_emit; /* Output module that emits source code
+ into the generated lexer file. */
+
+
+ /********************************************************
+ Constants
+ *******************************************************/
+ private static final boolean ERROR = false;
+ private static final boolean NOT_ERROR = true;
+ private static final int BUFFER_SIZE = 1024;
+
+ /********************************************************
+ Constants: Token Types
+ *******************************************************/
+ static final int EOS = 1;
+ static final int ANY = 2;
+ static final int AT_BOL = 3;
+ static final int AT_EOL = 4;
+ static final int CCL_END = 5;
+ static final int CCL_START = 6;
+ static final int CLOSE_CURLY = 7;
+ static final int CLOSE_PAREN = 8;
+ static final int CLOSURE = 9;
+ static final int DASH = 10;
+ static final int END_OF_INPUT = 11;
+ static final int L = 12;
+ static final int OPEN_CURLY = 13;
+ static final int OPEN_PAREN = 14;
+ static final int OPTIONAL = 15;
+ static final int OR = 16;
+ static final int PLUS_CLOSE = 17;
+
+ /***************************************************************
+ Function: CLexGen
+ **************************************************************/
+ CLexGen
+ (
+ String filename
+ )
+ throws java.io.FileNotFoundException, java.io.IOException
+ {
+ /* Successful initialization flag. */
+ m_init_flag = false;
+
+ /* Open input stream. */
+ m_instream = new java.io.FileReader(filename);
+ if (null == m_instream)
+ {
+ System.out.println("Error: Unable to open input file "
+ + filename + ".");
+ return;
+ }
+
+ /* Open output stream. */
+ m_outstream
+ = new java.io.PrintWriter(new java.io.BufferedWriter(
+ new java.io.FileWriter(filename + ".java")));
+ if (null == m_outstream)
+ {
+ System.out.println("Error: Unable to open output file "
+ + filename + ".java.");
+ return;
+ }
+
+ /* Create input buffer class. */
+ m_input = new CInput(m_instream);
+
+ /* Initialize character hash table. */
+ m_tokens = new Hashtable();
+ m_tokens.put(new Character('$'),new Integer(AT_EOL));
+ m_tokens.put(new Character('('),new Integer(OPEN_PAREN));
+ m_tokens.put(new Character(')'),new Integer(CLOSE_PAREN));
+ m_tokens.put(new Character('*'),new Integer(CLOSURE));
+ m_tokens.put(new Character('+'),new Integer(PLUS_CLOSE));
+ m_tokens.put(new Character('-'),new Integer(DASH));
+ m_tokens.put(new Character('.'),new Integer(ANY));
+ m_tokens.put(new Character('?'),new Integer(OPTIONAL));
+ m_tokens.put(new Character('['),new Integer(CCL_START));
+ m_tokens.put(new Character(']'),new Integer(CCL_END));
+ m_tokens.put(new Character('^'),new Integer(AT_BOL));
+ m_tokens.put(new Character('{'),new Integer(OPEN_CURLY));
+ m_tokens.put(new Character('|'),new Integer(OR));
+ m_tokens.put(new Character('}'),new Integer(CLOSE_CURLY));
+
+ /* Initialize spec structure. */
+ m_spec = new CSpec(this);
+
+ /* Nfa to dfa converter. */
+ m_nfa2dfa = new CNfa2Dfa();
+ m_minimize = new CMinimize();
+ m_makeNfa = new CMakeNfa();
+ m_simplifyNfa = new CSimplifyNfa();
+
+ m_emit = new CEmit();
+
+ /* Successful initialization flag. */
+ m_init_flag = true;
+ }
+
+ /***************************************************************
+ Function: generate
+ Description:
+ **************************************************************/
+ void generate
+ (
+ )
+ throws java.io.IOException, java.io.FileNotFoundException
+ {
+ if (false == m_init_flag)
+ {
+ CError.parse_error(CError.E_INIT,0);
+ }
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != this);
+ CUtility.ASSERT(null != m_outstream);
+ CUtility.ASSERT(null != m_input);
+ CUtility.ASSERT(null != m_tokens);
+ CUtility.ASSERT(null != m_spec);
+ CUtility.ASSERT(m_init_flag);
+ }
+
+ /*m_emit.emit_imports(m_spec,m_outstream);*/
+
+ if (m_spec.m_verbose)
+ {
+ System.out.println("Processing first section -- user code.");
+ }
+ userCode();
+ if (m_input.m_eof_reached)
+ {
+ CError.parse_error(CError.E_EOF,m_input.m_line_number);
+ }
+
+ if (m_spec.m_verbose)
+ {
+ System.out.println("Processing second section -- "
+ + "JLex declarations.");
+ }
+ userDeclare();
+ if (m_input.m_eof_reached)
+ {
+ CError.parse_error(CError.E_EOF,m_input.m_line_number);
+ }
+
+ if (m_spec.m_verbose)
+ {
+ System.out.println("Processing third section -- lexical rules.");
+ }
+ userRules();
+ if (CUtility.DO_DEBUG)
+ {
+ print_header();
+ }
+
+ if (m_spec.m_verbose)
+ {
+ System.out.println("Outputting lexical analyzer code.");
+ }
+ m_emit.emit(m_spec,m_outstream);
+
+ if (m_spec.m_verbose && true == CUtility.OLD_DUMP_DEBUG)
+ {
+ details();
+ }
+
+ m_outstream.close();
+ }
+
+ /***************************************************************
+ Function: userCode
+ Description: Process first section of specification,
+ echoing it into output file.
+ **************************************************************/
+ private void userCode
+ (
+ )
+ throws java.io.IOException
+ {
+ int count = 0;
+
+ if (false == m_init_flag)
+ {
+ CError.parse_error(CError.E_INIT,0);
+ }
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != this);
+ CUtility.ASSERT(null != m_outstream);
+ CUtility.ASSERT(null != m_input);
+ CUtility.ASSERT(null != m_tokens);
+ CUtility.ASSERT(null != m_spec);
+ }
+
+ if (m_input.m_eof_reached)
+ {
+ CError.parse_error(CError.E_EOF,0);
+ }
+
+ while (true)
+ {
+ if (m_input.getLine())
+ {
+ /* Eof reached. */
+ CError.parse_error(CError.E_EOF,0);
+ }
+
+ if (2 <= m_input.m_line_read
+ && '%' == m_input.m_line[0]
+ && '%' == m_input.m_line[1])
+ {
+ /* Discard remainder of line. */
+ m_input.m_line_index = m_input.m_line_read;
+ return;
+ }
+
+ m_outstream.print(new String(m_input.m_line,0,
+ m_input.m_line_read));
+ }
+ }
+
+ /***************************************************************
+ Function: getName
+ **************************************************************/
+ private char[] getName
+ (
+ )
+ {
+ char buffer[];
+ int elem;
+
+ /* Skip white space. */
+ while (m_input.m_line_index < m_input.m_line_read
+ && true == CUtility.isspace(m_input.m_line[m_input.m_line_index]))
+ {
+ ++m_input.m_line_index;
+ }
+
+ /* No name? */
+ if (m_input.m_line_index >= m_input.m_line_read)
+ {
+ CError.parse_error(CError.E_DIRECT,0);
+ }
+
+ /* Determine length. */
+ elem = m_input.m_line_index;
+ while (elem < m_input.m_line_read
+ && false == CUtility.isnewline(m_input.m_line[elem]))
+ {
+ ++elem;
+ }
+
+ /* Allocate non-terminated buffer of exact length. */
+ buffer = new char[elem - m_input.m_line_index];
+
+ /* Copy. */
+ elem = 0;
+ while (m_input.m_line_index < m_input.m_line_read
+ && false == CUtility.isnewline(m_input.m_line[m_input.m_line_index]))
+ {
+ buffer[elem] = m_input.m_line[m_input.m_line_index];
+ ++elem;
+ ++m_input.m_line_index;
+ }
+
+ return buffer;
+ }
+
+ private final int CLASS_CODE = 0;
+ private final int INIT_CODE = 1;
+ private final int EOF_CODE = 2;
+ private final int INIT_THROW_CODE = 3;
+ private final int YYLEX_THROW_CODE = 4;
+ private final int EOF_THROW_CODE = 5;
+ private final int EOF_VALUE_CODE = 6;
+
+ /***************************************************************
+ Function: packCode
+ Description:
+ **************************************************************/
+ private char[] packCode
+ (
+ char start_dir[],
+ char end_dir[],
+ char prev_code[],
+ int prev_read,
+ int specified
+ )
+ throws java.io.IOException
+ {
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(INIT_CODE == specified
+ || CLASS_CODE == specified
+ || EOF_CODE == specified
+ || EOF_VALUE_CODE == specified
+ || INIT_THROW_CODE == specified
+ || YYLEX_THROW_CODE == specified
+ || EOF_THROW_CODE == specified);
+ }
+
+ if (0 != CUtility.charncmp(m_input.m_line,
+ 0,
+ start_dir,
+ 0,
+ start_dir.length - 1))
+ {
+ CError.parse_error(CError.E_INTERNAL,0);
+ }
+
+ if (null == prev_code)
+ {
+ prev_code = new char[BUFFER_SIZE];
+ prev_read = 0;
+ }
+
+ if (prev_read >= prev_code.length)
+ {
+ prev_code = CUtility.doubleSize(prev_code);
+ }
+
+ m_input.m_line_index = start_dir.length - 1;
+ while (true)
+ {
+ while (m_input.m_line_index >= m_input.m_line_read)
+ {
+ if (m_input.getLine())
+ {
+ CError.parse_error(CError.E_EOF,m_input.m_line_number);
+ }
+
+ if (0 == CUtility.charncmp(m_input.m_line,
+ 0,
+ end_dir,
+ 0,
+ end_dir.length - 1))
+ {
+ m_input.m_line_index = end_dir.length - 1;
+
+ switch (specified)
+ {
+ case CLASS_CODE:
+ m_spec.m_class_read = prev_read;
+ break;
+
+ case INIT_CODE:
+ m_spec.m_init_read = prev_read;
+ break;
+
+ case EOF_CODE:
+ m_spec.m_eof_read = prev_read;
+ break;
+
+ case EOF_VALUE_CODE:
+ m_spec.m_eof_value_read = prev_read;
+ break;
+
+ case INIT_THROW_CODE:
+ m_spec.m_init_throw_read = prev_read;
+ break;
+
+ case YYLEX_THROW_CODE:
+ m_spec.m_yylex_throw_read = prev_read;
+ break;
+
+ case EOF_THROW_CODE:
+ m_spec.m_eof_throw_read = prev_read;
+ break;
+
+ default:
+ CError.parse_error(CError.E_INTERNAL,m_input.m_line_number);
+ break;
+ }
+
+ return prev_code;
+ }
+ }
+
+ while (m_input.m_line_index < m_input.m_line_read)
+ {
+ prev_code[prev_read] = m_input.m_line[m_input.m_line_index];
+ ++prev_read;
+ ++m_input.m_line_index;
+
+ if (prev_read >= prev_code.length)
+ {
+ prev_code = CUtility.doubleSize(prev_code);
+ }
+ }
+ }
+ }
+
+ /***************************************************************
+ Member Variables: JLex directives.
+ **************************************************************/
+ private char m_state_dir[] = {
+ '%', 's', 't',
+ 'a', 't', 'e',
+ '\0'
+ };
+
+ private char m_char_dir[] = {
+ '%', 'c', 'h',
+ 'a', 'r',
+ '\0'
+ };
+
+ private char m_line_dir[] = {
+ '%', 'l', 'i',
+ 'n', 'e',
+ '\0'
+ };
+
+ private char m_cup_dir[] = {
+ '%', 'c', 'u',
+ 'p',
+ '\0'
+ };
+
+ private char m_class_dir[] = {
+ '%', 'c', 'l',
+ 'a', 's', 's',
+ '\0'
+ };
+
+ private char m_implements_dir[] = {
+ '%', 'i', 'm', 'p', 'l', 'e', 'm', 'e', 'n', 't', 's',
+ '\0'
+ };
+
+ private char m_function_dir[] = {
+ '%', 'f', 'u',
+ 'n', 'c', 't',
+ 'i', 'o', 'n',
+ '\0'
+ };
+
+ private char m_type_dir[] = {
+ '%', 't', 'y',
+ 'p', 'e',
+ '\0'
+ };
+
+ private char m_integer_dir[] = {
+ '%', 'i', 'n',
+ 't', 'e', 'g',
+ 'e', 'r',
+ '\0'
+ };
+
+ private char m_intwrap_dir[] = {
+ '%', 'i', 'n',
+ 't', 'w', 'r',
+ 'a', 'p',
+ '\0'
+ };
+
+ private char m_full_dir[] = {
+ '%', 'f', 'u',
+ 'l', 'l',
+ '\0'
+ };
+
+ private char m_unicode_dir[] = {
+ '%', 'u', 'n',
+ 'i', 'c', 'o',
+ 'd', 'e',
+ '\0'
+ };
+
+ private char m_ignorecase_dir[] = {
+ '%', 'i', 'g',
+ 'n', 'o', 'r',
+ 'e', 'c', 'a',
+ 's', 'e',
+ '\0'
+ };
+
+ private char m_notunix_dir[] = {
+ '%', 'n', 'o',
+ 't', 'u', 'n',
+ 'i', 'x',
+ '\0'
+ };
+
+ private char m_init_code_dir[] = {
+ '%', 'i', 'n',
+ 'i', 't', '{',
+ '\0'
+ };
+
+ private char m_init_code_end_dir[] = {
+ '%', 'i', 'n',
+ 'i', 't', '}',
+ '\0'
+ };
+
+ private char m_init_throw_code_dir[] = {
+ '%', 'i', 'n',
+ 'i', 't', 't',
+ 'h', 'r', 'o',
+ 'w', '{',
+ '\0'
+ };
+
+ private char m_init_throw_code_end_dir[] = {
+ '%', 'i', 'n',
+ 'i', 't', 't',
+ 'h', 'r', 'o',
+ 'w', '}',
+ '\0'
+ };
+
+ private char m_yylex_throw_code_dir[] = {
+ '%', 'y', 'y', 'l',
+ 'e', 'x', 't',
+ 'h', 'r', 'o',
+ 'w', '{',
+ '\0'
+ };
+
+ private char m_yylex_throw_code_end_dir[] = {
+ '%', 'y', 'y', 'l',
+ 'e', 'x', 't',
+ 'h', 'r', 'o',
+ 'w', '}',
+ '\0'
+ };
+
+ private char m_eof_code_dir[] = {
+ '%', 'e', 'o',
+ 'f', '{',
+ '\0'
+ };
+
+ private char m_eof_code_end_dir[] = {
+ '%', 'e', 'o',
+ 'f', '}',
+ '\0'
+ };
+
+ private char m_eof_value_code_dir[] = {
+ '%', 'e', 'o',
+ 'f', 'v', 'a',
+ 'l', '{',
+ '\0'
+ };
+
+ private char m_eof_value_code_end_dir[] = {
+ '%', 'e', 'o',
+ 'f', 'v', 'a',
+ 'l', '}',
+ '\0'
+ };
+
+ private char m_eof_throw_code_dir[] = {
+ '%', 'e', 'o',
+ 'f', 't', 'h',
+ 'r', 'o', 'w',
+ '{',
+ '\0'
+ };
+
+ private char m_eof_throw_code_end_dir[] = {
+ '%', 'e', 'o',
+ 'f', 't', 'h',
+ 'r', 'o', 'w',
+ '}',
+ '\0'
+ };
+
+ private char m_class_code_dir[] = {
+ '%', '{',
+ '\0'
+ };
+
+ private char m_class_code_end_dir[] = {
+ '%', '}',
+ '\0'
+ };
+
+ private char m_yyeof_dir[] = {
+ '%', 'y', 'y',
+ 'e', 'o', 'f',
+ '\0'
+ };
+
+ private char m_public_dir[] = {
+ '%', 'p', 'u',
+ 'b', 'l', 'i',
+ 'c', '\0'
+ };
+
+ /***************************************************************
+ Function: userDeclare
+ Description:
+ **************************************************************/
+ private void userDeclare
+ (
+ )
+ throws java.io.IOException
+ {
+ int elem;
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != this);
+ CUtility.ASSERT(null != m_outstream);
+ CUtility.ASSERT(null != m_input);
+ CUtility.ASSERT(null != m_tokens);
+ CUtility.ASSERT(null != m_spec);
+ }
+
+ if (m_input.m_eof_reached)
+ {
+ /* End-of-file. */
+ CError.parse_error(CError.E_EOF,
+ m_input.m_line_number);
+ }
+
+ while (false == m_input.getLine())
+ {
+ /* Look for double percent. */
+ if (2 <= m_input.m_line_read
+ && '%' == m_input.m_line[0]
+ && '%' == m_input.m_line[1])
+ {
+ /* Mess around with line. */
+ m_input.m_line_read -= 2;
+ System.arraycopy(m_input.m_line, 2,
+ m_input.m_line, 0, m_input.m_line_read);
+
+ m_input.m_pushback_line = true;
+ /* Check for and discard empty line. */
+ if (0 == m_input.m_line_read
+ || '\n' == m_input.m_line[0])
+ {
+ m_input.m_pushback_line = false;
+ }
+
+ return;
+ }
+
+ if (0 == m_input.m_line_read)
+ {
+ continue;
+ }
+
+ if ('%' == m_input.m_line[0])
+ {
+ /* Special lex declarations. */
+ if (1 >= m_input.m_line_read)
+ {
+ CError.parse_error(CError.E_DIRECT,
+ m_input.m_line_number);
+ continue;
+ }
+
+ switch (m_input.m_line[1])
+ {
+ case '{':
+ if (0 == CUtility.charncmp(m_input.m_line,
+ 0,
+ m_class_code_dir,
+ 0,
+ m_class_code_dir.length - 1))
+ {
+ m_spec.m_class_code = packCode(m_class_code_dir,
+ m_class_code_end_dir,
+ m_spec.m_class_code,
+ m_spec.m_class_read,
+ CLASS_CODE);
+ break;
+ }
+
+ /* Bad directive. */
+ CError.parse_error(CError.E_DIRECT,
+ m_input.m_line_number);
+ break;
+
+ case 'c':
+ if (0 == CUtility.charncmp(m_input.m_line,
+ 0,
+ m_char_dir,
+ 0,
+ m_char_dir.length - 1))
+ {
+ /* Set line counting to ON. */
+ m_input.m_line_index = m_char_dir.length;
+ m_spec.m_count_chars = true;
+ break;
+ }
+ else if (0 == CUtility.charncmp(m_input.m_line,
+ 0,
+ m_class_dir,
+ 0,
+ m_class_dir.length - 1))
+ {
+ m_input.m_line_index = m_class_dir.length;
+ m_spec.m_class_name = getName();
+ break;
+ }
+ else if (0 == CUtility.charncmp(m_input.m_line,
+ 0,
+ m_cup_dir,
+ 0,
+ m_cup_dir.length - 1))
+ {
+ /* Set Java CUP compatibility to ON. */
+ m_input.m_line_index = m_cup_dir.length;
+ m_spec.m_cup_compatible = true;
+ // this is what %cup does: [CSA, 27-Jul-1999]
+ m_spec.m_implements_name =
+ "java_cup.runtime.Scanner".toCharArray();
+ m_spec.m_function_name =
+ "next_token".toCharArray();
+ m_spec.m_type_name =
+ "java_cup.runtime.Symbol".toCharArray();
+ break;
+ }
+
+ /* Bad directive. */
+ CError.parse_error(CError.E_DIRECT,
+ m_input.m_line_number);
+ break;
+
+ case 'e':
+ if (0 == CUtility.charncmp(m_input.m_line,
+ 0,
+ m_eof_code_dir,
+ 0,
+ m_eof_code_dir.length - 1))
+ {
+ m_spec.m_eof_code = packCode(m_eof_code_dir,
+ m_eof_code_end_dir,
+ m_spec.m_eof_code,
+ m_spec.m_eof_read,
+ EOF_CODE);
+ break;
+ }
+ else if (0 == CUtility.charncmp(m_input.m_line,
+ 0,
+ m_eof_value_code_dir,
+ 0,
+ m_eof_value_code_dir.length - 1))
+ {
+ m_spec.m_eof_value_code = packCode(m_eof_value_code_dir,
+ m_eof_value_code_end_dir,
+ m_spec.m_eof_value_code,
+ m_spec.m_eof_value_read,
+ EOF_VALUE_CODE);
+ break;
+ }
+ else if (0 == CUtility.charncmp(m_input.m_line,
+ 0,
+ m_eof_throw_code_dir,
+ 0,
+ m_eof_throw_code_dir.length - 1))
+ {
+ m_spec.m_eof_throw_code = packCode(m_eof_throw_code_dir,
+ m_eof_throw_code_end_dir,
+ m_spec.m_eof_throw_code,
+ m_spec.m_eof_throw_read,
+ EOF_THROW_CODE);
+ break;
+ }
+
+ /* Bad directive. */
+ CError.parse_error(CError.E_DIRECT,
+ m_input.m_line_number);
+ break;
+
+ case 'f':
+ if (0 == CUtility.charncmp(m_input.m_line,
+ 0,
+ m_function_dir,
+ 0,
+ m_function_dir.length - 1))
+ {
+ /* Set line counting to ON. */
+ m_input.m_line_index = m_function_dir.length;
+ m_spec.m_function_name = getName();
+ break;
+ }
+ else if (0 == CUtility.charncmp(m_input.m_line,
+ 0,
+ m_full_dir,
+ 0,
+ m_full_dir.length - 1))
+ {
+ m_input.m_line_index = m_full_dir.length;
+ m_spec.m_dtrans_ncols = CUtility.MAX_EIGHT_BIT + 1;
+ break;
+ }
+
+ /* Bad directive. */
+ CError.parse_error(CError.E_DIRECT,
+ m_input.m_line_number);
+ break;
+
+ case 'i':
+ if (0 == CUtility.charncmp(m_input.m_line,
+ 0,
+ m_integer_dir,
+ 0,
+ m_integer_dir.length - 1))
+ {
+ /* Set line counting to ON. */
+ m_input.m_line_index = m_integer_dir.length;
+ m_spec.m_integer_type = true;
+ break;
+ }
+ else if (0 == CUtility.charncmp(m_input.m_line,
+ 0,
+ m_intwrap_dir,
+ 0,
+ m_intwrap_dir.length - 1))
+ {
+ /* Set line counting to ON. */
+ m_input.m_line_index = m_integer_dir.length;
+ m_spec.m_intwrap_type = true;
+ break;
+ }
+ else if (0 == CUtility.charncmp(m_input.m_line,
+ 0,
+ m_init_code_dir,
+ 0,
+ m_init_code_dir.length - 1))
+ {
+ m_spec.m_init_code = packCode(m_init_code_dir,
+ m_init_code_end_dir,
+ m_spec.m_init_code,
+ m_spec.m_init_read,
+ INIT_CODE);
+ break;
+ }
+ else if (0 == CUtility.charncmp(m_input.m_line,
+ 0,
+ m_init_throw_code_dir,
+ 0,
+ m_init_throw_code_dir.length - 1))
+ {
+ m_spec.m_init_throw_code = packCode(m_init_throw_code_dir,
+ m_init_throw_code_end_dir,
+ m_spec.m_init_throw_code,
+ m_spec.m_init_throw_read,
+ INIT_THROW_CODE);
+ break;
+ }
+ else if (0 == CUtility.charncmp(m_input.m_line,
+ 0,
+ m_implements_dir,
+ 0,
+ m_implements_dir.length - 1))
+ {
+ m_input.m_line_index = m_implements_dir.length;
+ m_spec.m_implements_name = getName();
+ break;
+ }
+ else if (0 == CUtility.charncmp(m_input.m_line,
+ 0,
+ m_ignorecase_dir,
+ 0,
+ m_ignorecase_dir.length-1))
+ {
+ /* Set m_ignorecase to ON. */
+ m_input.m_line_index = m_ignorecase_dir.length;
+ m_spec.m_ignorecase = true;
+ break;
+ }
+
+ /* Bad directive. */
+ CError.parse_error(CError.E_DIRECT,
+ m_input.m_line_number);
+ break;
+
+ case 'l':
+ if (0 == CUtility.charncmp(m_input.m_line,
+ 0,
+ m_line_dir,
+ 0,
+ m_line_dir.length - 1))
+ {
+ /* Set line counting to ON. */
+ m_input.m_line_index = m_line_dir.length;
+ m_spec.m_count_lines = true;
+ break;
+ }
+
+ /* Bad directive. */
+ CError.parse_error(CError.E_DIRECT,
+ m_input.m_line_number);
+ break;
+
+ case 'n':
+ if (0 == CUtility.charncmp(m_input.m_line,
+ 0,
+ m_notunix_dir,
+ 0,
+ m_notunix_dir.length - 1))
+ {
+ /* Set line counting to ON. */
+ m_input.m_line_index = m_notunix_dir.length;
+ m_spec.m_unix = false;
+ break;
+ }
+
+ /* Bad directive. */
+ CError.parse_error(CError.E_DIRECT,
+ m_input.m_line_number);
+ break;
+
+ case 'p':
+ if (0 == CUtility.charncmp(m_input.m_line,
+ 0,
+ m_public_dir,
+ 0,
+ m_public_dir.length - 1))
+ {
+ /* Set public flag. */
+ m_input.m_line_index = m_public_dir.length;
+ m_spec.m_public = true;
+ break;
+ }
+
+ /* Bad directive. */
+ CError.parse_error(CError.E_DIRECT,
+ m_input.m_line_number);
+ break;
+
+ case 's':
+ if (0 == CUtility.charncmp(m_input.m_line,
+ 0,
+ m_state_dir,
+ 0,
+ m_state_dir.length - 1))
+ {
+ /* Recognize state list. */
+ m_input.m_line_index = m_state_dir.length;
+ saveStates();
+ break;
+ }
+
+ /* Undefined directive. */
+ CError.parse_error(CError.E_DIRECT,
+ m_input.m_line_number);
+ break;
+
+ case 't':
+ if (0 == CUtility.charncmp(m_input.m_line,
+ 0,
+ m_type_dir,
+ 0,
+ m_type_dir.length - 1))
+ {
+ /* Set Java CUP compatibility to ON. */
+ m_input.m_line_index = m_type_dir.length;
+ m_spec.m_type_name = getName();
+ break;
+ }
+
+ /* Undefined directive. */
+ CError.parse_error(CError.E_DIRECT,
+ m_input.m_line_number);
+ break;
+
+ case 'u':
+ if (0 == CUtility.charncmp(m_input.m_line,
+ 0,
+ m_unicode_dir,
+ 0,
+ m_unicode_dir.length - 1))
+ {
+ m_input.m_line_index = m_unicode_dir.length;
+ m_spec.m_dtrans_ncols= CUtility.MAX_SIXTEEN_BIT + 1;
+ break;
+ }
+
+ /* Bad directive. */
+ CError.parse_error(CError.E_DIRECT,
+ m_input.m_line_number);
+ break;
+
+ case 'y':
+ if (0 == CUtility.charncmp(m_input.m_line,
+ 0,
+ m_yyeof_dir,
+ 0,
+ m_yyeof_dir.length - 1))
+ {
+ m_input.m_line_index = m_yyeof_dir.length;
+ m_spec.m_yyeof = true;
+ break;
+ } else if (0 == CUtility.charncmp(m_input.m_line,
+ 0,
+ m_yylex_throw_code_dir,
+ 0,
+ m_yylex_throw_code_dir.length - 1))
+ {
+ m_spec.m_yylex_throw_code = packCode(m_yylex_throw_code_dir,
+ m_yylex_throw_code_end_dir,
+ m_spec.m_yylex_throw_code,
+ m_spec.m_yylex_throw_read,
+ YYLEX_THROW_CODE);
+ break;
+ }
+
+
+ /* Bad directive. */
+ CError.parse_error(CError.E_DIRECT,
+ m_input.m_line_number);
+ break;
+
+ default:
+ /* Undefined directive. */
+ CError.parse_error(CError.E_DIRECT,
+ m_input.m_line_number);
+ break;
+ }
+ }
+ else
+ {
+ /* Regular expression macro. */
+ m_input.m_line_index = 0;
+ saveMacro();
+ }
+
+ if (CUtility.OLD_DEBUG)
+ {
+ System.out.println("Line number "
+ + m_input.m_line_number + ":");
+ System.out.print(new String(m_input.m_line,
+ 0,m_input.m_line_read));
+ }
+ }
+ }
+
+ /***************************************************************
+ Function: userRules
+ Description: Processes third section of JLex
+ specification and creates minimized transition table.
+ **************************************************************/
+ private void userRules
+ (
+ )
+ throws java.io.IOException
+ {
+ int code;
+
+ if (false == m_init_flag)
+ {
+ CError.parse_error(CError.E_INIT,0);
+ }
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != this);
+ CUtility.ASSERT(null != m_outstream);
+ CUtility.ASSERT(null != m_input);
+ CUtility.ASSERT(null != m_tokens);
+ CUtility.ASSERT(null != m_spec);
+ }
+
+ /* UNDONE: Need to handle states preceding rules. */
+
+ if (m_spec.m_verbose)
+ {
+ System.out.println("Creating NFA machine representation.");
+ }
+ m_makeNfa.allocate_BOL_EOF(m_spec);
+ m_makeNfa.thompson(this,m_spec,m_input);
+
+ m_simplifyNfa.simplify(m_spec);
+
+ /*print_nfa();*/
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(END_OF_INPUT == m_spec.m_current_token);
+ }
+
+ if (m_spec.m_verbose)
+ {
+ System.out.println("Creating DFA transition table.");
+ }
+ m_nfa2dfa.make_dfa(this,m_spec);
+
+ if (CUtility.FOODEBUG) {
+ print_header();
+ }
+
+ if (m_spec.m_verbose)
+ {
+ System.out.println("Minimizing DFA transition table.");
+ }
+ m_minimize.min_dfa(m_spec);
+ }
+
+ /***************************************************************
+ Function: printccl
+ Description: Debugging routine that outputs readable form
+ of character class.
+ **************************************************************/
+ private void printccl
+ (
+ CSet set
+ )
+ {
+ int i;
+
+ System.out.print(" [");
+ for (i = 0; i < m_spec.m_dtrans_ncols; ++i)
+ {
+ if (set.contains(i))
+ {
+ System.out.print(interp_int(i));
+ }
+ }
+ System.out.print(']');
+ }
+
+ /***************************************************************
+ Function: plab
+ Description:
+ **************************************************************/
+ private String plab
+ (
+ CNfa state
+ )
+ {
+ int index;
+
+ if (null == state)
+ {
+ return (new String("--"));
+ }
+
+ index = m_spec.m_nfa_states.indexOf(state);
+
+ return ((new Integer(index)).toString());
+ }
+
+ /***************************************************************
+ Function: interp_int
+ Description:
+ **************************************************************/
+ private String interp_int
+ (
+ int i
+ )
+ {
+ switch (i)
+ {
+ case (int) '\b':
+ return (new String("\\b"));
+
+ case (int) '\t':
+ return (new String("\\t"));
+
+ case (int) '\n':
+ return (new String("\\n"));
+
+ case (int) '\f':
+ return (new String("\\f"));
+
+ case (int) '\r':
+ return (new String("\\r"));
+
+ case (int) ' ':
+ return (new String("\\ "));
+
+ default:
+ return ((new Character((char) i)).toString());
+ }
+ }
+
+ /***************************************************************
+ Function: print_nfa
+ Description:
+ **************************************************************/
+ void print_nfa
+ (
+ )
+ {
+ int elem;
+ CNfa nfa;
+ int size;
+ Enumeration states;
+ Integer index;
+ int i;
+ int j;
+ int vsize;
+ String state;
+
+ System.out.println("--------------------- NFA -----------------------");
+
+ size = m_spec.m_nfa_states.size();
+ for (elem = 0; elem < size; ++elem)
+ {
+ nfa = (CNfa) m_spec.m_nfa_states.elementAt(elem);
+
+ System.out.print("Nfa state " + plab(nfa) + ": ");
+
+ if (null == nfa.m_next)
+ {
+ System.out.print("(TERMINAL)");
+ }
+ else
+ {
+ System.out.print("--> " + plab(nfa.m_next));
+ System.out.print("--> " + plab(nfa.m_next2));
+
+ switch (nfa.m_edge)
+ {
+ case CNfa.CCL:
+ printccl(nfa.m_set);
+ break;
+
+ case CNfa.EPSILON:
+ System.out.print(" EPSILON ");
+ break;
+
+ default:
+ System.out.print(" " + interp_int(nfa.m_edge));
+ break;
+ }
+ }
+
+ if (0 == elem)
+ {
+ System.out.print(" (START STATE)");
+ }
+
+ if (null != nfa.m_accept)
+ {
+ System.out.print(" accepting "
+ + ((0 != (nfa.m_anchor & CSpec.START)) ? "^" : "")
+ + "<"
+ + (new String(nfa.m_accept.m_action,0,
+ nfa.m_accept.m_action_read))
+ + ">"
+ + ((0 != (nfa.m_anchor & CSpec.END)) ? "$" : ""));
+ }
+
+ System.out.println();
+ }
+
+ states = m_spec.m_states.keys();
+ while (states.hasMoreElements())
+ {
+ state = (String) states.nextElement();
+ index = (Integer) m_spec.m_states.get(state);
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != state);
+ CUtility.ASSERT(null != index);
+ }
+
+ System.out.println("State \"" + state
+ + "\" has identifying index "
+ + index.toString() + ".");
+ System.out.print("\tStart states of matching rules: ");
+
+ i = index.intValue();
+ vsize = m_spec.m_state_rules[i].size();
+
+ for (j = 0; j < vsize; ++j)
+ {
+ nfa = (CNfa) m_spec.m_state_rules[i].elementAt(j);
+
+ System.out.print(m_spec.m_nfa_states.indexOf(nfa) + " ");
+ }
+
+ System.out.println();
+ }
+
+ System.out.println("-------------------- NFA ----------------------");
+ }
+
+ /***************************************************************
+ Function: getStates
+ Description: Parses the state area of a rule,
+ from the beginning of a line.
+ < state1, state2 ... > regular_expression { action }
+ Returns null on only EOF. Returns all_states,
+ initialied properly to correspond to all states,
+ if no states are found.
+ Special Notes: This function treats commas as optional
+ and permits states to be spread over multiple lines.
+ **************************************************************/
+ private SparseBitSet all_states = null;
+ SparseBitSet getStates
+ (
+ )
+ throws java.io.IOException
+ {
+ int start_state;
+ int count_state;
+ SparseBitSet states;
+ String name;
+ Integer index;
+ int i;
+ int size;
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != this);
+ CUtility.ASSERT(null != m_outstream);
+ CUtility.ASSERT(null != m_input);
+ CUtility.ASSERT(null != m_tokens);
+ CUtility.ASSERT(null != m_spec);
+ }
+
+ states = null;
+
+ /* Skip white space. */
+ while (CUtility.isspace(m_input.m_line[m_input.m_line_index]))
+ {
+ ++m_input.m_line_index;
+
+ while (m_input.m_line_index >= m_input.m_line_read)
+ {
+ /* Must just be an empty line. */
+ if (m_input.getLine())
+ {
+ /* EOF found. */
+ return null;
+ }
+ }
+ }
+
+ /* Look for states. */
+ if ('<' == m_input.m_line[m_input.m_line_index])
+ {
+ ++m_input.m_line_index;
+
+ states = new SparseBitSet();
+
+ /* Parse states. */
+ while (true)
+ {
+ /* We may have reached the end of the line. */
+ while (m_input.m_line_index >= m_input.m_line_read)
+ {
+ if (m_input.getLine())
+ {
+ /* EOF found. */
+ CError.parse_error(CError.E_EOF,m_input.m_line_number);
+ return states;
+ }
+ }
+
+ while (true)
+ {
+ /* Skip white space. */
+ while (CUtility.isspace(m_input.m_line[m_input.m_line_index]))
+ {
+ ++m_input.m_line_index;
+
+ while (m_input.m_line_index >= m_input.m_line_read)
+ {
+ if (m_input.getLine())
+ {
+ /* EOF found. */
+ CError.parse_error(CError.E_EOF,m_input.m_line_number);
+ return states;
+ }
+ }
+ }
+
+ if (',' != m_input.m_line[m_input.m_line_index])
+ {
+ break;
+ }
+
+ ++m_input.m_line_index;
+ }
+
+ if ('>' == m_input.m_line[m_input.m_line_index])
+ {
+ ++m_input.m_line_index;
+ if (m_input.m_line_index < m_input.m_line_read)
+ {
+ m_advance_stop = true;
+ }
+ return states;
+ }
+
+ /* Read in state name. */
+ start_state = m_input.m_line_index;
+ while (false == CUtility.isspace(m_input.m_line[m_input.m_line_index])
+ && ',' != m_input.m_line[m_input.m_line_index]
+ && '>' != m_input.m_line[m_input.m_line_index])
+ {
+ ++m_input.m_line_index;
+
+ if (m_input.m_line_index >= m_input.m_line_read)
+ {
+ /* End of line means end of state name. */
+ break;
+ }
+ }
+ count_state = m_input.m_line_index - start_state;
+
+ /* Save name after checking definition. */
+ name = new String(m_input.m_line,
+ start_state,
+ count_state);
+ index = (Integer) m_spec.m_states.get(name);
+ if (null == index)
+ {
+ /* Uninitialized state. */
+ System.out.println("Uninitialized State Name: " + name);
+ CError.parse_error(CError.E_STATE,m_input.m_line_number);
+ }
+ states.set(index.intValue());
+ }
+ }
+
+ if (null == all_states)
+ {
+ all_states = new SparseBitSet();
+
+ size = m_spec.m_states.size();
+ for (i = 0; i < size; ++i)
+ {
+ all_states.set(i);
+ }
+ }
+
+ if (m_input.m_line_index < m_input.m_line_read)
+ {
+ m_advance_stop = true;
+ }
+ return all_states;
+ }
+
+ /********************************************************
+ Function: expandMacro
+ Description: Returns false on error, true otherwise.
+ *******************************************************/
+ private boolean expandMacro
+ (
+ )
+ {
+ int elem;
+ int start_macro;
+ int end_macro;
+ int start_name;
+ int count_name;
+ String def;
+ int def_elem;
+ String name;
+ char replace[];
+ int rep_elem;
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != this);
+ CUtility.ASSERT(null != m_outstream);
+ CUtility.ASSERT(null != m_input);
+ CUtility.ASSERT(null != m_tokens);
+ CUtility.ASSERT(null != m_spec);
+ }
+
+ /* Check for macro. */
+ if ('{' != m_input.m_line[m_input.m_line_index])
+ {
+ CError.parse_error(CError.E_INTERNAL,m_input.m_line_number);
+ return ERROR;
+ }
+
+ start_macro = m_input.m_line_index;
+ elem = m_input.m_line_index + 1;
+ if (elem >= m_input.m_line_read)
+ {
+ CError.impos("Unfinished macro name");
+ return ERROR;
+ }
+
+ /* Get macro name. */
+ start_name = elem;
+ while ('}' != m_input.m_line[elem])
+ {
+ ++elem;
+ if (elem >= m_input.m_line_read)
+ {
+ CError.impos("Unfinished macro name at line "
+ + m_input.m_line_number);
+ return ERROR;
+ }
+ }
+ count_name = elem - start_name;
+ end_macro = elem;
+
+ /* Check macro name. */
+ if (0 == count_name)
+ {
+ CError.impos("Nonexistent macro name");
+ return ERROR;
+ }
+
+ /* Debug checks. */
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(0 < count_name);
+ }
+
+ /* Retrieve macro definition. */
+ name = new String(m_input.m_line,start_name,count_name);
+ def = (String) m_spec.m_macros.get(name);
+ if (null == def)
+ {
+ /*CError.impos("Undefined macro \"" + name + "\".");*/
+ System.out.println("Error: Undefined macro \"" + name + "\".");
+ CError.parse_error(CError.E_NOMAC, m_input.m_line_number);
+ return ERROR;
+ }
+ if (CUtility.OLD_DUMP_DEBUG)
+ {
+ System.out.println("expanded escape: " + def);
+ }
+
+ /* Replace macro in new buffer,
+ beginning by copying first part of line buffer. */
+ replace = new char[m_input.m_line.length];
+ for (rep_elem = 0; rep_elem < start_macro; ++rep_elem)
+ {
+ replace[rep_elem] = m_input.m_line[rep_elem];
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(rep_elem < replace.length);
+ }
+ }
+
+ /* Copy macro definition. */
+ if (rep_elem >= replace.length)
+ {
+ replace = CUtility.doubleSize(replace);
+ }
+ for (def_elem = 0; def_elem < def.length(); ++def_elem)
+ {
+ replace[rep_elem] = def.charAt(def_elem);
+
+ ++rep_elem;
+ if (rep_elem >= replace.length)
+ {
+ replace = CUtility.doubleSize(replace);
+ }
+ }
+
+ /* Copy last part of line. */
+ if (rep_elem >= replace.length)
+ {
+ replace = CUtility.doubleSize(replace);
+ }
+ for (elem = end_macro + 1; elem < m_input.m_line_read; ++elem)
+ {
+ replace[rep_elem] = m_input.m_line[elem];
+
+ ++rep_elem;
+ if (rep_elem >= replace.length)
+ {
+ replace = CUtility.doubleSize(replace);
+ }
+ }
+
+ /* Replace buffer. */
+ m_input.m_line = replace;
+ m_input.m_line_read = rep_elem;
+
+ if (CUtility.OLD_DEBUG)
+ {
+ System.out.println(new String(m_input.m_line,0,m_input.m_line_read));
+ }
+ return NOT_ERROR;
+ }
+
+ /***************************************************************
+ Function: saveMacro
+ Description: Saves macro definition of form:
+ macro_name = macro_definition
+ **************************************************************/
+ private void saveMacro
+ (
+ )
+ {
+ int elem;
+ int start_name;
+ int count_name;
+ int start_def;
+ int count_def;
+ boolean saw_escape;
+ boolean in_quote;
+ boolean in_ccl;
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != this);
+ CUtility.ASSERT(null != m_outstream);
+ CUtility.ASSERT(null != m_input);
+ CUtility.ASSERT(null != m_tokens);
+ CUtility.ASSERT(null != m_spec);
+ }
+
+ /* Macro declarations are of the following form:
+ macro_name macro_definition */
+
+ elem = 0;
+
+ /* Skip white space preceding macro name. */
+ while (CUtility.isspace(m_input.m_line[elem]))
+ {
+ ++elem;
+ if (elem >= m_input.m_line_read)
+ {
+ /* End of line has been reached,
+ and line was found to be empty. */
+ return;
+ }
+ }
+
+ /* Read macro name. */
+ start_name = elem;
+ while (false == CUtility.isspace(m_input.m_line[elem])
+ && '=' != m_input.m_line[elem])
+ {
+ ++elem;
+ if (elem >= m_input.m_line_read)
+ {
+ /* Macro name but no associated definition. */
+ CError.parse_error(CError.E_MACDEF,m_input.m_line_number);
+ }
+ }
+ count_name = elem - start_name;
+
+ /* Check macro name. */
+ if (0 == count_name)
+ {
+ /* Nonexistent macro name. */
+ CError.parse_error(CError.E_MACDEF,m_input.m_line_number);
+ }
+
+ /* Skip white space between name and definition. */
+ while (CUtility.isspace(m_input.m_line[elem]))
+ {
+ ++elem;
+ if (elem >= m_input.m_line_read)
+ {
+ /* Macro name but no associated definition. */
+ CError.parse_error(CError.E_MACDEF,m_input.m_line_number);
+ }
+ }
+
+ if ('=' == m_input.m_line[elem])
+ {
+ ++elem;
+ if (elem >= m_input.m_line_read)
+ {
+ /* Macro name but no associated definition. */
+ CError.parse_error(CError.E_MACDEF,m_input.m_line_number);
+ }
+ }
+ else /* macro definition without = */
+ CError.parse_error(CError.E_MACDEF,m_input.m_line_number);
+
+ /* Skip white space between name and definition. */
+ while (CUtility.isspace(m_input.m_line[elem]))
+ {
+ ++elem;
+ if (elem >= m_input.m_line_read)
+ {
+ /* Macro name but no associated definition. */
+ CError.parse_error(CError.E_MACDEF,m_input.m_line_number);
+ }
+ }
+
+ /* Read macro definition. */
+ start_def = elem;
+ in_quote = false;
+ in_ccl = false;
+ saw_escape = false;
+ while (false == CUtility.isspace(m_input.m_line[elem])
+ || true == in_quote
+ || true == in_ccl
+ || true == saw_escape)
+ {
+ if ('\"' == m_input.m_line[elem] && false == saw_escape)
+ {
+ in_quote = !in_quote;
+ }
+
+ if ('\\' == m_input.m_line[elem] && false == saw_escape)
+ {
+ saw_escape = true;
+ }
+ else
+ {
+ saw_escape = false;
+ }
+ if (false == saw_escape && false == in_quote) { // CSA, 24-jul-99
+ if ('[' == m_input.m_line[elem] && false == in_ccl)
+ in_ccl = true;
+ if (']' == m_input.m_line[elem] && true == in_ccl)
+ in_ccl = false;
+ }
+
+ ++elem;
+ if (elem >= m_input.m_line_read)
+ {
+ /* End of line. */
+ break;
+ }
+ }
+ count_def = elem - start_def;
+
+ /* Check macro definition. */
+ if (0 == count_def)
+ {
+ /* Nonexistent macro name. */
+ CError.parse_error(CError.E_MACDEF,m_input.m_line_number);
+ }
+
+ /* Debug checks. */
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(0 < count_def);
+ CUtility.ASSERT(0 < count_name);
+ CUtility.ASSERT(null != m_spec.m_macros);
+ }
+
+ if (CUtility.OLD_DEBUG)
+ {
+ System.out.println("macro name \""
+ + new String(m_input.m_line,start_name,count_name)
+ + "\".");
+ System.out.println("macro definition \""
+ + new String(m_input.m_line,start_def,count_def)
+ + "\".");
+ }
+
+ /* Add macro name and definition to table. */
+ m_spec.m_macros.put(new String(m_input.m_line,start_name,count_name),
+ new String(m_input.m_line,start_def,count_def));
+ }
+
+ /***************************************************************
+ Function: saveStates
+ Description: Takes state declaration and makes entries
+ for them in state hashtable in CSpec structure.
+ State declaration should be of the form:
+ %state name0[, name1, name2 ...]
+ (But commas are actually optional as long as there is
+ white space in between them.)
+ **************************************************************/
+ private void saveStates
+ (
+ )
+ {
+ int start_state;
+ int count_state;
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != this);
+ CUtility.ASSERT(null != m_outstream);
+ CUtility.ASSERT(null != m_input);
+ CUtility.ASSERT(null != m_tokens);
+ CUtility.ASSERT(null != m_spec);
+ }
+
+ /* EOF found? */
+ if (m_input.m_eof_reached)
+ {
+ return;
+ }
+
+ /* Debug checks. */
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT('%' == m_input.m_line[0]);
+ CUtility.ASSERT('s' == m_input.m_line[1]);
+ CUtility.ASSERT(m_input.m_line_index <= m_input.m_line_read);
+ CUtility.ASSERT(0 <= m_input.m_line_index);
+ CUtility.ASSERT(0 <= m_input.m_line_read);
+ }
+
+ /* Blank line? No states? */
+ if (m_input.m_line_index >= m_input.m_line_read)
+ {
+ return;
+ }
+
+ while (m_input.m_line_index < m_input.m_line_read)
+ {
+ if (CUtility.OLD_DEBUG)
+ {
+ System.out.println("line read " + m_input.m_line_read
+ + "\tline index = " + m_input.m_line_index);
+ }
+
+ /* Skip white space. */
+ while (CUtility.isspace(m_input.m_line[m_input.m_line_index]))
+ {
+ ++m_input.m_line_index;
+ if (m_input.m_line_index >= m_input.m_line_read)
+ {
+ /* No more states to be found. */
+ return;
+ }
+ }
+
+ /* Look for state name. */
+ start_state = m_input.m_line_index;
+ while (false == CUtility.isspace(m_input.m_line[m_input.m_line_index])
+ && ',' != m_input.m_line[m_input.m_line_index])
+ {
+ ++m_input.m_line_index;
+ if (m_input.m_line_index >= m_input.m_line_read)
+ {
+ /* End of line and end of state name. */
+ break;
+ }
+ }
+ count_state = m_input.m_line_index - start_state;
+
+ if (CUtility.OLD_DEBUG)
+ {
+ System.out.println("State name \""
+ + new String(m_input.m_line,start_state,count_state)
+ + "\".");
+ System.out.println("Integer index \""
+ + m_spec.m_states.size()
+ + "\".");
+ }
+
+ /* Enter new state name, along with unique index. */
+ m_spec.m_states.put(new String(m_input.m_line,start_state,count_state),
+ new Integer(m_spec.m_states.size()));
+
+ /* Skip comma. */
+ if (',' == m_input.m_line[m_input.m_line_index])
+ {
+ ++m_input.m_line_index;
+ if (m_input.m_line_index >= m_input.m_line_read)
+ {
+ /* End of line. */
+ return;
+ }
+ }
+ }
+ }
+
+ /********************************************************
+ Function: expandEscape
+ Description: Takes escape sequence and returns
+ corresponding character code.
+ *******************************************************/
+ private char expandEscape
+ (
+ )
+ {
+ char r;
+
+ /* Debug checks. */
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(m_input.m_line_index < m_input.m_line_read);
+ CUtility.ASSERT(0 < m_input.m_line_read);
+ CUtility.ASSERT(0 <= m_input.m_line_index);
+ }
+
+ if ('\\' != m_input.m_line[m_input.m_line_index])
+ {
+ ++m_input.m_line_index;
+ return m_input.m_line[m_input.m_line_index - 1];
+ }
+ else
+ {
+ boolean unicode_escape = false;
+ ++m_input.m_line_index;
+ switch (m_input.m_line[m_input.m_line_index])
+ {
+ case 'b':
+ ++m_input.m_line_index;
+ return '\b';
+
+ case 't':
+ ++m_input.m_line_index;
+ return '\t';
+
+ case 'n':
+ ++m_input.m_line_index;
+ return '\n';
+
+ case 'f':
+ ++m_input.m_line_index;
+ return '\f';
+
+ case 'r':
+ ++m_input.m_line_index;
+ return '\r';
+
+ case '^':
+ ++m_input.m_line_index;
+ r=Character.toUpperCase(m_input.m_line[m_input.m_line_index]);
+ if (r<'@' || r>'Z') // non-fatal
+ CError.parse_error(CError.E_BADCTRL,m_input.m_line_number);
+ r = (char) (r - '@');
+ ++m_input.m_line_index;
+ return r;
+
+ case 'u':
+ unicode_escape = true;
+ case 'x':
+ ++m_input.m_line_index;
+ r = 0;
+ for (int i=0; i<(unicode_escape?4:2); i++)
+ if (CUtility.ishexdigit(m_input.m_line[m_input.m_line_index]))
+ {
+ r = (char) (r << 4);
+ r = (char) (r | CUtility.hex2bin(m_input.m_line[m_input.m_line_index]));
+ ++m_input.m_line_index;
+ }
+ else break;
+
+ return r;
+
+ default:
+ if (false == CUtility.isoctdigit(m_input.m_line[m_input.m_line_index]))
+ {
+ r = m_input.m_line[m_input.m_line_index];
+ ++m_input.m_line_index;
+ }
+ else
+ {
+ r = 0;
+ for (int i=0; i<3; i++)
+ if (CUtility.isoctdigit(m_input.m_line[m_input.m_line_index]))
+ {
+ r = (char) (r << 3);
+ r = (char) (r | CUtility.oct2bin(m_input.m_line[m_input.m_line_index]));
+ ++m_input.m_line_index;
+ }
+ else break;
+ }
+ return r;
+ }
+ }
+ }
+
+ /********************************************************
+ Function: packAccept
+ Description: Packages and returns CAccept
+ for action next in input stream.
+ *******************************************************/
+ CAccept packAccept
+ (
+ )
+ throws java.io.IOException
+ {
+ CAccept accept;
+ char action[];
+ int action_index;
+ int brackets;
+ boolean insinglequotes;
+ boolean indoublequotes;
+ boolean instarcomment;
+ boolean inslashcomment;
+ boolean escaped;
+ boolean slashed;
+
+ action = new char[BUFFER_SIZE];
+ action_index = 0;
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != this);
+ CUtility.ASSERT(null != m_outstream);
+ CUtility.ASSERT(null != m_input);
+ CUtility.ASSERT(null != m_tokens);
+ CUtility.ASSERT(null != m_spec);
+ }
+
+ /* Get a new line, if needed. */
+ while (m_input.m_line_index >= m_input.m_line_read)
+ {
+ if (m_input.getLine())
+ {
+ CError.parse_error(CError.E_EOF,m_input.m_line_number);
+ return null;
+ }
+ }
+
+ /* Look for beginning of action. */
+ while (CUtility.isspace(m_input.m_line[m_input.m_line_index]))
+ {
+ ++m_input.m_line_index;
+
+ /* Get a new line, if needed. */
+ while (m_input.m_line_index >= m_input.m_line_read)
+ {
+ if (m_input.getLine())
+ {
+ CError.parse_error(CError.E_EOF,m_input.m_line_number);
+ return null;
+ }
+ }
+ }
+
+ /* Look for brackets. */
+ if ('{' != m_input.m_line[m_input.m_line_index])
+ {
+ CError.parse_error(CError.E_BRACE,m_input.m_line_number);
+ }
+
+ /* Copy new line into action buffer. */
+ brackets = 0;
+ insinglequotes = indoublequotes = inslashcomment = instarcomment =
+ escaped = slashed = false;
+ while (true)
+ {
+ action[action_index] = m_input.m_line[m_input.m_line_index];
+
+ /* Look for quotes. */
+ if ((insinglequotes || indoublequotes) && escaped)
+ escaped=false; // only protects one char, but this is enough.
+ else if ((insinglequotes || indoublequotes) &&
+ '\\' == m_input.m_line[m_input.m_line_index])
+ escaped=true;
+ else if (!(insinglequotes || inslashcomment || instarcomment) &&
+ '\"' == m_input.m_line[m_input.m_line_index])
+ indoublequotes=!indoublequotes; // unescaped double quote.
+ else if (!(indoublequotes || inslashcomment || instarcomment) &&
+ '\'' == m_input.m_line[m_input.m_line_index])
+ insinglequotes=!insinglequotes; // unescaped single quote.
+ /* Look for comments. */
+ if (instarcomment) { // inside "/*" comment; look for "*/"
+ if (slashed && '/' == m_input.m_line[m_input.m_line_index])
+ instarcomment = slashed = false;
+ else // note that inside a star comment, slashed means starred
+ slashed = ('*' == m_input.m_line[m_input.m_line_index]);
+ } else if (!inslashcomment && !insinglequotes && !indoublequotes) {
+ // not in comment, look for /* or //
+ inslashcomment =
+ (slashed && '/' == m_input.m_line[m_input.m_line_index]);
+ instarcomment =
+ (slashed && '*' == m_input.m_line[m_input.m_line_index]);
+ slashed = ('/' == m_input.m_line[m_input.m_line_index]);
+ }
+
+ /* Look for brackets. */
+ if (!insinglequotes && !indoublequotes &&
+ !instarcomment && !inslashcomment) {
+ if ('{' == m_input.m_line[m_input.m_line_index])
+ {
+ ++brackets;
+ }
+ else if ('}' == m_input.m_line[m_input.m_line_index])
+ {
+ --brackets;
+
+ if (0 == brackets)
+ {
+ ++action_index;
+ ++m_input.m_line_index;
+
+ break;
+ }
+ }
+ }
+
+ ++action_index;
+ /* Double the buffer size, if needed. */
+ if (action_index >= action.length)
+ {
+ action = CUtility.doubleSize(action);
+ }
+
+ ++m_input.m_line_index;
+ /* Get a new line, if needed. */
+ while (m_input.m_line_index >= m_input.m_line_read)
+ {
+ inslashcomment = slashed = false;
+ if (insinglequotes || indoublequotes) { // non-fatal
+ CError.parse_error(CError.E_NEWLINE,m_input.m_line_number);
+ insinglequotes = indoublequotes = false;
+ }
+ if (m_input.getLine())
+ {
+ CError.parse_error(CError.E_SYNTAX,m_input.m_line_number);
+ return null;
+ }
+ }
+ }
+
+ accept = new CAccept(action,action_index,m_input.m_line_number);
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != accept);
+ }
+
+ if (CUtility.DESCENT_DEBUG)
+ {
+ System.out.print("Accepting action:");
+ System.out.println(new String(accept.m_action,0,accept.m_action_read));
+ }
+
+ return accept;
+ }
+
+ /********************************************************
+ Function: advance
+ Description: Returns code for next token.
+ *******************************************************/
+ private boolean m_advance_stop = false;
+ int advance
+ (
+ )
+ throws java.io.IOException
+ {
+ boolean saw_escape = false;
+ Integer code;
+
+ /*if (m_input.m_line_index > m_input.m_line_read) {
+ System.out.println("m_input.m_line_index = " + m_input.m_line_index);
+ System.out.println("m_input.m_line_read = " + m_input.m_line_read);
+ CUtility.ASSERT(m_input.m_line_index <= m_input.m_line_read);
+ }*/
+
+ if (m_input.m_eof_reached)
+ {
+ /* EOF has already been reached,
+ so return appropriate code. */
+
+ m_spec.m_current_token = END_OF_INPUT;
+ m_spec.m_lexeme = '\0';
+ return m_spec.m_current_token;
+ }
+
+ /* End of previous regular expression?
+ Refill line buffer? */
+ if (EOS == m_spec.m_current_token
+ /* ADDED */
+ || m_input.m_line_index >= m_input.m_line_read)
+ /* ADDED */
+ {
+ if (m_spec.m_in_quote)
+ {
+ CError.parse_error(CError.E_SYNTAX,m_input.m_line_number);
+ }
+
+ while (true)
+ {
+ if (false == m_advance_stop
+ || m_input.m_line_index >= m_input.m_line_read)
+ {
+ if (m_input.getLine())
+ {
+ /* EOF has already been reached,
+ so return appropriate code. */
+
+ m_spec.m_current_token = END_OF_INPUT;
+ m_spec.m_lexeme = '\0';
+ return m_spec.m_current_token;
+ }
+ m_input.m_line_index = 0;
+ }
+ else
+ {
+ m_advance_stop = false;
+ }
+
+ while (m_input.m_line_index < m_input.m_line_read
+ && true == CUtility.isspace(m_input.m_line[m_input.m_line_index]))
+ {
+ ++m_input.m_line_index;
+ }
+
+ if (m_input.m_line_index < m_input.m_line_read)
+ {
+ break;
+ }
+ }
+ }
+
+ if (CUtility.DEBUG) {
+ CUtility.ASSERT(m_input.m_line_index <= m_input.m_line_read);
+ }
+
+ while (true)
+ {
+ if (false == m_spec.m_in_quote
+ && '{' == m_input.m_line[m_input.m_line_index])
+ {
+ if (false == expandMacro())
+ {
+ break;
+ }
+
+ if (m_input.m_line_index >= m_input.m_line_read)
+ {
+ m_spec.m_current_token = EOS;
+ m_spec.m_lexeme = '\0';
+ return m_spec.m_current_token;
+ }
+ }
+ else if ('\"' == m_input.m_line[m_input.m_line_index])
+ {
+ m_spec.m_in_quote = !m_spec.m_in_quote;
+ ++m_input.m_line_index;
+
+ if (m_input.m_line_index >= m_input.m_line_read)
+ {
+ m_spec.m_current_token = EOS;
+ m_spec.m_lexeme = '\0';
+ return m_spec.m_current_token;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if (m_input.m_line_index > m_input.m_line_read) {
+ System.out.println("m_input.m_line_index = " + m_input.m_line_index);
+ System.out.println("m_input.m_line_read = " + m_input.m_line_read);
+ CUtility.ASSERT(m_input.m_line_index <= m_input.m_line_read);
+ }
+
+ /* Look for backslash, and corresponding
+ escape sequence. */
+ if ('\\' == m_input.m_line[m_input.m_line_index])
+ {
+ saw_escape = true;
+ }
+ else
+ {
+ saw_escape = false;
+ }
+
+ if (false == m_spec.m_in_quote)
+ {
+ if (false == m_spec.m_in_ccl &&
+ CUtility.isspace(m_input.m_line[m_input.m_line_index]))
+ {
+ /* White space means the end of
+ the current regular expression. */
+
+ m_spec.m_current_token = EOS;
+ m_spec.m_lexeme = '\0';
+ return m_spec.m_current_token;
+ }
+
+ /* Process escape sequence, if needed. */
+ if (saw_escape)
+ {
+ m_spec.m_lexeme = expandEscape();
+ }
+ else
+ {
+ m_spec.m_lexeme = m_input.m_line[m_input.m_line_index];
+ ++m_input.m_line_index;
+ }
+ }
+ else
+ {
+ if (saw_escape
+ && (m_input.m_line_index + 1) < m_input.m_line_read
+ && '\"' == m_input.m_line[m_input.m_line_index + 1])
+ {
+ m_spec.m_lexeme = '\"';
+ m_input.m_line_index = m_input.m_line_index + 2;
+ }
+ else
+ {
+ m_spec.m_lexeme = m_input.m_line[m_input.m_line_index];
+ ++m_input.m_line_index;
+ }
+ }
+
+ code = (Integer) m_tokens.get(new Character(m_spec.m_lexeme));
+ if (m_spec.m_in_quote || true == saw_escape)
+ {
+ m_spec.m_current_token = L;
+ }
+ else
+ {
+ if (null == code)
+ {
+ m_spec.m_current_token = L;
+ }
+ else
+ {
+ m_spec.m_current_token = code.intValue();
+ }
+ }
+
+ if (CCL_START == m_spec.m_current_token) m_spec.m_in_ccl = true;
+ if (CCL_END == m_spec.m_current_token) m_spec.m_in_ccl = false;
+
+ if (CUtility.FOODEBUG)
+ {
+ System.out.println("Lexeme: " + m_spec.m_lexeme
+ + "\tToken: " + m_spec.m_current_token
+ + "\tIndex: " + m_input.m_line_index);
+ }
+
+ return m_spec.m_current_token;
+ }
+
+ /***************************************************************
+ Function: details
+ Description: High level debugging routine.
+ **************************************************************/
+ private void details
+ (
+ )
+ {
+ Enumeration names;
+ String name;
+ String def;
+ Enumeration states;
+ String state;
+ Integer index;
+ int elem;
+ int size;
+
+ System.out.println();
+ System.out.println("\t** Macros **");
+ names = m_spec.m_macros.keys();
+ while (names.hasMoreElements())
+ {
+ name = (String) names.nextElement();
+ def = (String) m_spec.m_macros.get(name);
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != name);
+ CUtility.ASSERT(null != def);
+ }
+
+ System.out.println("Macro name \"" + name
+ + "\" has definition \""
+ + def + "\".");
+ }
+
+ System.out.println();
+ System.out.println("\t** States **");
+ states = m_spec.m_states.keys();
+ while (states.hasMoreElements())
+ {
+ state = (String) states.nextElement();
+ index = (Integer) m_spec.m_states.get(state);
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != state);
+ CUtility.ASSERT(null != index);
+ }
+
+ System.out.println("State \"" + state
+ + "\" has identifying index "
+ + index.toString() + ".");
+ }
+
+ System.out.println();
+ System.out.println("\t** Character Counting **");
+ if (false == m_spec.m_count_chars)
+ {
+ System.out.println("Character counting is off.");
+ }
+ else
+ {
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(m_spec.m_count_lines);
+ }
+
+ System.out.println("Character counting is on.");
+ }
+
+ System.out.println();
+ System.out.println("\t** Line Counting **");
+ if (false == m_spec.m_count_lines)
+ {
+ System.out.println("Line counting is off.");
+ }
+ else
+ {
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(m_spec.m_count_lines);
+ }
+
+ System.out.println("Line counting is on.");
+ }
+
+ System.out.println();
+ System.out.println("\t** Operating System Specificity **");
+ if (false == m_spec.m_unix)
+ {
+ System.out.println("Not generating UNIX-specific code.");
+ System.out.println("(This means that \"\\r\\n\" is a "
+ + "newline, rather than \"\\n\".)");
+ }
+ else
+ {
+ System.out.println("Generating UNIX-specific code.");
+ System.out.println("(This means that \"\\n\" is a "
+ + "newline, rather than \"\\r\\n\".)");
+ }
+
+ System.out.println();
+ System.out.println("\t** Java CUP Compatibility **");
+ if (false == m_spec.m_cup_compatible)
+ {
+ System.out.println("Generating CUP compatible code.");
+ System.out.println("(Scanner implements "
+ + "java_cup.runtime.Scanner.)");
+ }
+ else
+ {
+ System.out.println("Not generating CUP compatible code.");
+ }
+
+ if (CUtility.FOODEBUG) {
+ if (null != m_spec.m_nfa_states && null != m_spec.m_nfa_start)
+ {
+ System.out.println();
+ System.out.println("\t** NFA machine **");
+ print_nfa();
+ }
+ }
+
+ if (null != m_spec.m_dtrans_vector)
+ {
+ System.out.println();
+ System.out.println("\t** DFA transition table **");
+ /*print_header();*/
+ }
+
+ /*if (null != m_spec.m_accept_vector && null != m_spec.m_anchor_array)
+ {
+ System.out.println();
+ System.out.println("\t** Accept States and Anchor Vector **");
+ print_accept();
+ }*/
+ }
+
+ /***************************************************************
+ function: print_set
+ **************************************************************/
+ void print_set
+ (
+ Vector nfa_set
+ )
+ {
+ int size;
+ int elem;
+ CNfa nfa;
+
+ size = nfa_set.size();
+
+ if (0 == size)
+ {
+ System.out.print("empty ");
+ }
+
+ for (elem = 0; elem < size; ++elem)
+ {
+ nfa = (CNfa) nfa_set.elementAt(elem);
+ /*System.out.print(m_spec.m_nfa_states.indexOf(nfa) + " ");*/
+ System.out.print(nfa.m_label + " ");
+ }
+ }
+
+ /***************************************************************
+ Function: print_header
+ **************************************************************/
+ private void print_header
+ (
+ )
+ {
+ Enumeration states;
+ int i;
+ int j;
+ int chars_printed=0;
+ CDTrans dtrans;
+ int last_transition;
+ String str;
+ CAccept accept;
+ String state;
+ Integer index;
+
+ System.out.println("/*---------------------- DFA -----------------------");
+
+ states = m_spec.m_states.keys();
+ while (states.hasMoreElements())
+ {
+ state = (String) states.nextElement();
+ index = (Integer) m_spec.m_states.get(state);
+
+ if (CUtility.DEBUG)
+ {
+ CUtility.ASSERT(null != state);
+ CUtility.ASSERT(null != index);
+ }
+
+ System.out.println("State \"" + state
+ + "\" has identifying index "
+ + index.toString() + ".");
+
+ i = index.intValue();
+ if (CDTrans.F != m_spec.m_state_dtrans[i])
+ {
+ System.out.println("\tStart index in transition table: "
+ + m_spec.m_state_dtrans[i]);
+ }
+ else
+ {
+ System.out.println("\tNo associated transition states.");
+ }
+ }
+
+ for (i = 0; i < m_spec.m_dtrans_vector.size(); ++i)
+ {
+ dtrans = (CDTrans) m_spec.m_dtrans_vector.elementAt(i);
+
+ if (null == m_spec.m_accept_vector && null == m_spec.m_anchor_array)
+ {
+ if (null == dtrans.m_accept)
+ {
+ System.out.print(" * State " + i + " [nonaccepting]");
+ }
+ else
+ {
+ System.out.print(" * State " + i
+ + " [accepting, line "
+ + dtrans.m_accept.m_line_number
+ + " <"
+ + (new String(dtrans.m_accept.m_action,0,
+ dtrans.m_accept.m_action_read))
+ + ">]");
+ if (CSpec.NONE != dtrans.m_anchor)
+ {
+ System.out.print(" Anchor: "
+ + ((0 != (dtrans.m_anchor & CSpec.START))
+ ? "start " : "")
+ + ((0 != (dtrans.m_anchor & CSpec.END))
+ ? "end " : ""));
+ }
+ }
+ }
+ else
+ {
+ accept = (CAccept) m_spec.m_accept_vector.elementAt(i);
+
+ if (null == accept)
+ {
+ System.out.print(" * State " + i + " [nonaccepting]");
+ }
+ else
+ {
+ System.out.print(" * State " + i
+ + " [accepting, line "
+ + accept.m_line_number
+ + " <"
+ + (new String(accept.m_action,0,
+ accept.m_action_read))
+ + ">]");
+ if (CSpec.NONE != m_spec.m_anchor_array[i])
+ {
+ System.out.print(" Anchor: "
+ + ((0 != (m_spec.m_anchor_array[i] & CSpec.START))
+ ? "start " : "")
+ + ((0 != (m_spec.m_anchor_array[i] & CSpec.END))
+ ? "end " : ""));
+ }
+ }
+ }
+
+ last_transition = -1;
+ for (j = 0; j < m_spec.m_dtrans_ncols; ++j)
+ {
+ if (CDTrans.F != dtrans.m_dtrans[j])
+ {
+ if (last_transition != dtrans.m_dtrans[j])
+ {
+ System.out.println();
+ System.out.print(" * goto " + dtrans.m_dtrans[j]
+ + " on ");
+ chars_printed = 0;
+ }
+
+ str = interp_int((int) j);
+ System.out.print(str);
+
+ chars_printed = chars_printed + str.length();
+ if (56 < chars_printed)
+ {
+ System.out.println();
+ System.out.print(" * ");
+ chars_printed = 0;
+ }
+
+ last_transition = dtrans.m_dtrans[j];
+ }
+ }
+ System.out.println();
+ }
+ System.out.println(" */");
+ System.out.println();
+ }
+}
+
+/*
+ * SparseBitSet 25-Jul-1999.
+ * C. Scott Ananian <cananian@alumni.princeton.edu>
+ *
+ * Re-implementation of the standard java.util.BitSet to support sparse
+ * sets, which we need to efficiently support unicode character classes.
+ */
+
+/**
+ * A set of bits. The set automatically grows as more bits are
+ * needed.
+ *
+ * @version 1.00, 25 Jul 1999
+ * @author C. Scott Ananian
+ */
+final class SparseBitSet implements Cloneable {
+ /** Sorted array of bit-block offsets. */
+ int offs[];
+ /** Array of bit-blocks; each holding BITS bits. */
+ long bits[];
+ /** Number of blocks currently in use. */
+ int size;
+ /** log base 2 of BITS, for the identity: x/BITS == x >> LG_BITS */
+ static final private int LG_BITS = 6;
+ /** Number of bits in a block. */
+ static final private int BITS = 1<<LG_BITS;
+ /** BITS-1, using the identity: x % BITS == x & (BITS-1) */
+ static final private int BITS_M1 = BITS-1;
+
+ /**
+ * Creates an empty set.
+ */
+ public SparseBitSet() {
+ bits = new long[4];
+ offs = new int [4];
+ size = 0;
+ }
+
+ /**
+ * Creates an empty set with the specified size.
+ * @param nbits the size of the set
+ */
+ public SparseBitSet(int nbits) {
+ this();
+ }
+
+ /**
+ * Creates an empty set with the same size as the given set.
+ */
+ public SparseBitSet(SparseBitSet set) {
+ bits = new long[set.size];
+ offs = new int [set.size];
+ size = 0;
+ }
+
+ private void new_block(int bnum) {
+ new_block(bsearch(bnum), bnum);
+ }
+ private void new_block(int idx, int bnum) {
+ if (size==bits.length) { // resize
+ long[] nbits = new long[size*3];
+ int [] noffs = new int [size*3];
+ System.arraycopy(bits, 0, nbits, 0, size);
+ System.arraycopy(offs, 0, noffs, 0, size);
+ bits = nbits;
+ offs = noffs;
+ }
+ CUtility.ASSERT(size<bits.length);
+ insert_block(idx, bnum);
+ }
+ private void insert_block(int idx, int bnum) {
+ CUtility.ASSERT(idx<=size);
+ CUtility.ASSERT(idx==size || offs[idx]!=bnum);
+ System.arraycopy(bits, idx, bits, idx+1, size-idx);
+ System.arraycopy(offs, idx, offs, idx+1, size-idx);
+ offs[idx]=bnum;
+ bits[idx]=0; //clear them bits.
+ size++;
+ }
+ private int bsearch(int bnum) {
+ int l=0, r=size; // search interval is [l, r)
+ while (l<r) {
+ int p = (l+r)/2;
+ if (bnum<offs[p]) r=p;
+ else if (bnum>offs[p]) l=p+1;
+ else return p;
+ }
+ CUtility.ASSERT(l==r);
+ return l; // index at which the bnum *should* be, if it's not.
+ }
+
+ /**
+ * Sets a bit.
+ * @param bit the bit to be set
+ */
+ public void set(int bit) {
+ int bnum = bit >> LG_BITS;
+ int idx = bsearch(bnum);
+ if (idx >= size || offs[idx]!=bnum)
+ new_block(idx, bnum);
+ bits[idx] |= (1L << (bit & BITS_M1) );
+ }
+
+ /**
+ * Clears a bit.
+ * @param bit the bit to be cleared
+ */
+ public void clear(int bit) {
+ int bnum = bit >> LG_BITS;
+ int idx = bsearch(bnum);
+ if (idx >= size || offs[idx]!=bnum)
+ new_block(idx, bnum);
+ bits[idx] &= ~(1L << (bit & BITS_M1) );
+ }
+
+ /**
+ * Clears all bits.
+ */
+ public void clearAll() {
+ size = 0;
+ }
+
+ /**
+ * Gets a bit.
+ * @param bit the bit to be gotten
+ */
+ public boolean get(int bit) {
+ int bnum = bit >> LG_BITS;
+ int idx = bsearch(bnum);
+ if (idx >= size || offs[idx]!=bnum)
+ return false;
+ return 0 != ( bits[idx] & (1L << (bit & BITS_M1) ) );
+ }
+
+ /**
+ * Logically ANDs this bit set with the specified set of bits.
+ * @param set the bit set to be ANDed with
+ */
+ public void and(SparseBitSet set) {
+ binop(this, set, AND);
+ }
+
+ /**
+ * Logically ORs this bit set with the specified set of bits.
+ * @param set the bit set to be ORed with
+ */
+ public void or(SparseBitSet set) {
+ binop(this, set, OR);
+ }
+
+ /**
+ * Logically XORs this bit set with the specified set of bits.
+ * @param set the bit set to be XORed with
+ */
+ public void xor(SparseBitSet set) {
+ binop(this, set, XOR);
+ }
+
+ // BINARY OPERATION MACHINERY
+ private static interface BinOp {
+ public long op(long a, long b);
+ }
+ private static final BinOp AND = new BinOp() {
+ public final long op(long a, long b) { return a & b; }
+ };
+ private static final BinOp OR = new BinOp() {
+ public final long op(long a, long b) { return a | b; }
+ };
+ private static final BinOp XOR = new BinOp() {
+ public final long op(long a, long b) { return a ^ b; }
+ };
+ private static final void binop(SparseBitSet a, SparseBitSet b, BinOp op) {
+ int nsize = a.size + b.size;
+ long[] nbits;
+ int [] noffs;
+ int a_zero, a_size;
+ // be very clever and avoid allocating more memory if we can.
+ if (a.bits.length < nsize) { // oh well, have to make working space.
+ nbits = new long[nsize];
+ noffs = new int [nsize];
+ a_zero = 0; a_size = a.size;
+ } else { // reduce, reuse, recycle!
+ nbits = a.bits;
+ noffs = a.offs;
+ a_zero = a.bits.length - a.size; a_size = a.bits.length;
+ System.arraycopy(a.bits, 0, a.bits, a_zero, a.size);
+ System.arraycopy(a.offs, 0, a.offs, a_zero, a.size);
+ }
+ // ok, crunch through and binop those sets!
+ nsize = 0;
+ for (int i=a_zero, j=0; i<a_size || j<b.size; ) {
+ long nb; int no;
+ if (i<a_size && (j>=b.size || a.offs[i] < b.offs[j])) {
+ nb = op.op(a.bits[i], 0);
+ no = a.offs[i];
+ i++;
+ } else if (j<b.size && (i>=a_size || a.offs[i] > b.offs[j])) {
+ nb = op.op(0, b.bits[j]);
+ no = b.offs[j];
+ j++;
+ } else { // equal keys; merge.
+ nb = op.op(a.bits[i], b.bits[j]);
+ no = a.offs[i];
+ i++; j++;
+ }
+ if (nb!=0) {
+ nbits[nsize] = nb;
+ noffs[nsize] = no;
+ nsize++;
+ }
+ }
+ a.bits = nbits;
+ a.offs = noffs;
+ a.size = nsize;
+ }
+
+ /**
+ * Gets the hashcode.
+ */
+ public int hashCode() {
+ long h = 1234;
+ for (int i=0; i<size; i++)
+ h ^= bits[i] * offs[i];
+ return (int)((h >> 32) ^ h);
+ }
+
+ /**
+ * Calculates and returns the set's size
+ */
+ public int size() {
+ return (size==0)?0:((1+offs[size-1]) << LG_BITS);
+ }
+
+ /**
+ * Compares this object against the specified object.
+ * @param obj the object to commpare with
+ * @return true if the objects are the same; false otherwise.
+ */
+ public boolean equals(Object obj) {
+ if ((obj != null) && (obj instanceof SparseBitSet))
+ return equals(this, (SparseBitSet)obj);
+ return false;
+ }
+ /**
+ * Compares two SparseBitSets for equality.
+ * @return true if the objects are the same; false otherwise.
+ */
+ public static boolean equals(SparseBitSet a, SparseBitSet b) {
+ for (int i=0, j=0; i<a.size || j<b.size; ) {
+ if (i<a.size && (j>=b.size || a.offs[i] < b.offs[j])) {
+ if (a.bits[i++]!=0) return false;
+ } else if (j<b.size && (i>=a.size || a.offs[i] > b.offs[j])) {
+ if (b.bits[j++]!=0) return false;
+ } else { // equal keys
+ if (a.bits[i++]!=b.bits[j++]) return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Clones the SparseBitSet.
+ */
+ public Object clone() {
+ try {
+ SparseBitSet set = (SparseBitSet)super.clone();
+ set.bits = (long[]) bits.clone();
+ set.offs = (int []) offs.clone();
+ return set;
+ } catch (CloneNotSupportedException e) {
+ // this shouldn't happen, since we are Cloneable
+ throw new InternalError();
+ }
+ }
+
+ /**
+ * Return an <code>Enumeration</code> of <code>Integer</code>s
+ * which represent set bit indices in this SparseBitSet.
+ */
+ public Enumeration elements() {
+ return new Enumeration() {
+ int idx=-1, bit=BITS;
+ { advance(); }
+ public boolean hasMoreElements() {
+ return (idx<size);
+ }
+ public Object nextElement() {
+ int r = bit + (offs[idx] << LG_BITS);
+ advance();
+ return new Integer(r);
+ }
+ private void advance() {
+ while (idx<size) {
+ while (++bit<BITS)
+ if (0!=(bits[idx] & (1L<<bit)))
+ return;
+ idx++; bit=-1;
+ }
+ }
+ };
+ }
+ /**
+ * Converts the SparseBitSet to a String.
+ */
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append('{');
+ for (Enumeration e=elements(); e.hasMoreElements(); ) {
+ if (sb.length() > 1) sb.append(", ");
+ sb.append(e.nextElement());
+ }
+ sb.append('}');
+ return sb.toString();
+ }
+
+ /** Check validity. */
+ private boolean isValid() {
+ if (bits.length!=offs.length) return false;
+ if (size>bits.length) return false;
+ if (size!=0 && 0<=offs[0]) return false;
+ for (int i=1; i<size; i++)
+ if (offs[i] < offs[i-1])
+ return false;
+ return true;
+ }
+ /** Self-test. */
+ public static void main(String[] args) {
+ final int ITER = 500;
+ final int RANGE= 65536;
+ SparseBitSet a = new SparseBitSet();
+ CUtility.ASSERT(!a.get(0) && !a.get(1));
+ CUtility.ASSERT(!a.get(123329));
+ a.set(0); CUtility.ASSERT(a.get(0) && !a.get(1));
+ a.set(1); CUtility.ASSERT(a.get(0) && a.get(1));
+ a.clearAll();
+ CUtility.ASSERT(!a.get(0) && !a.get(1));
+ java.util.Random r = new java.util.Random();
+ java.util.Vector v = new java.util.Vector();
+ for (int n=0; n<ITER; n++) {
+ int rr = ((r.nextInt()>>>1) % RANGE) << 1;
+ a.set(rr); v.addElement(new Integer(rr));
+ // check that all the numbers are there.
+ CUtility.ASSERT(a.get(rr) && !a.get(rr+1) && !a.get(rr-1));
+ for (int i=0; i<v.size(); i++)
+ CUtility.ASSERT(a.get(((Integer)v.elementAt(i)).intValue()));
+ }
+ SparseBitSet b = (SparseBitSet) a.clone();
+ CUtility.ASSERT(a.equals(b) && b.equals(a));
+ for (int n=0; n<ITER/2; n++) {
+ int rr = (r.nextInt()>>>1) % v.size();
+ int m = ((Integer)v.elementAt(rr)).intValue();
+ b.clear(m); v.removeElementAt(rr);
+ // check that numbers are removed properly.
+ CUtility.ASSERT(!b.get(m));
+ }
+ CUtility.ASSERT(!a.equals(b));
+ SparseBitSet c = (SparseBitSet) a.clone();
+ SparseBitSet d = (SparseBitSet) a.clone();
+ c.and(a);
+ CUtility.ASSERT(c.equals(a) && a.equals(c));
+ c.xor(a);
+ CUtility.ASSERT(!c.equals(a) && c.size()==0);
+ d.or(b);
+ CUtility.ASSERT(d.equals(a) && !b.equals(d));
+ d.and(b);
+ CUtility.ASSERT(!d.equals(a) && b.equals(d));
+ d.xor(a);
+ CUtility.ASSERT(!d.equals(a) && !b.equals(d));
+ c.or(d); c.or(b);
+ CUtility.ASSERT(c.equals(a) && a.equals(c));
+ c = (SparseBitSet) d.clone();
+ c.and(b);
+ CUtility.ASSERT(c.size()==0);
+ System.out.println("Success.");
+ }
+}
+
+/************************************************************************
+ JLEX COPYRIGHT NOTICE, LICENSE AND DISCLAIMER.
+
+ Copyright 1996 by Elliot Joel Berk
+
+ Permission to use, copy, modify, and distribute this software and its
+ documentation for any purpose and without fee is hereby granted,
+ provided that the above copyright notice appear in all copies and that
+ both the copyright notice and this permission notice and warranty
+ disclaimer appear in supporting documentation, and that the name of
+ Elliot Joel Berk not be used in advertising or publicity pertaining
+ to distribution of the software without specific, written prior permission.
+
+ Elliot Joel Berk disclaims all warranties with regard to this software,
+ including all implied warranties of merchantability and fitness. In no event
+ shall Elliot Joel Berk be liable for any special, indirect or consequential
+ damages or any damages whatsoever resulting from loss of use, data or
+ profits, whether in an action of contract, negligence or other
+ tortious action, arising out of or in connection with the use or
+ performance of this software.
+ ***********************************************************************/
+// set emacs indentation
+// Local Variables:
+// c-basic-offset:2
+// End:
diff --git a/src/syntaxParser/JLex/SparseBitSet$1.class b/src/syntaxParser/JLex/SparseBitSet$1.class
new file mode 100644
index 0000000..57af847
--- /dev/null
+++ b/src/syntaxParser/JLex/SparseBitSet$1.class
Binary files differ
diff --git a/src/syntaxParser/JLex/SparseBitSet$2.class b/src/syntaxParser/JLex/SparseBitSet$2.class
new file mode 100644
index 0000000..6a97a1a
--- /dev/null
+++ b/src/syntaxParser/JLex/SparseBitSet$2.class
Binary files differ
diff --git a/src/syntaxParser/JLex/SparseBitSet$3.class b/src/syntaxParser/JLex/SparseBitSet$3.class
new file mode 100644
index 0000000..ed0d5a0
--- /dev/null
+++ b/src/syntaxParser/JLex/SparseBitSet$3.class
Binary files differ
diff --git a/src/syntaxParser/JLex/SparseBitSet$4.class b/src/syntaxParser/JLex/SparseBitSet$4.class
new file mode 100644
index 0000000..3fe8e9b
--- /dev/null
+++ b/src/syntaxParser/JLex/SparseBitSet$4.class
Binary files differ
diff --git a/src/syntaxParser/JLex/SparseBitSet$BinOp.class b/src/syntaxParser/JLex/SparseBitSet$BinOp.class
new file mode 100644
index 0000000..279caed
--- /dev/null
+++ b/src/syntaxParser/JLex/SparseBitSet$BinOp.class
Binary files differ
diff --git a/src/syntaxParser/JLex/SparseBitSet.class b/src/syntaxParser/JLex/SparseBitSet.class
new file mode 100644
index 0000000..fb750ec
--- /dev/null
+++ b/src/syntaxParser/JLex/SparseBitSet.class
Binary files differ
diff --git a/src/syntaxParser/List.java b/src/syntaxParser/List.java
new file mode 100644
index 0000000..685c504
--- /dev/null
+++ b/src/syntaxParser/List.java
@@ -0,0 +1,42 @@
+package syntaxParser;
+/* Author: Sorin stancu-Mara
+ * date: 8 feb 2008
+ * All the lists have the same caracteristics, therfore all of them derive from this class
+ * No need to verify that the list contain same type of elements since they are created using the grammar.
+ */
+
+class List implements IParseTreeNode {
+ IParseTreeNode element;
+ List next;
+ String tag;
+
+ public List(IParseTreeNode elem) {
+ element = elem;
+ next = null;
+ }
+
+ public List(IParseTreeNode elem, List next) {
+ element = elem;
+ this.next = next;
+ }
+
+ public void setTag(String tagName) {
+ tag = tagName;
+ if (next != null) {
+ next.setTag(tag);
+ }
+ }
+
+ public String toXML() {
+ String result = "";
+ if (tag != null) {
+ result += "<" + tag + ">";
+ result += element.toXML();
+ result += "</" + tag + ">";
+ } else
+ result += element.toXML();
+ if (next != null)
+ result += next.toXML();
+ return result;
+ }
+}
diff --git a/src/syntaxParser/Makefile b/src/syntaxParser/Makefile
new file mode 100644
index 0000000..0869ac7
--- /dev/null
+++ b/src/syntaxParser/Makefile
@@ -0,0 +1,34 @@
+# Author: Sorin Stancu-Mara
+# Date: 5 Feb 2007
+# Based on readme.txt provided by Mattia Parigiani
+
+JAR=jar
+JAVA=java
+JAVAC=javac
+
+all: SyntaxErrorException.class List.class WCPSParser.class WCPSSymbol.class WCPSScanner.class \
+ WCPSRequestProcessor.class
+
+%.class: %.java
+ cd .. ; $(JAVAC) syntaxParser/$<
+
+WCPSScanner.java: wcps.lex
+ $(JAVA) JLex.Main wcps.lex
+ mv wcps.lex.java WCPSScanner.java
+
+.PHONY:
+parser: wcps.cup
+ $(JAVA) java_cup.Main -parser WCPSParser -symbols WCPSSymbol -package syntaxParser <wcps.cup
+
+WCPSParser.java: parser
+
+
+WCPSSymbol.java: parser
+
+.PHONY:
+clean:
+ rm -f *.class WCPSScanner.java WCPSParser.java WCPSSymbol.java
+
+
+
+
diff --git a/src/syntaxParser/NumericScalarExpr.java b/src/syntaxParser/NumericScalarExpr.java
new file mode 100644
index 0000000..049c3b9
--- /dev/null
+++ b/src/syntaxParser/NumericScalarExpr.java
@@ -0,0 +1,51 @@
+package syntaxParser;
+/**
+ * NumericScalarExpr
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani, Sorin Stancu-Mara
+ */
+class NumericScalarExpr implements IParseTreeNode {
+ NumericScalarExpr leftNumericScalarExpr, rightNumericScalarExpr;
+ String function;
+ String constValue;
+
+ public NumericScalarExpr(String scalar){
+ constValue = scalar;
+ function = "scalar";
+ }
+
+
+ public NumericScalarExpr(String op, NumericScalarExpr expr) throws Exception{
+ leftNumericScalarExpr = expr;
+ if (op.equals("+")) function = "scalarUnaryPlus";
+ else if (op.equals("-")) function = "scalarUnaryMinus";
+ else if (op.equals("abs")) function = "scalarAbs";
+ else throw new Exception("Operator " + op + " is not recognized!");
+ }
+
+ public NumericScalarExpr(String op, NumericScalarExpr lbe, NumericScalarExpr rbe) throws Exception {
+ leftNumericScalarExpr = lbe ;
+ rightNumericScalarExpr = rbe ;
+ if (op.equals("+")) function = "scalarPlus";
+ else if (op.equals("-")) function = "scalarMinus";
+ else if (op.equals("*")) function = "scalarMult";
+ else if (op.equals("/")) function = "scalarDiv";
+ else throw new Exception("Operator " + op + " is not recognized!");
+ }
+
+ public String toXML() {
+ String result;
+ result = "<" + function + ">";
+ if (function.equals("scalar")) {
+ result += constValue;
+ } else {
+ result += leftNumericScalarExpr.toXML();
+ if (rightNumericScalarExpr != null) {
+ result += rightNumericScalarExpr.toXML();
+ }
+ }
+ result += "</" + function + ">";
+ return result;
+ }
+
+}
diff --git a/src/syntaxParser/ProcessingExpr.java b/src/syntaxParser/ProcessingExpr.java
new file mode 100644
index 0000000..738ad8f
--- /dev/null
+++ b/src/syntaxParser/ProcessingExpr.java
@@ -0,0 +1,18 @@
+package syntaxParser;
+/**
+ * ProcessingExpr
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani, Sorin Stancu-Mara
+ */
+class ProcessingExpr implements IParseTreeNode {
+ IParseTreeNode expr;
+ public ProcessingExpr( IParseTreeNode e ) {
+ expr = e;
+ }
+ public String toXML() {
+ return expr.toXML();
+ }
+
+
+
+}
diff --git a/src/syntaxParser/README b/src/syntaxParser/README
new file mode 100644
index 0000000..56a50da
--- /dev/null
+++ b/src/syntaxParser/README
@@ -0,0 +1,97 @@
+============================================================= README file =============================================================
+
+WCPS Abstract Parser and ProcessCoverage XML transformer tool
+Author: Mattia Parigiani
+
+
+
+
+The application folder contains the following:
+
+- Java CUP grammar specification file: "wcps.cup"
+- JLex Lexycal Analyzer / Scanner specification file: "wpcs.lex"
+- Utility Java classes for non-terminal symbols of grammar needed for XML conversion routines
+- batch file for parser generation under Windows OS: "run.bat"
+- Text files containing sample tested WCPS requests: "SAMPLE_REQUESTS.txt", "test_requests.txt"
+- JLex runtime executables directory: in sub directory "./JLex"
+- Java CUP runtime jar library : "java-cup-11a.jar"
+- Java CUP runtime executables directory: in sub directory "./java_cup"
+- Lexycal scanner generated source code and executable: respectevely "wcps.lex.java" and "WCPSScanner.class"
+- Parser generated source code and executable: respectevely "WCPSParser.java" and "WCPSParser.class"
+- Symbols generate source code and executable: respectevely "WCPSSymbol.java" and "WCPSSymbol.class"
+- README.txt file
+
+
+
+
+
+The tool may be used in the following two ways:
+1) Simple Usage
+2) Further developments
+
+
+
+======================================================================================================================================
+1) Simple Usage:
+
+Users that want to only use the WCPS Parser/Transformer utility need to do the following operations:
+
+ - Edit the "request.wcps" file and enter a valid WCPS request
+ The syntax will be considered to be valid if it can be parsed with no errors and if it is conformant to the
+ Java CUP grammar specification.
+
+ - Execute the WCPSRequestProcessor program:
+ This will produce the appropriate ProcessCoverage XMl request file is the parsed request does not contain
+ any syntax errors.
+
+ - Open the "wcpsRequest.xml" to see the output XML request file.
+
+ - Optionally connect to the WCPS service at http://mango.eecs.jacob-university.de:8080/wcps_0.3.5/ and submit the XML file
+ using the file upload field.
+ The coverage data will be returned only if the specified sets in the request exist on the server side.
+
+
+
+
+======================================================================================================================================
+2) Further Development:
+
+Users that may want to bring modification to the utility will mainly need to edit the CUP specification file and the JLex specification.
+- The CUP specification is within the "wcps.cup" file
+- The JLex specification is within the "wcps.lex" file
+
+Once modifications have been made the new parser can be generated by executing the following sequence of commands:
+
+- java JLex.Main wcps.lex
+ This generates the lexycal analyzer and scanner using JLex technology
+
+- java java_cup.Main -parser WCPSParser -symbols WCPSSymbol <wcps.cup
+ This generates the source for the parser and symbol class using Java CUP technology.
+ The sources are renamed WCPSParser.java and WCPSSymbol.java.
+ Different names may be used as long as the calling program also considers these changes
+
+- javac wcps.lex.java
+ This compiles the Scanner class generated by the JLex technology. The class is named wcps.lex.java by default.
+ This name is conventional and comes directly from the fact that the JLex specification file is called "wcps.lex"
+
+- javac WCPSParser.java WCPSSymbol.java WCPSRequestProcessor.java
+ This compiles the parser and the symbol sources together with the calling program (WCPSRequestProcessor).
+ Please see the source code for WCPSRequestProcessor.java to see the exact usage.
+
+At this moment, the parser is ready for any WCPS request. The WCPSRequestProcessor.java code is an example for how the parser can be invoked by
+reading a WCPS request string from a file (namely, "request.wcps"). To invoke the WCPSRequestProcessor.java example program simply call:
+
+- java WCPSRequestProcessor
+
+This is mainly what is specified in the previous section of this README file (Simple Usage)
+
+
+NOTE:
+Windows users can get the cascading effect of executing all these commands in a row by using the provided batch file (namely, "run.bat" ).
+From the windows command prompt, enter the application folder and type:
+
+- run
+
+Please have a look at the "run.bat" for further clarification
+
+====================================================================================================================================== \ No newline at end of file
diff --git a/src/syntaxParser/RangeValue.java b/src/syntaxParser/RangeValue.java
new file mode 100644
index 0000000..c8d4739
--- /dev/null
+++ b/src/syntaxParser/RangeValue.java
@@ -0,0 +1,17 @@
+package syntaxParser;
+/* Author: Sorin stancu-Mara
+ * Date: 9 Feb 2008
+ */
+
+class RangeValue implements IParseTreeNode {
+ String value;
+ public RangeValue(String value) {
+ this.value = value;
+ }
+ public RangeValue(StructuredLiteral value) {
+ this.value = value.toXML();
+ }
+ public String toXML() {
+ return value;
+ }
+}
diff --git a/src/syntaxParser/RangeValueList.java b/src/syntaxParser/RangeValueList.java
new file mode 100644
index 0000000..79630b0
--- /dev/null
+++ b/src/syntaxParser/RangeValueList.java
@@ -0,0 +1,10 @@
+package syntaxParser;
+
+class RangeValueList extends List {
+ public RangeValueList(RangeValue elem) { super((IParseTreeNode)elem); }
+ public RangeValueList(RangeValue elem, RangeValueList next) { super((IParseTreeNode)elem, (List)next); }
+}
+
+
+
+
diff --git a/src/syntaxParser/ReduceExpr.java b/src/syntaxParser/ReduceExpr.java
new file mode 100644
index 0000000..031921e
--- /dev/null
+++ b/src/syntaxParser/ReduceExpr.java
@@ -0,0 +1,19 @@
+package syntaxParser;
+/**
+ * ReduceExpr
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani, Sorin Stancu-Mara
+ */
+class ReduceExpr implements IParseTreeNode{
+ CoverageExpr coverageExpr;
+ String operator;
+
+ public ReduceExpr( CoverageExpr ce, String op){
+ coverageExpr = ce;
+ operator = op;
+ }
+
+ public String toXML(){
+ return "<" + operator + ">" + coverageExpr.toXML() + "</" + operator + ">";
+ }
+}
diff --git a/src/syntaxParser/ReturnClause.java b/src/syntaxParser/ReturnClause.java
new file mode 100644
index 0000000..36af7bb
--- /dev/null
+++ b/src/syntaxParser/ReturnClause.java
@@ -0,0 +1,16 @@
+package syntaxParser;
+/**
+ * ReturnClause
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani, Sorin Stancu-Mara
+ */
+class ReturnClause implements IParseTreeNode {
+ private ProcessingExpr processingExpr;
+ public ReturnClause( ProcessingExpr pr){
+ processingExpr =pr;
+ }
+
+ public String toXML(){
+ return processingExpr.toXML();
+ }
+}
diff --git a/src/syntaxParser/SAMPLE_REQUESTS.txt b/src/syntaxParser/SAMPLE_REQUESTS.txt
new file mode 100644
index 0000000..df8942a
--- /dev/null
+++ b/src/syntaxParser/SAMPLE_REQUESTS.txt
@@ -0,0 +1,52 @@
+
+
+
+
+ This file contains some sampled and tested WCPS requests as translated from their original ProcessCoverage.xml form.
+ The corresponding ProcesseCoverage.xml files where created and used in the development of the WCPS service.
+
+ The current test WCPS service is found at http://mango.eecs.jacobs-university.de:8080/wcps_0.3.5/
+
+ There are two ways to use them
+ 1) Directly from command line >> copy the request into the file "request.wcps" and run the java command:
+ java WCPSRequestProcessor
+ This supposes that the parser has already been generated and all binaries are already available in the application folder.
+ If this is not true, please refer to the README/INSTALL file for help on how to generate the parser/translater.
+ The application will generate the ProcessCoverage.xml file.
+ Now connect to http://mango.eecs.jacobs-university.de:8080/wcps_0.3.5/ and submit the xml request file.
+ The coverage response data will be displayed from the WCPS service servlet.
+
+ 2) From the Request Servlet >> This is still under development. The idea is that the user will be presented with a web interface
+ where to insert the request, he will submit such request and automagically get the relative coverage response data.
+
+
+
+
+
+
+
+extract request:
+
+ for m in (rgb) return encode(m, png)
+
+
+
+
+extract green channel request:
+
+ for m in (rgb) return encode ( m.green , png)
+
+
+
+
+scale request:
+
+ for m in (rgb) return encode ( scale ( scale( m,1,0,130,nearest neighbor ) , 0,0,640,nearest neighbor ) , png)
+
+
+
+
+
+scale and extract green channel request:
+
+ for m in (rgb) return encode ( scale ( scale( m,1,0,130,nearest neighbor ) , 0,0,640,nearest neighbor ).green , png) \ No newline at end of file
diff --git a/src/syntaxParser/ScalarExpr.java b/src/syntaxParser/ScalarExpr.java
new file mode 100644
index 0000000..e5b72a8
--- /dev/null
+++ b/src/syntaxParser/ScalarExpr.java
@@ -0,0 +1,18 @@
+package syntaxParser;
+/**
+ * ScalarExpr
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani, Sorin Stancu-Mara
+ */
+class ScalarExpr implements IParseTreeNode {
+ IParseTreeNode expr;
+
+ public ScalarExpr(IParseTreeNode e) {
+ expr = e;
+ }
+
+ public String toXML(){
+ return expr.toXML();
+ }
+
+}
diff --git a/src/syntaxParser/ScalarLit.java b/src/syntaxParser/ScalarLit.java
new file mode 100644
index 0000000..c9810a8
--- /dev/null
+++ b/src/syntaxParser/ScalarLit.java
@@ -0,0 +1,42 @@
+package syntaxParser;
+/**
+ * ScalarLit
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani
+ */
+class ScalarLit {
+
+ AtomicLit atomicLit;
+ ComplexLit complexLit;
+ String flag;
+
+ /**
+ * ScalarLit constructor comment.
+ */
+ public ScalarLit() {
+ super();
+ }
+ public ScalarLit( AtomicLit al){
+ atomicLit = al;
+ flag = "atomicLit";
+ }
+
+ public ScalarLit( ComplexLit cl){
+ complexLit = cl;
+ flag = "complexLit";
+ }
+
+ String toXML(){
+ String result="" ;
+ try {
+ if (flag.equals("complexLit")) {
+ result += complexLit.toXML();
+ } else if (flag.equals("atomicLit")) {
+ result += atomicLit.toXML();
+ }
+ } catch (Exception e ) {
+ e.printStackTrace();
+ }
+ return result;
+ }
+}
diff --git a/src/syntaxParser/ScalarLitList.java b/src/syntaxParser/ScalarLitList.java
new file mode 100644
index 0000000..49e187b
--- /dev/null
+++ b/src/syntaxParser/ScalarLitList.java
@@ -0,0 +1,52 @@
+package syntaxParser;
+/**
+ * ScalarLitList class represents a CoverageList.
+ * Creation date: (3/3/2003 2:52:55 AM)
+ * @author: mattia parigiani
+ */
+import java.util.*;
+public class ScalarLitList {
+ private Vector scalarLits;
+
+
+ /**
+ * CoverageList constructor comment.
+ */
+ public ScalarLitList() {
+ super();
+ }
+ public ScalarLitList(ScalarLit sl) {
+ scalarLits = new Vector();
+ scalarLits.add(sl);
+ }
+
+ public ScalarLitList(ScalarLit sl, ScalarLitList l) {
+ scalarLits = l.getScalarLits();
+ scalarLits.add(sl);
+ }
+
+
+ public Vector getScalarLits(){
+ return scalarLits;
+ }
+
+ String toXML(){
+ String result="" ;
+
+
+ for (Enumeration e=scalarLits.elements(); e.hasMoreElements(); ){
+ /*String s= (String)e.nextElement();
+ result += "\n<coverageOrSetName>";
+ result += (s instanceof String)? s: " ";
+ result += "</coverageOrSetName>\n";
+ */
+ }
+
+
+ result += "just parsing";
+ return result;
+ }
+
+
+
+}
diff --git a/src/syntaxParser/ScaleExpr.java b/src/syntaxParser/ScaleExpr.java
new file mode 100644
index 0000000..990a976
--- /dev/null
+++ b/src/syntaxParser/ScaleExpr.java
@@ -0,0 +1,24 @@
+package syntaxParser;
+/**
+ * ScaleExpr
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani, Sorin Stancu-Mara
+ */
+class ScaleExpr implements IParseTreeNode {
+
+ CoverageExpr coverageExpr;
+ AxisIntervalList intervalList;
+ FieldInterpolationList interpMethods;
+
+ public ScaleExpr( CoverageExpr ce, AxisIntervalList ail, FieldInterpolationList iml){
+ coverageExpr = ce;
+ intervalList = ail;
+ intervalList.setTag("scaleAxisSpec");
+ interpMethods = iml;
+ interpMethods.setTag("scaleFieldSpec");
+ }
+
+ public String toXML(){
+ return "<scale>" + intervalList.toXML() + interpMethods.toXML() + coverageExpr.toXML() + "</scale>";
+ }
+}
diff --git a/src/syntaxParser/SelectExpr.java b/src/syntaxParser/SelectExpr.java
new file mode 100644
index 0000000..aa8d23d
--- /dev/null
+++ b/src/syntaxParser/SelectExpr.java
@@ -0,0 +1,22 @@
+package syntaxParser;
+/**
+ * SelectExpr
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani, Sorin Stancu-Mara
+ */
+class SelectExpr implements IParseTreeNode {
+ CoverageExpr coverageExpr;
+ String field;
+
+ public SelectExpr( CoverageExpr ce, String se){
+ coverageExpr = ce;
+ field = se;
+ }
+ public String toXML(){
+ String result="<select>" ;
+ result += "<field>" + field + "</field>";
+ result += coverageExpr.toXML();
+ result += "</select>";
+ return result;
+ }
+}
diff --git a/src/syntaxParser/SetMetaDataExpr.java b/src/syntaxParser/SetMetaDataExpr.java
new file mode 100644
index 0000000..e8624b7
--- /dev/null
+++ b/src/syntaxParser/SetMetaDataExpr.java
@@ -0,0 +1,54 @@
+package syntaxParser;
+/**
+ * SetMetaDataExpr
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani, Sorin Stancu-Mara
+ */
+class SetMetaDataExpr implements IParseTreeNode {
+
+ String function;
+ CoverageExpr expr;
+ IParseTreeNode param;
+ String field;
+
+ public SetMetaDataExpr(String op, CoverageExpr expr,IParseTreeNode param) {
+ function = op;
+ this.expr = expr;
+ this.param = param;
+ }
+ public SetMetaDataExpr(String op, CoverageExpr expr, IParseTreeNode param, String field) {
+ function = op;
+ this.expr = expr;
+ this.param = param;
+ }
+
+ public String toXML(){
+ String result= "" ;
+
+ if (function.equals("setNullDefault")) {
+ result = "<setNullDefault>" + "<null>" + param.toXML() + "</null>"
+ + expr.toXML()
+ + "</setNullDefault>";
+ } else if (function.equals("setNullSet")) {
+ result = "<setNullSet>";
+ RangeValueList list = (RangeValueList) param;
+ list.setTag("null");
+ result += list.toXML();
+ result += expr.toXML() + "</setNullSet>";
+ } else if (function.equals("setInterpolationDefault")) {
+ result = "<setInterpolationDefault><field>" + field + "</field>"
+ + param.toXML() + expr.toXML() + "</setInterpolationDefault>";
+ } else if (function.equals("setInterpolationSet")) {
+ result = "<setInterpolationSet><field>" + field + "</field>" + param.toXML() +
+ expr.toXML() + "</setInterpolationSet>";
+ } else if (function.equals("setCrsSet")) {
+ // TODO(smsorin): schema/grammar inconsistencies
+ result += "<setCrsSet>" + expr.toXML()
+ + "</setCrsSet>";
+ }
+
+ result+= "";
+ return result;
+ }
+
+}
diff --git a/src/syntaxParser/SliceExpr.java b/src/syntaxParser/SliceExpr.java
new file mode 100644
index 0000000..58a69a5
--- /dev/null
+++ b/src/syntaxParser/SliceExpr.java
@@ -0,0 +1,20 @@
+package syntaxParser;
+/**
+ * SliceExpr
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani, Sorin Stancu-Mara
+ */
+class SliceExpr implements IParseTreeNode {
+
+ CoverageExpr coverageExpr;
+ AxisPointList pointList;
+ public SliceExpr( CoverageExpr ce, AxisPointList apl){
+ coverageExpr = ce;
+ pointList = apl;
+ pointList.setTag("sliceAxisSpec");
+ }
+
+ public String toXML(){
+ return "<slice>" + pointList.toXML() + coverageExpr.toXML() + "</slice>";
+ }
+}
diff --git a/src/syntaxParser/StoreExpr.java b/src/syntaxParser/StoreExpr.java
new file mode 100644
index 0000000..0848053
--- /dev/null
+++ b/src/syntaxParser/StoreExpr.java
@@ -0,0 +1,15 @@
+package syntaxParser;
+/* Author: Sorin Stancu-Mara
+Date: 7 Feb 2007
+*/
+
+class StoreExpr implements IParseTreeNode {
+ private EncodedCoverageExpr expr;
+ public StoreExpr(EncodedCoverageExpr e) {
+ expr = e;
+ expr.setStoreFlag();
+ }
+ public String toXML() {
+ return expr.toXML();
+ }
+}
diff --git a/src/syntaxParser/StructuredLiteral.java b/src/syntaxParser/StructuredLiteral.java
new file mode 100644
index 0000000..f6db33c
--- /dev/null
+++ b/src/syntaxParser/StructuredLiteral.java
@@ -0,0 +1,15 @@
+package syntaxParser;
+/* Author: Sorin Stancu-Mara
+ * Date 9 Feb 2007
+ */
+
+class StructuredLiteral implements IParseTreeNode {
+ RangeValueList values;
+ public StructuredLiteral(RangeValueList rvl) {
+ values = rvl;
+ }
+
+ public String toXML() {
+ return values.toXML();
+ }
+}
diff --git a/src/syntaxParser/SubsetExpr.java b/src/syntaxParser/SubsetExpr.java
new file mode 100644
index 0000000..d9020d3
--- /dev/null
+++ b/src/syntaxParser/SubsetExpr.java
@@ -0,0 +1,21 @@
+package syntaxParser;
+/**
+ * SubsetExpr
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani, Sorin Stancu-Mara
+ */
+class SubsetExpr implements IParseTreeNode {
+
+ IParseTreeNode expr;
+
+ public SubsetExpr( IParseTreeNode e ){
+ expr = e;
+ }
+
+ public String toXML(){
+ return expr.toXML();
+ }
+
+
+
+}
diff --git a/src/syntaxParser/SyntaxErrorException.java b/src/syntaxParser/SyntaxErrorException.java
new file mode 100644
index 0000000..e1aa32a
--- /dev/null
+++ b/src/syntaxParser/SyntaxErrorException.java
@@ -0,0 +1,26 @@
+package syntaxParser;
+
+public class SyntaxErrorException extends Exception {
+ private int line;
+ private int column;
+
+ public SyntaxErrorException(int line, int column) {
+ super("Syntax Error");
+ this.line = line;
+ this.column = column;
+ }
+
+ public SyntaxErrorException(int line, int column, String message) {
+ super(message);
+ this.line = line;
+ this.column = column;
+ }
+
+ public int getLine() {
+ return line;
+ }
+
+ public int getColumn() {
+ return column;
+ }
+}
diff --git a/src/syntaxParser/TrigonometricExpr.java b/src/syntaxParser/TrigonometricExpr.java
new file mode 100644
index 0000000..d1a4d06
--- /dev/null
+++ b/src/syntaxParser/TrigonometricExpr.java
@@ -0,0 +1,23 @@
+package syntaxParser;
+/**
+ * TrigonometricExpr
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani, Sorin Stancu-Mara
+ */
+class TrigonometricExpr implements IParseTreeNode {
+ String trigOperator;
+ CoverageExpr coverageExpr;
+
+ public TrigonometricExpr( CoverageExpr ce, String op){
+ trigOperator = op;
+ coverageExpr = ce;
+ }
+
+ public String toXML(){
+ String result= "" ;
+ result += "<" + trigOperator + ">";
+ result += coverageExpr.toXML() ;
+ result += "</" + trigOperator + ">";
+ return result;
+ }
+}
diff --git a/src/syntaxParser/TrimExpr.java b/src/syntaxParser/TrimExpr.java
new file mode 100644
index 0000000..359d139
--- /dev/null
+++ b/src/syntaxParser/TrimExpr.java
@@ -0,0 +1,21 @@
+package syntaxParser;
+/**
+ * TrimExpr
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani, Sorin Stancu-Mara
+ */
+class TrimExpr implements IParseTreeNode {
+
+ CoverageExpr coverageExpr;
+ AxisIntervalList axisIntervals;
+
+ public TrimExpr( CoverageExpr ce, AxisIntervalList al ){
+ coverageExpr = ce;
+ axisIntervals = al;
+ axisIntervals.setTag("trimAxisSpec");
+ }
+
+ public String toXML(){
+ return "<trim>" + axisIntervals.toXML() + coverageExpr.toXML() + "</trim>";
+ }
+}
diff --git a/src/syntaxParser/UnaryArithMeticExpr.java b/src/syntaxParser/UnaryArithMeticExpr.java
new file mode 100644
index 0000000..94d4167
--- /dev/null
+++ b/src/syntaxParser/UnaryArithMeticExpr.java
@@ -0,0 +1,31 @@
+package syntaxParser;
+/**
+ * UnaryArithmeticExpr
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani, Sorin Stancu-Mara
+ */
+class UnaryArithMeticExpr implements IParseTreeNode {
+
+ String operator;
+ CoverageExpr coverageExpr;
+
+ public UnaryArithMeticExpr( CoverageExpr ce, String op){
+ operator = op;
+ coverageExpr = ce;
+ }
+ public String toXML(){
+ String result= "" ;
+ String op;
+ if (operator.equals("+")) {
+ op = "unaryPlus";
+ } else if (operator.equals("-")) {
+ op = "unaryMinus";
+ } else {
+ op = operator;
+ }
+ result += "<" + op + ">\n";
+ result += coverageExpr.toXML() ;
+ result += "</" + op + ">\n";
+ return result;
+ }
+}
diff --git a/src/syntaxParser/UnaryInducedExpr.java b/src/syntaxParser/UnaryInducedExpr.java
new file mode 100644
index 0000000..2c0b9eb
--- /dev/null
+++ b/src/syntaxParser/UnaryInducedExpr.java
@@ -0,0 +1,23 @@
+package syntaxParser;
+/**
+ * UnaryInducedExpr
+ * Creation date: (3/3/2003 2:28:43 AM)
+ * @author: mattia parigiani, Sorin Stancu-Mara
+ */
+class UnaryInducedExpr implements IParseTreeNode {
+
+ IParseTreeNode expr;
+ String flag;
+
+ public UnaryInducedExpr( IParseTreeNode e ){
+ expr = e;
+ }
+
+
+ public String toXML(){
+ return expr.toXML();
+ }
+
+
+
+}
diff --git a/src/syntaxParser/VariableList.java b/src/syntaxParser/VariableList.java
new file mode 100644
index 0000000..f41d0a7
--- /dev/null
+++ b/src/syntaxParser/VariableList.java
@@ -0,0 +1,37 @@
+package syntaxParser;
+/* Author: Sorin Stancu-Mara
+ * Date: 8 Feb 2008
+ */
+
+class VariableList implements IParseTreeNode {
+ String axisType, iteratorName;
+ String lo,hi;
+ VariableList next;
+
+ public VariableList(String type, String name, String lo, String hi) {
+ axisType = type;
+ iteratorName = name;
+ this.lo = lo;
+ this.hi = hi;
+ next = null;
+ }
+
+ public VariableList(String type, String name, String lo, String hi, VariableList next) {
+ axisType = type;
+ iteratorName = name;
+ this.lo = lo;
+ this.hi = hi;
+ this.next = next;
+ }
+
+ public String toXML() {
+ String result = "<axisIterator><axisType>" + axisType + "</axisType>" +
+ "<iteratorVar>" + iteratorName + "</iteratorVar>" +
+ "<coord>" + lo + "</coord>" +
+ "<coord>" + hi + "</coord></axisIterator>";
+
+ if (next != null) result += next.toXML();
+ return result;
+ }
+
+}
diff --git a/src/syntaxParser/WCPSRequest.java b/src/syntaxParser/WCPSRequest.java
new file mode 100644
index 0000000..381244b
--- /dev/null
+++ b/src/syntaxParser/WCPSRequest.java
@@ -0,0 +1,42 @@
+package syntaxParser;
+/**
+ * WCPSRequest class represents a WCPSRequest.
+ * Creation date: (3/3/2003 2:52:55 AM)
+ * @author: *, Sorin Stancu-Mara
+ */
+import java.util.*;
+public class WCPSRequest implements IParseTreeNode {
+ private ForClause forClause;
+ private WhereClause whereClause;
+ private ReturnClause returnClause;
+
+ /**
+ * WCPSRequest constructor comment.
+ */
+ public WCPSRequest() {
+ super();
+ }
+ public WCPSRequest(ForClause f, ReturnClause r) {
+ forClause = f;
+ whereClause = null;
+ returnClause = r;
+ }
+ public WCPSRequest(ForClause f, WhereClause w, ReturnClause r) {
+ forClause = f;
+ whereClause = w;
+ returnClause = r;
+ }
+
+ public String toXML(){
+ String result="<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
+ result += "<processCoverage xmlns=\"http://www.opengis.net/wcps/1.0.0\" service=\"WCPS\" version=\"1.0.0\">\n";
+ result += forClause.toXML();
+ if (whereClause != null) {
+ result += whereClause.toXML();
+ }
+ result += returnClause.toXML();
+ result += "</processCoverage>";
+ return result;
+ }
+
+}
diff --git a/src/syntaxParser/WCPSRequestProcessor.java b/src/syntaxParser/WCPSRequestProcessor.java
new file mode 100644
index 0000000..c6fc86f
--- /dev/null
+++ b/src/syntaxParser/WCPSRequestProcessor.java
@@ -0,0 +1,46 @@
+package syntaxParser;
+/**
+ * WCPSRequestProcessor = Sample source code which makes use of the generated parser to parse a WCPS request stored in script file (request.wcps)
+ * The result XML ProcessCoverage file is stored in the file wcpsRequest.xml
+ * Creation date: (3/3/2003 3:22:26 AM)
+ * @author: mattia parigiani
+ */
+import java.io.*;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.*;
+import javax.xml.parsers.*;
+import javax.xml.transform.dom.*;
+import javax.xml.transform.stream.StreamResult;
+import org.w3c.dom.*;
+
+class WCPSRequestProcessor {
+
+ public static void main(String[] args){
+ try {
+ File inputFile = new File ("request.wcps");
+ WCPSParser parser= new WCPSParser(new WCPSScanner(new FileInputStream(inputFile)));
+ WCPSRequest pm= (WCPSRequest)parser.parse().value;
+ String xmlString=pm.toXML();
+
+ TransformerFactory factory = TransformerFactory.newInstance();
+ factory.setAttribute("indent-number", new Integer(4));
+ DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ Document doc = docBuilder.parse(new ByteArrayInputStream(xmlString.getBytes()));
+ Transformer transformer = factory.newTransformer();
+ transformer.setOutputProperty("omit-xml-declaration","no");
+ transformer.setOutputProperty(OutputKeys.METHOD, "xml");
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+ StringWriter sw = new StringWriter();
+ transformer.transform(new DOMSource(doc), new StreamResult(sw));
+ String formattedXML = sw.toString();
+
+ FileWriter fstream = new FileWriter("wcpsRequest.xml");
+ BufferedWriter out = new BufferedWriter(fstream);
+ out.write(formattedXML);
+ out.close();
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/syntaxParser/WhereClause.java b/src/syntaxParser/WhereClause.java
new file mode 100644
index 0000000..12eb97e
--- /dev/null
+++ b/src/syntaxParser/WhereClause.java
@@ -0,0 +1,14 @@
+package syntaxParser;
+/* Author: Sorin Stancu-Mara
+Date: 7 Feb 2007
+*/
+
+class WhereClause implements IParseTreeNode {
+ private BooleanScalarExpr expr;
+ public WhereClause(BooleanScalarExpr e) {
+ expr = e;
+ }
+ public String toXML() {
+ return "<where>" + expr.toXML() + "</where>";
+ }
+}
diff --git a/src/syntaxParser/java-cup-11a.jar b/src/syntaxParser/java-cup-11a.jar
new file mode 100644
index 0000000..73ffa0b
--- /dev/null
+++ b/src/syntaxParser/java-cup-11a.jar
Binary files differ
diff --git a/src/syntaxParser/java_cup/CUP$parser$actions.class b/src/syntaxParser/java_cup/CUP$parser$actions.class
new file mode 100644
index 0000000..b0b50b0
--- /dev/null
+++ b/src/syntaxParser/java_cup/CUP$parser$actions.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/Main.class b/src/syntaxParser/java_cup/Main.class
new file mode 100644
index 0000000..2947306
--- /dev/null
+++ b/src/syntaxParser/java_cup/Main.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/Main.java b/src/syntaxParser/java_cup/Main.java
new file mode 100644
index 0000000..50811b5
--- /dev/null
+++ b/src/syntaxParser/java_cup/Main.java
@@ -0,0 +1,854 @@
+
+package java_cup;
+
+import java.util.Enumeration;
+import java.io.*;
+
+/** This class serves as the main driver for the JavaCup system.
+ * It accepts user options and coordinates overall control flow.
+ * The main flow of control includes the following activities:
+ * <ul>
+ * <li> Parse user supplied arguments and options.
+ * <li> Open output files.
+ * <li> Parse the specification from standard input.
+ * <li> Check for unused terminals, non-terminals, and productions.
+ * <li> Build the state machine, tables, etc.
+ * <li> Output the generated code.
+ * <li> Close output files.
+ * <li> Print a summary if requested.
+ * </ul>
+ *
+ * Options to the main program include: <dl>
+ * <dt> -package name
+ * <dd> specify package generated classes go in [default none]
+ * <dt> -parser name
+ * <dd> specify parser class name [default "parser"]
+ * <dt> -symbols name
+ * <dd> specify name for symbol constant class [default "sym"]
+ * <dt> -interface
+ * <dd> emit symbol constant <i>interface</i>, rather than class
+ * <dt> -nonterms
+ * <dd> put non terminals in symbol constant class
+ * <dt> -expect #
+ * <dd> number of conflicts expected/allowed [default 0]
+ * <dt> -compact_red
+ * <dd> compact tables by defaulting to most frequent reduce
+ * <dt> -nowarn
+ * <dd> don't warn about useless productions, etc.
+ * <dt> -nosummary
+ * <dd> don't print the usual summary of parse states, etc.
+ * <dt> -progress
+ * <dd> print messages to indicate progress of the system
+ * <dt> -time
+ * <dd> print time usage summary
+ * <dt> -dump_grammar
+ * <dd> produce a dump of the symbols and grammar
+ * <dt> -dump_states
+ * <dd> produce a dump of parse state machine
+ * <dt> -dump_tables
+ * <dd> produce a dump of the parse tables
+ * <dt> -dump
+ * <dd> produce a dump of all of the above
+ * <dt> -debug
+ * <dd> turn on debugging messages within JavaCup
+ * <dt> -nopositions
+ * <dd> don't generate the positions code
+ * <dt> -noscanner
+ * <dd> don't refer to java_cup.runtime.Scanner in the parser
+ * (for compatibility with old runtimes)
+ * <dt> -version
+ * <dd> print version information for JavaCUP and halt.
+ * </dl>
+ *
+ * @version last updated: 7/3/96
+ * @author Frank Flannery
+ */
+
+public class Main {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+ /** Only constructor is private, so we do not allocate any instances of this
+ class. */
+ private Main() { }
+
+ /*-------------------------*/
+ /* Options set by the user */
+ /*-------------------------*/
+ /** User option -- do we print progress messages. */
+ protected static boolean print_progress = true;
+ /** User option -- do we produce a dump of the state machine */
+ protected static boolean opt_dump_states = false;
+ /** User option -- do we produce a dump of the parse tables */
+ protected static boolean opt_dump_tables = false;
+ /** User option -- do we produce a dump of the grammar */
+ protected static boolean opt_dump_grammar = false;
+ /** User option -- do we show timing information as a part of the summary */
+ protected static boolean opt_show_timing = false;
+ /** User option -- do we run produce extra debugging messages */
+ protected static boolean opt_do_debug = false;
+ /** User option -- do we compact tables by making most common reduce the
+ default action */
+ protected static boolean opt_compact_red = false;
+ /** User option -- should we include non terminal symbol numbers in the
+ symbol constant class. */
+ protected static boolean include_non_terms = false;
+ /** User option -- do not print a summary. */
+ protected static boolean no_summary = false;
+ /** User option -- number of conflicts to expect */
+ protected static int expect_conflicts = 0;
+
+ /* frankf added this 6/18/96 */
+ /** User option -- should generator generate code for left/right values? */
+ protected static boolean lr_values = true;
+
+ /** User option -- should symbols be put in a class or an interface? [CSA]*/
+ protected static boolean sym_interface = false;
+
+ /** User option -- should generator suppress references to
+ * java_cup.runtime.Scanner for compatibility with old runtimes? */
+ protected static boolean suppress_scanner = false;
+
+ /*----------------------------------------------------------------------*/
+ /* Timing data (not all of these time intervals are mutually exclusive) */
+ /*----------------------------------------------------------------------*/
+ /** Timing data -- when did we start */
+ protected static long start_time = 0;
+ /** Timing data -- when did we end preliminaries */
+ protected static long prelim_end = 0;
+ /** Timing data -- when did we end parsing */
+ protected static long parse_end = 0;
+ /** Timing data -- when did we end checking */
+ protected static long check_end = 0;
+ /** Timing data -- when did we end dumping */
+ protected static long dump_end = 0;
+ /** Timing data -- when did we end state and table building */
+ protected static long build_end = 0;
+ /** Timing data -- when did we end nullability calculation */
+ protected static long nullability_end = 0;
+ /** Timing data -- when did we end first set calculation */
+ protected static long first_end = 0;
+ /** Timing data -- when did we end state machine construction */
+ protected static long machine_end = 0;
+ /** Timing data -- when did we end table construction */
+ protected static long table_end = 0;
+ /** Timing data -- when did we end checking for non-reduced productions */
+ protected static long reduce_check_end = 0;
+ /** Timing data -- when did we finish emitting code */
+ protected static long emit_end = 0;
+ /** Timing data -- when were we completely done */
+ protected static long final_time = 0;
+
+ /* Additional timing information is also collected in emit */
+
+ /*-----------------------------------------------------------*/
+ /*--- Main Program ------------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** The main driver for the system.
+ * @param argv an array of strings containing command line arguments.
+ */
+ public static void main(String argv[])
+ throws internal_error, java.io.IOException, java.lang.Exception
+ {
+ boolean did_output = false;
+
+ start_time = System.currentTimeMillis();
+
+ /* process user options and arguments */
+ parse_args(argv);
+
+ /* frankf 6/18/96
+ hackish, yes, but works */
+ emit.set_lr_values(lr_values);
+ /* open output files */
+ if (print_progress) System.err.println("Opening files...");
+ /* use a buffered version of standard input */
+ input_file = new BufferedInputStream(System.in);
+
+ prelim_end = System.currentTimeMillis();
+
+ /* parse spec into internal data structures */
+ if (print_progress)
+ System.err.println("Parsing specification from standard input...");
+ parse_grammar_spec();
+
+ parse_end = System.currentTimeMillis();
+
+ /* don't proceed unless we are error free */
+ if (lexer.error_count == 0)
+ {
+ /* check for unused bits */
+ if (print_progress) System.err.println("Checking specification...");
+ check_unused();
+
+ check_end = System.currentTimeMillis();
+
+ /* build the state machine and parse tables */
+ if (print_progress) System.err.println("Building parse tables...");
+ build_parser();
+
+ build_end = System.currentTimeMillis();
+
+ /* output the generated code, if # of conflicts permits */
+ if (lexer.error_count != 0) {
+ // conflicts! don't emit code, don't dump tables.
+ opt_dump_tables = false;
+ } else { // everything's okay, emit parser.
+ if (print_progress) System.err.println("Writing parser...");
+ open_files();
+ emit_parser();
+ did_output = true;
+ }
+ }
+ /* fix up the times to make the summary easier */
+ emit_end = System.currentTimeMillis();
+
+ /* do requested dumps */
+ if (opt_dump_grammar) dump_grammar();
+ if (opt_dump_states) dump_machine();
+ if (opt_dump_tables) dump_tables();
+
+ dump_end = System.currentTimeMillis();
+
+ /* close input/output files */
+ if (print_progress) System.err.println("Closing files...");
+ close_files();
+
+ /* produce a summary if desired */
+ if (!no_summary) emit_summary(did_output);
+
+ /* If there were errors during the run,
+ * exit with non-zero status (makefile-friendliness). --CSA */
+ if (lexer.error_count != 0)
+ System.exit(100);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Print a "usage message" that described possible command line options,
+ * then exit.
+ * @param message a specific error message to preface the usage message by.
+ */
+ protected static void usage(String message)
+ {
+ System.err.println();
+ System.err.println(message);
+ System.err.println();
+ System.err.println(
+"Usage: " + version.program_name + " [options] [filename]\n" +
+" and expects a specification file on standard input if no filename is given.\n" +
+" Legal options include:\n" +
+" -package name specify package generated classes go in [default none]\n" +
+" -parser name specify parser class name [default \"parser\"]\n" +
+" -symbols name specify name for symbol constant class [default \"sym\"]\n"+
+" -interface put symbols in an interface, rather than a class\n" +
+" -nonterms put non terminals in symbol constant class\n" +
+" -expect # number of conflicts expected/allowed [default 0]\n" +
+" -compact_red compact tables by defaulting to most frequent reduce\n" +
+" -nowarn don't warn about useless productions, etc.\n" +
+" -nosummary don't print the usual summary of parse states, etc.\n" +
+" -nopositions don't propagate the left and right token position values\n" +
+" -noscanner don't refer to java_cup.runtime.Scanner\n" +
+" -progress print messages to indicate progress of the system\n" +
+" -time print time usage summary\n" +
+" -dump_grammar produce a human readable dump of the symbols and grammar\n"+
+" -dump_states produce a dump of parse state machine\n"+
+" -dump_tables produce a dump of the parse tables\n"+
+" -dump produce a dump of all of the above\n"+
+" -version print the version information for CUP and exit\n"
+ );
+ System.exit(1);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Parse command line options and arguments to set various user-option
+ * flags and variables.
+ * @param argv the command line arguments to be parsed.
+ */
+ protected static void parse_args(String argv[])
+ {
+ int len = argv.length;
+ int i;
+
+ /* parse the options */
+ for (i=0; i<len; i++)
+ {
+ /* try to get the various options */
+ if (argv[i].equals("-package"))
+ {
+ /* must have an arg */
+ if (++i >= len || argv[i].startsWith("-") ||
+ argv[i].endsWith(".cup"))
+ usage("-package must have a name argument");
+
+ /* record the name */
+ emit.package_name = argv[i];
+ }
+ else if (argv[i].equals("-parser"))
+ {
+ /* must have an arg */
+ if (++i >= len || argv[i].startsWith("-") ||
+ argv[i].endsWith(".cup"))
+ usage("-parser must have a name argument");
+
+ /* record the name */
+ emit.parser_class_name = argv[i];
+ }
+ else if (argv[i].equals("-symbols"))
+ {
+ /* must have an arg */
+ if (++i >= len || argv[i].startsWith("-") ||
+ argv[i].endsWith(".cup"))
+ usage("-symbols must have a name argument");
+
+ /* record the name */
+ emit.symbol_const_class_name = argv[i];
+ }
+ else if (argv[i].equals("-nonterms"))
+ {
+ include_non_terms = true;
+ }
+ else if (argv[i].equals("-expect"))
+ {
+ /* must have an arg */
+ if (++i >= len || argv[i].startsWith("-") ||
+ argv[i].endsWith(".cup"))
+ usage("-expect must have a name argument");
+
+ /* record the number */
+ try {
+ expect_conflicts = Integer.parseInt(argv[i]);
+ } catch (NumberFormatException e) {
+ usage("-expect must be followed by a decimal integer");
+ }
+ }
+ else if (argv[i].equals("-compact_red")) opt_compact_red = true;
+ else if (argv[i].equals("-nosummary")) no_summary = true;
+ else if (argv[i].equals("-nowarn")) emit.nowarn = true;
+ else if (argv[i].equals("-dump_states")) opt_dump_states = true;
+ else if (argv[i].equals("-dump_tables")) opt_dump_tables = true;
+ else if (argv[i].equals("-progress")) print_progress = true;
+ else if (argv[i].equals("-dump_grammar")) opt_dump_grammar = true;
+ else if (argv[i].equals("-dump"))
+ opt_dump_states = opt_dump_tables = opt_dump_grammar = true;
+ else if (argv[i].equals("-time")) opt_show_timing = true;
+ else if (argv[i].equals("-debug")) opt_do_debug = true;
+ /* frankf 6/18/96 */
+ else if (argv[i].equals("-nopositions")) lr_values = false;
+ /* CSA 12/21/97 */
+ else if (argv[i].equals("-interface")) sym_interface = true;
+ /* CSA 23-Jul-1999 */
+ else if (argv[i].equals("-noscanner")) suppress_scanner = true;
+ /* CSA 23-Jul-1999 */
+ else if (argv[i].equals("-version")) {
+ System.out.println(version.title_str);
+ System.exit(1);
+ }
+ /* CSA 24-Jul-1999; suggestion by Jean Vaucher */
+ else if (!argv[i].startsWith("-") && i==len-1) {
+ /* use input from file. */
+ try {
+ System.setIn(new FileInputStream(argv[i]));
+ } catch (java.io.FileNotFoundException e) {
+ usage("Unable to open \"" + argv[i] +"\" for input");
+ }
+ }
+ else
+ {
+ usage("Unrecognized option \"" + argv[i] + "\"");
+ }
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /*-------*/
+ /* Files */
+ /*-------*/
+
+ /** Input file. This is a buffered version of System.in. */
+ protected static BufferedInputStream input_file;
+
+ /** Output file for the parser class. */
+ protected static PrintWriter parser_class_file;
+
+ /** Output file for the symbol constant class. */
+ protected static PrintWriter symbol_class_file;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Open various files used by the system. */
+ protected static void open_files()
+ {
+ File fil;
+ String out_name;
+
+ /* open each of the output files */
+
+ /* parser class */
+ out_name = emit.parser_class_name + ".java";
+ fil = new File(out_name);
+ try {
+ parser_class_file = new PrintWriter(
+ new BufferedOutputStream(new FileOutputStream(fil), 4096));
+ } catch(Exception e) {
+ System.err.println("Can't open \"" + out_name + "\" for output");
+ System.exit(3);
+ }
+
+ /* symbol constants class */
+ out_name = emit.symbol_const_class_name + ".java";
+ fil = new File(out_name);
+ try {
+ symbol_class_file = new PrintWriter(
+ new BufferedOutputStream(new FileOutputStream(fil), 4096));
+ } catch(Exception e) {
+ System.err.println("Can't open \"" + out_name + "\" for output");
+ System.exit(4);
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Close various files used by the system. */
+ protected static void close_files() throws java.io.IOException
+ {
+ if (input_file != null) input_file.close();
+ if (parser_class_file != null) parser_class_file.close();
+ if (symbol_class_file != null) symbol_class_file.close();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Parse the grammar specification from standard input. This produces
+ * sets of terminal, non-terminals, and productions which can be accessed
+ * via static variables of the respective classes, as well as the setting
+ * of various variables (mostly in the emit class) for small user supplied
+ * items such as the code to scan with.
+ */
+ protected static void parse_grammar_spec() throws java.lang.Exception
+ {
+ parser parser_obj;
+
+ /* create a parser and parse with it */
+ parser_obj = new parser();
+ try {
+ if (opt_do_debug)
+ parser_obj.debug_parse();
+ else
+ parser_obj.parse();
+ } catch (Exception e)
+ {
+ /* something threw an exception. catch it and emit a message so we
+ have a line number to work with, then re-throw it */
+ lexer.emit_error("Internal error: Unexpected exception");
+ throw e;
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Check for unused symbols. Unreduced productions get checked when
+ * tables are created.
+ */
+ protected static void check_unused()
+ {
+ terminal term;
+ non_terminal nt;
+
+ /* check for unused terminals */
+ for (Enumeration t = terminal.all(); t.hasMoreElements(); )
+ {
+ term = (terminal)t.nextElement();
+
+ /* don't issue a message for EOF */
+ if (term == terminal.EOF) continue;
+
+ /* or error */
+ if (term == terminal.error) continue;
+
+ /* is this one unused */
+ if (term.use_count() == 0)
+ {
+ /* count it and warn if we are doing warnings */
+ emit.unused_term++;
+ if (!emit.nowarn)
+ {
+ System.err.println("Warning: Terminal \"" + term.name() +
+ "\" was declared but never used");
+ lexer.warning_count++;
+ }
+ }
+ }
+
+ /* check for unused non terminals */
+ for (Enumeration n = non_terminal.all(); n.hasMoreElements(); )
+ {
+ nt = (non_terminal)n.nextElement();
+
+ /* is this one unused */
+ if (nt.use_count() == 0)
+ {
+ /* count and warn if we are doing warnings */
+ emit.unused_term++;
+ if (!emit.nowarn)
+ {
+ System.err.println("Warning: Non terminal \"" + nt.name() +
+ "\" was declared but never used");
+ lexer.warning_count++;
+ }
+ }
+ }
+
+ }
+
+ /* . . . . . . . . . . . . . . . . . . . . . . . . .*/
+ /* . . Internal Results of Generating the Parser . .*/
+ /* . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Start state in the overall state machine. */
+ protected static lalr_state start_state;
+
+ /** Resulting parse action table. */
+ protected static parse_action_table action_table;
+
+ /** Resulting reduce-goto table. */
+ protected static parse_reduce_table reduce_table;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Build the (internal) parser from the previously parsed specification.
+ * This includes:<ul>
+ * <li> Computing nullability of non-terminals.
+ * <li> Computing first sets of non-terminals and productions.
+ * <li> Building the viable prefix recognizer machine.
+ * <li> Filling in the (internal) parse tables.
+ * <li> Checking for unreduced productions.
+ * </ul>
+ */
+ protected static void build_parser() throws internal_error
+ {
+ /* compute nullability of all non terminals */
+ if (opt_do_debug || print_progress)
+ System.err.println(" Computing non-terminal nullability...");
+ non_terminal.compute_nullability();
+
+ nullability_end = System.currentTimeMillis();
+
+ /* compute first sets of all non terminals */
+ if (opt_do_debug || print_progress)
+ System.err.println(" Computing first sets...");
+ non_terminal.compute_first_sets();
+
+ first_end = System.currentTimeMillis();
+
+ /* build the LR viable prefix recognition machine */
+ if (opt_do_debug || print_progress)
+ System.err.println(" Building state machine...");
+ start_state = lalr_state.build_machine(emit.start_production);
+
+ machine_end = System.currentTimeMillis();
+
+ /* build the LR parser action and reduce-goto tables */
+ if (opt_do_debug || print_progress)
+ System.err.println(" Filling in tables...");
+ action_table = new parse_action_table();
+ reduce_table = new parse_reduce_table();
+ for (Enumeration st = lalr_state.all(); st.hasMoreElements(); )
+ {
+ lalr_state lst = (lalr_state)st.nextElement();
+ lst.build_table_entries(
+ action_table, reduce_table);
+ }
+
+ table_end = System.currentTimeMillis();
+
+ /* check and warn for non-reduced productions */
+ if (opt_do_debug || print_progress)
+ System.err.println(" Checking for non-reduced productions...");
+ action_table.check_reductions();
+
+ reduce_check_end = System.currentTimeMillis();
+
+ /* if we have more conflicts than we expected issue a message and die */
+ if (emit.num_conflicts > expect_conflicts)
+ {
+ System.err.println("*** More conflicts encountered than expected " +
+ "-- parser generation aborted");
+ lexer.error_count++; // indicate the problem.
+ // we'll die on return, after clean up.
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Call the emit routines necessary to write out the generated parser. */
+ protected static void emit_parser() throws internal_error
+ {
+ emit.symbols(symbol_class_file, include_non_terms, sym_interface);
+ emit.parser(parser_class_file, action_table, reduce_table,
+ start_state.index(), emit.start_production, opt_compact_red,
+ suppress_scanner);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Helper routine to optionally return a plural or non-plural ending.
+ * @param val the numerical value determining plurality.
+ */
+ protected static String plural(int val)
+ {
+ if (val == 1)
+ return "";
+ else
+ return "s";
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Emit a long summary message to standard error (System.err) which
+ * summarizes what was found in the specification, how many states were
+ * produced, how many conflicts were found, etc. A detailed timing
+ * summary is also produced if it was requested by the user.
+ * @param output_produced did the system get far enough to generate code.
+ */
+ protected static void emit_summary(boolean output_produced)
+ {
+ final_time = System.currentTimeMillis();
+
+ if (no_summary) return;
+
+ System.err.println("------- " + version.title_str +
+ " Parser Generation Summary -------");
+
+ /* error and warning count */
+ System.err.println(" " + lexer.error_count + " error" +
+ plural(lexer.error_count) + " and " + lexer.warning_count +
+ " warning" + plural(lexer.warning_count));
+
+ /* basic stats */
+ System.err.print(" " + terminal.number() + " terminal" +
+ plural(terminal.number()) + ", ");
+ System.err.print(non_terminal.number() + " non-terminal" +
+ plural(non_terminal.number()) + ", and ");
+ System.err.println(production.number() + " production" +
+ plural(production.number()) + " declared, ");
+ System.err.println(" producing " + lalr_state.number() +
+ " unique parse states.");
+
+ /* unused symbols */
+ System.err.println(" " + emit.unused_term + " terminal" +
+ plural(emit.unused_term) + " declared but not used.");
+ System.err.println(" " + emit.unused_non_term + " non-terminal" +
+ plural(emit.unused_term) + " declared but not used.");
+
+ /* productions that didn't reduce */
+ System.err.println(" " + emit.not_reduced + " production" +
+ plural(emit.not_reduced) + " never reduced.");
+
+ /* conflicts */
+ System.err.println(" " + emit.num_conflicts + " conflict" +
+ plural(emit.num_conflicts) + " detected" +
+ " (" + expect_conflicts + " expected).");
+
+ /* code location */
+ if (output_produced)
+ System.err.println(" Code written to \"" + emit.parser_class_name +
+ ".java\", and \"" + emit.symbol_const_class_name + ".java\".");
+ else
+ System.err.println(" No code produced.");
+
+ if (opt_show_timing) show_times();
+
+ System.err.println(
+ "---------------------------------------------------- (" +
+ version.version_str + ")");
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Produce the optional timing summary as part of an overall summary. */
+ protected static void show_times()
+ {
+ long total_time = final_time - start_time;
+
+ System.err.println(". . . . . . . . . . . . . . . . . . . . . . . . . ");
+ System.err.println(" Timing Summary");
+ System.err.println(" Total time "
+ + timestr(final_time-start_time, total_time));
+ System.err.println(" Startup "
+ + timestr(prelim_end-start_time, total_time));
+ System.err.println(" Parse "
+ + timestr(parse_end-prelim_end, total_time) );
+ if (check_end != 0)
+ System.err.println(" Checking "
+ + timestr(check_end-parse_end, total_time));
+ if (check_end != 0 && build_end != 0)
+ System.err.println(" Parser Build "
+ + timestr(build_end-check_end, total_time));
+ if (nullability_end != 0 && check_end != 0)
+ System.err.println(" Nullability "
+ + timestr(nullability_end-check_end, total_time));
+ if (first_end != 0 && nullability_end != 0)
+ System.err.println(" First sets "
+ + timestr(first_end-nullability_end, total_time));
+ if (machine_end != 0 && first_end != 0)
+ System.err.println(" State build "
+ + timestr(machine_end-first_end, total_time));
+ if (table_end != 0 && machine_end != 0)
+ System.err.println(" Table build "
+ + timestr(table_end-machine_end, total_time));
+ if (reduce_check_end != 0 && table_end != 0)
+ System.err.println(" Checking "
+ + timestr(reduce_check_end-table_end, total_time));
+ if (emit_end != 0 && build_end != 0)
+ System.err.println(" Code Output "
+ + timestr(emit_end-build_end, total_time));
+ if (emit.symbols_time != 0)
+ System.err.println(" Symbols "
+ + timestr(emit.symbols_time, total_time));
+ if (emit.parser_time != 0)
+ System.err.println(" Parser class "
+ + timestr(emit.parser_time, total_time));
+ if (emit.action_code_time != 0)
+ System.err.println(" Actions "
+ + timestr(emit.action_code_time, total_time));
+ if (emit.production_table_time != 0)
+ System.err.println(" Prod table "
+ + timestr(emit.production_table_time, total_time));
+ if (emit.action_table_time != 0)
+ System.err.println(" Action tab "
+ + timestr(emit.action_table_time, total_time));
+ if (emit.goto_table_time != 0)
+ System.err.println(" Reduce tab "
+ + timestr(emit.goto_table_time, total_time));
+
+ System.err.println(" Dump Output "
+ + timestr(dump_end-emit_end, total_time));
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Helper routine to format a decimal based display of seconds and
+ * percentage of total time given counts of milliseconds. Note: this
+ * is broken for use with some instances of negative time (since we don't
+ * use any negative time here, we let if be for now).
+ * @param time_val the value being formatted (in ms).
+ * @param total_time total time percentages are calculated against (in ms).
+ */
+ protected static String timestr(long time_val, long total_time)
+ {
+ boolean neg;
+ long ms = 0;
+ long sec = 0;
+ long percent10;
+ String pad;
+
+ /* work with positives only */
+ neg = time_val < 0;
+ if (neg) time_val = -time_val;
+
+ /* pull out seconds and ms */
+ ms = time_val % 1000;
+ sec = time_val / 1000;
+
+ /* construct a pad to blank fill seconds out to 4 places */
+ if (sec < 10)
+ pad = " ";
+ else if (sec < 100)
+ pad = " ";
+ else if (sec < 1000)
+ pad = " ";
+ else
+ pad = "";
+
+ /* calculate 10 times the percentage of total */
+ percent10 = (time_val*1000)/total_time;
+
+ /* build and return the output string */
+ return (neg ? "-" : "") + pad + sec + "." +
+ ((ms%1000)/100) + ((ms%100)/10) + (ms%10) + "sec" +
+ " (" + percent10/10 + "." + percent10%10 + "%)";
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Produce a human readable dump of the grammar. */
+ public static void dump_grammar() throws internal_error
+ {
+ System.err.println("===== Terminals =====");
+ for (int tidx=0, cnt=0; tidx < terminal.number(); tidx++, cnt++)
+ {
+ System.err.print("["+tidx+"]"+terminal.find(tidx).name()+" ");
+ if ((cnt+1) % 5 == 0) System.err.println();
+ }
+ System.err.println();
+ System.err.println();
+
+ System.err.println("===== Non terminals =====");
+ for (int nidx=0, cnt=0; nidx < non_terminal.number(); nidx++, cnt++)
+ {
+ System.err.print("["+nidx+"]"+non_terminal.find(nidx).name()+" ");
+ if ((cnt+1) % 5 == 0) System.err.println();
+ }
+ System.err.println();
+ System.err.println();
+
+
+ System.err.println("===== Productions =====");
+ for (int pidx=0; pidx < production.number(); pidx++)
+ {
+ production prod = production.find(pidx);
+ System.err.print("["+pidx+"] "+prod.lhs().the_symbol().name() + " ::= ");
+ for (int i=0; i<prod.rhs_length(); i++)
+ if (prod.rhs(i).is_action())
+ System.err.print("{action} ");
+ else
+ System.err.print(
+ ((symbol_part)prod.rhs(i)).the_symbol().name() + " ");
+ System.err.println();
+ }
+ System.err.println();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Produce a (semi-) human readable dump of the complete viable prefix
+ * recognition state machine.
+ */
+ public static void dump_machine()
+ {
+ lalr_state ordered[] = new lalr_state[lalr_state.number()];
+
+ /* put the states in sorted order for a nicer display */
+ for (Enumeration s = lalr_state.all(); s.hasMoreElements(); )
+ {
+ lalr_state st = (lalr_state)s.nextElement();
+ ordered[st.index()] = st;
+ }
+
+ System.err.println("===== Viable Prefix Recognizer =====");
+ for (int i = 0; i<lalr_state.number(); i++)
+ {
+ if (ordered[i] == start_state) System.err.print("START ");
+ System.err.println(ordered[i]);
+ System.err.println("-------------------");
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Produce a (semi-) human readable dumps of the parse tables */
+ public static void dump_tables()
+ {
+ System.err.println(action_table);
+ System.err.println(reduce_table);
+ }
+
+ /*-----------------------------------------------------------*/
+
+}
+
diff --git a/src/syntaxParser/java_cup/SAVE/Main.java b/src/syntaxParser/java_cup/SAVE/Main.java
new file mode 100644
index 0000000..50811b5
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/Main.java
@@ -0,0 +1,854 @@
+
+package java_cup;
+
+import java.util.Enumeration;
+import java.io.*;
+
+/** This class serves as the main driver for the JavaCup system.
+ * It accepts user options and coordinates overall control flow.
+ * The main flow of control includes the following activities:
+ * <ul>
+ * <li> Parse user supplied arguments and options.
+ * <li> Open output files.
+ * <li> Parse the specification from standard input.
+ * <li> Check for unused terminals, non-terminals, and productions.
+ * <li> Build the state machine, tables, etc.
+ * <li> Output the generated code.
+ * <li> Close output files.
+ * <li> Print a summary if requested.
+ * </ul>
+ *
+ * Options to the main program include: <dl>
+ * <dt> -package name
+ * <dd> specify package generated classes go in [default none]
+ * <dt> -parser name
+ * <dd> specify parser class name [default "parser"]
+ * <dt> -symbols name
+ * <dd> specify name for symbol constant class [default "sym"]
+ * <dt> -interface
+ * <dd> emit symbol constant <i>interface</i>, rather than class
+ * <dt> -nonterms
+ * <dd> put non terminals in symbol constant class
+ * <dt> -expect #
+ * <dd> number of conflicts expected/allowed [default 0]
+ * <dt> -compact_red
+ * <dd> compact tables by defaulting to most frequent reduce
+ * <dt> -nowarn
+ * <dd> don't warn about useless productions, etc.
+ * <dt> -nosummary
+ * <dd> don't print the usual summary of parse states, etc.
+ * <dt> -progress
+ * <dd> print messages to indicate progress of the system
+ * <dt> -time
+ * <dd> print time usage summary
+ * <dt> -dump_grammar
+ * <dd> produce a dump of the symbols and grammar
+ * <dt> -dump_states
+ * <dd> produce a dump of parse state machine
+ * <dt> -dump_tables
+ * <dd> produce a dump of the parse tables
+ * <dt> -dump
+ * <dd> produce a dump of all of the above
+ * <dt> -debug
+ * <dd> turn on debugging messages within JavaCup
+ * <dt> -nopositions
+ * <dd> don't generate the positions code
+ * <dt> -noscanner
+ * <dd> don't refer to java_cup.runtime.Scanner in the parser
+ * (for compatibility with old runtimes)
+ * <dt> -version
+ * <dd> print version information for JavaCUP and halt.
+ * </dl>
+ *
+ * @version last updated: 7/3/96
+ * @author Frank Flannery
+ */
+
+public class Main {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+ /** Only constructor is private, so we do not allocate any instances of this
+ class. */
+ private Main() { }
+
+ /*-------------------------*/
+ /* Options set by the user */
+ /*-------------------------*/
+ /** User option -- do we print progress messages. */
+ protected static boolean print_progress = true;
+ /** User option -- do we produce a dump of the state machine */
+ protected static boolean opt_dump_states = false;
+ /** User option -- do we produce a dump of the parse tables */
+ protected static boolean opt_dump_tables = false;
+ /** User option -- do we produce a dump of the grammar */
+ protected static boolean opt_dump_grammar = false;
+ /** User option -- do we show timing information as a part of the summary */
+ protected static boolean opt_show_timing = false;
+ /** User option -- do we run produce extra debugging messages */
+ protected static boolean opt_do_debug = false;
+ /** User option -- do we compact tables by making most common reduce the
+ default action */
+ protected static boolean opt_compact_red = false;
+ /** User option -- should we include non terminal symbol numbers in the
+ symbol constant class. */
+ protected static boolean include_non_terms = false;
+ /** User option -- do not print a summary. */
+ protected static boolean no_summary = false;
+ /** User option -- number of conflicts to expect */
+ protected static int expect_conflicts = 0;
+
+ /* frankf added this 6/18/96 */
+ /** User option -- should generator generate code for left/right values? */
+ protected static boolean lr_values = true;
+
+ /** User option -- should symbols be put in a class or an interface? [CSA]*/
+ protected static boolean sym_interface = false;
+
+ /** User option -- should generator suppress references to
+ * java_cup.runtime.Scanner for compatibility with old runtimes? */
+ protected static boolean suppress_scanner = false;
+
+ /*----------------------------------------------------------------------*/
+ /* Timing data (not all of these time intervals are mutually exclusive) */
+ /*----------------------------------------------------------------------*/
+ /** Timing data -- when did we start */
+ protected static long start_time = 0;
+ /** Timing data -- when did we end preliminaries */
+ protected static long prelim_end = 0;
+ /** Timing data -- when did we end parsing */
+ protected static long parse_end = 0;
+ /** Timing data -- when did we end checking */
+ protected static long check_end = 0;
+ /** Timing data -- when did we end dumping */
+ protected static long dump_end = 0;
+ /** Timing data -- when did we end state and table building */
+ protected static long build_end = 0;
+ /** Timing data -- when did we end nullability calculation */
+ protected static long nullability_end = 0;
+ /** Timing data -- when did we end first set calculation */
+ protected static long first_end = 0;
+ /** Timing data -- when did we end state machine construction */
+ protected static long machine_end = 0;
+ /** Timing data -- when did we end table construction */
+ protected static long table_end = 0;
+ /** Timing data -- when did we end checking for non-reduced productions */
+ protected static long reduce_check_end = 0;
+ /** Timing data -- when did we finish emitting code */
+ protected static long emit_end = 0;
+ /** Timing data -- when were we completely done */
+ protected static long final_time = 0;
+
+ /* Additional timing information is also collected in emit */
+
+ /*-----------------------------------------------------------*/
+ /*--- Main Program ------------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** The main driver for the system.
+ * @param argv an array of strings containing command line arguments.
+ */
+ public static void main(String argv[])
+ throws internal_error, java.io.IOException, java.lang.Exception
+ {
+ boolean did_output = false;
+
+ start_time = System.currentTimeMillis();
+
+ /* process user options and arguments */
+ parse_args(argv);
+
+ /* frankf 6/18/96
+ hackish, yes, but works */
+ emit.set_lr_values(lr_values);
+ /* open output files */
+ if (print_progress) System.err.println("Opening files...");
+ /* use a buffered version of standard input */
+ input_file = new BufferedInputStream(System.in);
+
+ prelim_end = System.currentTimeMillis();
+
+ /* parse spec into internal data structures */
+ if (print_progress)
+ System.err.println("Parsing specification from standard input...");
+ parse_grammar_spec();
+
+ parse_end = System.currentTimeMillis();
+
+ /* don't proceed unless we are error free */
+ if (lexer.error_count == 0)
+ {
+ /* check for unused bits */
+ if (print_progress) System.err.println("Checking specification...");
+ check_unused();
+
+ check_end = System.currentTimeMillis();
+
+ /* build the state machine and parse tables */
+ if (print_progress) System.err.println("Building parse tables...");
+ build_parser();
+
+ build_end = System.currentTimeMillis();
+
+ /* output the generated code, if # of conflicts permits */
+ if (lexer.error_count != 0) {
+ // conflicts! don't emit code, don't dump tables.
+ opt_dump_tables = false;
+ } else { // everything's okay, emit parser.
+ if (print_progress) System.err.println("Writing parser...");
+ open_files();
+ emit_parser();
+ did_output = true;
+ }
+ }
+ /* fix up the times to make the summary easier */
+ emit_end = System.currentTimeMillis();
+
+ /* do requested dumps */
+ if (opt_dump_grammar) dump_grammar();
+ if (opt_dump_states) dump_machine();
+ if (opt_dump_tables) dump_tables();
+
+ dump_end = System.currentTimeMillis();
+
+ /* close input/output files */
+ if (print_progress) System.err.println("Closing files...");
+ close_files();
+
+ /* produce a summary if desired */
+ if (!no_summary) emit_summary(did_output);
+
+ /* If there were errors during the run,
+ * exit with non-zero status (makefile-friendliness). --CSA */
+ if (lexer.error_count != 0)
+ System.exit(100);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Print a "usage message" that described possible command line options,
+ * then exit.
+ * @param message a specific error message to preface the usage message by.
+ */
+ protected static void usage(String message)
+ {
+ System.err.println();
+ System.err.println(message);
+ System.err.println();
+ System.err.println(
+"Usage: " + version.program_name + " [options] [filename]\n" +
+" and expects a specification file on standard input if no filename is given.\n" +
+" Legal options include:\n" +
+" -package name specify package generated classes go in [default none]\n" +
+" -parser name specify parser class name [default \"parser\"]\n" +
+" -symbols name specify name for symbol constant class [default \"sym\"]\n"+
+" -interface put symbols in an interface, rather than a class\n" +
+" -nonterms put non terminals in symbol constant class\n" +
+" -expect # number of conflicts expected/allowed [default 0]\n" +
+" -compact_red compact tables by defaulting to most frequent reduce\n" +
+" -nowarn don't warn about useless productions, etc.\n" +
+" -nosummary don't print the usual summary of parse states, etc.\n" +
+" -nopositions don't propagate the left and right token position values\n" +
+" -noscanner don't refer to java_cup.runtime.Scanner\n" +
+" -progress print messages to indicate progress of the system\n" +
+" -time print time usage summary\n" +
+" -dump_grammar produce a human readable dump of the symbols and grammar\n"+
+" -dump_states produce a dump of parse state machine\n"+
+" -dump_tables produce a dump of the parse tables\n"+
+" -dump produce a dump of all of the above\n"+
+" -version print the version information for CUP and exit\n"
+ );
+ System.exit(1);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Parse command line options and arguments to set various user-option
+ * flags and variables.
+ * @param argv the command line arguments to be parsed.
+ */
+ protected static void parse_args(String argv[])
+ {
+ int len = argv.length;
+ int i;
+
+ /* parse the options */
+ for (i=0; i<len; i++)
+ {
+ /* try to get the various options */
+ if (argv[i].equals("-package"))
+ {
+ /* must have an arg */
+ if (++i >= len || argv[i].startsWith("-") ||
+ argv[i].endsWith(".cup"))
+ usage("-package must have a name argument");
+
+ /* record the name */
+ emit.package_name = argv[i];
+ }
+ else if (argv[i].equals("-parser"))
+ {
+ /* must have an arg */
+ if (++i >= len || argv[i].startsWith("-") ||
+ argv[i].endsWith(".cup"))
+ usage("-parser must have a name argument");
+
+ /* record the name */
+ emit.parser_class_name = argv[i];
+ }
+ else if (argv[i].equals("-symbols"))
+ {
+ /* must have an arg */
+ if (++i >= len || argv[i].startsWith("-") ||
+ argv[i].endsWith(".cup"))
+ usage("-symbols must have a name argument");
+
+ /* record the name */
+ emit.symbol_const_class_name = argv[i];
+ }
+ else if (argv[i].equals("-nonterms"))
+ {
+ include_non_terms = true;
+ }
+ else if (argv[i].equals("-expect"))
+ {
+ /* must have an arg */
+ if (++i >= len || argv[i].startsWith("-") ||
+ argv[i].endsWith(".cup"))
+ usage("-expect must have a name argument");
+
+ /* record the number */
+ try {
+ expect_conflicts = Integer.parseInt(argv[i]);
+ } catch (NumberFormatException e) {
+ usage("-expect must be followed by a decimal integer");
+ }
+ }
+ else if (argv[i].equals("-compact_red")) opt_compact_red = true;
+ else if (argv[i].equals("-nosummary")) no_summary = true;
+ else if (argv[i].equals("-nowarn")) emit.nowarn = true;
+ else if (argv[i].equals("-dump_states")) opt_dump_states = true;
+ else if (argv[i].equals("-dump_tables")) opt_dump_tables = true;
+ else if (argv[i].equals("-progress")) print_progress = true;
+ else if (argv[i].equals("-dump_grammar")) opt_dump_grammar = true;
+ else if (argv[i].equals("-dump"))
+ opt_dump_states = opt_dump_tables = opt_dump_grammar = true;
+ else if (argv[i].equals("-time")) opt_show_timing = true;
+ else if (argv[i].equals("-debug")) opt_do_debug = true;
+ /* frankf 6/18/96 */
+ else if (argv[i].equals("-nopositions")) lr_values = false;
+ /* CSA 12/21/97 */
+ else if (argv[i].equals("-interface")) sym_interface = true;
+ /* CSA 23-Jul-1999 */
+ else if (argv[i].equals("-noscanner")) suppress_scanner = true;
+ /* CSA 23-Jul-1999 */
+ else if (argv[i].equals("-version")) {
+ System.out.println(version.title_str);
+ System.exit(1);
+ }
+ /* CSA 24-Jul-1999; suggestion by Jean Vaucher */
+ else if (!argv[i].startsWith("-") && i==len-1) {
+ /* use input from file. */
+ try {
+ System.setIn(new FileInputStream(argv[i]));
+ } catch (java.io.FileNotFoundException e) {
+ usage("Unable to open \"" + argv[i] +"\" for input");
+ }
+ }
+ else
+ {
+ usage("Unrecognized option \"" + argv[i] + "\"");
+ }
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /*-------*/
+ /* Files */
+ /*-------*/
+
+ /** Input file. This is a buffered version of System.in. */
+ protected static BufferedInputStream input_file;
+
+ /** Output file for the parser class. */
+ protected static PrintWriter parser_class_file;
+
+ /** Output file for the symbol constant class. */
+ protected static PrintWriter symbol_class_file;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Open various files used by the system. */
+ protected static void open_files()
+ {
+ File fil;
+ String out_name;
+
+ /* open each of the output files */
+
+ /* parser class */
+ out_name = emit.parser_class_name + ".java";
+ fil = new File(out_name);
+ try {
+ parser_class_file = new PrintWriter(
+ new BufferedOutputStream(new FileOutputStream(fil), 4096));
+ } catch(Exception e) {
+ System.err.println("Can't open \"" + out_name + "\" for output");
+ System.exit(3);
+ }
+
+ /* symbol constants class */
+ out_name = emit.symbol_const_class_name + ".java";
+ fil = new File(out_name);
+ try {
+ symbol_class_file = new PrintWriter(
+ new BufferedOutputStream(new FileOutputStream(fil), 4096));
+ } catch(Exception e) {
+ System.err.println("Can't open \"" + out_name + "\" for output");
+ System.exit(4);
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Close various files used by the system. */
+ protected static void close_files() throws java.io.IOException
+ {
+ if (input_file != null) input_file.close();
+ if (parser_class_file != null) parser_class_file.close();
+ if (symbol_class_file != null) symbol_class_file.close();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Parse the grammar specification from standard input. This produces
+ * sets of terminal, non-terminals, and productions which can be accessed
+ * via static variables of the respective classes, as well as the setting
+ * of various variables (mostly in the emit class) for small user supplied
+ * items such as the code to scan with.
+ */
+ protected static void parse_grammar_spec() throws java.lang.Exception
+ {
+ parser parser_obj;
+
+ /* create a parser and parse with it */
+ parser_obj = new parser();
+ try {
+ if (opt_do_debug)
+ parser_obj.debug_parse();
+ else
+ parser_obj.parse();
+ } catch (Exception e)
+ {
+ /* something threw an exception. catch it and emit a message so we
+ have a line number to work with, then re-throw it */
+ lexer.emit_error("Internal error: Unexpected exception");
+ throw e;
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Check for unused symbols. Unreduced productions get checked when
+ * tables are created.
+ */
+ protected static void check_unused()
+ {
+ terminal term;
+ non_terminal nt;
+
+ /* check for unused terminals */
+ for (Enumeration t = terminal.all(); t.hasMoreElements(); )
+ {
+ term = (terminal)t.nextElement();
+
+ /* don't issue a message for EOF */
+ if (term == terminal.EOF) continue;
+
+ /* or error */
+ if (term == terminal.error) continue;
+
+ /* is this one unused */
+ if (term.use_count() == 0)
+ {
+ /* count it and warn if we are doing warnings */
+ emit.unused_term++;
+ if (!emit.nowarn)
+ {
+ System.err.println("Warning: Terminal \"" + term.name() +
+ "\" was declared but never used");
+ lexer.warning_count++;
+ }
+ }
+ }
+
+ /* check for unused non terminals */
+ for (Enumeration n = non_terminal.all(); n.hasMoreElements(); )
+ {
+ nt = (non_terminal)n.nextElement();
+
+ /* is this one unused */
+ if (nt.use_count() == 0)
+ {
+ /* count and warn if we are doing warnings */
+ emit.unused_term++;
+ if (!emit.nowarn)
+ {
+ System.err.println("Warning: Non terminal \"" + nt.name() +
+ "\" was declared but never used");
+ lexer.warning_count++;
+ }
+ }
+ }
+
+ }
+
+ /* . . . . . . . . . . . . . . . . . . . . . . . . .*/
+ /* . . Internal Results of Generating the Parser . .*/
+ /* . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Start state in the overall state machine. */
+ protected static lalr_state start_state;
+
+ /** Resulting parse action table. */
+ protected static parse_action_table action_table;
+
+ /** Resulting reduce-goto table. */
+ protected static parse_reduce_table reduce_table;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Build the (internal) parser from the previously parsed specification.
+ * This includes:<ul>
+ * <li> Computing nullability of non-terminals.
+ * <li> Computing first sets of non-terminals and productions.
+ * <li> Building the viable prefix recognizer machine.
+ * <li> Filling in the (internal) parse tables.
+ * <li> Checking for unreduced productions.
+ * </ul>
+ */
+ protected static void build_parser() throws internal_error
+ {
+ /* compute nullability of all non terminals */
+ if (opt_do_debug || print_progress)
+ System.err.println(" Computing non-terminal nullability...");
+ non_terminal.compute_nullability();
+
+ nullability_end = System.currentTimeMillis();
+
+ /* compute first sets of all non terminals */
+ if (opt_do_debug || print_progress)
+ System.err.println(" Computing first sets...");
+ non_terminal.compute_first_sets();
+
+ first_end = System.currentTimeMillis();
+
+ /* build the LR viable prefix recognition machine */
+ if (opt_do_debug || print_progress)
+ System.err.println(" Building state machine...");
+ start_state = lalr_state.build_machine(emit.start_production);
+
+ machine_end = System.currentTimeMillis();
+
+ /* build the LR parser action and reduce-goto tables */
+ if (opt_do_debug || print_progress)
+ System.err.println(" Filling in tables...");
+ action_table = new parse_action_table();
+ reduce_table = new parse_reduce_table();
+ for (Enumeration st = lalr_state.all(); st.hasMoreElements(); )
+ {
+ lalr_state lst = (lalr_state)st.nextElement();
+ lst.build_table_entries(
+ action_table, reduce_table);
+ }
+
+ table_end = System.currentTimeMillis();
+
+ /* check and warn for non-reduced productions */
+ if (opt_do_debug || print_progress)
+ System.err.println(" Checking for non-reduced productions...");
+ action_table.check_reductions();
+
+ reduce_check_end = System.currentTimeMillis();
+
+ /* if we have more conflicts than we expected issue a message and die */
+ if (emit.num_conflicts > expect_conflicts)
+ {
+ System.err.println("*** More conflicts encountered than expected " +
+ "-- parser generation aborted");
+ lexer.error_count++; // indicate the problem.
+ // we'll die on return, after clean up.
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Call the emit routines necessary to write out the generated parser. */
+ protected static void emit_parser() throws internal_error
+ {
+ emit.symbols(symbol_class_file, include_non_terms, sym_interface);
+ emit.parser(parser_class_file, action_table, reduce_table,
+ start_state.index(), emit.start_production, opt_compact_red,
+ suppress_scanner);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Helper routine to optionally return a plural or non-plural ending.
+ * @param val the numerical value determining plurality.
+ */
+ protected static String plural(int val)
+ {
+ if (val == 1)
+ return "";
+ else
+ return "s";
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Emit a long summary message to standard error (System.err) which
+ * summarizes what was found in the specification, how many states were
+ * produced, how many conflicts were found, etc. A detailed timing
+ * summary is also produced if it was requested by the user.
+ * @param output_produced did the system get far enough to generate code.
+ */
+ protected static void emit_summary(boolean output_produced)
+ {
+ final_time = System.currentTimeMillis();
+
+ if (no_summary) return;
+
+ System.err.println("------- " + version.title_str +
+ " Parser Generation Summary -------");
+
+ /* error and warning count */
+ System.err.println(" " + lexer.error_count + " error" +
+ plural(lexer.error_count) + " and " + lexer.warning_count +
+ " warning" + plural(lexer.warning_count));
+
+ /* basic stats */
+ System.err.print(" " + terminal.number() + " terminal" +
+ plural(terminal.number()) + ", ");
+ System.err.print(non_terminal.number() + " non-terminal" +
+ plural(non_terminal.number()) + ", and ");
+ System.err.println(production.number() + " production" +
+ plural(production.number()) + " declared, ");
+ System.err.println(" producing " + lalr_state.number() +
+ " unique parse states.");
+
+ /* unused symbols */
+ System.err.println(" " + emit.unused_term + " terminal" +
+ plural(emit.unused_term) + " declared but not used.");
+ System.err.println(" " + emit.unused_non_term + " non-terminal" +
+ plural(emit.unused_term) + " declared but not used.");
+
+ /* productions that didn't reduce */
+ System.err.println(" " + emit.not_reduced + " production" +
+ plural(emit.not_reduced) + " never reduced.");
+
+ /* conflicts */
+ System.err.println(" " + emit.num_conflicts + " conflict" +
+ plural(emit.num_conflicts) + " detected" +
+ " (" + expect_conflicts + " expected).");
+
+ /* code location */
+ if (output_produced)
+ System.err.println(" Code written to \"" + emit.parser_class_name +
+ ".java\", and \"" + emit.symbol_const_class_name + ".java\".");
+ else
+ System.err.println(" No code produced.");
+
+ if (opt_show_timing) show_times();
+
+ System.err.println(
+ "---------------------------------------------------- (" +
+ version.version_str + ")");
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Produce the optional timing summary as part of an overall summary. */
+ protected static void show_times()
+ {
+ long total_time = final_time - start_time;
+
+ System.err.println(". . . . . . . . . . . . . . . . . . . . . . . . . ");
+ System.err.println(" Timing Summary");
+ System.err.println(" Total time "
+ + timestr(final_time-start_time, total_time));
+ System.err.println(" Startup "
+ + timestr(prelim_end-start_time, total_time));
+ System.err.println(" Parse "
+ + timestr(parse_end-prelim_end, total_time) );
+ if (check_end != 0)
+ System.err.println(" Checking "
+ + timestr(check_end-parse_end, total_time));
+ if (check_end != 0 && build_end != 0)
+ System.err.println(" Parser Build "
+ + timestr(build_end-check_end, total_time));
+ if (nullability_end != 0 && check_end != 0)
+ System.err.println(" Nullability "
+ + timestr(nullability_end-check_end, total_time));
+ if (first_end != 0 && nullability_end != 0)
+ System.err.println(" First sets "
+ + timestr(first_end-nullability_end, total_time));
+ if (machine_end != 0 && first_end != 0)
+ System.err.println(" State build "
+ + timestr(machine_end-first_end, total_time));
+ if (table_end != 0 && machine_end != 0)
+ System.err.println(" Table build "
+ + timestr(table_end-machine_end, total_time));
+ if (reduce_check_end != 0 && table_end != 0)
+ System.err.println(" Checking "
+ + timestr(reduce_check_end-table_end, total_time));
+ if (emit_end != 0 && build_end != 0)
+ System.err.println(" Code Output "
+ + timestr(emit_end-build_end, total_time));
+ if (emit.symbols_time != 0)
+ System.err.println(" Symbols "
+ + timestr(emit.symbols_time, total_time));
+ if (emit.parser_time != 0)
+ System.err.println(" Parser class "
+ + timestr(emit.parser_time, total_time));
+ if (emit.action_code_time != 0)
+ System.err.println(" Actions "
+ + timestr(emit.action_code_time, total_time));
+ if (emit.production_table_time != 0)
+ System.err.println(" Prod table "
+ + timestr(emit.production_table_time, total_time));
+ if (emit.action_table_time != 0)
+ System.err.println(" Action tab "
+ + timestr(emit.action_table_time, total_time));
+ if (emit.goto_table_time != 0)
+ System.err.println(" Reduce tab "
+ + timestr(emit.goto_table_time, total_time));
+
+ System.err.println(" Dump Output "
+ + timestr(dump_end-emit_end, total_time));
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Helper routine to format a decimal based display of seconds and
+ * percentage of total time given counts of milliseconds. Note: this
+ * is broken for use with some instances of negative time (since we don't
+ * use any negative time here, we let if be for now).
+ * @param time_val the value being formatted (in ms).
+ * @param total_time total time percentages are calculated against (in ms).
+ */
+ protected static String timestr(long time_val, long total_time)
+ {
+ boolean neg;
+ long ms = 0;
+ long sec = 0;
+ long percent10;
+ String pad;
+
+ /* work with positives only */
+ neg = time_val < 0;
+ if (neg) time_val = -time_val;
+
+ /* pull out seconds and ms */
+ ms = time_val % 1000;
+ sec = time_val / 1000;
+
+ /* construct a pad to blank fill seconds out to 4 places */
+ if (sec < 10)
+ pad = " ";
+ else if (sec < 100)
+ pad = " ";
+ else if (sec < 1000)
+ pad = " ";
+ else
+ pad = "";
+
+ /* calculate 10 times the percentage of total */
+ percent10 = (time_val*1000)/total_time;
+
+ /* build and return the output string */
+ return (neg ? "-" : "") + pad + sec + "." +
+ ((ms%1000)/100) + ((ms%100)/10) + (ms%10) + "sec" +
+ " (" + percent10/10 + "." + percent10%10 + "%)";
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Produce a human readable dump of the grammar. */
+ public static void dump_grammar() throws internal_error
+ {
+ System.err.println("===== Terminals =====");
+ for (int tidx=0, cnt=0; tidx < terminal.number(); tidx++, cnt++)
+ {
+ System.err.print("["+tidx+"]"+terminal.find(tidx).name()+" ");
+ if ((cnt+1) % 5 == 0) System.err.println();
+ }
+ System.err.println();
+ System.err.println();
+
+ System.err.println("===== Non terminals =====");
+ for (int nidx=0, cnt=0; nidx < non_terminal.number(); nidx++, cnt++)
+ {
+ System.err.print("["+nidx+"]"+non_terminal.find(nidx).name()+" ");
+ if ((cnt+1) % 5 == 0) System.err.println();
+ }
+ System.err.println();
+ System.err.println();
+
+
+ System.err.println("===== Productions =====");
+ for (int pidx=0; pidx < production.number(); pidx++)
+ {
+ production prod = production.find(pidx);
+ System.err.print("["+pidx+"] "+prod.lhs().the_symbol().name() + " ::= ");
+ for (int i=0; i<prod.rhs_length(); i++)
+ if (prod.rhs(i).is_action())
+ System.err.print("{action} ");
+ else
+ System.err.print(
+ ((symbol_part)prod.rhs(i)).the_symbol().name() + " ");
+ System.err.println();
+ }
+ System.err.println();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Produce a (semi-) human readable dump of the complete viable prefix
+ * recognition state machine.
+ */
+ public static void dump_machine()
+ {
+ lalr_state ordered[] = new lalr_state[lalr_state.number()];
+
+ /* put the states in sorted order for a nicer display */
+ for (Enumeration s = lalr_state.all(); s.hasMoreElements(); )
+ {
+ lalr_state st = (lalr_state)s.nextElement();
+ ordered[st.index()] = st;
+ }
+
+ System.err.println("===== Viable Prefix Recognizer =====");
+ for (int i = 0; i<lalr_state.number(); i++)
+ {
+ if (ordered[i] == start_state) System.err.print("START ");
+ System.err.println(ordered[i]);
+ System.err.println("-------------------");
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Produce a (semi-) human readable dumps of the parse tables */
+ public static void dump_tables()
+ {
+ System.err.println(action_table);
+ System.err.println(reduce_table);
+ }
+
+ /*-----------------------------------------------------------*/
+
+}
+
diff --git a/src/syntaxParser/java_cup/SAVE/action_part.java b/src/syntaxParser/java_cup/SAVE/action_part.java
new file mode 100644
index 0000000..69e98f5
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/action_part.java
@@ -0,0 +1,93 @@
+
+package java_cup;
+
+/**
+ * This class represents a part of a production which contains an
+ * action. These are eventually eliminated from productions and converted
+ * to trailing actions by factoring out with a production that derives the
+ * empty string (and ends with this action).
+ *
+ * @see java_cup.production
+ * @version last update: 11/25/95
+ * @author Scott Hudson
+ */
+
+public class action_part extends production_part {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructors ------------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Simple constructor.
+ * @param code_str string containing the actual user code.
+ */
+ public action_part(String code_str)
+ {
+ super(/* never have a label on code */null);
+ _code_string = code_str;
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** String containing code for the action in question. */
+ protected String _code_string;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** String containing code for the action in question. */
+ public String code_string() {return _code_string;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Set the code string. */
+ public void set_code_string(String new_str) {_code_string = new_str;}
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Override to report this object as an action. */
+ public boolean is_action() { return true; }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Equality comparison for properly typed object. */
+ public boolean equals(action_part other)
+ {
+ /* compare the strings */
+ return other != null && super.equals(other) &&
+ other.code_string().equals(code_string());
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Generic equality comparison. */
+ public boolean equals(Object other)
+ {
+ if (!(other instanceof action_part))
+ return false;
+ else
+ return equals((action_part)other);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Produce a hash code. */
+ public int hashCode()
+ {
+ return super.hashCode() ^
+ (code_string()==null ? 0 : code_string().hashCode());
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to a string. */
+ public String toString()
+ {
+ return super.toString() + "{" + code_string() + "}";
+ }
+
+ /*-----------------------------------------------------------*/
+}
diff --git a/src/syntaxParser/java_cup/SAVE/action_production.java b/src/syntaxParser/java_cup/SAVE/action_production.java
new file mode 100644
index 0000000..3c0845f
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/action_production.java
@@ -0,0 +1,39 @@
+
+package java_cup;
+
+/** A specialized version of a production used when we split an existing
+ * production in order to remove an embedded action. Here we keep a bit
+ * of extra bookkeeping so that we know where we came from.
+ * @version last updated: 11/25/95
+ * @author Scott Hudson
+ */
+
+public class action_production extends production {
+
+ /** Constructor.
+ * @param base the production we are being factored out of.
+ * @param lhs_sym the LHS symbol for this production.
+ * @param rhs_parts array of production parts for the RHS.
+ * @param rhs_len how much of the rhs_parts array is valid.
+ * @param action_str the trailing reduce action for this production.
+ */
+ public action_production(
+ production base,
+ non_terminal lhs_sym,
+ production_part rhs_parts[],
+ int rhs_len,
+ String action_str)
+ throws internal_error
+ {
+ super(lhs_sym, rhs_parts, rhs_len, action_str);
+ _base_production = base;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** The production we were taken out of. */
+ protected production _base_production;
+
+ /** The production we were taken out of. */
+ public production base_production() {return _base_production;}
+}
diff --git a/src/syntaxParser/java_cup/SAVE/assoc.java b/src/syntaxParser/java_cup/SAVE/assoc.java
new file mode 100644
index 0000000..8d0b50e
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/assoc.java
@@ -0,0 +1,16 @@
+package java_cup;
+
+/* Defines integers that represent the associativity of terminals
+ * @version last updated: 7/3/96
+ * @author Frank Flannery
+ */
+
+public class assoc {
+
+ /* various associativities, no_prec being the default value */
+ public final static int left = 0;
+ public final static int right = 1;
+ public final static int nonassoc = 2;
+ public final static int no_prec = -1;
+
+} \ No newline at end of file
diff --git a/src/syntaxParser/java_cup/SAVE/emit.java b/src/syntaxParser/java_cup/SAVE/emit.java
new file mode 100644
index 0000000..9db9014
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/emit.java
@@ -0,0 +1,897 @@
+package java_cup;
+
+import java.io.PrintWriter;
+import java.util.Stack;
+import java.util.Enumeration;
+import java.util.Date;
+
+/**
+ * This class handles emitting generated code for the resulting parser.
+ * The various parse tables must be constructed, etc. before calling any
+ * routines in this class.<p>
+ *
+ * Three classes are produced by this code:
+ * <dl>
+ * <dt> symbol constant class
+ * <dd> this contains constant declarations for each terminal (and
+ * optionally each non-terminal).
+ * <dt> action class
+ * <dd> this non-public class contains code to invoke all the user actions
+ * that were embedded in the parser specification.
+ * <dt> parser class
+ * <dd> the specialized parser class consisting primarily of some user
+ * supplied general and initialization code, and the parse tables.
+ * </dl><p>
+ *
+ * Three parse tables are created as part of the parser class:
+ * <dl>
+ * <dt> production table
+ * <dd> lists the LHS non terminal number, and the length of the RHS of
+ * each production.
+ * <dt> action table
+ * <dd> for each state of the parse machine, gives the action to be taken
+ * (shift, reduce, or error) under each lookahead symbol.<br>
+ * <dt> reduce-goto table
+ * <dd> when a reduce on a given production is taken, the parse stack is
+ * popped back a number of elements corresponding to the RHS of the
+ * production. This reveals a prior state, which we transition out
+ * of under the LHS non terminal symbol for the production (as if we
+ * had seen the LHS symbol rather than all the symbols matching the
+ * RHS). This table is indexed by non terminal numbers and indicates
+ * how to make these transitions.
+ * </dl><p>
+ *
+ * In addition to the method interface, this class maintains a series of
+ * public global variables and flags indicating how misc. parts of the code
+ * and other output is to be produced, and counting things such as number of
+ * conflicts detected (see the source code and public variables below for
+ * more details).<p>
+ *
+ * This class is "static" (contains only static data and methods).<p>
+ *
+ * @see java_cup.main
+ * @version last update: 11/25/95
+ * @author Scott Hudson
+ */
+
+/* Major externally callable routines here include:
+ symbols - emit the symbol constant class
+ parser - emit the parser class
+
+ In addition the following major internal routines are provided:
+ emit_package - emit a package declaration
+ emit_action_code - emit the class containing the user's actions
+ emit_production_table - emit declaration and init for the production table
+ do_action_table - emit declaration and init for the action table
+ do_reduce_table - emit declaration and init for the reduce-goto table
+
+ Finally, this class uses a number of public instance variables to communicate
+ optional parameters and flags used to control how code is generated,
+ as well as to report counts of various things (such as number of conflicts
+ detected). These include:
+
+ prefix - a prefix string used to prefix names that would
+ otherwise "pollute" someone else's name space.
+ package_name - name of the package emitted code is placed in
+ (or null for an unnamed package.
+ symbol_const_class_name - name of the class containing symbol constants.
+ parser_class_name - name of the class for the resulting parser.
+ action_code - user supplied declarations and other code to be
+ placed in action class.
+ parser_code - user supplied declarations and other code to be
+ placed in parser class.
+ init_code - user supplied code to be executed as the parser
+ is being initialized.
+ scan_code - user supplied code to get the next Symbol.
+ start_production - the start production for the grammar.
+ import_list - list of imports for use with action class.
+ num_conflicts - number of conflicts detected.
+ nowarn - true if we are not to issue warning messages.
+ not_reduced - count of number of productions that never reduce.
+ unused_term - count of unused terminal symbols.
+ unused_non_term - count of unused non terminal symbols.
+ *_time - a series of symbols indicating how long various
+ sub-parts of code generation took (used to produce
+ optional time reports in main).
+*/
+
+public class emit {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Only constructor is private so no instances can be created. */
+ private emit() { }
+
+ /*-----------------------------------------------------------*/
+ /*--- Static (Class) Variables ------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** The prefix placed on names that pollute someone else's name space. */
+ public static String prefix = "CUP$";
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Package that the resulting code goes into (null is used for unnamed). */
+ public static String package_name = null;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Name of the generated class for symbol constants. */
+ public static String symbol_const_class_name = "sym";
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Name of the generated parser class. */
+ public static String parser_class_name = "parser";
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** User declarations for direct inclusion in user action class. */
+ public static String action_code = null;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** User declarations for direct inclusion in parser class. */
+ public static String parser_code = null;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** User code for user_init() which is called during parser initialization. */
+ public static String init_code = null;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** User code for scan() which is called to get the next Symbol. */
+ public static String scan_code = null;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** The start production of the grammar. */
+ public static production start_production = null;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** List of imports (Strings containing class names) to go with actions. */
+ public static Stack import_list = new Stack();
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Number of conflict found while building tables. */
+ public static int num_conflicts = 0;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Do we skip warnings? */
+ public static boolean nowarn = false;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Count of the number on non-reduced productions found. */
+ public static int not_reduced = 0;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Count of unused terminals. */
+ public static int unused_term = 0;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Count of unused non terminals. */
+ public static int unused_non_term = 0;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /* Timing values used to produce timing report in main.*/
+
+ /** Time to produce symbol constant class. */
+ public static long symbols_time = 0;
+
+ /** Time to produce parser class. */
+ public static long parser_time = 0;
+
+ /** Time to produce action code class. */
+ public static long action_code_time = 0;
+
+ /** Time to produce the production table. */
+ public static long production_table_time = 0;
+
+ /** Time to produce the action table. */
+ public static long action_table_time = 0;
+
+ /** Time to produce the reduce-goto table. */
+ public static long goto_table_time = 0;
+
+ /* frankf 6/18/96 */
+ protected static boolean _lr_values;
+
+ /** whether or not to emit code for left and right values */
+ public static boolean lr_values() {return _lr_values;}
+ protected static void set_lr_values(boolean b) { _lr_values = b;}
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Build a string with the standard prefix.
+ * @param str string to prefix.
+ */
+ protected static String pre(String str) {
+ return prefix + parser_class_name + "$" + str;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Emit a package spec if the user wants one.
+ * @param out stream to produce output on.
+ */
+ protected static void emit_package(PrintWriter out)
+ {
+ /* generate a package spec if we have a name for one */
+ if (package_name != null) {
+ out.println("package " + package_name + ";"); out.println();
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Emit code for the symbol constant class, optionally including non terms,
+ * if they have been requested.
+ * @param out stream to produce output on.
+ * @param emit_non_terms do we emit constants for non terminals?
+ * @param sym_interface should we emit an interface, rather than a class?
+ */
+ public static void symbols(PrintWriter out,
+ boolean emit_non_terms, boolean sym_interface)
+ {
+ terminal term;
+ non_terminal nt;
+ String class_or_interface = (sym_interface)?"interface":"class";
+
+ long start_time = System.currentTimeMillis();
+
+ /* top of file */
+ out.println();
+ out.println("//----------------------------------------------------");
+ out.println("// The following code was generated by " +
+ version.title_str);
+ out.println("// " + new Date());
+ out.println("//----------------------------------------------------");
+ out.println();
+ emit_package(out);
+
+ /* class header */
+ out.println("/** CUP generated " + class_or_interface +
+ " containing symbol constants. */");
+ out.println("public " + class_or_interface + " " +
+ symbol_const_class_name + " {");
+
+ out.println(" /* terminals */");
+
+ /* walk over the terminals */ /* later might sort these */
+ for (Enumeration e = terminal.all(); e.hasMoreElements(); )
+ {
+ term = (terminal)e.nextElement();
+
+ /* output a constant decl for the terminal */
+ out.println(" public static final int " + term.name() + " = " +
+ term.index() + ";");
+ }
+
+ /* do the non terminals if they want them (parser doesn't need them) */
+ if (emit_non_terms)
+ {
+ out.println();
+ out.println(" /* non terminals */");
+
+ /* walk over the non terminals */ /* later might sort these */
+ for (Enumeration e = non_terminal.all(); e.hasMoreElements(); )
+ {
+ nt = (non_terminal)e.nextElement();
+
+ /* output a constant decl for the terminal */
+ out.println(" static final int " + nt.name() + " = " +
+ nt.index() + ";");
+ }
+ }
+
+ /* end of class */
+ out.println("}");
+ out.println();
+
+ symbols_time = System.currentTimeMillis() - start_time;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Emit code for the non-public class holding the actual action code.
+ * @param out stream to produce output on.
+ * @param start_prod the start production of the grammar.
+ */
+ protected static void emit_action_code(PrintWriter out, production start_prod)
+ throws internal_error
+ {
+ production prod;
+
+ long start_time = System.currentTimeMillis();
+
+ /* class header */
+ out.println();
+ out.println(
+ "/** Cup generated class to encapsulate user supplied action code.*/"
+ );
+ out.println("class " + pre("actions") + " {");
+
+ /* user supplied code */
+ if (action_code != null)
+ {
+ out.println();
+ out.println(action_code);
+ }
+
+ /* field for parser object */
+ out.println(" private final "+parser_class_name+" parser;");
+
+ /* constructor */
+ out.println();
+ out.println(" /** Constructor */");
+ out.println(" " + pre("actions") + "("+parser_class_name+" parser) {");
+ out.println(" this.parser = parser;");
+ out.println(" }");
+
+ /* action method head */
+ out.println();
+ out.println(" /** Method with the actual generated action code. */");
+ out.println(" public final java_cup.runtime.Symbol " +
+ pre("do_action") + "(");
+ out.println(" int " + pre("act_num,"));
+ out.println(" java_cup.runtime.lr_parser " + pre("parser,"));
+ out.println(" java.util.Stack " + pre("stack,"));
+ out.println(" int " + pre("top)"));
+ out.println(" throws java.lang.Exception");
+ out.println(" {");
+
+ /* declaration of result symbol */
+ /* New declaration!! now return Symbol
+ 6/13/96 frankf */
+ out.println(" /* Symbol object for return from actions */");
+ out.println(" java_cup.runtime.Symbol " + pre("result") + ";");
+ out.println();
+
+ /* switch top */
+ out.println(" /* select the action based on the action number */");
+ out.println(" switch (" + pre("act_num") + ")");
+ out.println(" {");
+
+ /* emit action code for each production as a separate case */
+ for (Enumeration p = production.all(); p.hasMoreElements(); )
+ {
+ prod = (production)p.nextElement();
+
+ /* case label */
+ out.println(" /*. . . . . . . . . . . . . . . . . . . .*/");
+ out.println(" case " + prod.index() + ": // " +
+ prod.to_simple_string());
+
+ /* give them their own block to work in */
+ out.println(" {");
+
+ /* create the result symbol */
+ /*make the variable RESULT which will point to the new Symbol (see below)
+ and be changed by action code
+ 6/13/96 frankf */
+ out.println(" " + prod.lhs().the_symbol().stack_type() +
+ " RESULT = null;");
+
+ /* Add code to propagate RESULT assignments that occur in
+ * action code embedded in a production (ie, non-rightmost
+ * action code). 24-Mar-1998 CSA
+ */
+ for (int i=0; i<prod.rhs_length(); i++) {
+ // only interested in non-terminal symbols.
+ if (!(prod.rhs(i) instanceof symbol_part)) continue;
+ symbol s = ((symbol_part)prod.rhs(i)).the_symbol();
+ if (!(s instanceof non_terminal)) continue;
+ // skip this non-terminal unless it corresponds to
+ // an embedded action production.
+ if (((non_terminal)s).is_embedded_action == false) continue;
+ // OK, it fits. Make a conditional assignment to RESULT.
+ int index = prod.rhs_length() - i - 1; // last rhs is on top.
+ out.println(" " + "// propagate RESULT from " +
+ s.name());
+ out.println(" " + "if ( " +
+ "((java_cup.runtime.Symbol) " + emit.pre("stack") + ".elementAt("
+ + emit.pre("top") + "-" + index + ")).value != null )");
+ out.println(" " + "RESULT = " +
+ "(" + prod.lhs().the_symbol().stack_type() + ") " +
+ "((java_cup.runtime.Symbol) " + emit.pre("stack") + ".elementAt("
+ + emit.pre("top") + "-" + index + ")).value;");
+ }
+
+ /* if there is an action string, emit it */
+ if (prod.action() != null && prod.action().code_string() != null &&
+ !prod.action().equals(""))
+ out.println(prod.action().code_string());
+
+ /* here we have the left and right values being propagated.
+ must make this a command line option.
+ frankf 6/18/96 */
+
+ /* Create the code that assigns the left and right values of
+ the new Symbol that the production is reducing to */
+ if (emit.lr_values()) {
+ int loffset;
+ String leftstring, rightstring;
+ int roffset = 0;
+ rightstring = "((java_cup.runtime.Symbol)" + emit.pre("stack") + ".elementAt(" +
+ emit.pre("top") + "-" + roffset + ")).right";
+ if (prod.rhs_length() == 0)
+ leftstring = rightstring;
+ else {
+ loffset = prod.rhs_length() - 1;
+ leftstring = "((java_cup.runtime.Symbol)" + emit.pre("stack") + ".elementAt(" +
+ emit.pre("top") + "-" + loffset + ")).left";
+ }
+ out.println(" " + pre("result") + " = new java_cup.runtime.Symbol(" +
+ prod.lhs().the_symbol().index() + "/*" +
+ prod.lhs().the_symbol().name() + "*/" +
+ ", " + leftstring + ", " + rightstring + ", RESULT);");
+ } else {
+ out.println(" " + pre("result") + " = new java_cup.runtime.Symbol(" +
+ prod.lhs().the_symbol().index() + "/*" +
+ prod.lhs().the_symbol().name() + "*/" +
+ ", RESULT);");
+ }
+
+ /* end of their block */
+ out.println(" }");
+
+ /* if this was the start production, do action for accept */
+ if (prod == start_prod)
+ {
+ out.println(" /* ACCEPT */");
+ out.println(" " + pre("parser") + ".done_parsing();");
+ }
+
+ /* code to return lhs symbol */
+ out.println(" return " + pre("result") + ";");
+ out.println();
+ }
+
+ /* end of switch */
+ out.println(" /* . . . . . .*/");
+ out.println(" default:");
+ out.println(" throw new Exception(");
+ out.println(" \"Invalid action number found in " +
+ "internal parse table\");");
+ out.println();
+ out.println(" }");
+
+ /* end of method */
+ out.println(" }");
+
+ /* end of class */
+ out.println("}");
+ out.println();
+
+ action_code_time = System.currentTimeMillis() - start_time;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Emit the production table.
+ * @param out stream to produce output on.
+ */
+ protected static void emit_production_table(PrintWriter out)
+ {
+ production all_prods[];
+ production prod;
+
+ long start_time = System.currentTimeMillis();
+
+ /* collect up the productions in order */
+ all_prods = new production[production.number()];
+ for (Enumeration p = production.all(); p.hasMoreElements(); )
+ {
+ prod = (production)p.nextElement();
+ all_prods[prod.index()] = prod;
+ }
+
+ // make short[][]
+ short[][] prod_table = new short[production.number()][2];
+ for (int i = 0; i<production.number(); i++)
+ {
+ prod = all_prods[i];
+ // { lhs symbol , rhs size }
+ prod_table[i][0] = (short) prod.lhs().the_symbol().index();
+ prod_table[i][1] = (short) prod.rhs_length();
+ }
+ /* do the top of the table */
+ out.println();
+ out.println(" /** Production table. */");
+ out.println(" protected static final short _production_table[][] = ");
+ out.print (" unpackFromStrings(");
+ do_table_as_string(out, prod_table);
+ out.println(");");
+
+ /* do the public accessor method */
+ out.println();
+ out.println(" /** Access to production table. */");
+ out.println(" public short[][] production_table() " +
+ "{return _production_table;}");
+
+ production_table_time = System.currentTimeMillis() - start_time;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Emit the action table.
+ * @param out stream to produce output on.
+ * @param act_tab the internal representation of the action table.
+ * @param compact_reduces do we use the most frequent reduce as default?
+ */
+ protected static void do_action_table(
+ PrintWriter out,
+ parse_action_table act_tab,
+ boolean compact_reduces)
+ throws internal_error
+ {
+ parse_action_row row;
+ parse_action act;
+ int red;
+
+ long start_time = System.currentTimeMillis();
+
+ /* collect values for the action table */
+ short[][] action_table = new short[act_tab.num_states()][];
+ /* do each state (row) of the action table */
+ for (int i = 0; i < act_tab.num_states(); i++)
+ {
+ /* get the row */
+ row = act_tab.under_state[i];
+
+ /* determine the default for the row */
+ if (compact_reduces)
+ row.compute_default();
+ else
+ row.default_reduce = -1;
+
+ /* make temporary table for the row. */
+ short[] temp_table = new short[2*row.size()];
+ int nentries = 0;
+
+ /* do each column */
+ for (int j = 0; j < row.size(); j++)
+ {
+ /* extract the action from the table */
+ act = row.under_term[j];
+
+ /* skip error entries these are all defaulted out */
+ if (act.kind() != parse_action.ERROR)
+ {
+ /* first put in the symbol index, then the actual entry */
+
+ /* shifts get positive entries of state number + 1 */
+ if (act.kind() == parse_action.SHIFT)
+ {
+ /* make entry */
+ temp_table[nentries++] = (short) j;
+ temp_table[nentries++] = (short)
+ (((shift_action)act).shift_to().index() + 1);
+ }
+
+ /* reduce actions get negated entries of production# + 1 */
+ else if (act.kind() == parse_action.REDUCE)
+ {
+ /* if its the default entry let it get defaulted out */
+ red = ((reduce_action)act).reduce_with().index();
+ if (red != row.default_reduce) {
+ /* make entry */
+ temp_table[nentries++] = (short) j;
+ temp_table[nentries++] = (short) (-(red+1));
+ }
+ } else if (act.kind() == parse_action.NONASSOC)
+ {
+ /* do nothing, since we just want a syntax error */
+ }
+ /* shouldn't be anything else */
+ else
+ throw new internal_error("Unrecognized action code " +
+ act.kind() + " found in parse table");
+ }
+ }
+
+ /* now we know how big to make the row */
+ action_table[i] = new short[nentries + 2];
+ System.arraycopy(temp_table, 0, action_table[i], 0, nentries);
+
+ /* finish off the row with a default entry */
+ action_table[i][nentries++] = -1;
+ if (row.default_reduce != -1)
+ action_table[i][nentries++] = (short) (-(row.default_reduce+1));
+ else
+ action_table[i][nentries++] = 0;
+ }
+
+ /* finish off the init of the table */
+ out.println();
+ out.println(" /** Parse-action table. */");
+ out.println(" protected static final short[][] _action_table = ");
+ out.print (" unpackFromStrings(");
+ do_table_as_string(out, action_table);
+ out.println(");");
+
+ /* do the public accessor method */
+ out.println();
+ out.println(" /** Access to parse-action table. */");
+ out.println(" public short[][] action_table() {return _action_table;}");
+
+ action_table_time = System.currentTimeMillis() - start_time;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Emit the reduce-goto table.
+ * @param out stream to produce output on.
+ * @param red_tab the internal representation of the reduce-goto table.
+ */
+ protected static void do_reduce_table(
+ PrintWriter out,
+ parse_reduce_table red_tab)
+ {
+ lalr_state goto_st;
+ parse_action act;
+
+ long start_time = System.currentTimeMillis();
+
+ /* collect values for reduce-goto table */
+ short[][] reduce_goto_table = new short[red_tab.num_states()][];
+ /* do each row of the reduce-goto table */
+ for (int i=0; i<red_tab.num_states(); i++)
+ {
+ /* make temporary table for the row. */
+ short[] temp_table = new short[2*red_tab.under_state[i].size()];
+ int nentries = 0;
+ /* do each entry in the row */
+ for (int j=0; j<red_tab.under_state[i].size(); j++)
+ {
+ /* get the entry */
+ goto_st = red_tab.under_state[i].under_non_term[j];
+
+ /* if we have none, skip it */
+ if (goto_st != null)
+ {
+ /* make entries for the index and the value */
+ temp_table[nentries++] = (short) j;
+ temp_table[nentries++] = (short) goto_st.index();
+ }
+ }
+ /* now we know how big to make the row. */
+ reduce_goto_table[i] = new short[nentries+2];
+ System.arraycopy(temp_table, 0, reduce_goto_table[i], 0, nentries);
+
+ /* end row with default value */
+ reduce_goto_table[i][nentries++] = -1;
+ reduce_goto_table[i][nentries++] = -1;
+ }
+
+ /* emit the table. */
+ out.println();
+ out.println(" /** <code>reduce_goto</code> table. */");
+ out.println(" protected static final short[][] _reduce_table = ");
+ out.print (" unpackFromStrings(");
+ do_table_as_string(out, reduce_goto_table);
+ out.println(");");
+
+ /* do the public accessor method */
+ out.println();
+ out.println(" /** Access to <code>reduce_goto</code> table. */");
+ out.println(" public short[][] reduce_table() {return _reduce_table;}");
+ out.println();
+
+ goto_table_time = System.currentTimeMillis() - start_time;
+ }
+
+ // print a string array encoding the given short[][] array.
+ protected static void do_table_as_string(PrintWriter out, short[][] sa) {
+ out.println("new String[] {");
+ out.print(" \"");
+ int nchar=0, nbytes=0;
+ nbytes+=do_escaped(out, (char)(sa.length>>16));
+ nchar =do_newline(out, nchar, nbytes);
+ nbytes+=do_escaped(out, (char)(sa.length&0xFFFF));
+ nchar =do_newline(out, nchar, nbytes);
+ for (int i=0; i<sa.length; i++) {
+ nbytes+=do_escaped(out, (char)(sa[i].length>>16));
+ nchar =do_newline(out, nchar, nbytes);
+ nbytes+=do_escaped(out, (char)(sa[i].length&0xFFFF));
+ nchar =do_newline(out, nchar, nbytes);
+ for (int j=0; j<sa[i].length; j++) {
+ // contents of string are (value+2) to allow for common -1, 0 cases
+ // (UTF-8 encoding is most efficient for 0<c<0x80)
+ nbytes+=do_escaped(out, (char)(2+sa[i][j]));
+ nchar =do_newline(out, nchar, nbytes);
+ }
+ }
+ out.print("\" }");
+ }
+ // split string if it is very long; start new line occasionally for neatness
+ protected static int do_newline(PrintWriter out, int nchar, int nbytes) {
+ if (nbytes > 65500) { out.println("\", "); out.print(" \""); }
+ else if (nchar > 11) { out.println("\" +"); out.print(" \""); }
+ else return nchar+1;
+ return 0;
+ }
+ // output an escape sequence for the given character code.
+ protected static int do_escaped(PrintWriter out, char c) {
+ StringBuffer escape = new StringBuffer();
+ if (c <= 0xFF) {
+ escape.append(Integer.toOctalString(c));
+ while(escape.length() < 3) escape.insert(0, '0');
+ } else {
+ escape.append(Integer.toHexString(c));
+ while(escape.length() < 4) escape.insert(0, '0');
+ escape.insert(0, 'u');
+ }
+ escape.insert(0, '\\');
+ out.print(escape.toString());
+
+ // return number of bytes this takes up in UTF-8 encoding.
+ if (c == 0) return 2;
+ if (c >= 0x01 && c <= 0x7F) return 1;
+ if (c >= 0x80 && c <= 0x7FF) return 2;
+ return 3;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Emit the parser subclass with embedded tables.
+ * @param out stream to produce output on.
+ * @param action_table internal representation of the action table.
+ * @param reduce_table internal representation of the reduce-goto table.
+ * @param start_st start state of the parse machine.
+ * @param start_prod start production of the grammar.
+ * @param compact_reduces do we use most frequent reduce as default?
+ * @param suppress_scanner should scanner be suppressed for compatibility?
+ */
+ public static void parser(
+ PrintWriter out,
+ parse_action_table action_table,
+ parse_reduce_table reduce_table,
+ int start_st,
+ production start_prod,
+ boolean compact_reduces,
+ boolean suppress_scanner)
+ throws internal_error
+ {
+ long start_time = System.currentTimeMillis();
+
+ /* top of file */
+ out.println();
+ out.println("//----------------------------------------------------");
+ out.println("// The following code was generated by " +
+ version.title_str);
+ out.println("// " + new Date());
+ out.println("//----------------------------------------------------");
+ out.println();
+ emit_package(out);
+
+ /* user supplied imports */
+ for (int i = 0; i < import_list.size(); i++)
+ out.println("import " + import_list.elementAt(i) + ";");
+
+ /* class header */
+ out.println();
+ out.println("/** "+version.title_str+" generated parser.");
+ out.println(" * @version " + new Date());
+ out.println(" */");
+ out.println("public class " + parser_class_name +
+ " extends java_cup.runtime.lr_parser {");
+
+ /* constructors [CSA/davidm, 24-jul-99] */
+ out.println();
+ out.println(" /** Default constructor. */");
+ out.println(" public " + parser_class_name + "() {super();}");
+ if (!suppress_scanner) {
+ out.println();
+ out.println(" /** Constructor which sets the default scanner. */");
+ out.println(" public " + parser_class_name +
+ "(java_cup.runtime.Scanner s) {super(s);}");
+ }
+
+ /* emit the various tables */
+ emit_production_table(out);
+ do_action_table(out, action_table, compact_reduces);
+ do_reduce_table(out, reduce_table);
+
+ /* instance of the action encapsulation class */
+ out.println(" /** Instance of action encapsulation class. */");
+ out.println(" protected " + pre("actions") + " action_obj;");
+ out.println();
+
+ /* action object initializer */
+ out.println(" /** Action encapsulation object initializer. */");
+ out.println(" protected void init_actions()");
+ out.println(" {");
+ out.println(" action_obj = new " + pre("actions") + "(this);");
+ out.println(" }");
+ out.println();
+
+ /* access to action code */
+ out.println(" /** Invoke a user supplied parse action. */");
+ out.println(" public java_cup.runtime.Symbol do_action(");
+ out.println(" int act_num,");
+ out.println(" java_cup.runtime.lr_parser parser,");
+ out.println(" java.util.Stack stack,");
+ out.println(" int top)");
+ out.println(" throws java.lang.Exception");
+ out.println(" {");
+ out.println(" /* call code in generated class */");
+ out.println(" return action_obj." + pre("do_action(") +
+ "act_num, parser, stack, top);");
+ out.println(" }");
+ out.println("");
+
+
+ /* method to tell the parser about the start state */
+ out.println(" /** Indicates start state. */");
+ out.println(" public int start_state() {return " + start_st + ";}");
+
+ /* method to indicate start production */
+ out.println(" /** Indicates start production. */");
+ out.println(" public int start_production() {return " +
+ start_production.index() + ";}");
+ out.println();
+
+ /* methods to indicate EOF and error symbol indexes */
+ out.println(" /** <code>EOF</code> Symbol index. */");
+ out.println(" public int EOF_sym() {return " + terminal.EOF.index() +
+ ";}");
+ out.println();
+ out.println(" /** <code>error</code> Symbol index. */");
+ out.println(" public int error_sym() {return " + terminal.error.index() +
+ ";}");
+ out.println();
+
+ /* user supplied code for user_init() */
+ if (init_code != null)
+ {
+ out.println();
+ out.println(" /** User initialization code. */");
+ out.println(" public void user_init() throws java.lang.Exception");
+ out.println(" {");
+ out.println(init_code);
+ out.println(" }");
+ }
+
+ /* user supplied code for scan */
+ if (scan_code != null)
+ {
+ out.println();
+ out.println(" /** Scan to get the next Symbol. */");
+ out.println(" public java_cup.runtime.Symbol scan()");
+ out.println(" throws java.lang.Exception");
+ out.println(" {");
+ out.println(scan_code);
+ out.println(" }");
+ }
+
+ /* user supplied code */
+ if (parser_code != null)
+ {
+ out.println();
+ out.println(parser_code);
+ }
+
+ /* end of class */
+ out.println("}");
+
+ /* put out the action code class */
+ emit_action_code(out, start_prod);
+
+ parser_time = System.currentTimeMillis() - start_time;
+ }
+
+ /*-----------------------------------------------------------*/
+}
diff --git a/src/syntaxParser/java_cup/SAVE/internal_error.java b/src/syntaxParser/java_cup/SAVE/internal_error.java
new file mode 100644
index 0000000..4d3e7c2
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/internal_error.java
@@ -0,0 +1,22 @@
+
+package java_cup;
+
+/** Exception subclass for reporting internal errors in JavaCup. */
+public class internal_error extends Exception
+ {
+ /** Constructor with a message */
+ public internal_error(String msg)
+ {
+ super(msg);
+ }
+
+ /** Method called to do a forced error exit on an internal error
+ for cases when we can't actually throw the exception. */
+ public void crash()
+ {
+ System.err.println("JavaCUP Fatal Internal Error Detected");
+ System.err.println(getMessage());
+ printStackTrace();
+ System.exit(-1);
+ }
+ }
diff --git a/src/syntaxParser/java_cup/SAVE/lalr_item.java b/src/syntaxParser/java_cup/SAVE/lalr_item.java
new file mode 100644
index 0000000..fe92054
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/lalr_item.java
@@ -0,0 +1,330 @@
+package java_cup;
+
+import java.util.Stack;
+import java.util.Enumeration;
+
+/** This class represents an LALR item. Each LALR item consists of
+ * a production, a "dot" at a position within that production, and
+ * a set of lookahead symbols (terminal). (The first two of these parts
+ * are provide by the super class). An item is designed to represent a
+ * configuration that the parser may be in. For example, an item of the
+ * form: <pre>
+ * [A ::= B * C d E , {a,b,c}]
+ * </pre>
+ * indicates that the parser is in the middle of parsing the production <pre>
+ * A ::= B C d E
+ * </pre>
+ * that B has already been parsed, and that we will expect to see a lookahead
+ * of either a, b, or c once the complete RHS of this production has been
+ * found.<p>
+ *
+ * Items may initially be missing some items from their lookahead sets.
+ * Links are maintained from each item to the set of items that would need
+ * to be updated if symbols are added to its lookahead set. During
+ * "lookahead propagation", we add symbols to various lookahead sets and
+ * propagate these changes across these dependency links as needed.
+ *
+ * @see java_cup.lalr_item_set
+ * @see java_cup.lalr_state
+ * @version last updated: 11/25/95
+ * @author Scott Hudson
+ */
+public class lalr_item extends lr_item_core {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Full constructor.
+ * @param prod the production for the item.
+ * @param pos the position of the "dot" within the production.
+ * @param look the set of lookahead symbols.
+ */
+ public lalr_item(production prod, int pos, terminal_set look)
+ throws internal_error
+ {
+ super(prod, pos);
+ _lookahead = look;
+ _propagate_items = new Stack();
+ needs_propagation = true;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Constructor with default position (dot at start).
+ * @param prod the production for the item.
+ * @param look the set of lookahead symbols.
+ */
+ public lalr_item(production prod, terminal_set look) throws internal_error
+ {
+ this(prod,0,look);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Constructor with default position and empty lookahead set.
+ * @param prod the production for the item.
+ */
+ public lalr_item(production prod) throws internal_error
+ {
+ this(prod,0,new terminal_set());
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** The lookahead symbols of the item. */
+ protected terminal_set _lookahead;
+
+ /** The lookahead symbols of the item. */
+ public terminal_set lookahead() {return _lookahead;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Links to items that the lookahead needs to be propagated to. */
+ protected Stack _propagate_items;
+
+ /** Links to items that the lookahead needs to be propagated to */
+ public Stack propagate_items() {return _propagate_items;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Flag to indicate that this item needs to propagate its lookahead
+ * (whether it has changed or not).
+ */
+ protected boolean needs_propagation;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Add a new item to the set of items we propagate to. */
+ public void add_propagate(lalr_item prop_to)
+ {
+ _propagate_items.push(prop_to);
+ needs_propagation = true;
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Propagate incoming lookaheads through this item to others need to
+ * be changed.
+ * @params incoming symbols to potentially be added to lookahead of this item.
+ */
+ public void propagate_lookaheads(terminal_set incoming) throws internal_error
+ {
+ boolean change = false;
+
+ /* if we don't need to propagate, then bail out now */
+ if (!needs_propagation && (incoming == null || incoming.empty()))
+ return;
+
+ /* if we have null incoming, treat as an empty set */
+ if (incoming != null)
+ {
+ /* add the incoming to the lookahead of this item */
+ change = lookahead().add(incoming);
+ }
+
+ /* if we changed or need it anyway, propagate across our links */
+ if (change || needs_propagation)
+ {
+ /* don't need to propagate again */
+ needs_propagation = false;
+
+ /* propagate our lookahead into each item we are linked to */
+ for (int i = 0; i < propagate_items().size(); i++)
+ ((lalr_item)propagate_items().elementAt(i))
+ .propagate_lookaheads(lookahead());
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Produce the new lalr_item that results from shifting the dot one position
+ * to the right.
+ */
+ public lalr_item shift() throws internal_error
+ {
+ lalr_item result;
+
+ /* can't shift if we have dot already at the end */
+ if (dot_at_end())
+ throw new internal_error("Attempt to shift past end of an lalr_item");
+
+ /* create the new item w/ the dot shifted by one */
+ result = new lalr_item(the_production(), dot_pos()+1,
+ new terminal_set(lookahead()));
+
+ /* change in our lookahead needs to be propagated to this item */
+ add_propagate(result);
+
+ return result;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Calculate lookahead representing symbols that could appear after the
+ * symbol that the dot is currently in front of. Note: this routine must
+ * not be invoked before first sets and nullability has been calculated
+ * for all non terminals.
+ */
+ public terminal_set calc_lookahead(terminal_set lookahead_after)
+ throws internal_error
+ {
+ terminal_set result;
+ int pos;
+ production_part part;
+ symbol sym;
+
+ /* sanity check */
+ if (dot_at_end())
+ throw new internal_error(
+ "Attempt to calculate a lookahead set with a completed item");
+
+ /* start with an empty result */
+ result = new terminal_set();
+
+ /* consider all nullable symbols after the one to the right of the dot */
+ for (pos = dot_pos()+1; pos < the_production().rhs_length(); pos++)
+ {
+ part = the_production().rhs(pos);
+
+ /* consider what kind of production part it is -- skip actions */
+ if (!part.is_action())
+ {
+ sym = ((symbol_part)part).the_symbol();
+
+ /* if its a terminal add it in and we are done */
+ if (!sym.is_non_term())
+ {
+ result.add((terminal)sym);
+ return result;
+ }
+ else
+ {
+ /* otherwise add in first set of the non terminal */
+ result.add(((non_terminal)sym).first_set());
+
+ /* if its nullable we continue adding, if not, we are done */
+ if (!((non_terminal)sym).nullable())
+ return result;
+ }
+ }
+ }
+
+ /* if we get here everything past the dot was nullable
+ we add in the lookahead for after the production and we are done */
+ result.add(lookahead_after);
+ return result;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Determine if everything from the symbol one beyond the dot all the
+ * way to the end of the right hand side is nullable. This would indicate
+ * that the lookahead of this item must be included in the lookaheads of
+ * all items produced as a closure of this item. Note: this routine should
+ * not be invoked until after first sets and nullability have been
+ * calculated for all non terminals.
+ */
+ public boolean lookahead_visible() throws internal_error
+ {
+ production_part part;
+ symbol sym;
+
+ /* if the dot is at the end, we have a problem, but the cleanest thing
+ to do is just return true. */
+ if (dot_at_end()) return true;
+
+ /* walk down the rhs and bail if we get a non-nullable symbol */
+ for (int pos = dot_pos() + 1; pos < the_production().rhs_length(); pos++)
+ {
+ part = the_production().rhs(pos);
+
+ /* skip actions */
+ if (!part.is_action())
+ {
+ sym = ((symbol_part)part).the_symbol();
+
+ /* if its a terminal we fail */
+ if (!sym.is_non_term()) return false;
+
+ /* if its not nullable we fail */
+ if (!((non_terminal)sym).nullable()) return false;
+ }
+ }
+
+ /* if we get here its all nullable */
+ return true;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Equality comparison -- here we only require the cores to be equal since
+ * we need to do sets of items based only on core equality (ignoring
+ * lookahead sets).
+ */
+ public boolean equals(lalr_item other)
+ {
+ if (other == null) return false;
+ return super.equals(other);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Generic equality comparison. */
+ public boolean equals(Object other)
+ {
+ if (!(other instanceof lalr_item))
+ return false;
+ else
+ return equals((lalr_item)other);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Return a hash code -- here we only hash the core since we only test core
+ * matching in LALR items.
+ */
+ public int hashCode()
+ {
+ return super.hashCode();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to string. */
+ public String toString()
+ {
+ String result = "";
+
+ // additional output for debugging:
+ // result += "(" + obj_hash() + ")";
+ result += "[";
+ result += super.toString();
+ result += ", ";
+ if (lookahead() != null)
+ {
+ result += "{";
+ for (int t = 0; t < terminal.number(); t++)
+ if (lookahead().contains(t))
+ result += terminal.find(t).name() + " ";
+ result += "}";
+ }
+ else
+ result += "NULL LOOKAHEAD!!";
+ result += "]";
+
+ // additional output for debugging:
+ // result += " -> ";
+ // for (int i = 0; i<propagate_items().size(); i++)
+ // result+=((lalr_item)(propagate_items().elementAt(i))).obj_hash()+" ";
+ //
+ // if (needs_propagation) result += " NP";
+
+ return result;
+ }
+ /*-----------------------------------------------------------*/
+}
diff --git a/src/syntaxParser/java_cup/SAVE/lalr_item_set.java b/src/syntaxParser/java_cup/SAVE/lalr_item_set.java
new file mode 100644
index 0000000..233a68f
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/lalr_item_set.java
@@ -0,0 +1,371 @@
+
+package java_cup;
+
+import java.util.Hashtable;
+import java.util.Enumeration;
+
+/** This class represents a set of LALR items. For purposes of building
+ * these sets, items are considered unique only if they have unique cores
+ * (i.e., ignoring differences in their lookahead sets).<p>
+ *
+ * This class provides fairly conventional set oriented operations (union,
+ * sub/super-set tests, etc.), as well as an LALR "closure" operation (see
+ * compute_closure()).
+ *
+ * @see java_cup.lalr_item
+ * @see java_cup.lalr_state
+ * @version last updated: 3/6/96
+ * @author Scott Hudson
+ */
+
+public class lalr_item_set {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Constructor for an empty set. */
+ public lalr_item_set() { }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Constructor for cloning from another set.
+ * @param other indicates set we should copy from.
+ */
+ public lalr_item_set(lalr_item_set other)
+ throws internal_error
+ {
+ not_null(other);
+ _all = (Hashtable)other._all.clone();
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** A hash table to implement the set. We store the items using themselves
+ * as keys.
+ */
+ protected Hashtable _all = new Hashtable(11);
+
+ /** Access to all elements of the set. */
+ public Enumeration all() {return _all.elements();}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Cached hashcode for this set. */
+ protected Integer hashcode_cache = null;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Size of the set */
+ public int size() {return _all.size();}
+
+ /*-----------------------------------------------------------*/
+ /*--- Set Operation Methods ---------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Does the set contain a particular item?
+ * @param itm the item in question.
+ */
+ public boolean contains(lalr_item itm) {return _all.containsKey(itm);}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Return the item in the set matching a particular item (or null if not
+ * found)
+ * @param itm the item we are looking for.
+ */
+ public lalr_item find(lalr_item itm) {return (lalr_item)_all.get(itm);}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Is this set an (improper) subset of another?
+ * @param other the other set in question.
+ */
+ public boolean is_subset_of(lalr_item_set other) throws internal_error
+ {
+ not_null(other);
+
+ /* walk down our set and make sure every element is in the other */
+ for (Enumeration e = all(); e.hasMoreElements(); )
+ if (!other.contains((lalr_item)e.nextElement()))
+ return false;
+
+ /* they were all there */
+ return true;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Is this set an (improper) superset of another?
+ * @param other the other set in question.
+ */
+ public boolean is_superset_of(lalr_item_set other) throws internal_error
+ {
+ not_null(other);
+ return other.is_subset_of(this);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Add a singleton item, merging lookahead sets if the item is already
+ * part of the set. returns the element of the set that was added or
+ * merged into.
+ * @param itm the item being added.
+ */
+ public lalr_item add(lalr_item itm) throws internal_error
+ {
+ lalr_item other;
+
+ not_null(itm);
+
+ /* see if an item with a matching core is already there */
+ other = (lalr_item)_all.get(itm);
+
+ /* if so, merge this lookahead into the original and leave it */
+ if (other != null)
+ {
+ other.lookahead().add(itm.lookahead());
+ return other;
+ }
+ /* otherwise we just go in the set */
+ else
+ {
+ /* invalidate cached hashcode */
+ hashcode_cache = null;
+
+ _all.put(itm,itm);
+ return itm;
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Remove a single item if it is in the set.
+ * @param itm the item to remove.
+ */
+ public void remove(lalr_item itm) throws internal_error
+ {
+ not_null(itm);
+
+ /* invalidate cached hashcode */
+ hashcode_cache = null;
+
+ /* remove it from hash table implementing set */
+ _all.remove(itm);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Add a complete set, merging lookaheads where items are already in
+ * the set
+ * @param other the set to be added.
+ */
+ public void add(lalr_item_set other) throws internal_error
+ {
+ not_null(other);
+
+ /* walk down the other set and do the adds individually */
+ for (Enumeration e = other.all(); e.hasMoreElements(); )
+ add((lalr_item)e.nextElement());
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Remove (set subtract) a complete set.
+ * @param other the set to remove.
+ */
+ public void remove(lalr_item_set other) throws internal_error
+ {
+ not_null(other);
+
+ /* walk down the other set and do the removes individually */
+ for (Enumeration e = other.all(); e.hasMoreElements(); )
+ remove((lalr_item)e.nextElement());
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Remove and return one item from the set (done in hash order). */
+ public lalr_item get_one() throws internal_error
+ {
+ Enumeration the_set;
+ lalr_item result;
+
+ the_set = all();
+ if (the_set.hasMoreElements())
+ {
+ result = (lalr_item)the_set.nextElement();
+ remove(result);
+ return result;
+ }
+ else
+ return null;
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Helper function for null test. Throws an interal_error exception if its
+ * parameter is null.
+ * @param obj the object we are testing.
+ */
+ protected void not_null(Object obj) throws internal_error
+ {
+ if (obj == null)
+ throw new internal_error("Null object used in set operation");
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Compute the closure of the set using the LALR closure rules. Basically
+ * for every item of the form: <pre>
+ * [L ::= a *N alpha, l]
+ * </pre>
+ * (where N is a a non terminal and alpha is a string of symbols) make
+ * sure there are also items of the form: <pre>
+ * [N ::= *beta, first(alpha l)]
+ * </pre>
+ * corresponding to each production of N. Items with identical cores but
+ * differing lookahead sets are merged by creating a new item with the same
+ * core and the union of the lookahead sets (the LA in LALR stands for
+ * "lookahead merged" and this is where the merger is). This routine
+ * assumes that nullability and first sets have been computed for all
+ * productions before it is called.
+ */
+ public void compute_closure()
+ throws internal_error
+ {
+ lalr_item_set consider;
+ lalr_item itm, new_itm, add_itm;
+ non_terminal nt;
+ terminal_set new_lookaheads;
+ Enumeration p;
+ production prod;
+ boolean need_prop;
+
+
+
+ /* invalidate cached hashcode */
+ hashcode_cache = null;
+
+ /* each current element needs to be considered */
+ consider = new lalr_item_set(this);
+
+ /* repeat this until there is nothing else to consider */
+ while (consider.size() > 0)
+ {
+ /* get one item to consider */
+ itm = consider.get_one();
+
+ /* do we have a dot before a non terminal */
+ nt = itm.dot_before_nt();
+ if (nt != null)
+ {
+ /* create the lookahead set based on first after dot */
+ new_lookaheads = itm.calc_lookahead(itm.lookahead());
+
+ /* are we going to need to propagate our lookahead to new item */
+ need_prop = itm.lookahead_visible();
+
+ /* create items for each production of that non term */
+ for (p = nt.productions(); p.hasMoreElements(); )
+ {
+ prod = (production)p.nextElement();
+
+ /* create new item with dot at start and that lookahead */
+ new_itm = new lalr_item(prod,
+ new terminal_set(new_lookaheads));
+
+ /* add/merge item into the set */
+ add_itm = add(new_itm);
+ /* if propagation is needed link to that item */
+ if (need_prop)
+ itm.add_propagate(add_itm);
+
+ /* was this was a new item*/
+ if (add_itm == new_itm)
+ {
+ /* that may need further closure, consider it also */
+ consider.add(new_itm);
+ }
+ }
+ }
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Equality comparison. */
+ public boolean equals(lalr_item_set other)
+ {
+ if (other == null || other.size() != size()) return false;
+
+ /* once we know they are the same size, then improper subset does test */
+ try {
+ return is_subset_of(other);
+ } catch (internal_error e) {
+ /* can't throw error from here (because superclass doesn't) so crash */
+ e.crash();
+ return false;
+ }
+
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Generic equality comparison. */
+ public boolean equals(Object other)
+ {
+ if (!(other instanceof lalr_item_set))
+ return false;
+ else
+ return equals((lalr_item_set)other);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Return hash code. */
+ public int hashCode()
+ {
+ int result = 0;
+ Enumeration e;
+ int cnt;
+
+ /* only compute a new one if we don't have it cached */
+ if (hashcode_cache == null)
+ {
+ /* hash together codes from at most first 5 elements */
+ // CSA fix! we'd *like* to hash just a few elements, but
+ // that means equal sets will have inequal hashcodes, which
+ // we're not allowed (by contract) to do. So hash them all.
+ for (e = all(), cnt=0 ; e.hasMoreElements() /*&& cnt<5*/; cnt++)
+ result ^= ((lalr_item)e.nextElement()).hashCode();
+
+ hashcode_cache = new Integer(result);
+ }
+
+ return hashcode_cache.intValue();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to string. */
+ public String toString()
+ {
+ StringBuffer result = new StringBuffer();
+
+ result.append("{\n");
+ for (Enumeration e=all(); e.hasMoreElements(); )
+ {
+ result.append(" " + (lalr_item)e.nextElement() + "\n");
+ }
+ result.append("}");
+
+ return result.toString();
+ }
+ /*-----------------------------------------------------------*/
+}
+
diff --git a/src/syntaxParser/java_cup/SAVE/lalr_state.java b/src/syntaxParser/java_cup/SAVE/lalr_state.java
new file mode 100644
index 0000000..5298e87
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/lalr_state.java
@@ -0,0 +1,884 @@
+
+package java_cup;
+
+import java.util.Hashtable;
+import java.util.Enumeration;
+import java.util.Stack;
+
+/** This class represents a state in the LALR viable prefix recognition machine.
+ * A state consists of an LALR item set and a set of transitions to other
+ * states under terminal and non-terminal symbols. Each state represents
+ * a potential configuration of the parser. If the item set of a state
+ * includes an item such as: <pre>
+ * [A ::= B * C d E , {a,b,c}]
+ * </pre>
+ * this indicates that when the parser is in this state it is currently
+ * looking for an A of the given form, has already seen the B, and would
+ * expect to see an a, b, or c after this sequence is complete. Note that
+ * the parser is normally looking for several things at once (represented
+ * by several items). In our example above, the state would also include
+ * items such as: <pre>
+ * [C ::= * X e Z, {d}]
+ * [X ::= * f, {e}]
+ * </pre>
+ * to indicate that it was currently looking for a C followed by a d (which
+ * would be reduced into a C, matching the first symbol in our production
+ * above), and the terminal f followed by e.<p>
+ *
+ * At runtime, the parser uses a viable prefix recognition machine made up
+ * of these states to parse. The parser has two operations, shift and reduce.
+ * In a shift, it consumes one Symbol and makes a transition to a new state.
+ * This corresponds to "moving the dot past" a terminal in one or more items
+ * in the state (these new shifted items will then be found in the state at
+ * the end of the transition). For a reduce operation, the parser is
+ * signifying that it is recognizing the RHS of some production. To do this
+ * it first "backs up" by popping a stack of previously saved states. It
+ * pops off the same number of states as are found in the RHS of the
+ * production. This leaves the machine in the same state is was in when the
+ * parser first attempted to find the RHS. From this state it makes a
+ * transition based on the non-terminal on the LHS of the production. This
+ * corresponds to placing the parse in a configuration equivalent to having
+ * replaced all the symbols from the the input corresponding to the RHS with
+ * the symbol on the LHS.
+ *
+ * @see java_cup.lalr_item
+ * @see java_cup.lalr_item_set
+ * @see java_cup.lalr_transition
+ * @version last updated: 7/3/96
+ * @author Frank Flannery
+ *
+ */
+
+public class lalr_state {
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Constructor for building a state from a set of items.
+ * @param itms the set of items that makes up this state.
+ */
+ public lalr_state(lalr_item_set itms) throws internal_error
+ {
+ /* don't allow null or duplicate item sets */
+ if (itms == null)
+ throw new internal_error(
+ "Attempt to construct an LALR state from a null item set");
+
+ if (find_state(itms) != null)
+ throw new internal_error(
+ "Attempt to construct a duplicate LALR state");
+
+ /* assign a unique index */
+ _index = next_index++;
+
+ /* store the items */
+ _items = itms;
+
+ /* add to the global collection, keyed with its item set */
+ _all.put(_items,this);
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Static (Class) Variables ------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Collection of all states. */
+ protected static Hashtable _all = new Hashtable();
+
+ /** Collection of all states. */
+ public static Enumeration all() {return _all.elements();}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Indicate total number of states there are. */
+ public static int number() {return _all.size();}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Hash table to find states by their kernels (i.e, the original,
+ * unclosed, set of items -- which uniquely define the state). This table
+ * stores state objects using (a copy of) their kernel item sets as keys.
+ */
+ protected static Hashtable _all_kernels = new Hashtable();
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Find and return state with a given a kernel item set (or null if not
+ * found). The kernel item set is the subset of items that were used to
+ * originally create the state. These items are formed by "shifting the
+ * dot" within items of other states that have a transition to this one.
+ * The remaining elements of this state's item set are added during closure.
+ * @param itms the kernel set of the state we are looking for.
+ */
+ public static lalr_state find_state(lalr_item_set itms)
+ {
+ if (itms == null)
+ return null;
+ else
+ return (lalr_state)_all.get(itms);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Static counter for assigning unique state indexes. */
+ protected static int next_index = 0;
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** The item set for this state. */
+ protected lalr_item_set _items;
+
+ /** The item set for this state. */
+ public lalr_item_set items() {return _items;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** List of transitions out of this state. */
+ protected lalr_transition _transitions = null;
+
+ /** List of transitions out of this state. */
+ public lalr_transition transitions() {return _transitions;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Index of this state in the parse tables */
+ protected int _index;
+
+ /** Index of this state in the parse tables */
+ public int index() {return _index;}
+
+ /*-----------------------------------------------------------*/
+ /*--- Static Methods ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Helper routine for debugging -- produces a dump of the given state
+ * onto System.out.
+ */
+ protected static void dump_state(lalr_state st) throws internal_error
+ {
+ lalr_item_set itms;
+ lalr_item itm;
+ production_part part;
+
+ if (st == null)
+ {
+ System.out.println("NULL lalr_state");
+ return;
+ }
+
+ System.out.println("lalr_state [" + st.index() + "] {");
+ itms = st.items();
+ for (Enumeration e = itms.all(); e.hasMoreElements(); )
+ {
+ itm = (lalr_item)e.nextElement();
+ System.out.print(" [");
+ System.out.print(itm.the_production().lhs().the_symbol().name());
+ System.out.print(" ::= ");
+ for (int i = 0; i<itm.the_production().rhs_length(); i++)
+ {
+ if (i == itm.dot_pos()) System.out.print("(*) ");
+ part = itm.the_production().rhs(i);
+ if (part.is_action())
+ System.out.print("{action} ");
+ else
+ System.out.print(((symbol_part)part).the_symbol().name() + " ");
+ }
+ if (itm.dot_at_end()) System.out.print("(*) ");
+ System.out.println("]");
+ }
+ System.out.println("}");
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Propagate lookahead sets through the constructed viable prefix
+ * recognizer. When the machine is constructed, each item that results
+ in the creation of another such that its lookahead is included in the
+ other's will have a propagate link set up for it. This allows additions
+ to the lookahead of one item to be included in other items that it
+ was used to directly or indirectly create.
+ */
+ protected static void propagate_all_lookaheads() throws internal_error
+ {
+ /* iterate across all states */
+ for (Enumeration st = all(); st.hasMoreElements(); )
+ {
+ /* propagate lookaheads out of that state */
+ ((lalr_state)st.nextElement()).propagate_lookaheads();
+ }
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Add a transition out of this state to another.
+ * @param on_sym the symbol the transition is under.
+ * @param to_st the state the transition goes to.
+ */
+ public void add_transition(symbol on_sym, lalr_state to_st)
+ throws internal_error
+ {
+ lalr_transition trans;
+
+ /* create a new transition object and put it in our list */
+ trans = new lalr_transition(on_sym, to_st, _transitions);
+ _transitions = trans;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Build an LALR viable prefix recognition machine given a start
+ * production. This method operates by first building a start state
+ * from the start production (based on a single item with the dot at
+ * the beginning and EOF as expected lookahead). Then for each state
+ * it attempts to extend the machine by creating transitions out of
+ * the state to new or existing states. When considering extension
+ * from a state we make a transition on each symbol that appears before
+ * the dot in some item. For example, if we have the items: <pre>
+ * [A ::= a b * X c, {d,e}]
+ * [B ::= a b * X d, {a,b}]
+ * </pre>
+ * in some state, then we would be making a transition under X to a new
+ * state. This new state would be formed by a "kernel" of items
+ * corresponding to moving the dot past the X. In this case: <pre>
+ * [A ::= a b X * c, {d,e}]
+ * [B ::= a b X * Y, {a,b}]
+ * </pre>
+ * The full state would then be formed by "closing" this kernel set of
+ * items so that it included items that represented productions of things
+ * the parser was now looking for. In this case we would items
+ * corresponding to productions of Y, since various forms of Y are expected
+ * next when in this state (see lalr_item_set.compute_closure() for details
+ * on closure). <p>
+ *
+ * The process of building the viable prefix recognizer terminates when no
+ * new states can be added. However, in order to build a smaller number of
+ * states (i.e., corresponding to LALR rather than canonical LR) the state
+ * building process does not maintain full loookaheads in all items.
+ * Consequently, after the machine is built, we go back and propagate
+ * lookaheads through the constructed machine using a call to
+ * propagate_all_lookaheads(). This makes use of propagation links
+ * constructed during the closure and transition process.
+ *
+ * @param start_prod the start production of the grammar
+ * @see java_cup.lalr_item_set#compute_closure
+ * @see java_cup.lalr_state#propagate_all_lookaheads
+ */
+
+ public static lalr_state build_machine(production start_prod)
+ throws internal_error
+ {
+ lalr_state start_state;
+ lalr_item_set start_items;
+ lalr_item_set new_items;
+ lalr_item_set linked_items;
+ lalr_item_set kernel;
+ Stack work_stack = new Stack();
+ lalr_state st, new_st;
+ symbol_set outgoing;
+ lalr_item itm, new_itm, existing, fix_itm;
+ symbol sym, sym2;
+ Enumeration i, s, fix;
+
+ /* sanity check */
+ if (start_prod == null)
+ throw new internal_error(
+ "Attempt to build viable prefix recognizer using a null production");
+
+ /* build item with dot at front of start production and EOF lookahead */
+ start_items = new lalr_item_set();
+
+ itm = new lalr_item(start_prod);
+ itm.lookahead().add(terminal.EOF);
+
+ start_items.add(itm);
+
+ /* create copy the item set to form the kernel */
+ kernel = new lalr_item_set(start_items);
+
+ /* create the closure from that item set */
+ start_items.compute_closure();
+
+ /* build a state out of that item set and put it in our work set */
+ start_state = new lalr_state(start_items);
+ work_stack.push(start_state);
+
+ /* enter the state using the kernel as the key */
+ _all_kernels.put(kernel, start_state);
+
+ /* continue looking at new states until we have no more work to do */
+ while (!work_stack.empty())
+ {
+ /* remove a state from the work set */
+ st = (lalr_state)work_stack.pop();
+
+ /* gather up all the symbols that appear before dots */
+ outgoing = new symbol_set();
+ for (i = st.items().all(); i.hasMoreElements(); )
+ {
+ itm = (lalr_item)i.nextElement();
+
+ /* add the symbol before the dot (if any) to our collection */
+ sym = itm.symbol_after_dot();
+ if (sym != null) outgoing.add(sym);
+ }
+
+ /* now create a transition out for each individual symbol */
+ for (s = outgoing.all(); s.hasMoreElements(); )
+ {
+ sym = (symbol)s.nextElement();
+
+ /* will be keeping the set of items with propagate links */
+ linked_items = new lalr_item_set();
+
+ /* gather up shifted versions of all the items that have this
+ symbol before the dot */
+ new_items = new lalr_item_set();
+ for (i = st.items().all(); i.hasMoreElements();)
+ {
+ itm = (lalr_item)i.nextElement();
+
+ /* if this is the symbol we are working on now, add to set */
+ sym2 = itm.symbol_after_dot();
+ if (sym.equals(sym2))
+ {
+ /* add to the kernel of the new state */
+ new_items.add(itm.shift());
+
+ /* remember that itm has propagate link to it */
+ linked_items.add(itm);
+ }
+ }
+
+ /* use new items as state kernel */
+ kernel = new lalr_item_set(new_items);
+
+ /* have we seen this one already? */
+ new_st = (lalr_state)_all_kernels.get(kernel);
+
+ /* if we haven't, build a new state out of the item set */
+ if (new_st == null)
+ {
+ /* compute closure of the kernel for the full item set */
+ new_items.compute_closure();
+
+ /* build the new state */
+ new_st = new lalr_state(new_items);
+
+ /* add the new state to our work set */
+ work_stack.push(new_st);
+
+ /* put it in our kernel table */
+ _all_kernels.put(kernel, new_st);
+ }
+ /* otherwise relink propagation to items in existing state */
+ else
+ {
+ /* walk through the items that have links to the new state */
+ for (fix = linked_items.all(); fix.hasMoreElements(); )
+ {
+ fix_itm = (lalr_item)fix.nextElement();
+
+ /* look at each propagate link out of that item */
+ for (int l =0; l < fix_itm.propagate_items().size(); l++)
+ {
+ /* pull out item linked to in the new state */
+ new_itm =
+ (lalr_item)fix_itm.propagate_items().elementAt(l);
+
+ /* find corresponding item in the existing state */
+ existing = new_st.items().find(new_itm);
+
+ /* fix up the item so it points to the existing set */
+ if (existing != null)
+ fix_itm.propagate_items().setElementAt(existing ,l);
+ }
+ }
+ }
+
+ /* add a transition from current state to that state */
+ st.add_transition(sym, new_st);
+ }
+ }
+
+ /* all done building states */
+
+ /* propagate complete lookahead sets throughout the states */
+ propagate_all_lookaheads();
+
+ return start_state;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Propagate lookahead sets out of this state. This recursively
+ * propagates to all items that have propagation links from some item
+ * in this state.
+ */
+ protected void propagate_lookaheads() throws internal_error
+ {
+ /* recursively propagate out from each item in the state */
+ for (Enumeration itm = items().all(); itm.hasMoreElements(); )
+ ((lalr_item)itm.nextElement()).propagate_lookaheads(null);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Fill in the parse table entries for this state. There are two
+ * parse tables that encode the viable prefix recognition machine, an
+ * action table and a reduce-goto table. The rows in each table
+ * correspond to states of the machine. The columns of the action table
+ * are indexed by terminal symbols and correspond to either transitions
+ * out of the state (shift entries) or reductions from the state to some
+ * previous state saved on the stack (reduce entries). All entries in the
+ * action table that are not shifts or reduces, represent errors. The
+ * reduce-goto table is indexed by non terminals and represents transitions
+ * out of a state on that non-terminal.<p>
+ * Conflicts occur if more than one action needs to go in one entry of the
+ * action table (this cannot happen with the reduce-goto table). Conflicts
+ * are resolved by always shifting for shift/reduce conflicts and choosing
+ * the lowest numbered production (hence the one that appeared first in
+ * the specification) in reduce/reduce conflicts. All conflicts are
+ * reported and if more conflicts are detected than were declared by the
+ * user, code generation is aborted.
+ *
+ * @param act_table the action table to put entries in.
+ * @param reduce_table the reduce-goto table to put entries in.
+ */
+ public void build_table_entries(
+ parse_action_table act_table,
+ parse_reduce_table reduce_table)
+ throws internal_error
+ {
+ parse_action_row our_act_row;
+ parse_reduce_row our_red_row;
+ lalr_item itm;
+ parse_action act, other_act;
+ symbol sym;
+ terminal_set conflict_set = new terminal_set();
+
+ /* pull out our rows from the tables */
+ our_act_row = act_table.under_state[index()];
+ our_red_row = reduce_table.under_state[index()];
+
+ /* consider each item in our state */
+ for (Enumeration i = items().all(); i.hasMoreElements(); )
+ {
+ itm = (lalr_item)i.nextElement();
+
+
+ /* if its completed (dot at end) then reduce under the lookahead */
+ if (itm.dot_at_end())
+ {
+ act = new reduce_action(itm.the_production());
+
+ /* consider each lookahead symbol */
+ for (int t = 0; t < terminal.number(); t++)
+ {
+ /* skip over the ones not in the lookahead */
+ if (!itm.lookahead().contains(t)) continue;
+
+ /* if we don't already have an action put this one in */
+ if (our_act_row.under_term[t].kind() ==
+ parse_action.ERROR)
+ {
+ our_act_row.under_term[t] = act;
+ }
+ else
+ {
+ /* we now have at least one conflict */
+ terminal term = terminal.find(t);
+ other_act = our_act_row.under_term[t];
+
+ /* if the other act was not a shift */
+ if ((other_act.kind() != parse_action.SHIFT) &&
+ (other_act.kind() != parse_action.NONASSOC))
+ {
+ /* if we have lower index hence priority, replace it*/
+ if (itm.the_production().index() <
+ ((reduce_action)other_act).reduce_with().index())
+ {
+ /* replace the action */
+ our_act_row.under_term[t] = act;
+ }
+ } else {
+ /* Check precedences,see if problem is correctable */
+ if(fix_with_precedence(itm.the_production(),
+ t, our_act_row, act)) {
+ term = null;
+ }
+ }
+ if(term!=null) {
+
+ conflict_set.add(term);
+ }
+ }
+ }
+ }
+ }
+
+ /* consider each outgoing transition */
+ for (lalr_transition trans=transitions(); trans!=null; trans=trans.next())
+ {
+ /* if its on an terminal add a shift entry */
+ sym = trans.on_symbol();
+ if (!sym.is_non_term())
+ {
+ act = new shift_action(trans.to_state());
+
+ /* if we don't already have an action put this one in */
+ if ( our_act_row.under_term[sym.index()].kind() ==
+ parse_action.ERROR)
+ {
+ our_act_row.under_term[sym.index()] = act;
+ }
+ else
+ {
+ /* we now have at least one conflict */
+ production p = ((reduce_action)our_act_row.under_term[sym.index()]).reduce_with();
+
+ /* shift always wins */
+ if (!fix_with_precedence(p, sym.index(), our_act_row, act)) {
+ our_act_row.under_term[sym.index()] = act;
+ conflict_set.add(terminal.find(sym.index()));
+ }
+ }
+ }
+ else
+ {
+ /* for non terminals add an entry to the reduce-goto table */
+ our_red_row.under_non_term[sym.index()] = trans.to_state();
+ }
+ }
+
+ /* if we end up with conflict(s), report them */
+ if (!conflict_set.empty())
+ report_conflicts(conflict_set);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+
+ /** Procedure that attempts to fix a shift/reduce error by using
+ * precedences. --frankf 6/26/96
+ *
+ * if a production (also called rule) or the lookahead terminal
+ * has a precedence, then the table can be fixed. if the rule
+ * has greater precedence than the terminal, a reduce by that rule
+ * in inserted in the table. If the terminal has a higher precedence,
+ * it is shifted. if they have equal precedence, then the associativity
+ * of the precedence is used to determine what to put in the table:
+ * if the precedence is left associative, the action is to reduce.
+ * if the precedence is right associative, the action is to shift.
+ * if the precedence is non associative, then it is a syntax error.
+ *
+ * @param p the production
+ * @param term_index the index of the lokahead terminal
+ * @param parse_action_row a row of the action table
+ * @param act the rule in conflict with the table entry
+ */
+
+ protected boolean fix_with_precedence(
+ production p,
+ int term_index,
+ parse_action_row table_row,
+ parse_action act)
+
+ throws internal_error {
+
+ terminal term = terminal.find(term_index);
+
+ /* if the production has a precedence number, it can be fixed */
+ if (p.precedence_num() > assoc.no_prec) {
+
+ /* if production precedes terminal, put reduce in table */
+ if (p.precedence_num() > term.precedence_num()) {
+ table_row.under_term[term_index] =
+ insert_reduce(table_row.under_term[term_index],act);
+ return true;
+ }
+
+ /* if terminal precedes rule, put shift in table */
+ else if (p.precedence_num() < term.precedence_num()) {
+ table_row.under_term[term_index] =
+ insert_shift(table_row.under_term[term_index],act);
+ return true;
+ }
+ else { /* they are == precedence */
+
+ /* equal precedences have equal sides, so only need to
+ look at one: if it is right, put shift in table */
+ if (term.precedence_side() == assoc.right) {
+ table_row.under_term[term_index] =
+ insert_shift(table_row.under_term[term_index],act);
+ return true;
+ }
+
+ /* if it is left, put reduce in table */
+ else if (term.precedence_side() == assoc.left) {
+ table_row.under_term[term_index] =
+ insert_reduce(table_row.under_term[term_index],act);
+ return true;
+ }
+
+ /* if it is nonassoc, we're not allowed to have two nonassocs
+ of equal precedence in a row, so put in NONASSOC */
+ else if (term.precedence_side() == assoc.nonassoc) {
+ table_row.under_term[term_index] = new nonassoc_action();
+ return true;
+ } else {
+ /* something really went wrong */
+ throw new internal_error("Unable to resolve conflict correctly");
+ }
+ }
+ }
+ /* check if terminal has precedence, if so, shift, since
+ rule does not have precedence */
+ else if (term.precedence_num() > assoc.no_prec) {
+ table_row.under_term[term_index] =
+ insert_shift(table_row.under_term[term_index],act);
+ return true;
+ }
+
+ /* otherwise, neither the rule nor the terminal has a precedence,
+ so it can't be fixed. */
+ return false;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+
+ /* given two actions, and an action type, return the
+ action of that action type. give an error if they are of
+ the same action, because that should never have tried
+ to be fixed
+
+ */
+ protected parse_action insert_action(
+ parse_action a1,
+ parse_action a2,
+ int act_type)
+ throws internal_error
+ {
+ if ((a1.kind() == act_type) && (a2.kind() == act_type)) {
+ throw new internal_error("Conflict resolution of bogus actions");
+ } else if (a1.kind() == act_type) {
+ return a1;
+ } else if (a2.kind() == act_type) {
+ return a2;
+ } else {
+ throw new internal_error("Conflict resolution of bogus actions");
+ }
+ }
+
+ /* find the shift in the two actions */
+ protected parse_action insert_shift(
+ parse_action a1,
+ parse_action a2)
+ throws internal_error
+ {
+ return insert_action(a1, a2, parse_action.SHIFT);
+ }
+
+ /* find the reduce in the two actions */
+ protected parse_action insert_reduce(
+ parse_action a1,
+ parse_action a2)
+ throws internal_error
+ {
+ return insert_action(a1, a2, parse_action.REDUCE);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Produce warning messages for all conflicts found in this state. */
+ protected void report_conflicts(terminal_set conflict_set)
+ throws internal_error
+ {
+ lalr_item itm, compare;
+ symbol shift_sym;
+
+ boolean after_itm;
+
+ /* consider each element */
+ for (Enumeration itms = items().all(); itms.hasMoreElements(); )
+ {
+ itm = (lalr_item)itms.nextElement();
+
+ /* clear the S/R conflict set for this item */
+
+ /* if it results in a reduce, it could be a conflict */
+ if (itm.dot_at_end())
+ {
+ /* not yet after itm */
+ after_itm = false;
+
+ /* compare this item against all others looking for conflicts */
+ for (Enumeration comps = items().all(); comps.hasMoreElements(); )
+ {
+ compare = (lalr_item)comps.nextElement();
+
+ /* if this is the item, next one is after it */
+ if (itm == compare) after_itm = true;
+
+ /* only look at it if its not the same item */
+ if (itm != compare)
+ {
+ /* is it a reduce */
+ if (compare.dot_at_end())
+ {
+ /* only look at reduces after itm */
+ if (after_itm)
+ /* does the comparison item conflict? */
+ if (compare.lookahead().intersects(itm.lookahead()))
+ /* report a reduce/reduce conflict */
+ report_reduce_reduce(itm, compare);
+ }
+ }
+ }
+ /* report S/R conflicts under all the symbols we conflict under */
+ for (int t = 0; t < terminal.number(); t++)
+ if (conflict_set.contains(t))
+ report_shift_reduce(itm,t);
+ }
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Produce a warning message for one reduce/reduce conflict.
+ *
+ * @param itm1 first item in conflict.
+ * @param itm2 second item in conflict.
+ */
+ protected void report_reduce_reduce(lalr_item itm1, lalr_item itm2)
+ throws internal_error
+ {
+ boolean comma_flag = false;
+
+ System.err.println("*** Reduce/Reduce conflict found in state #"+index());
+ System.err.print (" between ");
+ System.err.println(itm1.to_simple_string());
+ System.err.print (" and ");
+ System.err.println(itm2.to_simple_string());
+ System.err.print(" under symbols: {" );
+ for (int t = 0; t < terminal.number(); t++)
+ {
+ if (itm1.lookahead().contains(t) && itm2.lookahead().contains(t))
+ {
+ if (comma_flag) System.err.print(", "); else comma_flag = true;
+ System.err.print(terminal.find(t).name());
+ }
+ }
+ System.err.println("}");
+ System.err.print(" Resolved in favor of ");
+ if (itm1.the_production().index() < itm2.the_production().index())
+ System.err.println("the first production.\n");
+ else
+ System.err.println("the second production.\n");
+
+ /* count the conflict */
+ emit.num_conflicts++;
+ lexer.warning_count++;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Produce a warning message for one shift/reduce conflict.
+ *
+ * @param red_itm the item with the reduce.
+ * @param conflict_sym the index of the symbol conflict occurs under.
+ */
+ protected void report_shift_reduce(
+ lalr_item red_itm,
+ int conflict_sym)
+ throws internal_error
+ {
+ lalr_item itm;
+ symbol shift_sym;
+
+ /* emit top part of message including the reduce item */
+ System.err.println("*** Shift/Reduce conflict found in state #"+index());
+ System.err.print (" between ");
+ System.err.println(red_itm.to_simple_string());
+
+ /* find and report on all items that shift under our conflict symbol */
+ for (Enumeration itms = items().all(); itms.hasMoreElements(); )
+ {
+ itm = (lalr_item)itms.nextElement();
+
+ /* only look if its not the same item and not a reduce */
+ if (itm != red_itm && !itm.dot_at_end())
+ {
+ /* is it a shift on our conflicting terminal */
+ shift_sym = itm.symbol_after_dot();
+ if (!shift_sym.is_non_term() && shift_sym.index() == conflict_sym)
+ {
+ /* yes, report on it */
+ System.err.println(" and " + itm.to_simple_string());
+ }
+ }
+ }
+ System.err.println(" under symbol "+ terminal.find(conflict_sym).name());
+ System.err.println(" Resolved in favor of shifting.\n");
+
+ /* count the conflict */
+ emit.num_conflicts++;
+ lexer.warning_count++;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Equality comparison. */
+ public boolean equals(lalr_state other)
+ {
+ /* we are equal if our item sets are equal */
+ return other != null && items().equals(other.items());
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Generic equality comparison. */
+ public boolean equals(Object other)
+ {
+ if (!(other instanceof lalr_state))
+ return false;
+ else
+ return equals((lalr_state)other);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Produce a hash code. */
+ public int hashCode()
+ {
+ /* just use the item set hash code */
+ return items().hashCode();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to a string. */
+ public String toString()
+ {
+ String result;
+ lalr_transition tr;
+
+ /* dump the item set */
+ result = "lalr_state [" + index() + "]: " + _items + "\n";
+
+ /* do the transitions */
+ for (tr = transitions(); tr != null; tr = tr.next())
+ {
+ result += tr;
+ result += "\n";
+ }
+
+ return result;
+ }
+
+ /*-----------------------------------------------------------*/
+}
diff --git a/src/syntaxParser/java_cup/SAVE/lalr_transition.java b/src/syntaxParser/java_cup/SAVE/lalr_transition.java
new file mode 100644
index 0000000..1c941bd
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/lalr_transition.java
@@ -0,0 +1,93 @@
+package java_cup;
+
+/** This class represents a transition in an LALR viable prefix recognition
+ * machine. Transitions can be under terminals for non-terminals. They are
+ * internally linked together into singly linked lists containing all the
+ * transitions out of a single state via the _next field.
+ *
+ * @see java_cup.lalr_state
+ * @version last updated: 11/25/95
+ * @author Scott Hudson
+ *
+ */
+public class lalr_transition {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Full constructor.
+ * @param on_sym symbol we are transitioning on.
+ * @param to_st state we transition to.
+ * @param nxt next transition in linked list.
+ */
+ public lalr_transition(symbol on_sym, lalr_state to_st, lalr_transition nxt)
+ throws internal_error
+ {
+ /* sanity checks */
+ if (on_sym == null)
+ throw new internal_error("Attempt to create transition on null symbol");
+ if (to_st == null)
+ throw new internal_error("Attempt to create transition to null state");
+
+ /* initialize */
+ _on_symbol = on_sym;
+ _to_state = to_st;
+ _next = nxt;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Constructor with null next.
+ * @param on_sym symbol we are transitioning on.
+ * @param to_st state we transition to.
+ */
+ public lalr_transition(symbol on_sym, lalr_state to_st) throws internal_error
+ {
+ this(on_sym, to_st, null);
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** The symbol we make the transition on. */
+ protected symbol _on_symbol;
+
+ /** The symbol we make the transition on. */
+ public symbol on_symbol() {return _on_symbol;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** The state we transition to. */
+ protected lalr_state _to_state;
+
+ /** The state we transition to. */
+ public lalr_state to_state() {return _to_state;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Next transition in linked list of transitions out of a state */
+ protected lalr_transition _next;
+
+ /** Next transition in linked list of transitions out of a state */
+ public lalr_transition next() {return _next;}
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Convert to a string. */
+ public String toString()
+ {
+ String result;
+
+ result = "transition on " + on_symbol().name() + " to state [";
+ result += _to_state.index();
+ result += "]";
+
+ return result;
+ }
+
+ /*-----------------------------------------------------------*/
+}
diff --git a/src/syntaxParser/java_cup/SAVE/lexer.java b/src/syntaxParser/java_cup/SAVE/lexer.java
new file mode 100644
index 0000000..2230d12
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/lexer.java
@@ -0,0 +1,543 @@
+package java_cup;
+
+import java_cup.runtime.Symbol;
+import java.util.Hashtable;
+
+/** This class implements a small scanner (aka lexical analyzer or lexer) for
+ * the JavaCup specification. This scanner reads characters from standard
+ * input (System.in) and returns integers corresponding to the terminal
+ * number of the next Symbol. Once end of input is reached the EOF Symbol is
+ * returned on every subsequent call.<p>
+ * Symbols currently returned include: <pre>
+ * Symbol Constant Returned Symbol Constant Returned
+ * ------ ----------------- ------ -----------------
+ * "package" PACKAGE "import" IMPORT
+ * "code" CODE "action" ACTION
+ * "parser" PARSER "terminal" TERMINAL
+ * "non" NON "init" INIT
+ * "scan" SCAN "with" WITH
+ * "start" START "precedence" PRECEDENCE
+ * "left" LEFT "right" RIGHT
+ * "nonassoc" NONASSOC "%prec PRECENT_PREC
+ * [ LBRACK ] RBRACK
+ * ; SEMI
+ * , COMMA * STAR
+ * . DOT : COLON
+ * ::= COLON_COLON_EQUALS | BAR
+ * identifier ID {:...:} CODE_STRING
+ * "nonterminal" NONTERMINAL
+ * </pre>
+ * All symbol constants are defined in sym.java which is generated by
+ * JavaCup from parser.cup.<p>
+ *
+ * In addition to the scanner proper (called first via init() then with
+ * next_token() to get each Symbol) this class provides simple error and
+ * warning routines and keeps a count of errors and warnings that is
+ * publicly accessible.<p>
+ *
+ * This class is "static" (i.e., it has only static members and methods).
+ *
+ * @version last updated: 7/3/96
+ * @author Frank Flannery
+ */
+public class lexer {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** The only constructor is private, so no instances can be created. */
+ private lexer() { }
+
+ /*-----------------------------------------------------------*/
+ /*--- Static (Class) Variables ------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** First character of lookahead. */
+ protected static int next_char;
+
+ /** Second character of lookahead. */
+ protected static int next_char2;
+
+ /** Second character of lookahead. */
+ protected static int next_char3;
+
+ /** Second character of lookahead. */
+ protected static int next_char4;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** EOF constant. */
+ protected static final int EOF_CHAR = -1;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Table of keywords. Keywords are initially treated as identifiers.
+ * Just before they are returned we look them up in this table to see if
+ * they match one of the keywords. The string of the name is the key here,
+ * which indexes Integer objects holding the symbol number.
+ */
+ protected static Hashtable keywords = new Hashtable(23);
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Table of single character symbols. For ease of implementation, we
+ * store all unambiguous single character Symbols in this table of Integer
+ * objects keyed by Integer objects with the numerical value of the
+ * appropriate char (currently Character objects have a bug which precludes
+ * their use in tables).
+ */
+ protected static Hashtable char_symbols = new Hashtable(11);
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Current line number for use in error messages. */
+ protected static int current_line = 1;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Character position in current line. */
+ protected static int current_position = 1;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Character position in current line. */
+ protected static int absolute_position = 1;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Count of total errors detected so far. */
+ public static int error_count = 0;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Count of warnings issued so far */
+ public static int warning_count = 0;
+
+ /*-----------------------------------------------------------*/
+ /*--- Static Methods ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Initialize the scanner. This sets up the keywords and char_symbols
+ * tables and reads the first two characters of lookahead.
+ */
+ public static void init() throws java.io.IOException
+ {
+ /* set up the keyword table */
+ keywords.put("package", new Integer(sym.PACKAGE));
+ keywords.put("import", new Integer(sym.IMPORT));
+ keywords.put("code", new Integer(sym.CODE));
+ keywords.put("action", new Integer(sym.ACTION));
+ keywords.put("parser", new Integer(sym.PARSER));
+ keywords.put("terminal", new Integer(sym.TERMINAL));
+ keywords.put("non", new Integer(sym.NON));
+ keywords.put("nonterminal",new Integer(sym.NONTERMINAL));// [CSA]
+ keywords.put("init", new Integer(sym.INIT));
+ keywords.put("scan", new Integer(sym.SCAN));
+ keywords.put("with", new Integer(sym.WITH));
+ keywords.put("start", new Integer(sym.START));
+ keywords.put("precedence", new Integer(sym.PRECEDENCE));
+ keywords.put("left", new Integer(sym.LEFT));
+ keywords.put("right", new Integer(sym.RIGHT));
+ keywords.put("nonassoc", new Integer(sym.NONASSOC));
+
+ /* set up the table of single character symbols */
+ char_symbols.put(new Integer(';'), new Integer(sym.SEMI));
+ char_symbols.put(new Integer(','), new Integer(sym.COMMA));
+ char_symbols.put(new Integer('*'), new Integer(sym.STAR));
+ char_symbols.put(new Integer('.'), new Integer(sym.DOT));
+ char_symbols.put(new Integer('|'), new Integer(sym.BAR));
+ char_symbols.put(new Integer('['), new Integer(sym.LBRACK));
+ char_symbols.put(new Integer(']'), new Integer(sym.RBRACK));
+
+ /* read two characters of lookahead */
+ next_char = System.in.read();
+ if (next_char == EOF_CHAR) {
+ next_char2 = EOF_CHAR;
+ next_char3 = EOF_CHAR;
+ next_char4 = EOF_CHAR;
+ } else {
+ next_char2 = System.in.read();
+ if (next_char2 == EOF_CHAR) {
+ next_char3 = EOF_CHAR;
+ next_char4 = EOF_CHAR;
+ } else {
+ next_char3 = System.in.read();
+ if (next_char3 == EOF_CHAR) {
+ next_char4 = EOF_CHAR;
+ } else {
+ next_char4 = System.in.read();
+ }
+ }
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Advance the scanner one character in the input stream. This moves
+ * next_char2 to next_char and then reads a new next_char2.
+ */
+ protected static void advance() throws java.io.IOException
+ {
+ int old_char;
+
+ old_char = next_char;
+ next_char = next_char2;
+ if (next_char == EOF_CHAR) {
+ next_char2 = EOF_CHAR;
+ next_char3 = EOF_CHAR;
+ next_char4 = EOF_CHAR;
+ } else {
+ next_char2 = next_char3;
+ if (next_char2 == EOF_CHAR) {
+ next_char3 = EOF_CHAR;
+ next_char4 = EOF_CHAR;
+ } else {
+ next_char3 = next_char4;
+ if (next_char3 == EOF_CHAR) {
+ next_char4 = EOF_CHAR;
+ } else {
+ next_char4 = System.in.read();
+ }
+ }
+ }
+
+ /* count this */
+ absolute_position++;
+ current_position++;
+ if (old_char == '\n' || (old_char == '\r' && next_char!='\n'))
+ {
+ current_line++;
+ current_position = 1;
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Emit an error message. The message will be marked with both the
+ * current line number and the position in the line. Error messages
+ * are printed on standard error (System.err).
+ * @param message the message to print.
+ */
+ public static void emit_error(String message)
+ {
+ System.err.println("Error at " + current_line + "(" + current_position +
+ "): " + message);
+ error_count++;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Emit a warning message. The message will be marked with both the
+ * current line number and the position in the line. Messages are
+ * printed on standard error (System.err).
+ * @param message the message to print.
+ */
+ public static void emit_warn(String message)
+ {
+ System.err.println("Warning at " + current_line + "(" + current_position +
+ "): " + message);
+ warning_count++;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Determine if a character is ok to start an id.
+ * @param ch the character in question.
+ */
+ protected static boolean id_start_char(int ch)
+ {
+ /* allow for % in identifiers. a hack to allow my
+ %prec in. Should eventually make lex spec for this
+ frankf */
+ return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') ||
+ (ch == '_');
+
+ // later need to deal with non-8-bit chars here
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Determine if a character is ok for the middle of an id.
+ * @param ch the character in question.
+ */
+ protected static boolean id_char(int ch)
+ {
+ return id_start_char(ch) || (ch >= '0' && ch <= '9');
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Try to look up a single character symbol, returns -1 for not found.
+ * @param ch the character in question.
+ */
+ protected static int find_single_char(int ch)
+ {
+ Integer result;
+
+ result = (Integer)char_symbols.get(new Integer((char)ch));
+ if (result == null)
+ return -1;
+ else
+ return result.intValue();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Handle swallowing up a comment. Both old style C and new style C++
+ * comments are handled.
+ */
+ protected static void swallow_comment() throws java.io.IOException
+ {
+ /* next_char == '/' at this point */
+
+ /* is it a traditional comment */
+ if (next_char2 == '*')
+ {
+ /* swallow the opener */
+ advance(); advance();
+
+ /* swallow the comment until end of comment or EOF */
+ for (;;)
+ {
+ /* if its EOF we have an error */
+ if (next_char == EOF_CHAR)
+ {
+ emit_error("Specification file ends inside a comment");
+ return;
+ }
+
+ /* if we can see the closer we are done */
+ if (next_char == '*' && next_char2 == '/')
+ {
+ advance();
+ advance();
+ return;
+ }
+
+ /* otherwise swallow char and move on */
+ advance();
+ }
+ }
+
+ /* is its a new style comment */
+ if (next_char2 == '/')
+ {
+ /* swallow the opener */
+ advance(); advance();
+
+ /* swallow to '\n', '\r', '\f', or EOF */
+ while (next_char != '\n' && next_char != '\r' &&
+ next_char != '\f' && next_char!=EOF_CHAR)
+ advance();
+
+ return;
+
+ }
+
+ /* shouldn't get here, but... if we get here we have an error */
+ emit_error("Malformed comment in specification -- ignored");
+ advance();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Swallow up a code string. Code strings begin with "{:" and include
+ all characters up to the first occurrence of ":}" (there is no way to
+ include ":}" inside a code string). The routine returns a String
+ object suitable for return by the scanner.
+ */
+ protected static Symbol do_code_string() throws java.io.IOException
+ {
+ StringBuffer result = new StringBuffer();
+
+ /* at this point we have lookahead of "{:" -- swallow that */
+ advance(); advance();
+
+ /* save chars until we see ":}" */
+ while (!(next_char == ':' && next_char2 == '}'))
+ {
+ /* if we have run off the end issue a message and break out of loop */
+ if (next_char == EOF_CHAR)
+ {
+ emit_error("Specification file ends inside a code string");
+ break;
+ }
+
+ /* otherwise record the char and move on */
+ result.append(new Character((char)next_char));
+ advance();
+ }
+
+ /* advance past the closer and build a return Symbol */
+ advance(); advance();
+ return new Symbol(sym.CODE_STRING, result.toString());
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Process an identifier. Identifiers begin with a letter, underscore,
+ * or dollar sign, which is followed by zero or more letters, numbers,
+ * underscores or dollar signs. This routine returns a String suitable
+ * for return by the scanner.
+ */
+ protected static Symbol do_id() throws java.io.IOException
+ {
+ StringBuffer result = new StringBuffer();
+ String result_str;
+ Integer keyword_num;
+ char buffer[] = new char[1];
+
+ /* next_char holds first character of id */
+ buffer[0] = (char)next_char;
+ result.append(buffer,0,1);
+ advance();
+
+ /* collect up characters while they fit in id */
+ while(id_char(next_char))
+ {
+ buffer[0] = (char)next_char;
+ result.append(buffer,0,1);
+ advance();
+ }
+
+ /* extract a string and try to look it up as a keyword */
+ result_str = result.toString();
+ keyword_num = (Integer)keywords.get(result_str);
+
+ /* if we found something, return that keyword */
+ if (keyword_num != null)
+ return new Symbol(keyword_num.intValue());
+
+ /* otherwise build and return an id Symbol with an attached string */
+ return new Symbol(sym.ID, result_str);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Return one Symbol. This is the main external interface to the scanner.
+ * It consumes sufficient characters to determine the next input Symbol
+ * and returns it. To help with debugging, this routine actually calls
+ * real_next_token() which does the work. If you need to debug the
+ * parser, this can be changed to call debug_next_token() which prints
+ * a debugging message before returning the Symbol.
+ */
+ public static Symbol next_token() throws java.io.IOException
+ {
+ return real_next_token();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Debugging version of next_token(). This routine calls the real scanning
+ * routine, prints a message on System.out indicating what the Symbol is,
+ * then returns it.
+ */
+ public static Symbol debug_next_token() throws java.io.IOException
+ {
+ Symbol result = real_next_token();
+ System.out.println("# next_Symbol() => " + result.sym);
+ return result;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** The actual routine to return one Symbol. This is normally called from
+ * next_token(), but for debugging purposes can be called indirectly from
+ * debug_next_token().
+ */
+ protected static Symbol real_next_token() throws java.io.IOException
+ {
+ int sym_num;
+
+ for (;;)
+ {
+ /* look for white space */
+ if (next_char == ' ' || next_char == '\t' || next_char == '\n' ||
+ next_char == '\f' || next_char == '\r')
+ {
+ /* advance past it and try the next character */
+ advance();
+ continue;
+ }
+
+ /* look for a single character symbol */
+ sym_num = find_single_char(next_char);
+ if (sym_num != -1)
+ {
+ /* found one -- advance past it and return a Symbol for it */
+ advance();
+ return new Symbol(sym_num);
+ }
+
+ /* look for : or ::= */
+ if (next_char == ':')
+ {
+ /* if we don't have a second ':' return COLON */
+ if (next_char2 != ':')
+ {
+ advance();
+ return new Symbol(sym.COLON);
+ }
+
+ /* move forward and look for the '=' */
+ advance();
+ if (next_char2 == '=')
+ {
+ advance(); advance();
+ return new Symbol(sym.COLON_COLON_EQUALS);
+ }
+ else
+ {
+ /* return just the colon (already consumed) */
+ return new Symbol(sym.COLON);
+ }
+ }
+
+ /* find a "%prec" string and return it. otherwise, a '%' was found,
+ which has no right being in the specification otherwise */
+ if (next_char == '%') {
+ advance();
+ if ((next_char == 'p') && (next_char2 == 'r') && (next_char3 == 'e') &&
+ (next_char4 == 'c')) {
+ advance();
+ advance();
+ advance();
+ advance();
+ return new Symbol(sym.PERCENT_PREC);
+ } else {
+ emit_error("Found extraneous percent sign");
+ }
+ }
+
+ /* look for a comment */
+ if (next_char == '/' && (next_char2 == '*' || next_char2 == '/'))
+ {
+ /* swallow then continue the scan */
+ swallow_comment();
+ continue;
+ }
+
+ /* look for start of code string */
+ if (next_char == '{' && next_char2 == ':')
+ return do_code_string();
+
+ /* look for an id or keyword */
+ if (id_start_char(next_char)) return do_id();
+
+ /* look for EOF */
+ if (next_char == EOF_CHAR) return new Symbol(sym.EOF);
+
+ /* if we get here, we have an unrecognized character */
+ emit_warn("Unrecognized character '" +
+ new Character((char)next_char) + "'(" + next_char +
+ ") -- ignored");
+
+ /* advance past it */
+ advance();
+ }
+ }
+
+ /*-----------------------------------------------------------*/
+}
+
diff --git a/src/syntaxParser/java_cup/SAVE/lr_item_core.java b/src/syntaxParser/java_cup/SAVE/lr_item_core.java
new file mode 100644
index 0000000..c0fa656
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/lr_item_core.java
@@ -0,0 +1,280 @@
+
+package java_cup;
+
+/** The "core" of an LR item. This includes a production and the position
+ * of a marker (the "dot") within the production. Typically item cores
+ * are written using a production with an embedded "dot" to indicate their
+ * position. For example: <pre>
+ * A ::= B * C d E
+ * </pre>
+ * This represents a point in a parse where the parser is trying to match
+ * the given production, and has succeeded in matching everything before the
+ * "dot" (and hence is expecting to see the symbols after the dot next). See
+ * lalr_item, lalr_item_set, and lalr_start for full details on the meaning
+ * and use of items.
+ *
+ * @see java_cup.lalr_item
+ * @see java_cup.lalr_item_set
+ * @see java_cup.lalr_state
+ * @version last updated: 11/25/95
+ * @author Scott Hudson
+*/
+
+public class lr_item_core {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Full constructor.
+ * @param prod production this item uses.
+ * @param pos position of the "dot" within the item.
+ */
+ public lr_item_core(production prod, int pos) throws internal_error
+ {
+ symbol after_dot = null;
+ production_part part;
+
+ if (prod == null)
+ throw new internal_error(
+ "Attempt to create an lr_item_core with a null production");
+
+ _the_production = prod;
+
+ if (pos < 0 || pos > _the_production.rhs_length())
+ throw new internal_error(
+ "Attempt to create an lr_item_core with a bad dot position");
+
+ _dot_pos = pos;
+
+ /* compute and cache hash code now */
+ _core_hash_cache = 13*_the_production.hashCode() + pos;
+
+ /* cache the symbol after the dot */
+ if (_dot_pos < _the_production.rhs_length())
+ {
+ part = _the_production.rhs(_dot_pos);
+ if (!part.is_action())
+ _symbol_after_dot = ((symbol_part)part).the_symbol();
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Constructor for dot at start of right hand side.
+ * @param prod production this item uses.
+ */
+ public lr_item_core(production prod) throws internal_error
+ {
+ this(prod,0);
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** The production for the item. */
+ protected production _the_production;
+
+ /** The production for the item. */
+ public production the_production() {return _the_production;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** The position of the "dot" -- this indicates the part of the production
+ * that the marker is before, so 0 indicates a dot at the beginning of
+ * the RHS.
+ */
+ protected int _dot_pos;
+
+ /** The position of the "dot" -- this indicates the part of the production
+ * that the marker is before, so 0 indicates a dot at the beginning of
+ * the RHS.
+ */
+ public int dot_pos() {return _dot_pos;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Cache of the hash code. */
+ protected int _core_hash_cache;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Cache of symbol after the dot. */
+ protected symbol _symbol_after_dot = null;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Is the dot at the end of the production? */
+ public boolean dot_at_end()
+ {
+ return _dot_pos >= _the_production.rhs_length();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Return the symbol after the dot. If there is no symbol after the dot
+ * we return null. */
+ public symbol symbol_after_dot()
+ {
+ /* use the cached symbol */
+ return _symbol_after_dot;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Determine if we have a dot before a non terminal, and if so which one
+ * (return null or the non terminal).
+ */
+ public non_terminal dot_before_nt()
+ {
+ symbol sym;
+
+ /* get the symbol after the dot */
+ sym = symbol_after_dot();
+
+ /* if it exists and is a non terminal, return it */
+ if (sym != null && sym.is_non_term())
+ return (non_terminal)sym;
+ else
+ return null;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Produce a new lr_item_core that results from shifting the dot one
+ * position to the right.
+ */
+ public lr_item_core shift_core() throws internal_error
+ {
+ if (dot_at_end())
+ throw new internal_error(
+ "Attempt to shift past end of an lr_item_core");
+
+ return new lr_item_core(_the_production, _dot_pos+1);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Equality comparison for the core only. This is separate out because we
+ * need separate access in a super class.
+ */
+ public boolean core_equals(lr_item_core other)
+ {
+ return other != null &&
+ _the_production.equals(other._the_production) &&
+ _dot_pos == other._dot_pos;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Equality comparison. */
+ public boolean equals(lr_item_core other) {return core_equals(other);}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Generic equality comparison. */
+ public boolean equals(Object other)
+ {
+ if (!(other instanceof lr_item_core))
+ return false;
+ else
+ return equals((lr_item_core)other);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Hash code for the core (separated so we keep non overridden version). */
+ public int core_hashCode()
+ {
+ return _core_hash_cache;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Hash code for the item. */
+ public int hashCode()
+ {
+ return _core_hash_cache;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Return the hash code that object would have provided for us so we have
+ * a (nearly) unique id for debugging.
+ */
+ protected int obj_hash()
+ {
+ return super.hashCode();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to a string (separated out from toString() so we can call it
+ * from subclass that overrides toString()).
+ */
+ public String to_simple_string() throws internal_error
+ {
+ String result;
+ production_part part;
+
+ if (_the_production.lhs() != null &&
+ _the_production.lhs().the_symbol() != null &&
+ _the_production.lhs().the_symbol().name() != null)
+ result = _the_production.lhs().the_symbol().name();
+ else
+ result = "$$NULL$$";
+
+ result += " ::= ";
+
+ for (int i = 0; i<_the_production.rhs_length(); i++)
+ {
+ /* do we need the dot before this one? */
+ if (i == _dot_pos)
+ result += "(*) ";
+
+ /* print the name of the part */
+ if (_the_production.rhs(i) == null)
+ {
+ result += "$$NULL$$ ";
+ }
+ else
+ {
+ part = _the_production.rhs(i);
+ if (part == null)
+ result += "$$NULL$$ ";
+ else if (part.is_action())
+ result += "{ACTION} ";
+ else if (((symbol_part)part).the_symbol() != null &&
+ ((symbol_part)part).the_symbol().name() != null)
+ result += ((symbol_part)part).the_symbol().name() + " ";
+ else
+ result += "$$NULL$$ ";
+ }
+ }
+
+ /* put the dot after if needed */
+ if (_dot_pos == _the_production.rhs_length())
+ result += "(*) ";
+
+ return result;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to a string */
+ public String toString()
+ {
+ /* can't throw here since super class doesn't, so we crash instead */
+ try {
+ return to_simple_string();
+ } catch(internal_error e) {
+ e.crash();
+ return null;
+ }
+ }
+
+ /*-----------------------------------------------------------*/
+
+}
+
diff --git a/src/syntaxParser/java_cup/SAVE/non_terminal.java b/src/syntaxParser/java_cup/SAVE/non_terminal.java
new file mode 100644
index 0000000..9354a7f
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/non_terminal.java
@@ -0,0 +1,301 @@
+package java_cup;
+
+import java.util.Hashtable;
+import java.util.Enumeration;
+
+/** This class represents a non-terminal symbol in the grammar. Each
+ * non terminal has a textual name, an index, and a string which indicates
+ * the type of object it will be implemented with at runtime (i.e. the class
+ * of object that will be pushed on the parse stack to represent it).
+ *
+ * @version last updated: 11/25/95
+ * @author Scott Hudson
+ */
+
+public class non_terminal extends symbol {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Full constructor.
+ * @param nm the name of the non terminal.
+ * @param tp the type string for the non terminal.
+ */
+ public non_terminal(String nm, String tp)
+ {
+ /* super class does most of the work */
+ super(nm, tp);
+
+ /* add to set of all non terminals and check for duplicates */
+ Object conflict = _all.put(nm,this);
+ if (conflict != null)
+ // can't throw an exception here because these are used in static
+ // initializers, so we crash instead
+ // was:
+ // throw new internal_error("Duplicate non-terminal ("+nm+") created");
+ (new internal_error("Duplicate non-terminal ("+nm+") created")).crash();
+
+ /* assign a unique index */
+ _index = next_index++;
+
+ /* add to by_index set */
+ _all_by_index.put(new Integer(_index), this);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Constructor with default type.
+ * @param nm the name of the non terminal.
+ */
+ public non_terminal(String nm)
+ {
+ this(nm, null);
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Static (Class) Variables ------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Table of all non-terminals -- elements are stored using name strings
+ * as the key
+ */
+ protected static Hashtable _all = new Hashtable();
+
+ /** Access to all non-terminals. */
+ public static Enumeration all() {return _all.elements();}
+
+ /** lookup a non terminal by name string */
+ public static non_terminal find(String with_name)
+ {
+ if (with_name == null)
+ return null;
+ else
+ return (non_terminal)_all.get(with_name);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Table of all non terminals indexed by their index number. */
+ protected static Hashtable _all_by_index = new Hashtable();
+
+ /** Lookup a non terminal by index. */
+ public static non_terminal find(int indx)
+ {
+ Integer the_indx = new Integer(indx);
+
+ return (non_terminal)_all_by_index.get(the_indx);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Total number of non-terminals. */
+ public static int number() {return _all.size();}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Static counter to assign unique indexes. */
+ protected static int next_index = 0;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Static counter for creating unique non-terminal names */
+ static protected int next_nt = 0;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** special non-terminal for start symbol */
+ public static final non_terminal START_nt = new non_terminal("$START");
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** flag non-terminals created to embed action productions */
+ public boolean is_embedded_action = false; /* added 24-Mar-1998, CSA */
+
+ /*-----------------------------------------------------------*/
+ /*--- Static Methods ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Method for creating a new uniquely named hidden non-terminal using
+ * the given string as a base for the name (or "NT$" if null is passed).
+ * @param prefix base name to construct unique name from.
+ */
+ static non_terminal create_new(String prefix) throws internal_error
+ {
+ if (prefix == null) prefix = "NT$";
+ return new non_terminal(prefix + next_nt++);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** static routine for creating a new uniquely named hidden non-terminal */
+ static non_terminal create_new() throws internal_error
+ {
+ return create_new(null);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Compute nullability of all non-terminals. */
+ public static void compute_nullability() throws internal_error
+ {
+ boolean change = true;
+ non_terminal nt;
+ Enumeration e;
+ production prod;
+
+ /* repeat this process until there is no change */
+ while (change)
+ {
+ /* look for a new change */
+ change = false;
+
+ /* consider each non-terminal */
+ for (e=all(); e.hasMoreElements(); )
+ {
+ nt = (non_terminal)e.nextElement();
+
+ /* only look at things that aren't already marked nullable */
+ if (!nt.nullable())
+ {
+ if (nt.looks_nullable())
+ {
+ nt._nullable = true;
+ change = true;
+ }
+ }
+ }
+ }
+
+ /* do one last pass over the productions to finalize all of them */
+ for (e=production.all(); e.hasMoreElements(); )
+ {
+ prod = (production)e.nextElement();
+ prod.set_nullable(prod.check_nullable());
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Compute first sets for all non-terminals. This assumes nullability has
+ * already computed.
+ */
+ public static void compute_first_sets() throws internal_error
+ {
+ boolean change = true;
+ Enumeration n;
+ Enumeration p;
+ non_terminal nt;
+ production prod;
+ terminal_set prod_first;
+
+ /* repeat this process until we have no change */
+ while (change)
+ {
+ /* look for a new change */
+ change = false;
+
+ /* consider each non-terminal */
+ for (n = all(); n.hasMoreElements(); )
+ {
+ nt = (non_terminal)n.nextElement();
+
+ /* consider every production of that non terminal */
+ for (p = nt.productions(); p.hasMoreElements(); )
+ {
+ prod = (production)p.nextElement();
+
+ /* get the updated first of that production */
+ prod_first = prod.check_first_set();
+
+ /* if this going to add anything, add it */
+ if (!prod_first.is_subset_of(nt._first_set))
+ {
+ change = true;
+ nt._first_set.add(prod_first);
+ }
+ }
+ }
+ }
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Table of all productions with this non terminal on the LHS. */
+ protected Hashtable _productions = new Hashtable(11);
+
+ /** Access to productions with this non terminal on the LHS. */
+ public Enumeration productions() {return _productions.elements();}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Total number of productions with this non terminal on the LHS. */
+ public int num_productions() {return _productions.size();}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Add a production to our set of productions. */
+ public void add_production(production prod) throws internal_error
+ {
+ /* catch improper productions */
+ if (prod == null || prod.lhs() == null || prod.lhs().the_symbol() != this)
+ throw new internal_error(
+ "Attempt to add invalid production to non terminal production table");
+
+ /* add it to the table, keyed with itself */
+ _productions.put(prod,prod);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Nullability of this non terminal. */
+ protected boolean _nullable;
+
+ /** Nullability of this non terminal. */
+ public boolean nullable() {return _nullable;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** First set for this non-terminal. */
+ protected terminal_set _first_set = new terminal_set();
+
+ /** First set for this non-terminal. */
+ public terminal_set first_set() {return _first_set;}
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Indicate that this symbol is a non-terminal. */
+ public boolean is_non_term()
+ {
+ return true;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Test to see if this non terminal currently looks nullable. */
+ protected boolean looks_nullable() throws internal_error
+ {
+ /* look and see if any of the productions now look nullable */
+ for (Enumeration e = productions(); e.hasMoreElements(); )
+ /* if the production can go to empty, we are nullable */
+ if (((production)e.nextElement()).check_nullable())
+ return true;
+
+ /* none of the productions can go to empty, so we are not nullable */
+ return false;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** convert to string */
+ public String toString()
+ {
+ return super.toString() + "[" + index() + "]" + (nullable() ? "*" : "");
+ }
+
+ /*-----------------------------------------------------------*/
+}
diff --git a/src/syntaxParser/java_cup/SAVE/nonassoc_action.java b/src/syntaxParser/java_cup/SAVE/nonassoc_action.java
new file mode 100644
index 0000000..3882324
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/nonassoc_action.java
@@ -0,0 +1,71 @@
+
+package java_cup;
+
+/** This class represents a shift/reduce nonassociative error within the
+ * parse table. If action_table element is assign to type
+ * nonassoc_action, it cannot be changed, and signifies that there
+ * is a conflict between shifting and reducing a production and a
+ * terminal that shouldn't be next to each other.
+ *
+ * @version last updated: 7/2/96
+ * @author Frank Flannery
+ */
+public class nonassoc_action extends parse_action {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Simple constructor.
+ */
+ public nonassoc_action() throws internal_error
+ {
+ /* don't need to set anything, since it signifies error */
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Quick access to type of action. */
+ public int kind() {return NONASSOC;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Equality test. */
+ public boolean equals(parse_action other)
+ {
+ return other != null && other.kind() == NONASSOC;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Generic equality test. */
+ public boolean equals(Object other)
+ {
+ if (other instanceof parse_action)
+ return equals((parse_action)other);
+ else
+ return false;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Compute a hash code. */
+ public int hashCode()
+ {
+ /* all objects of this class hash together */
+ return 0xCafe321;
+ }
+
+
+
+ /** Convert to string. */
+ public String toString()
+ {
+ return "NONASSOC";
+ }
+
+ /*-----------------------------------------------------------*/
+
+}
diff --git a/src/syntaxParser/java_cup/SAVE/parse_action.java b/src/syntaxParser/java_cup/SAVE/parse_action.java
new file mode 100644
index 0000000..9228663
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/parse_action.java
@@ -0,0 +1,92 @@
+
+package java_cup;
+
+/** This class serves as the base class for entries in a parse action table.
+ * Full entries will either be SHIFT(state_num), REDUCE(production), NONASSOC,
+ * or ERROR. Objects of this base class will default to ERROR, while
+ * the other three types will be represented by subclasses.
+ *
+ * @see java_cup.reduce_action
+ * @see java_cup.shift_action
+ * @version last updated: 7/2/96
+ * @author Frank Flannery
+ */
+
+public class parse_action {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Simple constructor. */
+ public parse_action()
+ {
+ /* nothing to do in the base class */
+ }
+
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Static (Class) Variables ------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Constant for action type -- error action. */
+ public static final int ERROR = 0;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Constant for action type -- shift action. */
+ public static final int SHIFT = 1;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Constants for action type -- reduce action. */
+ public static final int REDUCE = 2;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Constants for action type -- reduce action. */
+ public static final int NONASSOC = 3;
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Quick access to the type -- base class defaults to error. */
+ public int kind() {return ERROR;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Equality test. */
+ public boolean equals(parse_action other)
+ {
+ /* we match all error actions */
+ return other != null && other.kind() == ERROR;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Generic equality test. */
+ public boolean equals(Object other)
+ {
+ if (other instanceof parse_action)
+ return equals((parse_action)other);
+ else
+ return false;
+ }
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Compute a hash code. */
+ public int hashCode()
+ {
+ /* all objects of this class hash together */
+ return 0xCafe123;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to string. */
+ public String toString() {return "ERROR";}
+
+ /*-----------------------------------------------------------*/
+}
+
diff --git a/src/syntaxParser/java_cup/SAVE/parse_action_row.java b/src/syntaxParser/java_cup/SAVE/parse_action_row.java
new file mode 100644
index 0000000..817b8c5
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/parse_action_row.java
@@ -0,0 +1,106 @@
+
+package java_cup;
+
+/** This class represents one row (corresponding to one machine state) of the
+ * parse action table.
+ */
+public class parse_action_row {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Simple constructor. Note: this should not be used until the number of
+ * terminals in the grammar has been established.
+ */
+ public parse_action_row()
+ {
+ /* make sure the size is set */
+ if (_size <= 0 ) _size = terminal.number();
+
+ /* allocate the array */
+ under_term = new parse_action[size()];
+
+ /* set each element to an error action */
+ for (int i=0; i<_size; i++)
+ under_term[i] = new parse_action();
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Static (Class) Variables ------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Number of columns (terminals) in every row. */
+ protected static int _size = 0;
+
+ /** Number of columns (terminals) in every row. */
+ public static int size() {return _size;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Table of reduction counts (reused by compute_default()). */
+ protected static int reduction_count[] = null;
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Actual action entries for the row. */
+ public parse_action under_term[];
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Default (reduce) action for this row. -1 will represent default
+ * of error.
+ */
+ public int default_reduce;
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Compute the default (reduce) action for this row and store it in
+ * default_reduce. In the case of non-zero default we will have the
+ * effect of replacing all errors by that reduction. This may cause
+ * us to do erroneous reduces, but will never cause us to shift past
+ * the point of the error and never cause an incorrect parse. -1 will
+ * be used to encode the fact that no reduction can be used as a
+ * default (in which case error will be used).
+ */
+ public void compute_default()
+ {
+ int i, prod, max_prod, max_red;
+
+ /* if we haven't allocated the count table, do so now */
+ if (reduction_count == null)
+ reduction_count = new int[production.number()];
+
+ /* clear the reduction count table and maximums */
+ for (i = 0; i < production.number(); i++)
+ reduction_count[i] = 0;
+ max_prod = -1;
+ max_red = 0;
+
+ /* walk down the row and look at the reduces */
+ for (i = 0; i < size(); i++)
+ if (under_term[i].kind() == parse_action.REDUCE)
+ {
+ /* count the reduce in the proper production slot and keep the
+ max up to date */
+ prod = ((reduce_action)under_term[i]).reduce_with().index();
+ reduction_count[prod]++;
+ if (reduction_count[prod] > max_red)
+ {
+ max_red = reduction_count[prod];
+ max_prod = prod;
+ }
+ }
+
+ /* record the max as the default (or -1 for not found) */
+ default_reduce = max_prod;
+ }
+
+ /*-----------------------------------------------------------*/
+
+}
+
diff --git a/src/syntaxParser/java_cup/SAVE/parse_action_table.java b/src/syntaxParser/java_cup/SAVE/parse_action_table.java
new file mode 100644
index 0000000..1e0edb2
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/parse_action_table.java
@@ -0,0 +1,143 @@
+
+package java_cup;
+
+import java.util.Enumeration;
+
+/** This class represents the complete "action" table of the parser.
+ * It has one row for each state in the parse machine, and a column for
+ * each terminal symbol. Each entry in the table represents a shift,
+ * reduce, or an error.
+ *
+ * @see java_cup.parse_action
+ * @see java_cup.parse_action_row
+ * @version last updated: 11/25/95
+ * @author Scott Hudson
+ */
+public class parse_action_table {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Simple constructor. All terminals, non-terminals, and productions must
+ * already have been entered, and the viable prefix recognizer should
+ * have been constructed before this is called.
+ */
+ public parse_action_table()
+ {
+ /* determine how many states we are working with */
+ _num_states = lalr_state.number();
+
+ /* allocate the array and fill it in with empty rows */
+ under_state = new parse_action_row[_num_states];
+ for (int i=0; i<_num_states; i++)
+ under_state[i] = new parse_action_row();
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** How many rows/states are in the machine/table. */
+ protected int _num_states;
+
+ /** How many rows/states are in the machine/table. */
+ public int num_states() {return _num_states;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Actual array of rows, one per state. */
+ public parse_action_row[] under_state;
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Check the table to ensure that all productions have been reduced.
+ * Issue a warning message (to System.err) for each production that
+ * is never reduced.
+ */
+ public void check_reductions()
+ throws internal_error
+ {
+ parse_action act;
+ production prod;
+
+ /* tabulate reductions -- look at every table entry */
+ for (int row = 0; row < num_states(); row++)
+ {
+ for (int col = 0; col < under_state[row].size(); col++)
+ {
+ /* look at the action entry to see if its a reduce */
+ act = under_state[row].under_term[col];
+ if (act != null && act.kind() == parse_action.REDUCE)
+ {
+ /* tell production that we used it */
+ ((reduce_action)act).reduce_with().note_reduction_use();
+ }
+ }
+ }
+
+ /* now go across every production and make sure we hit it */
+ for (Enumeration p = production.all(); p.hasMoreElements(); )
+ {
+ prod = (production)p.nextElement();
+
+ /* if we didn't hit it give a warning */
+ if (prod.num_reductions() == 0)
+ {
+ /* count it *
+ emit.not_reduced++;
+
+ /* give a warning if they haven't been turned off */
+ if (!emit.nowarn)
+ {
+ System.err.println("*** Production \"" +
+ prod.to_simple_string() + "\" never reduced");
+ lexer.warning_count++;
+ }
+ }
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*
+
+ /** Convert to a string. */
+ public String toString()
+ {
+ String result;
+ int cnt;
+
+ result = "-------- ACTION_TABLE --------\n";
+ for (int row = 0; row < num_states(); row++)
+ {
+ result += "From state #" + row + "\n";
+ cnt = 0;
+ for (int col = 0; col < under_state[row].size(); col++)
+ {
+ /* if the action is not an error print it */
+ if (under_state[row].under_term[col].kind() != parse_action.ERROR)
+ {
+ result += " [term " + col + ":" + under_state[row].under_term[col] + "]";
+
+ /* end the line after the 2nd one */
+ cnt++;
+ if (cnt == 2)
+ {
+ result += "\n";
+ cnt = 0;
+ }
+ }
+ }
+ /* finish the line if we haven't just done that */
+ if (cnt != 0) result += "\n";
+ }
+ result += "------------------------------";
+
+ return result;
+ }
+
+ /*-----------------------------------------------------------*/
+
+}
+
diff --git a/src/syntaxParser/java_cup/SAVE/parse_reduce_row.java b/src/syntaxParser/java_cup/SAVE/parse_reduce_row.java
new file mode 100644
index 0000000..57d978e
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/parse_reduce_row.java
@@ -0,0 +1,41 @@
+
+package java_cup;
+
+/** This class represents one row (corresponding to one machine state) of the
+ * reduce-goto parse table.
+ */
+public class parse_reduce_row {
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Simple constructor. Note: this should not be used until the number
+ * of terminals in the grammar has been established.
+ */
+ public parse_reduce_row()
+ {
+ /* make sure the size is set */
+ if (_size <= 0 ) _size = non_terminal.number();
+
+ /* allocate the array */
+ under_non_term = new lalr_state[size()];
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Static (Class) Variables ------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Number of columns (non terminals) in every row. */
+ protected static int _size = 0;
+
+ /** Number of columns (non terminals) in every row. */
+ public static int size() {return _size;}
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Actual entries for the row. */
+ public lalr_state under_non_term[];
+}
+
diff --git a/src/syntaxParser/java_cup/SAVE/parse_reduce_table.java b/src/syntaxParser/java_cup/SAVE/parse_reduce_table.java
new file mode 100644
index 0000000..9ac1b11
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/parse_reduce_table.java
@@ -0,0 +1,99 @@
+
+package java_cup;
+
+import java.util.Enumeration;
+
+/** This class represents the complete "reduce-goto" table of the parser.
+ * It has one row for each state in the parse machines, and a column for
+ * each terminal symbol. Each entry contains a state number to shift to
+ * as the last step of a reduce.
+ *
+ * @see java_cup.parse_reduce_row
+ * @version last updated: 11/25/95
+ * @author Scott Hudson
+ */
+public class parse_reduce_table {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Simple constructor. Note: all terminals, non-terminals, and productions
+ * must already have been entered, and the viable prefix recognizer should
+ * have been constructed before this is called.
+ */
+ public parse_reduce_table()
+ {
+ /* determine how many states we are working with */
+ _num_states = lalr_state.number();
+
+ /* allocate the array and fill it in with empty rows */
+ under_state = new parse_reduce_row[_num_states];
+ for (int i=0; i<_num_states; i++)
+ under_state[i] = new parse_reduce_row();
+ }
+
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** How many rows/states in the machine/table. */
+ protected int _num_states;
+
+ /** How many rows/states in the machine/table. */
+ public int num_states() {return _num_states;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Actual array of rows, one per state */
+ public parse_reduce_row[] under_state;
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Convert to a string. */
+ public String toString()
+ {
+ String result;
+ lalr_state goto_st;
+ int cnt;
+
+ result = "-------- REDUCE_TABLE --------\n";
+ for (int row = 0; row < num_states(); row++)
+ {
+ result += "From state #" + row + "\n";
+ cnt = 0;
+ for (int col = 0; col < under_state[row].size(); col++)
+ {
+ /* pull out the table entry */
+ goto_st = under_state[row].under_non_term[col];
+
+ /* if it has action in it, print it */
+ if (goto_st != null)
+ {
+ result += " [non term " + col + "->";
+ result += "state " + goto_st.index() + "]";
+
+ /* end the line after the 3rd one */
+ cnt++;
+ if (cnt == 3)
+ {
+ result += "\n";
+ cnt = 0;
+ }
+ }
+ }
+ /* finish the line if we haven't just done that */
+ if (cnt != 0) result += "\n";
+ }
+ result += "-----------------------------";
+
+ return result;
+ }
+
+ /*-----------------------------------------------------------*/
+
+}
+
diff --git a/src/syntaxParser/java_cup/SAVE/parser.cup b/src/syntaxParser/java_cup/SAVE/parser.cup
new file mode 100644
index 0000000..8af0d05
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/parser.cup
@@ -0,0 +1,863 @@
+
+/*================================================================*/
+/*
+ JavaCup Specification for the JavaCup Specification Language
+ by Scott Hudson, GVU Center, Georgia Tech, August 1995
+ and Frank Flannery, Department of Computer Science, Princeton Univ,
+ July 1996
+ Bug Fixes: C. Scott Ananian, Dept of Electrical Engineering, Princeton
+ University, October 1996. [later Massachusetts Institute of Technology]
+
+
+ This JavaCup specification is used to implement JavaCup itself.
+ It specifies the parser for the JavaCup specification language.
+ (It also serves as a reasonable example of what a typical JavaCup
+ spec looks like).
+
+ The specification has the following parts:
+ Package and import declarations
+ These serve the same purpose as in a normal Java source file
+ (and will appear in the generated code for the parser). In this
+ case we are part of the java_cup package and we import both the
+ java_cup runtime system and Hashtable from the standard Java
+ utilities package.
+
+ Action code
+ This section provides code that is included with the class encapsulating
+ the various pieces of user code embedded in the grammar (i.e., the
+ semantic actions). This provides a series of helper routines and
+ data structures that the semantic actions use.
+
+ Parser code
+ This section provides code included in the parser class itself. In
+ this case we override the default error reporting routines.
+
+ Init with and scan with
+ These sections provide small bits of code that initialize, then
+ indicate how to invoke the scanner.
+
+ Symbols and grammar
+ These sections declare all the terminal and non terminal symbols
+ and the types of objects that they will be represented by at runtime,
+ then indicate the start symbol of the grammar (), and finally provide
+ the grammar itself (with embedded actions).
+
+ Operation of the parser
+ The parser acts primarily by accumulating data structures representing
+ various parts of the specification. Various small parts (e.g., single
+ code strings) are stored as static variables of the emit class and
+ in a few cases as variables declared in the action code section.
+ Terminals, non terminals, and productions, are maintained as collection
+ accessible via static methods of those classes. In addition, two
+ symbol tables are kept:
+ symbols maintains the name to object mapping for all symbols
+ non_terms maintains a separate mapping containing only the non terms
+
+ Several intermediate working structures are also declared in the action
+ code section. These include: rhs_parts, rhs_pos, and lhs_nt which
+ build up parts of the current production while it is being parsed.
+
+ Author(s)
+ Scott Hudson, GVU Center, Georgia Tech.
+ Frank Flannery, Department of Computer Science, Princeton Univ.
+ C. Scott Ananian, Department of Electrical Engineering, Princeton Univ.
+
+ Revisions
+ v0.9a First released version [SEH] 8/29/95
+ v0.9b Updated for beta language (throws clauses) [SEH] 11/25/95
+ v0.10a Made many improvements/changes. now offers:
+ return value
+ left/right positions and propagations
+ cleaner label references
+ precedence and associativity for terminals
+ contextual precedence for productions
+ [FF] 7/3/96
+ v0.10b Fixed %prec directive so it works like it's supposed to.
+ [CSA] 10/10/96
+ v0.10g Added support for array types on symbols.
+ [CSA] 03/23/98
+ v0.10i Broaden set of IDs allowed in multipart_id and label_id so
+ that only java reserved words (and not CUP reserved words like
+ 'parser' and 'start') are prohibited. Allow reordering of
+ action code, parser code, init code, and scan with sections,
+ and made closing semicolon optional for these sections.
+ Added 'nonterminal' as a terminal symbol, finally fixing a
+ spelling mistake that's been around since the beginning.
+ For backwards compatibility, you can still misspell the
+ word if you like.
+*/
+/*================================================================*/
+
+package java_cup;
+import java_cup.runtime.*;
+import java.util.Hashtable;
+
+/*----------------------------------------------------------------*/
+
+action code {:
+ /** helper routine to clone a new production part adding a given label */
+ protected production_part add_lab(production_part part, String lab)
+ throws internal_error
+ {
+ /* if there is no label, or this is an action, just return the original */
+ if (lab == null || part.is_action()) return part;
+
+ /* otherwise build a new one with the given label attached */
+ return new symbol_part(((symbol_part)part).the_symbol(),lab);
+ }
+
+ /** max size of right hand side we will support */
+ protected final int MAX_RHS = 200;
+
+ /** array for accumulating right hand side parts */
+ protected production_part[] rhs_parts = new production_part[MAX_RHS];
+
+ /** where we are currently in building a right hand side */
+ protected int rhs_pos = 0;
+
+ /** start a new right hand side */
+ protected void new_rhs() {rhs_pos = 0; }
+
+ /** add a new right hand side part */
+ protected void add_rhs_part(production_part part) throws java.lang.Exception
+ {
+ if (rhs_pos >= MAX_RHS)
+ throw new Exception("Internal Error: Productions limited to " +
+ MAX_RHS + " symbols and actions");
+
+ rhs_parts[rhs_pos] = part;
+ rhs_pos++;
+ }
+
+ /** string to build up multiple part names */
+ protected String multipart_name = new String();
+
+ /** append a new name segment to the accumulated multipart name */
+ protected void append_multipart(String name)
+ {
+ String dot = "";
+
+ /* if we aren't just starting out, put on a dot */
+ if (multipart_name.length() != 0) dot = ".";
+
+ multipart_name = multipart_name.concat(dot + name);
+ }
+
+ /** table of declared symbols -- contains production parts indexed by name */
+ protected Hashtable symbols = new Hashtable();
+
+ /** table of just non terminals -- contains non_terminals indexed by name */
+ protected Hashtable non_terms = new Hashtable();
+
+ /** declared start non_terminal */
+ protected non_terminal start_nt = null;
+
+ /** left hand side non terminal of the current production */
+ protected non_terminal lhs_nt;
+
+ /** Current precedence number */
+ int _cur_prec = 0;
+
+ /** Current precedence side */
+ int _cur_side = assoc.no_prec;
+
+ /** update the precedences we are declaring */
+ protected void update_precedence(int p) {
+ _cur_side = p;
+ _cur_prec++;
+ }
+ /** add relevant data to terminals */
+ protected void add_precedence(String term) {
+ if (term == null) {
+ System.err.println("Unable to add precedence to nonexistent terminal");
+ } else {
+ symbol_part sp = (symbol_part)symbols.get(term);
+ if (sp == null) {
+ System.err.println("Could find terminal " + term + " while declaring precedence");
+ } else {
+ java_cup.symbol sym = sp.the_symbol();
+ if (sym instanceof terminal)
+ ((terminal)sym).set_precedence(_cur_side, _cur_prec);
+ else System.err.println("Precedence declaration: Can't find terminal " + term);
+ }
+ }
+ }
+:};
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+parser code {:
+
+ /* override error routines */
+
+ public void report_fatal_error(
+ String message,
+ Object info)
+ {
+ done_parsing();
+ lexer.emit_error(message);
+ System.err.println("Can't recover from previous error(s), giving up.");
+ System.exit(1);
+ }
+
+ public void report_error(String message, Object info)
+ {
+ lexer.emit_error(message);
+ }
+:};
+
+/*----------------------------------------------------------------*/
+
+init with {: lexer.init(); :};
+scan with {: return lexer.next_token(); :};
+
+/*----------------------------------------------------------------*/
+
+terminal
+ PACKAGE, IMPORT, CODE, ACTION, PARSER, TERMINAL, NON, INIT, SCAN, WITH,
+ START, SEMI, COMMA, STAR, DOT, COLON, COLON_COLON_EQUALS, BAR, PRECEDENCE,
+ LEFT, RIGHT, NONASSOC, PERCENT_PREC, LBRACK, RBRACK, NONTERMINAL;
+
+terminal String ID, CODE_STRING;
+
+non terminal
+ spec, package_spec, import_list, action_code_part,
+ code_parts, code_part, opt_semi, non_terminal,
+ parser_code_part, symbol_list, start_spec, production_list,
+ multipart_id, import_spec, import_id, init_code, scan_code, symbol,
+ type_id, term_name_list, non_term_name_list, production, prod_part_list,
+ prod_part, new_term_id, new_non_term_id, rhs_list, rhs, empty,
+ precedence_list, preced, terminal_list, precedence_l, declares_term,
+ declares_non_term;
+
+non terminal String nt_id, symbol_id, label_id, opt_label, terminal_id,
+ term_id, robust_id;
+
+/*----------------------------------------------------------------*/
+
+start with spec;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+spec ::=
+ {:
+ /* declare "error" as a terminal */
+ symbols.put("error", new symbol_part(terminal.error));
+
+ /* declare start non terminal */
+ non_terms.put("$START", non_terminal.START_nt);
+ :}
+ package_spec
+ import_list
+ code_parts
+ symbol_list
+ precedence_list
+ start_spec
+ production_list
+ |
+ /* error recovery assuming something went wrong before symbols
+ and we have TERMINAL or NON TERMINAL to sync on. if we get
+ an error after that, we recover inside symbol_list or
+ production_list
+ */
+ error
+ symbol_list
+ precedence_list
+ start_spec
+ production_list
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+package_spec ::=
+ PACKAGE
+ multipart_id
+ {:
+ /* save the package name */
+ emit.package_name = multipart_name;
+
+ /* reset the accumulated multipart name */
+ multipart_name = new String();
+ :}
+ SEMI
+ |
+ empty
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+import_list ::=
+ import_list
+ import_spec
+ |
+ empty
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+import_spec ::=
+ IMPORT
+ import_id
+ {:
+ /* save this import on the imports list */
+ emit.import_list.push(multipart_name);
+
+ /* reset the accumulated multipart name */
+ multipart_name = new String();
+ :}
+ SEMI
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+// allow any order; all parts are optional. [CSA, 23-Jul-1999]
+// (we check in the part action to make sure we don't have 2 of any part)
+code_part ::=
+ action_code_part | parser_code_part | init_code | scan_code ;
+code_parts ::=
+ | code_parts code_part;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+action_code_part ::=
+ ACTION CODE CODE_STRING:user_code opt_semi
+ {:
+ if (emit.action_code!=null)
+ lexer.emit_error("Redundant action code (skipping)");
+ else /* save the user included code string */
+ emit.action_code = user_code;
+ :}
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+parser_code_part ::=
+ PARSER CODE CODE_STRING:user_code opt_semi
+ {:
+ if (emit.parser_code!=null)
+ lexer.emit_error("Redundant parser code (skipping)");
+ else /* save the user included code string */
+ emit.parser_code = user_code;
+ :}
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+init_code ::=
+ INIT WITH CODE_STRING:user_code opt_semi
+ {:
+ if (emit.init_code!=null)
+ lexer.emit_error("Redundant init code (skipping)");
+ else /* save the user code */
+ emit.init_code = user_code;
+ :}
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+scan_code ::=
+ SCAN WITH CODE_STRING:user_code opt_semi
+ {:
+ if (emit.scan_code!=null)
+ lexer.emit_error("Redundant scan code (skipping)");
+ else /* save the user code */
+ emit.scan_code = user_code;
+ :}
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+symbol_list ::= symbol_list symbol | symbol;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+symbol ::=
+ TERMINAL
+ type_id
+ declares_term
+ |
+ TERMINAL
+ declares_term
+ |
+ non_terminal
+ type_id
+ declares_non_term
+ |
+ non_terminal
+ declares_non_term
+ |
+ /* error recovery productions -- sync on semicolon */
+
+ TERMINAL
+ error
+ {:
+ /* reset the accumulated multipart name */
+ multipart_name = new String();
+ :}
+ SEMI
+ |
+ non_terminal
+ error
+ {:
+ /* reset the accumulated multipart name */
+ multipart_name = new String();
+ :}
+ SEMI
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+declares_term ::=
+ term_name_list
+ {:
+ /* reset the accumulated multipart name */
+ multipart_name = new String();
+ :}
+ SEMI
+ ;
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+declares_non_term ::=
+ non_term_name_list
+ {:
+ /* reset the accumulated multipart name */
+ multipart_name = new String();
+ :}
+ SEMI
+ ;
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+term_name_list ::= term_name_list COMMA new_term_id | new_term_id;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+non_term_name_list ::=
+ non_term_name_list
+ COMMA
+ new_non_term_id
+ |
+ new_non_term_id
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+
+precedence_list ::= precedence_l | empty;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+precedence_l ::= precedence_l preced | preced;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+preced ::=
+ PRECEDENCE LEFT
+ {:
+ update_precedence(assoc.left);
+ :}
+ terminal_list SEMI
+ |
+ PRECEDENCE RIGHT
+ {:
+ update_precedence(assoc.right);
+ :}
+ terminal_list SEMI
+ |
+ PRECEDENCE NONASSOC
+ {:
+ update_precedence(assoc.nonassoc);
+ :}
+ terminal_list SEMI
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+terminal_list ::= terminal_list COMMA terminal_id
+ |
+ terminal_id
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+terminal_id ::= term_id:sym
+ {:
+ add_precedence(sym);
+ RESULT = sym;
+ :};
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+term_id ::= symbol_id:sym
+ {:
+ /* check that the symbol_id is a terminal */
+ if (symbols.get(sym) == null)
+ {
+ /* issue a message */
+ lexer.emit_error("Terminal \"" + sym +
+ "\" has not been declared");
+ }
+ RESULT = sym;
+ :};
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+start_spec ::=
+ START WITH nt_id:start_name
+ {:
+ /* verify that the name has been declared as a non terminal */
+ non_terminal nt = (non_terminal)non_terms.get(start_name);
+ if (nt == null)
+ {
+ lexer.emit_error( "Start non terminal \"" + start_name +
+ "\" has not been declared");
+ }
+ else
+ {
+ /* remember the non-terminal for later */
+ start_nt = nt;
+
+ /* build a special start production */
+ new_rhs();
+ add_rhs_part(add_lab(new symbol_part(start_nt), "start_val"));
+ add_rhs_part(new symbol_part(terminal.EOF));
+ add_rhs_part(new action_part("RESULT = start_val;"));
+ emit.start_production =
+ new production(non_terminal.START_nt, rhs_parts, rhs_pos);
+ new_rhs();
+ }
+ :}
+ SEMI
+ |
+ empty
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+production_list ::= production_list production | production;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+production ::=
+ nt_id:lhs_id
+ {:
+ /* lookup the lhs nt */
+ lhs_nt = (non_terminal)non_terms.get(lhs_id);
+
+ /* if it wasn't declared, emit a message */
+ if (lhs_nt == null)
+ {
+ if (lexer.error_count == 0)
+ lexer.emit_error("LHS non terminal \"" + lhs_id +
+ "\" has not been declared");
+ }
+
+ /* reset the rhs accumulation */
+ new_rhs();
+ :}
+ COLON_COLON_EQUALS
+ {: :}
+ rhs_list
+ SEMI
+ |
+ error
+ {: lexer.emit_error("Syntax Error"); :}
+ SEMI
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+rhs_list ::= rhs_list BAR rhs | rhs;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+rhs ::=
+ prod_part_list PERCENT_PREC term_id:term_name
+ {:
+ java_cup.symbol sym = null;
+ if (lhs_nt != null)
+ {
+ /* Find the precedence symbol */
+ if (term_name == null) {
+ System.err.println("No terminal for contextual precedence");
+ sym = null;
+ } else {
+ sym = ((symbol_part)symbols.get(term_name)).the_symbol();
+ }
+ /* build the production */
+ production p;
+ if ((sym!=null) && (sym instanceof terminal)) {
+ p = new production(lhs_nt, rhs_parts, rhs_pos,
+ ((terminal)sym).precedence_num(),
+ ((terminal)sym).precedence_side());
+ ((symbol_part)symbols.get(term_name)).the_symbol().note_use();
+ } else {
+ System.err.println("Invalid terminal " + term_name +
+ " for contextual precedence assignment");
+ p = new production(lhs_nt, rhs_parts, rhs_pos);
+ }
+
+ /* if we have no start non-terminal declared and this is
+ the first production, make its lhs nt the start_nt
+ and build a special start production for it. */
+ if (start_nt == null)
+ {
+ start_nt = lhs_nt;
+
+ /* build a special start production */
+ new_rhs();
+ add_rhs_part(add_lab(new symbol_part(start_nt),"start_val"));
+ add_rhs_part(new symbol_part(terminal.EOF));
+ add_rhs_part(new action_part("RESULT = start_val;"));
+ if ((sym!=null) && (sym instanceof terminal)) {
+ emit.start_production =
+ new production(non_terminal.START_nt, rhs_parts,
+ rhs_pos, ((terminal)sym).precedence_num(),
+ ((terminal)sym).precedence_side());
+ } else {
+ emit.start_production =
+ new production(non_terminal.START_nt, rhs_parts, rhs_pos);
+ }
+ new_rhs();
+ }
+ }
+
+ /* reset the rhs accumulation in any case */
+ new_rhs();
+ :}
+ |
+ prod_part_list
+ {:
+ if (lhs_nt != null)
+ {
+ /* build the production */
+ production p = new production(lhs_nt, rhs_parts, rhs_pos);
+
+ /* if we have no start non-terminal declared and this is
+ the first production, make its lhs nt the start_nt
+ and build a special start production for it. */
+ if (start_nt == null)
+ {
+ start_nt = lhs_nt;
+
+ /* build a special start production */
+ new_rhs();
+ add_rhs_part(add_lab(new symbol_part(start_nt),"start_val"));
+ add_rhs_part(new symbol_part(terminal.EOF));
+ add_rhs_part(new action_part("RESULT = start_val;"));
+ emit.start_production =
+ new production(non_terminal.START_nt, rhs_parts, rhs_pos);
+
+ new_rhs();
+ }
+ }
+
+ /* reset the rhs accumulation in any case */
+ new_rhs();
+ :}
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+prod_part_list ::= prod_part_list prod_part | empty;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+prod_part ::=
+ symbol_id:symid opt_label:labid
+ {:
+ /* try to look up the id */
+ production_part symb = (production_part)symbols.get(symid);
+
+ /* if that fails, symbol is undeclared */
+ if (symb == null)
+ {
+ if (lexer.error_count == 0)
+ lexer.emit_error("java_cup.runtime.Symbol \"" + symid +
+ "\" has not been declared");
+ }
+ else
+ {
+ /* add a labeled production part */
+ add_rhs_part(add_lab(symb, labid));
+ }
+ :}
+ |
+ CODE_STRING:code_str
+ {:
+ /* add a new production part */
+ add_rhs_part(new action_part(code_str));
+ :}
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+opt_label ::=
+ COLON label_id:labid
+ {: RESULT = labid; :}
+ |
+ empty
+ {: RESULT = null; :}
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+multipart_id ::=
+ multipart_id DOT robust_id:another_id
+ {: append_multipart(another_id); :}
+ |
+ robust_id:an_id
+ {: append_multipart(an_id); :}
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+import_id ::=
+ multipart_id DOT STAR
+ {: append_multipart("*"); :}
+ |
+ multipart_id
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+type_id ::= multipart_id
+ | type_id LBRACK RBRACK
+ {: multipart_name = multipart_name.concat("[]"); :}
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+new_term_id ::=
+ ID:term_id
+ {:
+ /* see if this terminal has been declared before */
+ if (symbols.get(term_id) != null)
+ {
+ /* issue a message */
+ lexer.emit_error("java_cup.runtime.Symbol \"" + term_id +
+ "\" has already been declared");
+ }
+ else
+ {
+ /* if no type declared, declare one */
+ if (multipart_name.equals("")) {
+ append_multipart("Object");
+ }
+ /* build a production_part and put it in the table */
+ symbols.put(term_id,
+ new symbol_part(new terminal(term_id, multipart_name)));
+ }
+ :}
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+new_non_term_id ::=
+ ID:non_term_id
+ {:
+ /* see if this non terminal has been declared before */
+ if (symbols.get(non_term_id) != null)
+ {
+ /* issue a message */
+ lexer.emit_error( "java_cup.runtime.Symbol \"" + non_term_id +
+ "\" has already been declared");
+ }
+ else
+ {
+ if (multipart_name.equals("")) {
+ append_multipart("Object");
+ }
+ /* build the non terminal object */
+ non_terminal this_nt =
+ new non_terminal(non_term_id, multipart_name);
+
+ /* put it in the non_terms table */
+ non_terms.put(non_term_id, this_nt);
+
+ /* build a production_part and put it in the symbols table */
+ symbols.put(non_term_id, new symbol_part(this_nt));
+ }
+ :}
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+nt_id ::=
+ ID:the_id
+ {: RESULT = the_id; :}
+ | error
+ {:
+ lexer.emit_error("Illegal use of reserved word");
+ RESULT="ILLEGAL";
+ :}
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+symbol_id ::=
+ ID:the_id
+ {: RESULT = the_id; :}
+ | error
+ {:
+ lexer.emit_error("Illegal use of reserved word");
+ RESULT="ILLEGAL";
+ :}
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+label_id ::=
+ robust_id:the_id
+ {: RESULT = the_id; :}
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+robust_id ::= /* all ids that aren't reserved words in Java */
+ ID:the_id {: RESULT = the_id; :}
+ /* package is reserved. */
+ /* import is reserved. */
+ | CODE {: RESULT = "code"; :}
+ | ACTION {: RESULT = "action"; :}
+ | PARSER {: RESULT = "parser"; :}
+ | TERMINAL {: RESULT = "terminal"; :}
+ | NON {: RESULT = "non"; :}
+ | NONTERMINAL {: RESULT = "nonterminal"; :}
+ | INIT {: RESULT = "init"; :}
+ | SCAN {: RESULT = "scan"; :}
+ | WITH {: RESULT = "with"; :}
+ | START {: RESULT = "start"; :}
+ | PRECEDENCE {: RESULT = "precedence"; :}
+ | LEFT {: RESULT = "left"; :}
+ | RIGHT {: RESULT = "right"; :}
+ | NONASSOC {: RESULT = "nonassoc"; :}
+ | error
+ {:
+ lexer.emit_error("Illegal use of reserved word");
+ RESULT="ILLEGAL";
+ :}
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+non_terminal ::= NON TERMINAL | NONTERMINAL;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+opt_semi ::= /* nothing */
+ | SEMI;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+empty ::= /* nothing */;
+
+/*----------------------------------------------------------------*/
+
+
+
+
+
+
+
+
+
diff --git a/src/syntaxParser/java_cup/SAVE/parser.java b/src/syntaxParser/java_cup/SAVE/parser.java
new file mode 100644
index 0000000..163968e
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/parser.java
@@ -0,0 +1,1849 @@
+
+//----------------------------------------------------
+// The following code was generated by CUP v0.10k
+// Sun Jul 25 13:35:26 EDT 1999
+//----------------------------------------------------
+
+package java_cup;
+
+import java_cup.runtime.*;
+import java.util.Hashtable;
+
+/** CUP v0.10k generated parser.
+ * @version Sun Jul 25 13:35:26 EDT 1999
+ */
+public class parser extends java_cup.runtime.lr_parser {
+
+ /** Default constructor. */
+ public parser() {super();}
+
+ /** Constructor which sets the default scanner. */
+ public parser(java_cup.runtime.Scanner s) {super(s);}
+
+ /** Production table. */
+ protected static final short _production_table[][] =
+ unpackFromStrings(new String[] {
+ "\000\153\000\002\002\004\000\002\055\002\000\002\003" +
+ "\012\000\002\003\007\000\002\056\002\000\002\004\006" +
+ "\000\002\004\003\000\002\005\004\000\002\005\003\000" +
+ "\002\057\002\000\002\020\006\000\002\010\003\000\002" +
+ "\010\003\000\002\010\003\000\002\010\003\000\002\007" +
+ "\002\000\002\007\004\000\002\006\006\000\002\013\006" +
+ "\000\002\022\006\000\002\023\006\000\002\014\004\000" +
+ "\002\014\003\000\002\024\005\000\002\024\004\000\002" +
+ "\024\005\000\002\024\004\000\002\060\002\000\002\024" +
+ "\006\000\002\061\002\000\002\024\006\000\002\062\002" +
+ "\000\002\044\005\000\002\063\002\000\002\045\005\000" +
+ "\002\026\005\000\002\026\003\000\002\027\005\000\002" +
+ "\027\003\000\002\040\003\000\002\040\003\000\002\043" +
+ "\004\000\002\043\003\000\002\064\002\000\002\041\007" +
+ "\000\002\065\002\000\002\041\007\000\002\066\002\000" +
+ "\002\041\007\000\002\042\005\000\002\042\003\000\002" +
+ "\052\003\000\002\053\003\000\002\067\002\000\002\015" +
+ "\007\000\002\015\003\000\002\016\004\000\002\016\003" +
+ "\000\002\070\002\000\002\071\002\000\002\030\010\000" +
+ "\002\072\002\000\002\030\005\000\002\035\005\000\002" +
+ "\035\003\000\002\036\005\000\002\036\003\000\002\031" +
+ "\004\000\002\031\003\000\002\032\004\000\002\032\003" +
+ "\000\002\051\004\000\002\051\003\000\002\017\005\000" +
+ "\002\017\003\000\002\021\005\000\002\021\003\000\002" +
+ "\025\003\000\002\025\005\000\002\033\003\000\002\034" +
+ "\003\000\002\046\003\000\002\046\003\000\002\047\003" +
+ "\000\002\047\003\000\002\050\003\000\002\054\003\000" +
+ "\002\054\003\000\002\054\003\000\002\054\003\000\002" +
+ "\054\003\000\002\054\003\000\002\054\003\000\002\054" +
+ "\003\000\002\054\003\000\002\054\003\000\002\054\003" +
+ "\000\002\054\003\000\002\054\003\000\002\054\003\000" +
+ "\002\054\003\000\002\054\003\000\002\012\004\000\002" +
+ "\012\003\000\002\011\002\000\002\011\003\000\002\037" +
+ "\002" });
+
+ /** Access to production table. */
+ public short[][] production_table() {return _production_table;}
+
+ /** Parse-action table. */
+ protected static final short[][] _action_table =
+ unpackFromStrings(new String[] {
+ "\000\247\000\026\003\006\004\000\005\000\007\000\010" +
+ "\000\011\000\012\000\013\000\014\000\035\000\001\002" +
+ "\000\004\002\251\001\002\000\024\004\200\005\uff97\007" +
+ "\uff97\010\uff97\011\uff97\012\uff97\013\uff97\014\uff97\035\uff97" +
+ "\001\002\000\010\011\007\012\012\035\014\001\002\000" +
+ "\042\003\163\006\026\007\027\010\040\011\036\012\022" +
+ "\013\042\014\030\015\017\016\015\026\033\027\023\030" +
+ "\035\031\041\035\025\036\160\001\002\000\020\003\uffeb" +
+ "\011\uffeb\012\uffeb\016\uffeb\026\uffeb\035\uffeb\036\uffeb\001" +
+ "\002\000\020\003\uff97\011\007\012\012\016\uff97\026\065" +
+ "\035\014\036\uff97\001\002\000\004\011\061\001\002\000" +
+ "\042\003\034\006\026\007\027\010\040\011\036\012\022" +
+ "\013\042\014\030\015\017\016\015\026\033\027\023\030" +
+ "\035\031\041\035\025\036\016\001\002\000\042\003\uff9a" +
+ "\006\uff9a\007\uff9a\010\uff9a\011\uff9a\012\uff9a\013\uff9a\014" +
+ "\uff9a\015\uff9a\016\uff9a\026\uff9a\027\uff9a\030\uff9a\031\uff9a" +
+ "\035\uff9a\036\uff9a\001\002\000\022\003\uffa1\017\uffa1\022" +
+ "\uffa1\025\uffa1\032\uffa1\033\uffa1\036\uffa1\037\uffa1\001\002" +
+ "\000\014\017\uffb1\020\uffb1\022\uffab\033\uffab\036\uffab\001" +
+ "\002\000\022\003\uffa2\017\uffa2\022\uffa2\025\uffa2\032\uffa2" +
+ "\033\uffa2\036\uffa2\037\uffa2\001\002\000\006\017\uffe0\020" +
+ "\055\001\002\000\010\022\051\033\uffb4\036\uffb4\001\002" +
+ "\000\022\003\uffa6\017\uffa6\022\uffa6\025\uffa6\032\uffa6\033" +
+ "\uffa6\036\uffa6\037\uffa6\001\002\000\022\003\uff9f\017\uff9f" +
+ "\022\uff9f\025\uff9f\032\uff9f\033\uff9f\036\uff9f\037\uff9f\001" +
+ "\002\000\006\033\047\036\045\001\002\000\022\003\uffa5" +
+ "\017\uffa5\022\uffa5\025\uffa5\032\uffa5\033\uffa5\036\uffa5\037" +
+ "\uffa5\001\002\000\022\003\uffaa\017\uffaa\022\uffaa\025\uffaa" +
+ "\032\uffaa\033\uffaa\036\uffaa\037\uffaa\001\002\000\022\003" +
+ "\uffa9\017\uffa9\022\uffa9\025\uffa9\032\uffa9\033\uffa9\036\uffa9" +
+ "\037\uffa9\001\002\000\022\003\uffa3\017\uffa3\022\uffa3\025" +
+ "\uffa3\032\uffa3\033\uffa3\036\uffa3\037\uffa3\001\002\000\012" +
+ "\017\uffb7\022\uffb7\033\uffb7\036\uffb7\001\002\000\020\003" +
+ "\uffe7\011\uffe7\012\uffe7\016\uffe7\026\uffe7\035\uffe7\036\uffe7" +
+ "\001\002\000\022\003\uffa0\017\uffa0\022\uffa0\025\uffa0\032" +
+ "\uffa0\033\uffa0\036\uffa0\037\uffa0\001\002\000\012\017\uffe4" +
+ "\022\uff9c\033\uff9c\036\uff9c\001\002\000\022\003\uff9e\017" +
+ "\uff9e\022\uff9e\025\uff9e\032\uff9e\033\uff9e\036\uff9e\037\uff9e" +
+ "\001\002\000\022\003\uffa7\017\uffa7\022\uffa7\025\uffa7\032" +
+ "\uffa7\033\uffa7\036\uffa7\037\uffa7\001\002\000\006\017\uffdb" +
+ "\020\uffdb\001\002\000\022\003\uffa8\017\uffa8\022\uffa8\025" +
+ "\uffa8\032\uffa8\033\uffa8\036\uffa8\037\uffa8\001\002\000\022" +
+ "\003\uff9d\017\uff9d\022\uff9d\025\uff9d\032\uff9d\033\uff9d\036" +
+ "\uff9d\037\uff9d\001\002\000\022\003\uffa4\017\uffa4\022\uffa4" +
+ "\025\uffa4\032\uffa4\033\uffa4\036\uffa4\037\uffa4\001\002\000" +
+ "\004\017\044\001\002\000\020\003\uffe3\011\uffe3\012\uffe3" +
+ "\016\uffe3\026\uffe3\035\uffe3\036\uffe3\001\002\000\006\017" +
+ "\uffb1\020\uffb1\001\002\000\020\003\uffe8\011\uffe8\012\uffe8" +
+ "\016\uffe8\026\uffe8\035\uffe8\036\uffe8\001\002\000\004\034" +
+ "\050\001\002\000\006\033\uffb3\036\uffb3\001\002\000\042" +
+ "\003\054\006\026\007\027\010\040\011\036\012\022\013" +
+ "\042\014\030\015\017\016\015\026\033\027\023\030\035" +
+ "\031\041\035\025\036\053\001\002\000\012\017\uffb8\022" +
+ "\uffb8\033\uffb8\036\uffb8\001\002\000\022\003\uffab\017\uffab" +
+ "\022\uffab\025\uffab\032\uffab\033\uffab\036\uffab\037\uffab\001" +
+ "\002\000\022\003\uff9c\017\uff9c\022\uff9c\025\uff9c\032\uff9c" +
+ "\033\uff9c\036\uff9c\037\uff9c\001\002\000\004\036\045\001" +
+ "\002\000\004\017\057\001\002\000\020\003\uffdf\011\uffdf" +
+ "\012\uffdf\016\uffdf\026\uffdf\035\uffdf\036\uffdf\001\002\000" +
+ "\006\017\uffdc\020\uffdc\001\002\000\042\003\uff9b\006\uff9b" +
+ "\007\uff9b\010\uff9b\011\uff9b\012\uff9b\013\uff9b\014\uff9b\015" +
+ "\uff9b\016\uff9b\026\uff9b\027\uff9b\030\uff9b\031\uff9b\035\uff9b" +
+ "\036\uff9b\001\002\000\010\003\uff97\016\116\036\uff97\001" +
+ "\002\000\012\003\uffda\016\uffda\026\065\036\uffda\001\002" +
+ "\000\010\003\uffd9\016\uffd9\036\uffd9\001\002\000\010\027" +
+ "\071\030\072\031\070\001\002\000\020\003\uffec\011\uffec" +
+ "\012\uffec\016\uffec\026\uffec\035\uffec\036\uffec\001\002\000" +
+ "\012\003\uffd7\016\uffd7\026\uffd7\036\uffd7\001\002\000\006" +
+ "\003\uffd2\036\uffd2\001\002\000\006\003\uffd6\036\uffd6\001" +
+ "\002\000\006\003\uffd4\036\uffd4\001\002\000\006\003\077" +
+ "\036\074\001\002\000\022\003\uffae\017\uffae\020\uffae\023" +
+ "\uffae\025\uffae\032\uffae\036\uffae\037\uffae\001\002\000\010" +
+ "\017\uffcd\020\uffcd\025\uffcd\001\002\000\006\017\uffce\020" +
+ "\uffce\001\002\000\022\003\uffad\017\uffad\020\uffad\023\uffad" +
+ "\025\uffad\032\uffad\036\uffad\037\uffad\001\002\000\006\017" +
+ "\102\020\103\001\002\000\006\017\uffcf\020\uffcf\001\002" +
+ "\000\012\003\uffd3\016\uffd3\026\uffd3\036\uffd3\001\002\000" +
+ "\006\003\077\036\074\001\002\000\006\017\uffd0\020\uffd0" +
+ "\001\002\000\006\003\077\036\074\001\002\000\006\017" +
+ "\107\020\103\001\002\000\012\003\uffd5\016\uffd5\026\uffd5" +
+ "\036\uffd5\001\002\000\006\003\077\036\074\001\002\000" +
+ "\006\017\112\020\103\001\002\000\012\003\uffd1\016\uffd1" +
+ "\026\uffd1\036\uffd1\001\002\000\012\003\uffd8\016\uffd8\026" +
+ "\uffd8\036\uffd8\001\002\000\006\003\uffca\036\uffca\001\002" +
+ "\000\006\003\126\036\120\001\002\000\004\015\117\001" +
+ "\002\000\006\003\122\036\120\001\002\000\006\017\uffb0" +
+ "\024\uffb0\001\002\000\004\017\uffcc\001\002\000\004\017" +
+ "\uffaf\001\002\000\004\017\124\001\002\000\006\003\uffcb" +
+ "\036\uffcb\001\002\000\004\024\uffc7\001\002\000\006\017" +
+ "\uffc4\024\uffaf\001\002\000\010\002\ufffe\003\126\036\120" +
+ "\001\002\000\010\002\uffc8\003\uffc8\036\uffc8\001\002\000" +
+ "\010\002\uffc9\003\uffc9\036\uffc9\001\002\000\004\017\133" +
+ "\001\002\000\010\002\uffc3\003\uffc3\036\uffc3\001\002\000" +
+ "\004\024\135\001\002\000\016\003\uffc6\017\uffc6\025\uffc6" +
+ "\032\uffc6\036\uffc6\037\uffc6\001\002\000\016\003\uff97\017" +
+ "\uff97\025\uff97\032\uff97\036\uff97\037\uff97\001\002\000\016" +
+ "\003\uffbd\017\uffbd\025\uffbd\032\uffbd\036\uffbd\037\uffbd\001" +
+ "\002\000\016\003\077\017\uffbf\025\uffbf\032\147\036\074" +
+ "\037\146\001\002\000\006\017\uffc1\025\uffc1\001\002\000" +
+ "\006\017\143\025\144\001\002\000\010\002\uffc5\003\uffc5" +
+ "\036\uffc5\001\002\000\016\003\uff97\017\uff97\025\uff97\032" +
+ "\uff97\036\uff97\037\uff97\001\002\000\006\017\uffc2\025\uffc2" +
+ "\001\002\000\016\003\uffbb\017\uffbb\025\uffbb\032\uffbb\036" +
+ "\uffbb\037\uffbb\001\002\000\006\003\077\036\074\001\002" +
+ "\000\020\003\uff97\017\uff97\023\154\025\uff97\032\uff97\036" +
+ "\uff97\037\uff97\001\002\000\016\003\uffbe\017\uffbe\025\uffbe" +
+ "\032\uffbe\036\uffbe\037\uffbe\001\002\000\016\003\uffb9\017" +
+ "\uffb9\025\uffb9\032\uffb9\036\uffb9\037\uffb9\001\002\000\016" +
+ "\003\uffbc\017\uffbc\025\uffbc\032\uffbc\036\uffbc\037\uffbc\001" +
+ "\002\000\042\003\054\006\026\007\027\010\040\011\036" +
+ "\012\022\013\042\014\030\015\017\016\015\026\033\027" +
+ "\023\030\035\031\041\035\025\036\053\001\002\000\016" +
+ "\003\uffba\017\uffba\025\uffba\032\uffba\036\uffba\037\uffba\001" +
+ "\002\000\016\003\uffac\017\uffac\025\uffac\032\uffac\036\uffac" +
+ "\037\uffac\001\002\000\006\017\uffc0\025\uffc0\001\002\000" +
+ "\014\017\uffb2\020\uffb2\022\uffab\033\uffab\036\uffab\001\002" +
+ "\000\006\033\047\036\170\001\002\000\006\017\uffdd\020" +
+ "\uffdd\001\002\000\012\017\uffe6\022\uff9c\033\uff9c\036\uff9c" +
+ "\001\002\000\020\003\uffe9\011\uffe9\012\uffe9\016\uffe9\026" +
+ "\uffe9\035\uffe9\036\uffe9\001\002\000\006\017\uffe2\020\167" +
+ "\001\002\000\004\017\172\001\002\000\004\036\170\001" +
+ "\002\000\006\017\uffb2\020\uffb2\001\002\000\006\017\uffde" +
+ "\020\uffde\001\002\000\020\003\uffe1\011\uffe1\012\uffe1\016" +
+ "\uffe1\026\uffe1\035\uffe1\036\uffe1\001\002\000\004\017\174" +
+ "\001\002\000\020\003\uffe5\011\uffe5\012\uffe5\016\uffe5\026" +
+ "\uffe5\035\uffe5\036\uffe5\001\002\000\020\003\uffea\011\uffea" +
+ "\012\uffea\016\uffea\026\uffea\035\uffea\036\uffea\001\002\000" +
+ "\022\005\ufffb\007\ufffb\010\ufffb\011\ufffb\012\ufffb\013\ufffb" +
+ "\014\ufffb\035\ufffb\001\002\000\022\005\uff97\007\uff97\010" +
+ "\uff97\011\uff97\012\uff97\013\uff97\014\uff97\035\uff97\001\002" +
+ "\000\042\003\054\006\026\007\027\010\040\011\036\012" +
+ "\022\013\042\014\030\015\017\016\015\026\033\027\023" +
+ "\030\035\031\041\035\025\036\053\001\002\000\006\017" +
+ "\ufffd\022\051\001\002\000\004\017\203\001\002\000\022" +
+ "\005\ufffc\007\ufffc\010\ufffc\011\ufffc\012\ufffc\013\ufffc\014" +
+ "\ufffc\035\ufffc\001\002\000\022\005\210\007\ufff2\010\ufff2" +
+ "\011\ufff2\012\ufff2\013\ufff2\014\ufff2\035\ufff2\001\002\000" +
+ "\022\005\ufff9\007\ufff9\010\ufff9\011\ufff9\012\ufff9\013\ufff9" +
+ "\014\ufff9\035\ufff9\001\002\000\020\007\223\010\224\011" +
+ "\007\012\012\013\227\014\225\035\014\001\002\000\022" +
+ "\005\ufffa\007\ufffa\010\ufffa\011\ufffa\012\ufffa\013\ufffa\014" +
+ "\ufffa\035\ufffa\001\002\000\042\003\054\006\026\007\027" +
+ "\010\040\011\036\012\022\013\042\014\030\015\017\016" +
+ "\015\026\033\027\023\030\035\031\041\035\025\036\053" +
+ "\001\002\000\006\017\uffb5\022\215\001\002\000\004\017" +
+ "\ufff8\001\002\000\004\017\214\001\002\000\022\005\ufff7" +
+ "\007\ufff7\010\ufff7\011\ufff7\012\ufff7\013\ufff7\014\ufff7\035" +
+ "\ufff7\001\002\000\044\003\054\006\026\007\027\010\040" +
+ "\011\036\012\022\013\042\014\030\015\017\016\015\021" +
+ "\216\026\033\027\023\030\035\031\041\035\025\036\053" +
+ "\001\002\000\004\017\uffb6\001\002\000\020\007\ufff3\010" +
+ "\ufff3\011\ufff3\012\ufff3\013\ufff3\014\ufff3\035\ufff3\001\002" +
+ "\000\020\007\ufff5\010\ufff5\011\ufff5\012\ufff5\013\ufff5\014" +
+ "\ufff5\035\ufff5\001\002\000\020\007\ufff1\010\ufff1\011\ufff1" +
+ "\012\ufff1\013\ufff1\014\ufff1\035\ufff1\001\002\000\020\007" +
+ "\ufff4\010\ufff4\011\ufff4\012\ufff4\013\ufff4\014\ufff4\035\ufff4" +
+ "\001\002\000\004\006\246\001\002\000\004\006\243\001" +
+ "\002\000\004\015\240\001\002\000\020\007\ufff6\010\ufff6" +
+ "\011\ufff6\012\ufff6\013\ufff6\014\ufff6\035\ufff6\001\002\000" +
+ "\004\015\234\001\002\000\020\003\uff97\011\007\012\012" +
+ "\016\uff97\026\065\035\014\036\uff97\001\002\000\010\003" +
+ "\uff97\016\116\036\uff97\001\002\000\006\003\126\036\120" +
+ "\001\002\000\010\002\uffff\003\126\036\120\001\002\000" +
+ "\004\037\235\001\002\000\022\007\uff99\010\uff99\011\uff99" +
+ "\012\uff99\013\uff99\014\uff99\017\236\035\uff99\001\002\000" +
+ "\020\007\uff98\010\uff98\011\uff98\012\uff98\013\uff98\014\uff98" +
+ "\035\uff98\001\002\000\020\007\uffee\010\uffee\011\uffee\012" +
+ "\uffee\013\uffee\014\uffee\035\uffee\001\002\000\004\037\241" +
+ "\001\002\000\022\007\uff99\010\uff99\011\uff99\012\uff99\013" +
+ "\uff99\014\uff99\017\236\035\uff99\001\002\000\020\007\uffed" +
+ "\010\uffed\011\uffed\012\uffed\013\uffed\014\uffed\035\uffed\001" +
+ "\002\000\004\037\244\001\002\000\022\007\uff99\010\uff99" +
+ "\011\uff99\012\uff99\013\uff99\014\uff99\017\236\035\uff99\001" +
+ "\002\000\020\007\uffef\010\uffef\011\uffef\012\uffef\013\uffef" +
+ "\014\uffef\035\uffef\001\002\000\004\037\247\001\002\000" +
+ "\022\007\uff99\010\uff99\011\uff99\012\uff99\013\uff99\014\uff99" +
+ "\017\236\035\uff99\001\002\000\020\007\ufff0\010\ufff0\011" +
+ "\ufff0\012\ufff0\013\ufff0\014\ufff0\035\ufff0\001\002\000\004" +
+ "\002\001\001\002" });
+
+ /** Access to parse-action table. */
+ public short[][] action_table() {return _action_table;}
+
+ /** <code>reduce_goto</code> table. */
+ protected static final short[][] _reduce_table =
+ unpackFromStrings(new String[] {
+ "\000\247\000\006\003\003\055\004\001\001\000\002\001" +
+ "\001\000\006\004\176\037\175\001\001\000\010\012\012" +
+ "\014\010\024\007\001\001\000\016\017\020\025\160\026" +
+ "\164\033\161\044\163\054\030\001\001\000\002\001\001" +
+ "\000\016\012\012\024\065\037\063\040\061\041\066\043" +
+ "\062\001\001\000\002\001\001\000\016\017\020\025\023" +
+ "\027\017\034\036\045\031\054\030\001\001\000\002\001" +
+ "\001\000\002\001\001\000\002\001\001\000\002\001\001" +
+ "\000\004\063\055\001\001\000\002\001\001\000\002\001" +
+ "\001\000\002\001\001\000\010\027\017\034\036\045\045" +
+ "\001\001\000\002\001\001\000\002\001\001\000\002\001" +
+ "\001\000\002\001\001\000\002\001\001\000\002\001\001" +
+ "\000\002\001\001\000\004\061\042\001\001\000\002\001" +
+ "\001\000\002\001\001\000\002\001\001\000\002\001\001" +
+ "\000\002\001\001\000\002\001\001\000\002\001\001\000" +
+ "\002\001\001\000\002\001\001\000\002\001\001\000\002" +
+ "\001\001\000\002\001\001\000\004\054\051\001\001\000" +
+ "\002\001\001\000\002\001\001\000\002\001\001\000\004" +
+ "\034\057\001\001\000\002\001\001\000\002\001\001\000" +
+ "\002\001\001\000\002\001\001\000\006\015\114\037\113" +
+ "\001\001\000\004\041\112\001\001\000\002\001\001\000" +
+ "\002\001\001\000\002\001\001\000\002\001\001\000\004" +
+ "\066\107\001\001\000\004\064\104\001\001\000\004\065" +
+ "\072\001\001\000\012\042\077\047\074\052\100\053\075" +
+ "\001\001\000\002\001\001\000\002\001\001\000\002\001" +
+ "\001\000\002\001\001\000\002\001\001\000\002\001\001" +
+ "\000\002\001\001\000\010\047\074\052\103\053\075\001" +
+ "\001\000\002\001\001\000\012\042\105\047\074\052\100" +
+ "\053\075\001\001\000\002\001\001\000\002\001\001\000" +
+ "\012\042\110\047\074\052\100\053\075\001\001\000\002" +
+ "\001\001\000\002\001\001\000\002\001\001\000\002\001" +
+ "\001\000\010\016\126\030\127\046\124\001\001\000\002" +
+ "\001\001\000\004\046\120\001\001\000\002\001\001\000" +
+ "\004\067\122\001\001\000\002\001\001\000\002\001\001" +
+ "\000\002\001\001\000\004\070\133\001\001\000\004\072" +
+ "\131\001\001\000\006\030\130\046\124\001\001\000\002" +
+ "\001\001\000\002\001\001\000\002\001\001\000\002\001" +
+ "\001\000\002\001\001\000\004\071\135\001\001\000\012" +
+ "\031\137\035\141\036\140\037\136\001\001\000\002\001" +
+ "\001\000\006\032\150\047\147\001\001\000\002\001\001" +
+ "\000\002\001\001\000\002\001\001\000\010\031\137\036" +
+ "\144\037\136\001\001\000\002\001\001\000\002\001\001" +
+ "\000\006\047\074\053\156\001\001\000\006\037\151\051" +
+ "\152\001\001\000\002\001\001\000\002\001\001\000\002" +
+ "\001\001\000\006\050\154\054\155\001\001\000\002\001" +
+ "\001\000\002\001\001\000\002\001\001\000\002\001\001" +
+ "\000\010\026\164\033\161\044\174\001\001\000\002\001" +
+ "\001\000\004\060\172\001\001\000\002\001\001\000\004" +
+ "\062\165\001\001\000\002\001\001\000\004\033\170\001" +
+ "\001\000\002\001\001\000\002\001\001\000\002\001\001" +
+ "\000\002\001\001\000\002\001\001\000\002\001\001\000" +
+ "\002\001\001\000\006\005\203\037\204\001\001\000\006" +
+ "\017\200\054\030\001\001\000\004\056\201\001\001\000" +
+ "\002\001\001\000\002\001\001\000\006\007\205\020\206" +
+ "\001\001\000\002\001\001\000\022\006\225\010\220\012" +
+ "\012\013\217\014\227\022\221\023\216\024\007\001\001" +
+ "\000\002\001\001\000\010\017\210\021\211\054\030\001" +
+ "\001\000\002\001\001\000\004\057\212\001\001\000\002" +
+ "\001\001\000\002\001\001\000\004\054\051\001\001\000" +
+ "\002\001\001\000\002\001\001\000\002\001\001\000\002" +
+ "\001\001\000\002\001\001\000\002\001\001\000\002\001" +
+ "\001\000\002\001\001\000\002\001\001\000\002\001\001" +
+ "\000\016\012\012\024\065\037\063\040\230\041\066\043" +
+ "\062\001\001\000\006\015\231\037\113\001\001\000\010" +
+ "\016\232\030\127\046\124\001\001\000\006\030\130\046" +
+ "\124\001\001\000\002\001\001\000\004\011\236\001\001" +
+ "\000\002\001\001\000\002\001\001\000\002\001\001\000" +
+ "\004\011\241\001\001\000\002\001\001\000\002\001\001" +
+ "\000\004\011\244\001\001\000\002\001\001\000\002\001" +
+ "\001\000\004\011\247\001\001\000\002\001\001\000\002" +
+ "\001\001" });
+
+ /** Access to <code>reduce_goto</code> table. */
+ public short[][] reduce_table() {return _reduce_table;}
+
+ /** Instance of action encapsulation class. */
+ protected CUP$parser$actions action_obj;
+
+ /** Action encapsulation object initializer. */
+ protected void init_actions()
+ {
+ action_obj = new CUP$parser$actions(this);
+ }
+
+ /** Invoke a user supplied parse action. */
+ public java_cup.runtime.Symbol do_action(
+ int act_num,
+ java_cup.runtime.lr_parser parser,
+ java.util.Stack stack,
+ int top)
+ throws java.lang.Exception
+ {
+ /* call code in generated class */
+ return action_obj.CUP$parser$do_action(act_num, parser, stack, top);
+ }
+
+ /** Indicates start state. */
+ public int start_state() {return 0;}
+ /** Indicates start production. */
+ public int start_production() {return 0;}
+
+ /** <code>EOF</code> Symbol index. */
+ public int EOF_sym() {return 0;}
+
+ /** <code>error</code> Symbol index. */
+ public int error_sym() {return 1;}
+
+
+ /** User initialization code. */
+ public void user_init() throws java.lang.Exception
+ {
+ lexer.init();
+ }
+
+ /** Scan to get the next Symbol. */
+ public java_cup.runtime.Symbol scan()
+ throws java.lang.Exception
+ {
+ return lexer.next_token();
+ }
+
+
+
+ /* override error routines */
+
+ public void report_fatal_error(
+ String message,
+ Object info)
+ {
+ done_parsing();
+ lexer.emit_error(message);
+ System.err.println("Can't recover from previous error(s), giving up.");
+ System.exit(1);
+ }
+
+ public void report_error(String message, Object info)
+ {
+ lexer.emit_error(message);
+ }
+
+}
+
+/** Cup generated class to encapsulate user supplied action code.*/
+class CUP$parser$actions {
+
+
+ /** helper routine to clone a new production part adding a given label */
+ protected production_part add_lab(production_part part, String lab)
+ throws internal_error
+ {
+ /* if there is no label, or this is an action, just return the original */
+ if (lab == null || part.is_action()) return part;
+
+ /* otherwise build a new one with the given label attached */
+ return new symbol_part(((symbol_part)part).the_symbol(),lab);
+ }
+
+ /** max size of right hand side we will support */
+ protected final int MAX_RHS = 200;
+
+ /** array for accumulating right hand side parts */
+ protected production_part[] rhs_parts = new production_part[MAX_RHS];
+
+ /** where we are currently in building a right hand side */
+ protected int rhs_pos = 0;
+
+ /** start a new right hand side */
+ protected void new_rhs() {rhs_pos = 0; }
+
+ /** add a new right hand side part */
+ protected void add_rhs_part(production_part part) throws java.lang.Exception
+ {
+ if (rhs_pos >= MAX_RHS)
+ throw new Exception("Internal Error: Productions limited to " +
+ MAX_RHS + " symbols and actions");
+
+ rhs_parts[rhs_pos] = part;
+ rhs_pos++;
+ }
+
+ /** string to build up multiple part names */
+ protected String multipart_name = new String();
+
+ /** append a new name segment to the accumulated multipart name */
+ protected void append_multipart(String name)
+ {
+ String dot = "";
+
+ /* if we aren't just starting out, put on a dot */
+ if (multipart_name.length() != 0) dot = ".";
+
+ multipart_name = multipart_name.concat(dot + name);
+ }
+
+ /** table of declared symbols -- contains production parts indexed by name */
+ protected Hashtable symbols = new Hashtable();
+
+ /** table of just non terminals -- contains non_terminals indexed by name */
+ protected Hashtable non_terms = new Hashtable();
+
+ /** declared start non_terminal */
+ protected non_terminal start_nt = null;
+
+ /** left hand side non terminal of the current production */
+ protected non_terminal lhs_nt;
+
+ /** Current precedence number */
+ int _cur_prec = 0;
+
+ /** Current precedence side */
+ int _cur_side = assoc.no_prec;
+
+ /** update the precedences we are declaring */
+ protected void update_precedence(int p) {
+ _cur_side = p;
+ _cur_prec++;
+ }
+ /** add relevant data to terminals */
+ protected void add_precedence(String term) {
+ if (term == null) {
+ System.err.println("Unable to add precedence to nonexistent terminal");
+ } else {
+ symbol_part sp = (symbol_part)symbols.get(term);
+ if (sp == null) {
+ System.err.println("Could find terminal " + term + " while declaring precedence");
+ } else {
+ java_cup.symbol sym = sp.the_symbol();
+ if (sym instanceof terminal)
+ ((terminal)sym).set_precedence(_cur_side, _cur_prec);
+ else System.err.println("Precedence declaration: Can't find terminal " + term);
+ }
+ }
+ }
+
+ private final parser parser;
+
+ /** Constructor */
+ CUP$parser$actions(parser parser) {
+ this.parser = parser;
+ }
+
+ /** Method with the actual generated action code. */
+ public final java_cup.runtime.Symbol CUP$parser$do_action(
+ int CUP$parser$act_num,
+ java_cup.runtime.lr_parser CUP$parser$parser,
+ java.util.Stack CUP$parser$stack,
+ int CUP$parser$top)
+ throws java.lang.Exception
+ {
+ /* Symbol object for return from actions */
+ java_cup.runtime.Symbol CUP$parser$result;
+
+ /* select the action based on the action number */
+ switch (CUP$parser$act_num)
+ {
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 106: // empty ::=
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(29/*empty*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 105: // opt_semi ::= SEMI
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(7/*opt_semi*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 104: // opt_semi ::=
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(7/*opt_semi*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 103: // non_terminal ::= NONTERMINAL
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(8/*non_terminal*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 102: // non_terminal ::= NON TERMINAL
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(8/*non_terminal*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 101: // robust_id ::= error
+ {
+ String RESULT = null;
+
+ lexer.emit_error("Illegal use of reserved word");
+ RESULT="ILLEGAL";
+
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 100: // robust_id ::= NONASSOC
+ {
+ String RESULT = null;
+ RESULT = "nonassoc";
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 99: // robust_id ::= RIGHT
+ {
+ String RESULT = null;
+ RESULT = "right";
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 98: // robust_id ::= LEFT
+ {
+ String RESULT = null;
+ RESULT = "left";
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 97: // robust_id ::= PRECEDENCE
+ {
+ String RESULT = null;
+ RESULT = "precedence";
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 96: // robust_id ::= START
+ {
+ String RESULT = null;
+ RESULT = "start";
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 95: // robust_id ::= WITH
+ {
+ String RESULT = null;
+ RESULT = "with";
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 94: // robust_id ::= SCAN
+ {
+ String RESULT = null;
+ RESULT = "scan";
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 93: // robust_id ::= INIT
+ {
+ String RESULT = null;
+ RESULT = "init";
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 92: // robust_id ::= NONTERMINAL
+ {
+ String RESULT = null;
+ RESULT = "nonterminal";
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 91: // robust_id ::= NON
+ {
+ String RESULT = null;
+ RESULT = "non";
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 90: // robust_id ::= TERMINAL
+ {
+ String RESULT = null;
+ RESULT = "terminal";
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 89: // robust_id ::= PARSER
+ {
+ String RESULT = null;
+ RESULT = "parser";
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 88: // robust_id ::= ACTION
+ {
+ String RESULT = null;
+ RESULT = "action";
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 87: // robust_id ::= CODE
+ {
+ String RESULT = null;
+ RESULT = "code";
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 86: // robust_id ::= ID
+ {
+ String RESULT = null;
+ int the_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int the_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String the_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+ RESULT = the_id;
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 85: // label_id ::= robust_id
+ {
+ String RESULT = null;
+ int the_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int the_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String the_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+ RESULT = the_id;
+ CUP$parser$result = new java_cup.runtime.Symbol(38/*label_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 84: // symbol_id ::= error
+ {
+ String RESULT = null;
+
+ lexer.emit_error("Illegal use of reserved word");
+ RESULT="ILLEGAL";
+
+ CUP$parser$result = new java_cup.runtime.Symbol(37/*symbol_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 83: // symbol_id ::= ID
+ {
+ String RESULT = null;
+ int the_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int the_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String the_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+ RESULT = the_id;
+ CUP$parser$result = new java_cup.runtime.Symbol(37/*symbol_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 82: // nt_id ::= error
+ {
+ String RESULT = null;
+
+ lexer.emit_error("Illegal use of reserved word");
+ RESULT="ILLEGAL";
+
+ CUP$parser$result = new java_cup.runtime.Symbol(36/*nt_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 81: // nt_id ::= ID
+ {
+ String RESULT = null;
+ int the_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int the_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String the_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+ RESULT = the_id;
+ CUP$parser$result = new java_cup.runtime.Symbol(36/*nt_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 80: // new_non_term_id ::= ID
+ {
+ Object RESULT = null;
+ int non_term_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int non_term_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String non_term_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+
+ /* see if this non terminal has been declared before */
+ if (symbols.get(non_term_id) != null)
+ {
+ /* issue a message */
+ lexer.emit_error( "java_cup.runtime.Symbol \"" + non_term_id +
+ "\" has already been declared");
+ }
+ else
+ {
+ if (multipart_name.equals("")) {
+ append_multipart("Object");
+ }
+ /* build the non terminal object */
+ non_terminal this_nt =
+ new non_terminal(non_term_id, multipart_name);
+
+ /* put it in the non_terms table */
+ non_terms.put(non_term_id, this_nt);
+
+ /* build a production_part and put it in the symbols table */
+ symbols.put(non_term_id, new symbol_part(this_nt));
+ }
+
+ CUP$parser$result = new java_cup.runtime.Symbol(26/*new_non_term_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 79: // new_term_id ::= ID
+ {
+ Object RESULT = null;
+ int term_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int term_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String term_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+
+ /* see if this terminal has been declared before */
+ if (symbols.get(term_id) != null)
+ {
+ /* issue a message */
+ lexer.emit_error("java_cup.runtime.Symbol \"" + term_id +
+ "\" has already been declared");
+ }
+ else
+ {
+ /* if no type declared, declare one */
+ if (multipart_name.equals("")) {
+ append_multipart("Object");
+ }
+ /* build a production_part and put it in the table */
+ symbols.put(term_id,
+ new symbol_part(new terminal(term_id, multipart_name)));
+ }
+
+ CUP$parser$result = new java_cup.runtime.Symbol(25/*new_term_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 78: // type_id ::= type_id LBRACK RBRACK
+ {
+ Object RESULT = null;
+ multipart_name = multipart_name.concat("[]");
+ CUP$parser$result = new java_cup.runtime.Symbol(19/*type_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 77: // type_id ::= multipart_id
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(19/*type_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 76: // import_id ::= multipart_id
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(15/*import_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 75: // import_id ::= multipart_id DOT STAR
+ {
+ Object RESULT = null;
+ append_multipart("*");
+ CUP$parser$result = new java_cup.runtime.Symbol(15/*import_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 74: // multipart_id ::= robust_id
+ {
+ Object RESULT = null;
+ int an_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int an_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String an_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+ append_multipart(an_id);
+ CUP$parser$result = new java_cup.runtime.Symbol(13/*multipart_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 73: // multipart_id ::= multipart_id DOT robust_id
+ {
+ Object RESULT = null;
+ int another_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int another_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String another_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+ append_multipart(another_id);
+ CUP$parser$result = new java_cup.runtime.Symbol(13/*multipart_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 72: // opt_label ::= empty
+ {
+ String RESULT = null;
+ RESULT = null;
+ CUP$parser$result = new java_cup.runtime.Symbol(39/*opt_label*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 71: // opt_label ::= COLON label_id
+ {
+ String RESULT = null;
+ int labidleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int labidright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String labid = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+ RESULT = labid;
+ CUP$parser$result = new java_cup.runtime.Symbol(39/*opt_label*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 70: // prod_part ::= CODE_STRING
+ {
+ Object RESULT = null;
+ int code_strleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int code_strright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String code_str = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+
+ /* add a new production part */
+ add_rhs_part(new action_part(code_str));
+
+ CUP$parser$result = new java_cup.runtime.Symbol(24/*prod_part*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 69: // prod_part ::= symbol_id opt_label
+ {
+ Object RESULT = null;
+ int symidleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left;
+ int symidright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).right;
+ String symid = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+ int labidleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int labidright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String labid = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+
+ /* try to look up the id */
+ production_part symb = (production_part)symbols.get(symid);
+
+ /* if that fails, symbol is undeclared */
+ if (symb == null)
+ {
+ if (lexer.error_count == 0)
+ lexer.emit_error("java_cup.runtime.Symbol \"" + symid +
+ "\" has not been declared");
+ }
+ else
+ {
+ /* add a labeled production part */
+ add_rhs_part(add_lab(symb, labid));
+ }
+
+ CUP$parser$result = new java_cup.runtime.Symbol(24/*prod_part*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 68: // prod_part_list ::= empty
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(23/*prod_part_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 67: // prod_part_list ::= prod_part_list prod_part
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(23/*prod_part_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 66: // rhs ::= prod_part_list
+ {
+ Object RESULT = null;
+
+ if (lhs_nt != null)
+ {
+ /* build the production */
+ production p = new production(lhs_nt, rhs_parts, rhs_pos);
+
+ /* if we have no start non-terminal declared and this is
+ the first production, make its lhs nt the start_nt
+ and build a special start production for it. */
+ if (start_nt == null)
+ {
+ start_nt = lhs_nt;
+
+ /* build a special start production */
+ new_rhs();
+ add_rhs_part(add_lab(new symbol_part(start_nt),"start_val"));
+ add_rhs_part(new symbol_part(terminal.EOF));
+ add_rhs_part(new action_part("RESULT = start_val;"));
+ emit.start_production =
+ new production(non_terminal.START_nt, rhs_parts, rhs_pos);
+
+ new_rhs();
+ }
+ }
+
+ /* reset the rhs accumulation in any case */
+ new_rhs();
+
+ CUP$parser$result = new java_cup.runtime.Symbol(28/*rhs*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 65: // rhs ::= prod_part_list PERCENT_PREC term_id
+ {
+ Object RESULT = null;
+ int term_nameleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int term_nameright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String term_name = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+
+ java_cup.symbol sym = null;
+ if (lhs_nt != null)
+ {
+ /* Find the precedence symbol */
+ if (term_name == null) {
+ System.err.println("No terminal for contextual precedence");
+ sym = null;
+ } else {
+ sym = ((symbol_part)symbols.get(term_name)).the_symbol();
+ }
+ /* build the production */
+ production p;
+ if ((sym!=null) && (sym instanceof terminal)) {
+ p = new production(lhs_nt, rhs_parts, rhs_pos,
+ ((terminal)sym).precedence_num(),
+ ((terminal)sym).precedence_side());
+ ((symbol_part)symbols.get(term_name)).the_symbol().note_use();
+ } else {
+ System.err.println("Invalid terminal " + term_name +
+ " for contextual precedence assignment");
+ p = new production(lhs_nt, rhs_parts, rhs_pos);
+ }
+
+ /* if we have no start non-terminal declared and this is
+ the first production, make its lhs nt the start_nt
+ and build a special start production for it. */
+ if (start_nt == null)
+ {
+ start_nt = lhs_nt;
+
+ /* build a special start production */
+ new_rhs();
+ add_rhs_part(add_lab(new symbol_part(start_nt),"start_val"));
+ add_rhs_part(new symbol_part(terminal.EOF));
+ add_rhs_part(new action_part("RESULT = start_val;"));
+ if ((sym!=null) && (sym instanceof terminal)) {
+ emit.start_production =
+ new production(non_terminal.START_nt, rhs_parts,
+ rhs_pos, ((terminal)sym).precedence_num(),
+ ((terminal)sym).precedence_side());
+ } else {
+ emit.start_production =
+ new production(non_terminal.START_nt, rhs_parts, rhs_pos);
+ }
+ new_rhs();
+ }
+ }
+
+ /* reset the rhs accumulation in any case */
+ new_rhs();
+
+ CUP$parser$result = new java_cup.runtime.Symbol(28/*rhs*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 64: // rhs_list ::= rhs
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(27/*rhs_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 63: // rhs_list ::= rhs_list BAR rhs
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(27/*rhs_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 62: // production ::= error NT$13 SEMI
+ {
+ Object RESULT = null;
+ // propagate RESULT from NT$13
+ if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value != null )
+ RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(22/*production*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 61: // NT$13 ::=
+ {
+ Object RESULT = null;
+ lexer.emit_error("Syntax Error");
+ CUP$parser$result = new java_cup.runtime.Symbol(56/*NT$13*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 60: // production ::= nt_id NT$11 COLON_COLON_EQUALS NT$12 rhs_list SEMI
+ {
+ Object RESULT = null;
+ // propagate RESULT from NT$11
+ if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-4)).value != null )
+ RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-4)).value;
+ // propagate RESULT from NT$12
+ if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value != null )
+ RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
+ int lhs_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-5)).left;
+ int lhs_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-5)).right;
+ String lhs_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-5)).value;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(22/*production*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-5)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 59: // NT$12 ::=
+ {
+ Object RESULT = null;
+ int lhs_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left;
+ int lhs_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).right;
+ String lhs_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(55/*NT$12*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 58: // NT$11 ::=
+ {
+ Object RESULT = null;
+ int lhs_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int lhs_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String lhs_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+
+ /* lookup the lhs nt */
+ lhs_nt = (non_terminal)non_terms.get(lhs_id);
+
+ /* if it wasn't declared, emit a message */
+ if (lhs_nt == null)
+ {
+ if (lexer.error_count == 0)
+ lexer.emit_error("LHS non terminal \"" + lhs_id +
+ "\" has not been declared");
+ }
+
+ /* reset the rhs accumulation */
+ new_rhs();
+
+ CUP$parser$result = new java_cup.runtime.Symbol(54/*NT$11*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 57: // production_list ::= production
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(12/*production_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 56: // production_list ::= production_list production
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(12/*production_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 55: // start_spec ::= empty
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(11/*start_spec*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 54: // start_spec ::= START WITH nt_id NT$10 SEMI
+ {
+ Object RESULT = null;
+ // propagate RESULT from NT$10
+ if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value != null )
+ RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+ int start_nameleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left;
+ int start_nameright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).right;
+ String start_name = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(11/*start_spec*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-4)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 53: // NT$10 ::=
+ {
+ Object RESULT = null;
+ int start_nameleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int start_nameright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String start_name = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+
+ /* verify that the name has been declared as a non terminal */
+ non_terminal nt = (non_terminal)non_terms.get(start_name);
+ if (nt == null)
+ {
+ lexer.emit_error( "Start non terminal \"" + start_name +
+ "\" has not been declared");
+ }
+ else
+ {
+ /* remember the non-terminal for later */
+ start_nt = nt;
+
+ /* build a special start production */
+ new_rhs();
+ add_rhs_part(add_lab(new symbol_part(start_nt), "start_val"));
+ add_rhs_part(new symbol_part(terminal.EOF));
+ add_rhs_part(new action_part("RESULT = start_val;"));
+ emit.start_production =
+ new production(non_terminal.START_nt, rhs_parts, rhs_pos);
+ new_rhs();
+ }
+
+ CUP$parser$result = new java_cup.runtime.Symbol(53/*NT$10*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 52: // term_id ::= symbol_id
+ {
+ String RESULT = null;
+ int symleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int symright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String sym = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+
+ /* check that the symbol_id is a terminal */
+ if (symbols.get(sym) == null)
+ {
+ /* issue a message */
+ lexer.emit_error("Terminal \"" + sym +
+ "\" has not been declared");
+ }
+ RESULT = sym;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(41/*term_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 51: // terminal_id ::= term_id
+ {
+ String RESULT = null;
+ int symleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int symright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String sym = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+
+ add_precedence(sym);
+ RESULT = sym;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(40/*terminal_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 50: // terminal_list ::= terminal_id
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(32/*terminal_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 49: // terminal_list ::= terminal_list COMMA terminal_id
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(32/*terminal_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 48: // preced ::= PRECEDENCE NONASSOC NT$9 terminal_list SEMI
+ {
+ Object RESULT = null;
+ // propagate RESULT from NT$9
+ if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value != null )
+ RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(31/*preced*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-4)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 47: // NT$9 ::=
+ {
+ Object RESULT = null;
+
+ update_precedence(assoc.nonassoc);
+
+ CUP$parser$result = new java_cup.runtime.Symbol(52/*NT$9*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 46: // preced ::= PRECEDENCE RIGHT NT$8 terminal_list SEMI
+ {
+ Object RESULT = null;
+ // propagate RESULT from NT$8
+ if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value != null )
+ RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(31/*preced*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-4)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 45: // NT$8 ::=
+ {
+ Object RESULT = null;
+
+ update_precedence(assoc.right);
+
+ CUP$parser$result = new java_cup.runtime.Symbol(51/*NT$8*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 44: // preced ::= PRECEDENCE LEFT NT$7 terminal_list SEMI
+ {
+ Object RESULT = null;
+ // propagate RESULT from NT$7
+ if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value != null )
+ RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(31/*preced*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-4)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 43: // NT$7 ::=
+ {
+ Object RESULT = null;
+
+ update_precedence(assoc.left);
+
+ CUP$parser$result = new java_cup.runtime.Symbol(50/*NT$7*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 42: // precedence_l ::= preced
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(33/*precedence_l*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 41: // precedence_l ::= precedence_l preced
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(33/*precedence_l*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 40: // precedence_list ::= empty
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(30/*precedence_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 39: // precedence_list ::= precedence_l
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(30/*precedence_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 38: // non_term_name_list ::= new_non_term_id
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(21/*non_term_name_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 37: // non_term_name_list ::= non_term_name_list COMMA new_non_term_id
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(21/*non_term_name_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 36: // term_name_list ::= new_term_id
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(20/*term_name_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 35: // term_name_list ::= term_name_list COMMA new_term_id
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(20/*term_name_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 34: // declares_non_term ::= non_term_name_list NT$6 SEMI
+ {
+ Object RESULT = null;
+ // propagate RESULT from NT$6
+ if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value != null )
+ RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(35/*declares_non_term*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 33: // NT$6 ::=
+ {
+ Object RESULT = null;
+
+ /* reset the accumulated multipart name */
+ multipart_name = new String();
+
+ CUP$parser$result = new java_cup.runtime.Symbol(49/*NT$6*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 32: // declares_term ::= term_name_list NT$5 SEMI
+ {
+ Object RESULT = null;
+ // propagate RESULT from NT$5
+ if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value != null )
+ RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(34/*declares_term*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 31: // NT$5 ::=
+ {
+ Object RESULT = null;
+
+ /* reset the accumulated multipart name */
+ multipart_name = new String();
+
+ CUP$parser$result = new java_cup.runtime.Symbol(48/*NT$5*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 30: // symbol ::= non_terminal error NT$4 SEMI
+ {
+ Object RESULT = null;
+ // propagate RESULT from NT$4
+ if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value != null )
+ RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(18/*symbol*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-3)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 29: // NT$4 ::=
+ {
+ Object RESULT = null;
+
+ /* reset the accumulated multipart name */
+ multipart_name = new String();
+
+ CUP$parser$result = new java_cup.runtime.Symbol(47/*NT$4*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 28: // symbol ::= TERMINAL error NT$3 SEMI
+ {
+ Object RESULT = null;
+ // propagate RESULT from NT$3
+ if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value != null )
+ RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(18/*symbol*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-3)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 27: // NT$3 ::=
+ {
+ Object RESULT = null;
+
+ /* reset the accumulated multipart name */
+ multipart_name = new String();
+
+ CUP$parser$result = new java_cup.runtime.Symbol(46/*NT$3*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 26: // symbol ::= non_terminal declares_non_term
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(18/*symbol*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 25: // symbol ::= non_terminal type_id declares_non_term
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(18/*symbol*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 24: // symbol ::= TERMINAL declares_term
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(18/*symbol*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 23: // symbol ::= TERMINAL type_id declares_term
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(18/*symbol*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 22: // symbol_list ::= symbol
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(10/*symbol_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 21: // symbol_list ::= symbol_list symbol
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(10/*symbol_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 20: // scan_code ::= SCAN WITH CODE_STRING opt_semi
+ {
+ Object RESULT = null;
+ int user_codeleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left;
+ int user_coderight = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).right;
+ String user_code = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+
+ if (emit.scan_code!=null)
+ lexer.emit_error("Redundant scan code (skipping)");
+ else /* save the user code */
+ emit.scan_code = user_code;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(17/*scan_code*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-3)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 19: // init_code ::= INIT WITH CODE_STRING opt_semi
+ {
+ Object RESULT = null;
+ int user_codeleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left;
+ int user_coderight = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).right;
+ String user_code = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+
+ if (emit.init_code!=null)
+ lexer.emit_error("Redundant init code (skipping)");
+ else /* save the user code */
+ emit.init_code = user_code;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(16/*init_code*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-3)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 18: // parser_code_part ::= PARSER CODE CODE_STRING opt_semi
+ {
+ Object RESULT = null;
+ int user_codeleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left;
+ int user_coderight = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).right;
+ String user_code = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+
+ if (emit.parser_code!=null)
+ lexer.emit_error("Redundant parser code (skipping)");
+ else /* save the user included code string */
+ emit.parser_code = user_code;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(9/*parser_code_part*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-3)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 17: // action_code_part ::= ACTION CODE CODE_STRING opt_semi
+ {
+ Object RESULT = null;
+ int user_codeleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left;
+ int user_coderight = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).right;
+ String user_code = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+
+ if (emit.action_code!=null)
+ lexer.emit_error("Redundant action code (skipping)");
+ else /* save the user included code string */
+ emit.action_code = user_code;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(4/*action_code_part*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-3)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 16: // code_parts ::= code_parts code_part
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(5/*code_parts*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 15: // code_parts ::=
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(5/*code_parts*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 14: // code_part ::= scan_code
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(6/*code_part*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 13: // code_part ::= init_code
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(6/*code_part*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 12: // code_part ::= parser_code_part
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(6/*code_part*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 11: // code_part ::= action_code_part
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(6/*code_part*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 10: // import_spec ::= IMPORT import_id NT$2 SEMI
+ {
+ Object RESULT = null;
+ // propagate RESULT from NT$2
+ if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value != null )
+ RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(14/*import_spec*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-3)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 9: // NT$2 ::=
+ {
+ Object RESULT = null;
+
+ /* save this import on the imports list */
+ emit.import_list.push(multipart_name);
+
+ /* reset the accumulated multipart name */
+ multipart_name = new String();
+
+ CUP$parser$result = new java_cup.runtime.Symbol(45/*NT$2*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 8: // import_list ::= empty
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(3/*import_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 7: // import_list ::= import_list import_spec
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(3/*import_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 6: // package_spec ::= empty
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(2/*package_spec*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 5: // package_spec ::= PACKAGE multipart_id NT$1 SEMI
+ {
+ Object RESULT = null;
+ // propagate RESULT from NT$1
+ if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value != null )
+ RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(2/*package_spec*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-3)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 4: // NT$1 ::=
+ {
+ Object RESULT = null;
+
+ /* save the package name */
+ emit.package_name = multipart_name;
+
+ /* reset the accumulated multipart name */
+ multipart_name = new String();
+
+ CUP$parser$result = new java_cup.runtime.Symbol(44/*NT$1*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 3: // spec ::= error symbol_list precedence_list start_spec production_list
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(1/*spec*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-4)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 2: // spec ::= NT$0 package_spec import_list code_parts symbol_list precedence_list start_spec production_list
+ {
+ Object RESULT = null;
+ // propagate RESULT from NT$0
+ if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-7)).value != null )
+ RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-7)).value;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(1/*spec*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-7)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 1: // NT$0 ::=
+ {
+ Object RESULT = null;
+
+ /* declare "error" as a terminal */
+ symbols.put("error", new symbol_part(terminal.error));
+
+ /* declare start non terminal */
+ non_terms.put("$START", non_terminal.START_nt);
+
+ CUP$parser$result = new java_cup.runtime.Symbol(43/*NT$0*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 0: // $START ::= spec EOF
+ {
+ Object RESULT = null;
+ int start_valleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left;
+ int start_valright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).right;
+ Object start_val = (Object)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+ RESULT = start_val;
+ CUP$parser$result = new java_cup.runtime.Symbol(0/*$START*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ /* ACCEPT */
+ CUP$parser$parser.done_parsing();
+ return CUP$parser$result;
+
+ /* . . . . . .*/
+ default:
+ throw new Exception(
+ "Invalid action number found in internal parse table");
+
+ }
+ }
+}
+
diff --git a/src/syntaxParser/java_cup/SAVE/production.java b/src/syntaxParser/java_cup/SAVE/production.java
new file mode 100644
index 0000000..5a41287
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/production.java
@@ -0,0 +1,756 @@
+
+package java_cup;
+
+import java.util.Hashtable;
+import java.util.Enumeration;
+
+/** This class represents a production in the grammar. It contains
+ * a LHS non terminal, and an array of RHS symbols. As various
+ * transformations are done on the RHS of the production, it may shrink.
+ * As a result a separate length is always maintained to indicate how much
+ * of the RHS array is still valid.<p>
+ *
+ * I addition to construction and manipulation operations, productions provide
+ * methods for factoring out actions (see remove_embedded_actions()), for
+ * computing the nullability of the production (i.e., can it derive the empty
+ * string, see check_nullable()), and operations for computing its first
+ * set (i.e., the set of terminals that could appear at the beginning of some
+ * string derived from the production, see check_first_set()).
+ *
+ * @see java_cup.production_part
+ * @see java_cup.symbol_part
+ * @see java_cup.action_part
+ * @version last updated: 7/3/96
+ * @author Frank Flannery
+ */
+
+public class production {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Full constructor. This constructor accepts a LHS non terminal,
+ * an array of RHS parts (including terminals, non terminals, and
+ * actions), and a string for a final reduce action. It does several
+ * manipulations in the process of creating a production object.
+ * After some validity checking it translates labels that appear in
+ * actions into code for accessing objects on the runtime parse stack.
+ * It them merges adjacent actions if they appear and moves any trailing
+ * action into the final reduce actions string. Next it removes any
+ * embedded actions by factoring them out with new action productions.
+ * Finally it assigns a unique index to the production.<p>
+ *
+ * Factoring out of actions is accomplished by creating new "hidden"
+ * non terminals. For example if the production was originally: <pre>
+ * A ::= B {action} C D
+ * </pre>
+ * then it is factored into two productions:<pre>
+ * A ::= B X C D
+ * X ::= {action}
+ * </pre>
+ * (where X is a unique new non terminal). This has the effect of placing
+ * all actions at the end where they can be handled as part of a reduce by
+ * the parser.
+ */
+ public production(
+ non_terminal lhs_sym,
+ production_part rhs_parts[],
+ int rhs_l,
+ String action_str)
+ throws internal_error
+ {
+ int i;
+ action_part tail_action;
+ String declare_str;
+ int rightlen = rhs_l;
+
+ /* remember the length */
+ if (rhs_l >= 0)
+ _rhs_length = rhs_l;
+ else if (rhs_parts != null)
+ _rhs_length = rhs_parts.length;
+ else
+ _rhs_length = 0;
+
+ /* make sure we have a valid left-hand-side */
+ if (lhs_sym == null)
+ throw new internal_error(
+ "Attempt to construct a production with a null LHS");
+
+ /* I'm not translating labels anymore, I'm adding code to declare
+ labels as valid variables. This way, the users code string is
+ untouched
+ 6/96 frankf */
+
+ /* check if the last part of the right hand side is an action. If
+ it is, it won't be on the stack, so we don't want to count it
+ in the rightlen. Then when we search down the stack for a
+ Symbol, we don't try to search past action */
+
+ if (rhs_l > 0) {
+ if (rhs_parts[rhs_l - 1].is_action()) {
+ rightlen = rhs_l - 1;
+ } else {
+ rightlen = rhs_l;
+ }
+ }
+
+ /* get the generated declaration code for the necessary labels. */
+ declare_str = declare_labels(
+ rhs_parts, rightlen, action_str);
+
+ if (action_str == null)
+ action_str = declare_str;
+ else
+ action_str = declare_str + action_str;
+
+ /* count use of lhs */
+ lhs_sym.note_use();
+
+ /* create the part for left-hand-side */
+ _lhs = new symbol_part(lhs_sym);
+
+ /* merge adjacent actions (if any) */
+ _rhs_length = merge_adjacent_actions(rhs_parts, _rhs_length);
+
+ /* strip off any trailing action */
+ tail_action = strip_trailing_action(rhs_parts, _rhs_length);
+ if (tail_action != null) _rhs_length--;
+
+ /* Why does this run through the right hand side happen
+ over and over? here a quick combination of two
+ prior runs plus one I wanted of my own
+ frankf 6/25/96 */
+ /* allocate and copy over the right-hand-side */
+ /* count use of each rhs symbol */
+ _rhs = new production_part[_rhs_length];
+ for (i=0; i<_rhs_length; i++) {
+ _rhs[i] = rhs_parts[i];
+ if (!_rhs[i].is_action()) {
+ ((symbol_part)_rhs[i]).the_symbol().note_use();
+ if (((symbol_part)_rhs[i]).the_symbol() instanceof terminal) {
+ _rhs_prec =
+ ((terminal)((symbol_part)_rhs[i]).the_symbol()).precedence_num();
+ _rhs_assoc =
+ ((terminal)((symbol_part)_rhs[i]).the_symbol()).precedence_side();
+ }
+ }
+ }
+
+ /*now action string is really declaration string, so put it in front!
+ 6/14/96 frankf */
+ if (action_str == null) action_str = "";
+ if (tail_action != null && tail_action.code_string() != null)
+ action_str = action_str + "\t\t" + tail_action.code_string();
+
+ /* stash the action */
+ _action = new action_part(action_str);
+
+ /* rewrite production to remove any embedded actions */
+ remove_embedded_actions();
+
+ /* assign an index */
+ _index = next_index++;
+
+ /* put us in the global collection of productions */
+ _all.put(new Integer(_index),this);
+
+ /* put us in the production list of the lhs non terminal */
+ lhs_sym.add_production(this);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Constructor with no action string. */
+ public production(
+ non_terminal lhs_sym,
+ production_part rhs_parts[],
+ int rhs_l)
+ throws internal_error
+ {
+ this(lhs_sym,rhs_parts,rhs_l,null);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /* Constructor with precedence and associativity of production
+ contextually define */
+ public production(
+ non_terminal lhs_sym,
+ production_part rhs_parts[],
+ int rhs_l,
+ String action_str,
+ int prec_num,
+ int prec_side)
+ throws internal_error
+ {
+ this(lhs_sym,rhs_parts,rhs_l,action_str);
+
+ /* set the precedence */
+ set_precedence_num(prec_num);
+ set_precedence_side(prec_side);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /* Constructor w/ no action string and contextual precedence
+ defined */
+ public production(
+ non_terminal lhs_sym,
+ production_part rhs_parts[],
+ int rhs_l,
+ int prec_num,
+ int prec_side)
+ throws internal_error
+ {
+ this(lhs_sym,rhs_parts,rhs_l,null);
+ /* set the precedence */
+ set_precedence_num(prec_num);
+ set_precedence_side(prec_side);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Static (Class) Variables ------------------*/
+ /*-----------------------------------------------------------*/
+
+
+ /** Table of all productions. Elements are stored using their index as
+ * the key.
+ */
+ protected static Hashtable _all = new Hashtable();
+
+ /** Access to all productions. */
+ public static Enumeration all() {return _all.elements();}
+
+ /** Lookup a production by index. */
+ public static production find(int indx) {
+ return (production) _all.get(new Integer(indx));
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Total number of productions. */
+ public static int number() {return _all.size();}
+
+ /** Static counter for assigning unique index numbers. */
+ protected static int next_index;
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** The left hand side non-terminal. */
+ protected symbol_part _lhs;
+
+ /** The left hand side non-terminal. */
+ public symbol_part lhs() {return _lhs;}
+
+
+ /** The precedence of the rule */
+ protected int _rhs_prec = -1;
+ protected int _rhs_assoc = -1;
+
+ /** Access to the precedence of the rule */
+ public int precedence_num() { return _rhs_prec; }
+ public int precedence_side() { return _rhs_assoc; }
+
+ /** Setting the precedence of a rule */
+ public void set_precedence_num(int prec_num) {
+ _rhs_prec = prec_num;
+ }
+ public void set_precedence_side(int prec_side) {
+ _rhs_assoc = prec_side;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** A collection of parts for the right hand side. */
+ protected production_part _rhs[];
+
+ /** Access to the collection of parts for the right hand side. */
+ public production_part rhs(int indx) throws internal_error
+ {
+ if (indx >= 0 && indx < _rhs_length)
+ return _rhs[indx];
+ else
+ throw new internal_error(
+ "Index out of range for right hand side of production");
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** How much of the right hand side array we are presently using. */
+ protected int _rhs_length;
+
+ /** How much of the right hand side array we are presently using. */
+ public int rhs_length() {return _rhs_length;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** An action_part containing code for the action to be performed when we
+ * reduce with this production.
+ */
+ protected action_part _action;
+
+ /** An action_part containing code for the action to be performed when we
+ * reduce with this production.
+ */
+ public action_part action() {return _action;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Index number of the production. */
+ protected int _index;
+
+ /** Index number of the production. */
+ public int index() {return _index;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Count of number of reductions using this production. */
+ protected int _num_reductions = 0;
+
+ /** Count of number of reductions using this production. */
+ public int num_reductions() {return _num_reductions;}
+
+ /** Increment the count of reductions with this non-terminal */
+ public void note_reduction_use() {_num_reductions++;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Is the nullability of the production known or unknown? */
+ protected boolean _nullable_known = false;
+
+ /** Is the nullability of the production known or unknown? */
+ public boolean nullable_known() {return _nullable_known;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Nullability of the production (can it derive the empty string). */
+ protected boolean _nullable = false;
+
+ /** Nullability of the production (can it derive the empty string). */
+ public boolean nullable() {return _nullable;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** First set of the production. This is the set of terminals that
+ * could appear at the front of some string derived from this production.
+ */
+ protected terminal_set _first_set = new terminal_set();
+
+ /** First set of the production. This is the set of terminals that
+ * could appear at the front of some string derived from this production.
+ */
+ public terminal_set first_set() {return _first_set;}
+
+ /*-----------------------------------------------------------*/
+ /*--- Static Methods ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Determine if a given character can be a label id starter.
+ * @param c the character in question.
+ */
+ protected static boolean is_id_start(char c)
+ {
+ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_');
+
+ //later need to handle non-8-bit chars here
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Determine if a character can be in a label id.
+ * @param c the character in question.
+ */
+ protected static boolean is_id_char(char c)
+ {
+ return is_id_start(c) || (c >= '0' && c <= '9');
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+
+ /** Return label declaration code
+ * @param labelname the label name
+ * @param stack_type the stack type of label?
+ * @author frankf
+ */
+ protected String make_declaration(
+ String labelname,
+ String stack_type,
+ int offset)
+ {
+ String ret;
+
+ /* Put in the left/right value labels */
+ if (emit.lr_values())
+ ret = "\t\tint " + labelname + "left = ((java_cup.runtime.Symbol)" +
+ emit.pre("stack") + ".elementAt(" + emit.pre("top") +
+ "-" + offset + ")).left;\n" +
+ "\t\tint " + labelname + "right = ((java_cup.runtime.Symbol)" +
+ emit.pre("stack") + ".elementAt(" + emit.pre("top") +
+ "-" + offset + ")).right;\n";
+ else ret = "";
+
+ /* otherwise, just declare label. */
+ return ret + "\t\t" + stack_type + " " + labelname + " = (" + stack_type +
+ ")((" + "java_cup.runtime.Symbol) " + emit.pre("stack") + ".elementAt(" + emit.pre("top")
+ + "-" + offset + ")).value;\n";
+
+ }
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Declare label names as valid variables within the action string
+ * @param rhs array of RHS parts.
+ * @param rhs_len how much of rhs to consider valid.
+ * @param final_action the final action string of the production.
+ * @param lhs_type the object type associated with the LHS symbol.
+ */
+ protected String declare_labels(
+ production_part rhs[],
+ int rhs_len,
+ String final_action)
+ {
+ String declaration = "";
+
+ symbol_part part;
+ action_part act_part;
+ int pos;
+
+ /* walk down the parts and extract the labels */
+ for (pos = 0; pos < rhs_len; pos++)
+ {
+ if (!rhs[pos].is_action())
+ {
+ part = (symbol_part)rhs[pos];
+
+ /* if it has a label, make declaration! */
+ if (part.label() != null)
+ {
+ declaration = declaration +
+ make_declaration(part.label(), part.the_symbol().stack_type(),
+ rhs_len-pos-1);
+ }
+ }
+ }
+ return declaration;
+ }
+
+
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Helper routine to merge adjacent actions in a set of RHS parts
+ * @param rhs_parts array of RHS parts.
+ * @param len amount of that array that is valid.
+ * @return remaining valid length.
+ */
+ protected int merge_adjacent_actions(production_part rhs_parts[], int len)
+ {
+ int from_loc, to_loc, merge_cnt;
+
+ /* bail out early if we have no work to do */
+ if (rhs_parts == null || len == 0) return 0;
+
+ merge_cnt = 0;
+ to_loc = -1;
+ for (from_loc=0; from_loc<len; from_loc++)
+ {
+ /* do we go in the current position or one further */
+ if (to_loc < 0 || !rhs_parts[to_loc].is_action()
+ || !rhs_parts[from_loc].is_action())
+ {
+ /* next one */
+ to_loc++;
+
+ /* clear the way for it */
+ if (to_loc != from_loc) rhs_parts[to_loc] = null;
+ }
+
+ /* if this is not trivial? */
+ if (to_loc != from_loc)
+ {
+ /* do we merge or copy? */
+ if (rhs_parts[to_loc] != null && rhs_parts[to_loc].is_action() &&
+ rhs_parts[from_loc].is_action())
+ {
+ /* merge */
+ rhs_parts[to_loc] = new action_part(
+ ((action_part)rhs_parts[to_loc]).code_string() +
+ ((action_part)rhs_parts[from_loc]).code_string());
+ merge_cnt++;
+ }
+ else
+ {
+ /* copy */
+ rhs_parts[to_loc] = rhs_parts[from_loc];
+ }
+ }
+ }
+
+ /* return the used length */
+ return len - merge_cnt;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Helper routine to strip a trailing action off rhs and return it
+ * @param rhs_parts array of RHS parts.
+ * @param len how many of those are valid.
+ * @return the removed action part.
+ */
+ protected action_part strip_trailing_action(
+ production_part rhs_parts[],
+ int len)
+ {
+ action_part result;
+
+ /* bail out early if we have nothing to do */
+ if (rhs_parts == null || len == 0) return null;
+
+ /* see if we have a trailing action */
+ if (rhs_parts[len-1].is_action())
+ {
+ /* snip it out and return it */
+ result = (action_part)rhs_parts[len-1];
+ rhs_parts[len-1] = null;
+ return result;
+ }
+ else
+ return null;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Remove all embedded actions from a production by factoring them
+ * out into individual action production using new non terminals.
+ * if the original production was: <pre>
+ * A ::= B {action1} C {action2} D
+ * </pre>
+ * then it will be factored into: <pre>
+ * A ::= B NT$1 C NT$2 D
+ * NT$1 ::= {action1}
+ * NT$2 ::= {action2}
+ * </pre>
+ * where NT$1 and NT$2 are new system created non terminals.
+ */
+
+ /* the declarations added to the parent production are also passed along,
+ as they should be perfectly valid in this code string, since it
+ was originally a code string in the parent, not on its own.
+ frank 6/20/96 */
+ protected void remove_embedded_actions(
+
+ ) throws internal_error
+ {
+ non_terminal new_nt;
+ production new_prod;
+ String declare_str;
+
+ /* walk over the production and process each action */
+ for (int act_loc = 0; act_loc < rhs_length(); act_loc++)
+ if (rhs(act_loc).is_action())
+ {
+
+
+ declare_str = declare_labels(
+ _rhs, act_loc, "");
+ /* create a new non terminal for the action production */
+ new_nt = non_terminal.create_new();
+ new_nt.is_embedded_action = true; /* 24-Mar-1998, CSA */
+
+ /* create a new production with just the action */
+ new_prod = new action_production(this, new_nt, null, 0,
+ declare_str + ((action_part)rhs(act_loc)).code_string());
+
+ /* replace the action with the generated non terminal */
+ _rhs[act_loc] = new symbol_part(new_nt);
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Check to see if the production (now) appears to be nullable.
+ * A production is nullable if its RHS could derive the empty string.
+ * This results when the RHS is empty or contains only non terminals
+ * which themselves are nullable.
+ */
+ public boolean check_nullable() throws internal_error
+ {
+ production_part part;
+ symbol sym;
+ int pos;
+
+ /* if we already know bail out early */
+ if (nullable_known()) return nullable();
+
+ /* if we have a zero size RHS we are directly nullable */
+ if (rhs_length() == 0)
+ {
+ /* stash and return the result */
+ return set_nullable(true);
+ }
+
+ /* otherwise we need to test all of our parts */
+ for (pos=0; pos<rhs_length(); pos++)
+ {
+ part = rhs(pos);
+
+ /* only look at non-actions */
+ if (!part.is_action())
+ {
+ sym = ((symbol_part)part).the_symbol();
+
+ /* if its a terminal we are definitely not nullable */
+ if (!sym.is_non_term())
+ return set_nullable(false);
+ /* its a non-term, is it marked nullable */
+ else if (!((non_terminal)sym).nullable())
+ /* this one not (yet) nullable, so we aren't */
+ return false;
+ }
+ }
+
+ /* if we make it here all parts are nullable */
+ return set_nullable(true);
+ }
+
+ /** set (and return) nullability */
+ boolean set_nullable(boolean v)
+ {
+ _nullable_known = true;
+ _nullable = v;
+ return v;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Update (and return) the first set based on current NT firsts.
+ * This assumes that nullability has already been computed for all non
+ * terminals and productions.
+ */
+ public terminal_set check_first_set() throws internal_error
+ {
+ int part;
+ symbol sym;
+
+ /* walk down the right hand side till we get past all nullables */
+ for (part=0; part<rhs_length(); part++)
+ {
+ /* only look at non-actions */
+ if (!rhs(part).is_action())
+ {
+ sym = ((symbol_part)rhs(part)).the_symbol();
+
+ /* is it a non-terminal?*/
+ if (sym.is_non_term())
+ {
+ /* add in current firsts from that NT */
+ _first_set.add(((non_terminal)sym).first_set());
+
+ /* if its not nullable, we are done */
+ if (!((non_terminal)sym).nullable())
+ break;
+ }
+ else
+ {
+ /* its a terminal -- add that to the set */
+ _first_set.add((terminal)sym);
+
+ /* we are done */
+ break;
+ }
+ }
+ }
+
+ /* return our updated first set */
+ return first_set();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Equality comparison. */
+ public boolean equals(production other)
+ {
+ if (other == null) return false;
+ return other._index == _index;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Generic equality comparison. */
+ public boolean equals(Object other)
+ {
+ if (!(other instanceof production))
+ return false;
+ else
+ return equals((production)other);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Produce a hash code. */
+ public int hashCode()
+ {
+ /* just use a simple function of the index */
+ return _index*13;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to a string. */
+ public String toString()
+ {
+ String result;
+
+ /* catch any internal errors */
+ try {
+ result = "production [" + index() + "]: ";
+ result += ((lhs() != null) ? lhs().toString() : "$$NULL-LHS$$");
+ result += " :: = ";
+ for (int i = 0; i<rhs_length(); i++)
+ result += rhs(i) + " ";
+ result += ";";
+ if (action() != null && action().code_string() != null)
+ result += " {" + action().code_string() + "}";
+
+ if (nullable_known())
+ if (nullable())
+ result += "[NULLABLE]";
+ else
+ result += "[NOT NULLABLE]";
+ } catch (internal_error e) {
+ /* crash on internal error since we can't throw it from here (because
+ superclass does not throw anything. */
+ e.crash();
+ result = null;
+ }
+
+ return result;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to a simpler string. */
+ public String to_simple_string() throws internal_error
+ {
+ String result;
+
+ result = ((lhs() != null) ? lhs().the_symbol().name() : "NULL_LHS");
+ result += " ::= ";
+ for (int i = 0; i < rhs_length(); i++)
+ if (!rhs(i).is_action())
+ result += ((symbol_part)rhs(i)).the_symbol().name() + " ";
+
+ return result;
+ }
+
+ /*-----------------------------------------------------------*/
+
+}
diff --git a/src/syntaxParser/java_cup/SAVE/production_part.java b/src/syntaxParser/java_cup/SAVE/production_part.java
new file mode 100644
index 0000000..a790ec0
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/production_part.java
@@ -0,0 +1,94 @@
+package java_cup;
+
+/** This class represents one part (either a symbol or an action) of a
+ * production. In this base class it contains only an optional label
+ * string that the user can use to refer to the part within actions.<p>
+ *
+ * This is an abstract class.
+ *
+ * @see java_cup.production
+ * @version last updated: 11/25/95
+ * @author Scott Hudson
+ */
+public abstract class production_part {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Simple constructor. */
+ public production_part(String lab)
+ {
+ _label = lab;
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Optional label for referring to the part within an action (null for
+ * no label).
+ */
+ protected String _label;
+
+ /** Optional label for referring to the part within an action (null for
+ * no label).
+ */
+ public String label() {return _label;}
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Indicate if this is an action (rather than a symbol). Here in the
+ * base class, we don't this know yet, so its an abstract method.
+ */
+ public abstract boolean is_action();
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Equality comparison. */
+ public boolean equals(production_part other)
+ {
+ if (other == null) return false;
+
+ /* compare the labels */
+ if (label() != null)
+ return label().equals(other.label());
+ else
+ return other.label() == null;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Generic equality comparison. */
+ public boolean equals(Object other)
+ {
+ if (!(other instanceof production_part))
+ return false;
+ else
+ return equals((production_part)other);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Produce a hash code. */
+ public int hashCode()
+ {
+ return label()==null ? 0 : label().hashCode();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to a string. */
+ public String toString()
+ {
+ if (label() != null)
+ return label() + ":";
+ else
+ return " ";
+ }
+
+ /*-----------------------------------------------------------*/
+
+}
diff --git a/src/syntaxParser/java_cup/SAVE/reduce_action.java b/src/syntaxParser/java_cup/SAVE/reduce_action.java
new file mode 100644
index 0000000..e8f4c84
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/reduce_action.java
@@ -0,0 +1,84 @@
+
+package java_cup;
+
+/** This class represents a reduce action within the parse table.
+ * The action simply stores the production that it reduces with and
+ * responds to queries about its type.
+ *
+ * @version last updated: 11/25/95
+ * @author Scott Hudson
+ */
+public class reduce_action extends parse_action {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Simple constructor.
+ * @param prod the production this action reduces with.
+ */
+ public reduce_action(production prod ) throws internal_error
+ {
+ /* sanity check */
+ if (prod == null)
+ throw new internal_error(
+ "Attempt to create a reduce_action with a null production");
+
+ _reduce_with = prod;
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** The production we reduce with. */
+ protected production _reduce_with;
+
+ /** The production we reduce with. */
+ public production reduce_with() {return _reduce_with;}
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Quick access to type of action. */
+ public int kind() {return REDUCE;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Equality test. */
+ public boolean equals(reduce_action other)
+ {
+ return other != null && other.reduce_with() == reduce_with();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Generic equality test. */
+ public boolean equals(Object other)
+ {
+ if (other instanceof reduce_action)
+ return equals((reduce_action)other);
+ else
+ return false;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Compute a hash code. */
+ public int hashCode()
+ {
+ /* use the hash code of the production we are reducing with */
+ return reduce_with().hashCode();
+ }
+
+
+ /** Convert to string. */
+ public String toString()
+ {
+ return "REDUCE(with prod " + reduce_with().index() + ")";
+ }
+
+ /*-----------------------------------------------------------*/
+
+}
diff --git a/src/syntaxParser/java_cup/SAVE/shift_action.java b/src/syntaxParser/java_cup/SAVE/shift_action.java
new file mode 100644
index 0000000..33fc17a
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/shift_action.java
@@ -0,0 +1,82 @@
+
+package java_cup;
+
+/** This class represents a shift action within the parse table.
+ * The action simply stores the state that it shifts to and responds
+ * to queries about its type.
+ *
+ * @version last updated: 11/25/95
+ * @author Scott Hudson
+ */
+public class shift_action extends parse_action {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Simple constructor.
+ * @param shft_to the state that this action shifts to.
+ */
+ public shift_action(lalr_state shft_to) throws internal_error
+ {
+ /* sanity check */
+ if (shft_to == null)
+ throw new internal_error(
+ "Attempt to create a shift_action to a null state");
+
+ _shift_to = shft_to;
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** The state we shift to. */
+ protected lalr_state _shift_to;
+
+ /** The state we shift to. */
+ public lalr_state shift_to() {return _shift_to;}
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Quick access to type of action. */
+ public int kind() {return SHIFT;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Equality test. */
+ public boolean equals(shift_action other)
+ {
+ return other != null && other.shift_to() == shift_to();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Generic equality test. */
+ public boolean equals(Object other)
+ {
+ if (other instanceof shift_action)
+ return equals((shift_action)other);
+ else
+ return false;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Compute a hash code. */
+ public int hashCode()
+ {
+ /* use the hash code of the state we are shifting to */
+ return shift_to().hashCode();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to a string. */
+ public String toString() {return "SHIFT(to state " + shift_to().index() + ")";}
+
+ /*-----------------------------------------------------------*/
+
+}
diff --git a/src/syntaxParser/java_cup/SAVE/sym.java b/src/syntaxParser/java_cup/SAVE/sym.java
new file mode 100644
index 0000000..9810a3d
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/sym.java
@@ -0,0 +1,43 @@
+
+//----------------------------------------------------
+// The following code was generated by CUP v0.10k
+// Sun Jul 25 13:35:26 EDT 1999
+//----------------------------------------------------
+
+package java_cup;
+
+/** CUP generated class containing symbol constants. */
+public class sym {
+ /* terminals */
+ public static final int NON = 8;
+ public static final int NONTERMINAL = 27;
+ public static final int STAR = 15;
+ public static final int SEMI = 13;
+ public static final int CODE = 4;
+ public static final int EOF = 0;
+ public static final int NONASSOC = 23;
+ public static final int LEFT = 21;
+ public static final int PACKAGE = 2;
+ public static final int COLON = 17;
+ public static final int WITH = 11;
+ public static final int IMPORT = 3;
+ public static final int error = 1;
+ public static final int COLON_COLON_EQUALS = 18;
+ public static final int COMMA = 14;
+ public static final int DOT = 16;
+ public static final int SCAN = 10;
+ public static final int ID = 28;
+ public static final int INIT = 9;
+ public static final int PARSER = 6;
+ public static final int TERMINAL = 7;
+ public static final int PRECEDENCE = 20;
+ public static final int LBRACK = 25;
+ public static final int RBRACK = 26;
+ public static final int PERCENT_PREC = 24;
+ public static final int START = 12;
+ public static final int RIGHT = 22;
+ public static final int BAR = 19;
+ public static final int ACTION = 5;
+ public static final int CODE_STRING = 29;
+}
+
diff --git a/src/syntaxParser/java_cup/SAVE/symbol.java b/src/syntaxParser/java_cup/SAVE/symbol.java
new file mode 100644
index 0000000..94d8b7d
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/symbol.java
@@ -0,0 +1,107 @@
+package java_cup;
+
+/** This abstract class serves as the base class for grammar symbols (i.e.,
+ * both terminals and non-terminals). Each symbol has a name string, and
+ * a string giving the type of object that the symbol will be represented by
+ * on the runtime parse stack. In addition, each symbol maintains a use count
+ * in order to detect symbols that are declared but never used, and an index
+ * number that indicates where it appears in parse tables (index numbers are
+ * unique within terminals or non terminals, but not across both).
+ *
+ * @see java_cup.terminal
+ * @see java_cup.non_terminal
+ * @version last updated: 7/3/96
+ * @author Frank Flannery
+ */
+public abstract class symbol {
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Full constructor.
+ * @param nm the name of the symbol.
+ * @param tp a string with the type name.
+ */
+ public symbol(String nm, String tp)
+ {
+ /* sanity check */
+ if (nm == null) nm = "";
+
+ /* apply default if no type given */
+ if (tp == null) tp = "Object";
+
+ _name = nm;
+ _stack_type = tp;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Constructor with default type.
+ * @param nm the name of the symbol.
+ */
+ public symbol(String nm)
+ {
+ this(nm, null);
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** String for the human readable name of the symbol. */
+ protected String _name;
+
+ /** String for the human readable name of the symbol. */
+ public String name() {return _name;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** String for the type of object used for the symbol on the parse stack. */
+ protected String _stack_type;
+
+ /** String for the type of object used for the symbol on the parse stack. */
+ public String stack_type() {return _stack_type;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Count of how many times the symbol appears in productions. */
+ protected int _use_count = 0;
+
+ /** Count of how many times the symbol appears in productions. */
+ public int use_count() {return _use_count;}
+
+ /** Increment the use count. */
+ public void note_use() {_use_count++;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Index of this symbol (terminal or non terminal) in the parse tables.
+ * Note: indexes are unique among terminals and unique among non terminals,
+ * however, a terminal may have the same index as a non-terminal, etc.
+ */
+ protected int _index;
+
+ /** Index of this symbol (terminal or non terminal) in the parse tables.
+ * Note: indexes are unique among terminals and unique among non terminals,
+ * however, a terminal may have the same index as a non-terminal, etc.
+ */
+ public int index() {return _index;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Indicate if this is a non-terminal. Here in the base class we
+ * don't know, so this is abstract.
+ */
+ public abstract boolean is_non_term();
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to a string. */
+ public String toString()
+ {
+ return name();
+ }
+
+ /*-----------------------------------------------------------*/
+
+}
diff --git a/src/syntaxParser/java_cup/SAVE/symbol_part.java b/src/syntaxParser/java_cup/SAVE/symbol_part.java
new file mode 100644
index 0000000..9142b5f
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/symbol_part.java
@@ -0,0 +1,100 @@
+package java_cup;
+
+/** This class represents a part of a production which is a symbol (terminal
+ * or non terminal). This simply maintains a reference to the symbol in
+ * question.
+ *
+ * @see java_cup.production
+ * @version last updated: 11/25/95
+ * @author Scott Hudson
+ */
+public class symbol_part extends production_part {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Full constructor.
+ * @param sym the symbol that this part is made up of.
+ * @param lab an optional label string for the part.
+ */
+ public symbol_part(symbol sym, String lab) throws internal_error
+ {
+ super(lab);
+
+ if (sym == null)
+ throw new internal_error(
+ "Attempt to construct a symbol_part with a null symbol");
+ _the_symbol = sym;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Constructor with no label.
+ * @param sym the symbol that this part is made up of.
+ */
+ public symbol_part(symbol sym) throws internal_error
+ {
+ this(sym,null);
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** The symbol that this part is made up of. */
+ protected symbol _the_symbol;
+
+ /** The symbol that this part is made up of. */
+ public symbol the_symbol() {return _the_symbol;}
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Respond that we are not an action part. */
+ public boolean is_action() { return false; }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Equality comparison. */
+ public boolean equals(symbol_part other)
+ {
+ return other != null && super.equals(other) &&
+ the_symbol().equals(other.the_symbol());
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Generic equality comparison. */
+ public boolean equals(Object other)
+ {
+ if (!(other instanceof symbol_part))
+ return false;
+ else
+ return equals((symbol_part)other);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Produce a hash code. */
+ public int hashCode()
+ {
+ return super.hashCode() ^
+ (the_symbol()==null ? 0 : the_symbol().hashCode());
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to a string. */
+ public String toString()
+ {
+ if (the_symbol() != null)
+ return super.toString() + the_symbol();
+ else
+ return super.toString() + "$$MISSING-SYMBOL$$";
+ }
+
+ /*-----------------------------------------------------------*/
+
+}
diff --git a/src/syntaxParser/java_cup/SAVE/symbol_set.java b/src/syntaxParser/java_cup/SAVE/symbol_set.java
new file mode 100644
index 0000000..a1aec10
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/symbol_set.java
@@ -0,0 +1,231 @@
+
+package java_cup;
+
+import java.util.Hashtable;
+import java.util.Enumeration;
+
+/** This class represents a set of symbols and provides a series of
+ * set operations to manipulate them.
+ *
+ * @see java_cup.symbol
+ * @version last updated: 11/25/95
+ * @author Scott Hudson
+ */
+public class symbol_set {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Constructor for an empty set. */
+ public symbol_set() { }
+
+ /** Constructor for cloning from another set.
+ * @param other the set we are cloning from.
+ */
+ public symbol_set(symbol_set other) throws internal_error
+ {
+ not_null(other);
+ _all = (Hashtable)other._all.clone();
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** A hash table to hold the set. Symbols are keyed using their name string.
+ */
+ protected Hashtable _all = new Hashtable(11);
+
+ /** Access to all elements of the set. */
+ public Enumeration all() {return _all.elements();}
+
+ /** size of the set */
+ public int size() {return _all.size();}
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Helper function to test for a null object and throw an exception
+ * if one is found.
+ * @param obj the object we are testing.
+ */
+ protected void not_null(Object obj) throws internal_error
+ {
+ if (obj == null)
+ throw new internal_error("Null object used in set operation");
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Determine if the set contains a particular symbol.
+ * @param sym the symbol we are looking for.
+ */
+ public boolean contains(symbol sym) {return _all.containsKey(sym.name());}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Determine if this set is an (improper) subset of another.
+ * @param other the set we are testing against.
+ */
+ public boolean is_subset_of(symbol_set other) throws internal_error
+ {
+ not_null(other);
+
+ /* walk down our set and make sure every element is in the other */
+ for (Enumeration e = all(); e.hasMoreElements(); )
+ if (!other.contains((symbol)e.nextElement()))
+ return false;
+
+ /* they were all there */
+ return true;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Determine if this set is an (improper) superset of another.
+ * @param other the set we are are testing against.
+ */
+ public boolean is_superset_of(symbol_set other) throws internal_error
+ {
+ not_null(other);
+ return other.is_subset_of(this);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Add a single symbol to the set.
+ * @param sym the symbol we are adding.
+ * @return true if this changes the set.
+ */
+ public boolean add(symbol sym) throws internal_error
+ {
+ Object previous;
+
+ not_null(sym);
+
+ /* put the object in */
+ previous = _all.put(sym.name(),sym);
+
+ /* if we had a previous, this is no change */
+ return previous == null;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Remove a single symbol if it is in the set.
+ * @param sym the symbol we are removing.
+ */
+ public void remove(symbol sym) throws internal_error
+ {
+ not_null(sym);
+ _all.remove(sym.name());
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Add (union) in a complete set.
+ * @param other the set we are adding in.
+ * @return true if this changes the set.
+ */
+ public boolean add(symbol_set other) throws internal_error
+ {
+ boolean result = false;
+
+ not_null(other);
+
+ /* walk down the other set and do the adds individually */
+ for (Enumeration e = other.all(); e.hasMoreElements(); )
+ result = add((symbol)e.nextElement()) || result;
+
+ return result;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Remove (set subtract) a complete set.
+ * @param other the set we are removing.
+ */
+ public void remove(symbol_set other) throws internal_error
+ {
+ not_null(other);
+
+ /* walk down the other set and do the removes individually */
+ for (Enumeration e = other.all(); e.hasMoreElements(); )
+ remove((symbol)e.nextElement());
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Equality comparison. */
+ public boolean equals(symbol_set other)
+ {
+ if (other == null || other.size() != size()) return false;
+
+ /* once we know they are the same size, then improper subset does test */
+ try {
+ return is_subset_of(other);
+ } catch (internal_error e) {
+ /* can't throw the error (because super class doesn't), so we crash */
+ e.crash();
+ return false;
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Generic equality comparison. */
+ public boolean equals(Object other)
+ {
+ if (!(other instanceof symbol_set))
+ return false;
+ else
+ return equals((symbol_set)other);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Compute a hash code. */
+ public int hashCode()
+ {
+ int result = 0;
+ int cnt;
+ Enumeration e;
+
+ /* hash together codes from at most first 5 elements */
+ for (e = all(), cnt=0 ; e.hasMoreElements() && cnt<5; cnt++)
+ result ^= ((symbol)e.nextElement()).hashCode();
+
+ return result;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to a string. */
+ public String toString()
+ {
+ String result;
+ boolean comma_flag;
+
+ result = "{";
+ comma_flag = false;
+ for (Enumeration e = all(); e.hasMoreElements(); )
+ {
+ if (comma_flag)
+ result += ", ";
+ else
+ comma_flag = true;
+
+ result += ((symbol)e.nextElement()).name();
+ }
+ result += "}";
+
+ return result;
+ }
+
+ /*-----------------------------------------------------------*/
+
+}
+
+
diff --git a/src/syntaxParser/java_cup/SAVE/terminal.java b/src/syntaxParser/java_cup/SAVE/terminal.java
new file mode 100644
index 0000000..e1a40aa
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/terminal.java
@@ -0,0 +1,169 @@
+package java_cup;
+
+import java_cup.assoc;
+import java.util.Hashtable;
+import java.util.Enumeration;
+
+/** This class represents a terminal symbol in the grammar. Each terminal
+ * has a textual name, an index, and a string which indicates the type of
+ * object it will be implemented with at runtime (i.e. the class of object
+ * that will be returned by the scanner and pushed on the parse stack to
+ * represent it).
+ *
+ * @version last updated: 7/3/96
+ * @author Frank Flannery
+ */
+public class terminal extends symbol {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Full constructor.
+ * @param nm the name of the terminal.
+ * @param tp the type of the terminal.
+ */
+ public terminal(String nm, String tp, int precedence_side, int precedence_num)
+ {
+ /* superclass does most of the work */
+ super(nm, tp);
+
+ /* add to set of all terminals and check for duplicates */
+ Object conflict = _all.put(nm,this);
+ if (conflict != null)
+ // can't throw an execption here because this is used in static
+ // initializers, so we do a crash instead
+ // was:
+ // throw new internal_error("Duplicate terminal (" + nm + ") created");
+ (new internal_error("Duplicate terminal (" + nm + ") created")).crash();
+
+ /* assign a unique index */
+ _index = next_index++;
+
+ /* set the precedence */
+ _precedence_num = precedence_num;
+ _precedence_side = precedence_side;
+
+ /* add to by_index set */
+ _all_by_index.put(new Integer(_index), this);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Constructor for non-precedented terminal
+ */
+
+ public terminal(String nm, String tp)
+ {
+ this(nm, tp, assoc.no_prec, -1);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Constructor with default type.
+ * @param nm the name of the terminal.
+ */
+ public terminal(String nm)
+ {
+ this(nm, null);
+ }
+
+ /*-----------------------------------------------------------*/
+ /*------------------- Class Variables ---------------------*/
+ /*-----------------------------------------------------------*/
+
+ private int _precedence_num;
+ private int _precedence_side;
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Static (Class) Variables ------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Table of all terminals. Elements are stored using name strings as
+ * the key
+ */
+ protected static Hashtable _all = new Hashtable();
+
+ /** Access to all terminals. */
+ public static Enumeration all() {return _all.elements();}
+
+ /** Lookup a terminal by name string. */
+ public static terminal find(String with_name)
+ {
+ if (with_name == null)
+ return null;
+ else
+ return (terminal)_all.get(with_name);
+ }
+
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Table of all terminals indexed by their index number. */
+ protected static Hashtable _all_by_index = new Hashtable();
+
+ /** Lookup a terminal by index. */
+ public static terminal find(int indx)
+ {
+ Integer the_indx = new Integer(indx);
+
+ return (terminal)_all_by_index.get(the_indx);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Total number of terminals. */
+ public static int number() {return _all.size();}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Static counter to assign unique index. */
+ protected static int next_index = 0;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Special terminal for end of input. */
+ public static final terminal EOF = new terminal("EOF");
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** special terminal used for error recovery */
+ public static final terminal error = new terminal("error");
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Report this symbol as not being a non-terminal. */
+ public boolean is_non_term()
+ {
+ return false;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to a string. */
+ public String toString()
+ {
+ return super.toString() + "[" + index() + "]";
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** get the precedence of a terminal */
+ public int precedence_num() {
+ return _precedence_num;
+ }
+ public int precedence_side() {
+ return _precedence_side;
+ }
+
+ /** set the precedence of a terminal */
+ public void set_precedence(int p, int new_prec) {
+ _precedence_side = p;
+ _precedence_num = new_prec;
+ }
+
+ /*-----------------------------------------------------------*/
+
+}
diff --git a/src/syntaxParser/java_cup/SAVE/terminal_set.java b/src/syntaxParser/java_cup/SAVE/terminal_set.java
new file mode 100644
index 0000000..e921cb5
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/terminal_set.java
@@ -0,0 +1,253 @@
+
+package java_cup;
+
+import java.util.BitSet;
+
+/** A set of terminals implemented as a bitset.
+ * @version last updated: 11/25/95
+ * @author Scott Hudson
+ */
+public class terminal_set {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Constructor for an empty set. */
+ public terminal_set()
+ {
+ /* allocate the bitset at what is probably the right size */
+ _elements = new BitSet(terminal.number());
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Constructor for cloning from another set.
+ * @param other the set we are cloning from.
+ */
+ public terminal_set(terminal_set other)
+ throws internal_error
+ {
+ not_null(other);
+ _elements = (BitSet)other._elements.clone();
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Static (Class) Variables ------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Constant for the empty set. */
+ public static final terminal_set EMPTY = new terminal_set();
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Bitset to implement the actual set. */
+ protected BitSet _elements;
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Helper function to test for a null object and throw an exception if
+ * one is found.
+ * @param obj the object we are testing.
+ */
+ protected void not_null(Object obj) throws internal_error
+ {
+ if (obj == null)
+ throw new internal_error("Null object used in set operation");
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Determine if the set is empty. */
+ public boolean empty()
+ {
+ return equals(EMPTY);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Determine if the set contains a particular terminal.
+ * @param sym the terminal symbol we are looking for.
+ */
+ public boolean contains(terminal sym)
+ throws internal_error
+ {
+ not_null(sym);
+ return _elements.get(sym.index());
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Given its index determine if the set contains a particular terminal.
+ * @param indx the index of the terminal in question.
+ */
+ public boolean contains(int indx)
+ {
+ return _elements.get(indx);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Determine if this set is an (improper) subset of another.
+ * @param other the set we are testing against.
+ */
+ public boolean is_subset_of(terminal_set other)
+ throws internal_error
+ {
+ not_null(other);
+
+ /* make a copy of the other set */
+ BitSet copy_other = (BitSet)other._elements.clone();
+
+ /* and or in */
+ copy_other.or(_elements);
+
+ /* if it hasn't changed, we were a subset */
+ return copy_other.equals(other._elements);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Determine if this set is an (improper) superset of another.
+ * @param other the set we are testing against.
+ */
+ public boolean is_superset_of(terminal_set other)
+ throws internal_error
+ {
+ not_null(other);
+ return other.is_subset_of(this);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Add a single terminal to the set.
+ * @param sym the terminal being added.
+ * @return true if this changes the set.
+ */
+ public boolean add(terminal sym)
+ throws internal_error
+ {
+ boolean result;
+
+ not_null(sym);
+
+ /* see if we already have this */
+ result = _elements.get(sym.index());
+
+ /* if not we add it */
+ if (!result)
+ _elements.set(sym.index());
+
+ return result;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Remove a terminal if it is in the set.
+ * @param sym the terminal being removed.
+ */
+ public void remove(terminal sym)
+ throws internal_error
+ {
+ not_null(sym);
+ _elements.clear(sym.index());
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Add (union) in a complete set.
+ * @param other the set being added.
+ * @return true if this changes the set.
+ */
+ public boolean add(terminal_set other)
+ throws internal_error
+ {
+ not_null(other);
+
+ /* make a copy */
+ BitSet copy = (BitSet)_elements.clone();
+
+ /* or in the other set */
+ _elements.or(other._elements);
+
+ /* changed if we are not the same as the copy */
+ return !_elements.equals(copy);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Determine if this set intersects another.
+ * @param other the other set in question.
+ */
+ public boolean intersects(terminal_set other)
+ throws internal_error
+ {
+ not_null(other);
+
+ /* make a copy of the other set */
+ BitSet copy = (BitSet)other._elements.clone();
+
+ /* xor out our values */
+ copy.xor(this._elements);
+
+ /* see if its different */
+ return !copy.equals(other._elements);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Equality comparison. */
+ public boolean equals(terminal_set other)
+ {
+ if (other == null)
+ return false;
+ else
+ return _elements.equals(other._elements);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Generic equality comparison. */
+ public boolean equals(Object other)
+ {
+ if (!(other instanceof terminal_set))
+ return false;
+ else
+ return equals((terminal_set)other);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to string. */
+ public String toString()
+ {
+ String result;
+ boolean comma_flag;
+
+ result = "{";
+ comma_flag = false;
+ for (int t = 0; t < terminal.number(); t++)
+ {
+ if (_elements.get(t))
+ {
+ if (comma_flag)
+ result += ", ";
+ else
+ comma_flag = true;
+
+ result += terminal.find(t).name();
+ }
+ }
+ result += "}";
+
+ return result;
+ }
+
+ /*-----------------------------------------------------------*/
+
+}
+
diff --git a/src/syntaxParser/java_cup/SAVE/version.java b/src/syntaxParser/java_cup/SAVE/version.java
new file mode 100644
index 0000000..06600b5
--- /dev/null
+++ b/src/syntaxParser/java_cup/SAVE/version.java
@@ -0,0 +1,55 @@
+
+package java_cup;
+
+/** This class contains version and authorship information.
+ * It contains only static data elements and basically just a central
+ * place to put this kind of information so it can be updated easily
+ * for each release.
+ *
+ * Version numbers used here are broken into 3 parts: major, minor, and
+ * update, and are written as v<major>.<minor>.<update> (e.g. v0.10a).
+ * Major numbers will change at the time of major reworking of some
+ * part of the system. Minor numbers for each public release or
+ * change big enough to cause incompatibilities. Finally update
+ * letter will be incremented for small bug fixes and changes that
+ * probably wouldn't be noticed by a user.
+ *
+ * @version last updated: 12/22/97 [CSA]
+ * @author Frank Flannery
+ */
+
+public class version {
+ /** The major version number. */
+ public static final int major = 0;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** The minor version number. */
+ public static final int minor = 10;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** The update letter. */
+ public static final char update = 'k';
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** String for the current version. */
+ public static final String version_str = "v" + major + "." + minor + update;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Full title of the system */
+ public static final String title_str = "CUP " + version_str;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Name of the author */
+ public static final String author_str =
+ "Scott E. Hudson, Frank Flannery, and C. Scott Ananian";
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** The command name normally used to invoke this program */
+ public static final String program_name = "java_cup";
+}
diff --git a/src/syntaxParser/java_cup/action_part.class b/src/syntaxParser/java_cup/action_part.class
new file mode 100644
index 0000000..419eefb
--- /dev/null
+++ b/src/syntaxParser/java_cup/action_part.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/action_part.java b/src/syntaxParser/java_cup/action_part.java
new file mode 100644
index 0000000..69e98f5
--- /dev/null
+++ b/src/syntaxParser/java_cup/action_part.java
@@ -0,0 +1,93 @@
+
+package java_cup;
+
+/**
+ * This class represents a part of a production which contains an
+ * action. These are eventually eliminated from productions and converted
+ * to trailing actions by factoring out with a production that derives the
+ * empty string (and ends with this action).
+ *
+ * @see java_cup.production
+ * @version last update: 11/25/95
+ * @author Scott Hudson
+ */
+
+public class action_part extends production_part {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructors ------------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Simple constructor.
+ * @param code_str string containing the actual user code.
+ */
+ public action_part(String code_str)
+ {
+ super(/* never have a label on code */null);
+ _code_string = code_str;
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** String containing code for the action in question. */
+ protected String _code_string;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** String containing code for the action in question. */
+ public String code_string() {return _code_string;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Set the code string. */
+ public void set_code_string(String new_str) {_code_string = new_str;}
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Override to report this object as an action. */
+ public boolean is_action() { return true; }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Equality comparison for properly typed object. */
+ public boolean equals(action_part other)
+ {
+ /* compare the strings */
+ return other != null && super.equals(other) &&
+ other.code_string().equals(code_string());
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Generic equality comparison. */
+ public boolean equals(Object other)
+ {
+ if (!(other instanceof action_part))
+ return false;
+ else
+ return equals((action_part)other);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Produce a hash code. */
+ public int hashCode()
+ {
+ return super.hashCode() ^
+ (code_string()==null ? 0 : code_string().hashCode());
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to a string. */
+ public String toString()
+ {
+ return super.toString() + "{" + code_string() + "}";
+ }
+
+ /*-----------------------------------------------------------*/
+}
diff --git a/src/syntaxParser/java_cup/action_production.class b/src/syntaxParser/java_cup/action_production.class
new file mode 100644
index 0000000..01329be
--- /dev/null
+++ b/src/syntaxParser/java_cup/action_production.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/action_production.java b/src/syntaxParser/java_cup/action_production.java
new file mode 100644
index 0000000..3c0845f
--- /dev/null
+++ b/src/syntaxParser/java_cup/action_production.java
@@ -0,0 +1,39 @@
+
+package java_cup;
+
+/** A specialized version of a production used when we split an existing
+ * production in order to remove an embedded action. Here we keep a bit
+ * of extra bookkeeping so that we know where we came from.
+ * @version last updated: 11/25/95
+ * @author Scott Hudson
+ */
+
+public class action_production extends production {
+
+ /** Constructor.
+ * @param base the production we are being factored out of.
+ * @param lhs_sym the LHS symbol for this production.
+ * @param rhs_parts array of production parts for the RHS.
+ * @param rhs_len how much of the rhs_parts array is valid.
+ * @param action_str the trailing reduce action for this production.
+ */
+ public action_production(
+ production base,
+ non_terminal lhs_sym,
+ production_part rhs_parts[],
+ int rhs_len,
+ String action_str)
+ throws internal_error
+ {
+ super(lhs_sym, rhs_parts, rhs_len, action_str);
+ _base_production = base;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** The production we were taken out of. */
+ protected production _base_production;
+
+ /** The production we were taken out of. */
+ public production base_production() {return _base_production;}
+}
diff --git a/src/syntaxParser/java_cup/assoc.class b/src/syntaxParser/java_cup/assoc.class
new file mode 100644
index 0000000..b81980a
--- /dev/null
+++ b/src/syntaxParser/java_cup/assoc.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/assoc.java b/src/syntaxParser/java_cup/assoc.java
new file mode 100644
index 0000000..8d0b50e
--- /dev/null
+++ b/src/syntaxParser/java_cup/assoc.java
@@ -0,0 +1,16 @@
+package java_cup;
+
+/* Defines integers that represent the associativity of terminals
+ * @version last updated: 7/3/96
+ * @author Frank Flannery
+ */
+
+public class assoc {
+
+ /* various associativities, no_prec being the default value */
+ public final static int left = 0;
+ public final static int right = 1;
+ public final static int nonassoc = 2;
+ public final static int no_prec = -1;
+
+} \ No newline at end of file
diff --git a/src/syntaxParser/java_cup/emit.class b/src/syntaxParser/java_cup/emit.class
new file mode 100644
index 0000000..602be0c
--- /dev/null
+++ b/src/syntaxParser/java_cup/emit.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/emit.java b/src/syntaxParser/java_cup/emit.java
new file mode 100644
index 0000000..9db9014
--- /dev/null
+++ b/src/syntaxParser/java_cup/emit.java
@@ -0,0 +1,897 @@
+package java_cup;
+
+import java.io.PrintWriter;
+import java.util.Stack;
+import java.util.Enumeration;
+import java.util.Date;
+
+/**
+ * This class handles emitting generated code for the resulting parser.
+ * The various parse tables must be constructed, etc. before calling any
+ * routines in this class.<p>
+ *
+ * Three classes are produced by this code:
+ * <dl>
+ * <dt> symbol constant class
+ * <dd> this contains constant declarations for each terminal (and
+ * optionally each non-terminal).
+ * <dt> action class
+ * <dd> this non-public class contains code to invoke all the user actions
+ * that were embedded in the parser specification.
+ * <dt> parser class
+ * <dd> the specialized parser class consisting primarily of some user
+ * supplied general and initialization code, and the parse tables.
+ * </dl><p>
+ *
+ * Three parse tables are created as part of the parser class:
+ * <dl>
+ * <dt> production table
+ * <dd> lists the LHS non terminal number, and the length of the RHS of
+ * each production.
+ * <dt> action table
+ * <dd> for each state of the parse machine, gives the action to be taken
+ * (shift, reduce, or error) under each lookahead symbol.<br>
+ * <dt> reduce-goto table
+ * <dd> when a reduce on a given production is taken, the parse stack is
+ * popped back a number of elements corresponding to the RHS of the
+ * production. This reveals a prior state, which we transition out
+ * of under the LHS non terminal symbol for the production (as if we
+ * had seen the LHS symbol rather than all the symbols matching the
+ * RHS). This table is indexed by non terminal numbers and indicates
+ * how to make these transitions.
+ * </dl><p>
+ *
+ * In addition to the method interface, this class maintains a series of
+ * public global variables and flags indicating how misc. parts of the code
+ * and other output is to be produced, and counting things such as number of
+ * conflicts detected (see the source code and public variables below for
+ * more details).<p>
+ *
+ * This class is "static" (contains only static data and methods).<p>
+ *
+ * @see java_cup.main
+ * @version last update: 11/25/95
+ * @author Scott Hudson
+ */
+
+/* Major externally callable routines here include:
+ symbols - emit the symbol constant class
+ parser - emit the parser class
+
+ In addition the following major internal routines are provided:
+ emit_package - emit a package declaration
+ emit_action_code - emit the class containing the user's actions
+ emit_production_table - emit declaration and init for the production table
+ do_action_table - emit declaration and init for the action table
+ do_reduce_table - emit declaration and init for the reduce-goto table
+
+ Finally, this class uses a number of public instance variables to communicate
+ optional parameters and flags used to control how code is generated,
+ as well as to report counts of various things (such as number of conflicts
+ detected). These include:
+
+ prefix - a prefix string used to prefix names that would
+ otherwise "pollute" someone else's name space.
+ package_name - name of the package emitted code is placed in
+ (or null for an unnamed package.
+ symbol_const_class_name - name of the class containing symbol constants.
+ parser_class_name - name of the class for the resulting parser.
+ action_code - user supplied declarations and other code to be
+ placed in action class.
+ parser_code - user supplied declarations and other code to be
+ placed in parser class.
+ init_code - user supplied code to be executed as the parser
+ is being initialized.
+ scan_code - user supplied code to get the next Symbol.
+ start_production - the start production for the grammar.
+ import_list - list of imports for use with action class.
+ num_conflicts - number of conflicts detected.
+ nowarn - true if we are not to issue warning messages.
+ not_reduced - count of number of productions that never reduce.
+ unused_term - count of unused terminal symbols.
+ unused_non_term - count of unused non terminal symbols.
+ *_time - a series of symbols indicating how long various
+ sub-parts of code generation took (used to produce
+ optional time reports in main).
+*/
+
+public class emit {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Only constructor is private so no instances can be created. */
+ private emit() { }
+
+ /*-----------------------------------------------------------*/
+ /*--- Static (Class) Variables ------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** The prefix placed on names that pollute someone else's name space. */
+ public static String prefix = "CUP$";
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Package that the resulting code goes into (null is used for unnamed). */
+ public static String package_name = null;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Name of the generated class for symbol constants. */
+ public static String symbol_const_class_name = "sym";
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Name of the generated parser class. */
+ public static String parser_class_name = "parser";
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** User declarations for direct inclusion in user action class. */
+ public static String action_code = null;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** User declarations for direct inclusion in parser class. */
+ public static String parser_code = null;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** User code for user_init() which is called during parser initialization. */
+ public static String init_code = null;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** User code for scan() which is called to get the next Symbol. */
+ public static String scan_code = null;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** The start production of the grammar. */
+ public static production start_production = null;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** List of imports (Strings containing class names) to go with actions. */
+ public static Stack import_list = new Stack();
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Number of conflict found while building tables. */
+ public static int num_conflicts = 0;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Do we skip warnings? */
+ public static boolean nowarn = false;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Count of the number on non-reduced productions found. */
+ public static int not_reduced = 0;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Count of unused terminals. */
+ public static int unused_term = 0;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Count of unused non terminals. */
+ public static int unused_non_term = 0;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /* Timing values used to produce timing report in main.*/
+
+ /** Time to produce symbol constant class. */
+ public static long symbols_time = 0;
+
+ /** Time to produce parser class. */
+ public static long parser_time = 0;
+
+ /** Time to produce action code class. */
+ public static long action_code_time = 0;
+
+ /** Time to produce the production table. */
+ public static long production_table_time = 0;
+
+ /** Time to produce the action table. */
+ public static long action_table_time = 0;
+
+ /** Time to produce the reduce-goto table. */
+ public static long goto_table_time = 0;
+
+ /* frankf 6/18/96 */
+ protected static boolean _lr_values;
+
+ /** whether or not to emit code for left and right values */
+ public static boolean lr_values() {return _lr_values;}
+ protected static void set_lr_values(boolean b) { _lr_values = b;}
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Build a string with the standard prefix.
+ * @param str string to prefix.
+ */
+ protected static String pre(String str) {
+ return prefix + parser_class_name + "$" + str;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Emit a package spec if the user wants one.
+ * @param out stream to produce output on.
+ */
+ protected static void emit_package(PrintWriter out)
+ {
+ /* generate a package spec if we have a name for one */
+ if (package_name != null) {
+ out.println("package " + package_name + ";"); out.println();
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Emit code for the symbol constant class, optionally including non terms,
+ * if they have been requested.
+ * @param out stream to produce output on.
+ * @param emit_non_terms do we emit constants for non terminals?
+ * @param sym_interface should we emit an interface, rather than a class?
+ */
+ public static void symbols(PrintWriter out,
+ boolean emit_non_terms, boolean sym_interface)
+ {
+ terminal term;
+ non_terminal nt;
+ String class_or_interface = (sym_interface)?"interface":"class";
+
+ long start_time = System.currentTimeMillis();
+
+ /* top of file */
+ out.println();
+ out.println("//----------------------------------------------------");
+ out.println("// The following code was generated by " +
+ version.title_str);
+ out.println("// " + new Date());
+ out.println("//----------------------------------------------------");
+ out.println();
+ emit_package(out);
+
+ /* class header */
+ out.println("/** CUP generated " + class_or_interface +
+ " containing symbol constants. */");
+ out.println("public " + class_or_interface + " " +
+ symbol_const_class_name + " {");
+
+ out.println(" /* terminals */");
+
+ /* walk over the terminals */ /* later might sort these */
+ for (Enumeration e = terminal.all(); e.hasMoreElements(); )
+ {
+ term = (terminal)e.nextElement();
+
+ /* output a constant decl for the terminal */
+ out.println(" public static final int " + term.name() + " = " +
+ term.index() + ";");
+ }
+
+ /* do the non terminals if they want them (parser doesn't need them) */
+ if (emit_non_terms)
+ {
+ out.println();
+ out.println(" /* non terminals */");
+
+ /* walk over the non terminals */ /* later might sort these */
+ for (Enumeration e = non_terminal.all(); e.hasMoreElements(); )
+ {
+ nt = (non_terminal)e.nextElement();
+
+ /* output a constant decl for the terminal */
+ out.println(" static final int " + nt.name() + " = " +
+ nt.index() + ";");
+ }
+ }
+
+ /* end of class */
+ out.println("}");
+ out.println();
+
+ symbols_time = System.currentTimeMillis() - start_time;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Emit code for the non-public class holding the actual action code.
+ * @param out stream to produce output on.
+ * @param start_prod the start production of the grammar.
+ */
+ protected static void emit_action_code(PrintWriter out, production start_prod)
+ throws internal_error
+ {
+ production prod;
+
+ long start_time = System.currentTimeMillis();
+
+ /* class header */
+ out.println();
+ out.println(
+ "/** Cup generated class to encapsulate user supplied action code.*/"
+ );
+ out.println("class " + pre("actions") + " {");
+
+ /* user supplied code */
+ if (action_code != null)
+ {
+ out.println();
+ out.println(action_code);
+ }
+
+ /* field for parser object */
+ out.println(" private final "+parser_class_name+" parser;");
+
+ /* constructor */
+ out.println();
+ out.println(" /** Constructor */");
+ out.println(" " + pre("actions") + "("+parser_class_name+" parser) {");
+ out.println(" this.parser = parser;");
+ out.println(" }");
+
+ /* action method head */
+ out.println();
+ out.println(" /** Method with the actual generated action code. */");
+ out.println(" public final java_cup.runtime.Symbol " +
+ pre("do_action") + "(");
+ out.println(" int " + pre("act_num,"));
+ out.println(" java_cup.runtime.lr_parser " + pre("parser,"));
+ out.println(" java.util.Stack " + pre("stack,"));
+ out.println(" int " + pre("top)"));
+ out.println(" throws java.lang.Exception");
+ out.println(" {");
+
+ /* declaration of result symbol */
+ /* New declaration!! now return Symbol
+ 6/13/96 frankf */
+ out.println(" /* Symbol object for return from actions */");
+ out.println(" java_cup.runtime.Symbol " + pre("result") + ";");
+ out.println();
+
+ /* switch top */
+ out.println(" /* select the action based on the action number */");
+ out.println(" switch (" + pre("act_num") + ")");
+ out.println(" {");
+
+ /* emit action code for each production as a separate case */
+ for (Enumeration p = production.all(); p.hasMoreElements(); )
+ {
+ prod = (production)p.nextElement();
+
+ /* case label */
+ out.println(" /*. . . . . . . . . . . . . . . . . . . .*/");
+ out.println(" case " + prod.index() + ": // " +
+ prod.to_simple_string());
+
+ /* give them their own block to work in */
+ out.println(" {");
+
+ /* create the result symbol */
+ /*make the variable RESULT which will point to the new Symbol (see below)
+ and be changed by action code
+ 6/13/96 frankf */
+ out.println(" " + prod.lhs().the_symbol().stack_type() +
+ " RESULT = null;");
+
+ /* Add code to propagate RESULT assignments that occur in
+ * action code embedded in a production (ie, non-rightmost
+ * action code). 24-Mar-1998 CSA
+ */
+ for (int i=0; i<prod.rhs_length(); i++) {
+ // only interested in non-terminal symbols.
+ if (!(prod.rhs(i) instanceof symbol_part)) continue;
+ symbol s = ((symbol_part)prod.rhs(i)).the_symbol();
+ if (!(s instanceof non_terminal)) continue;
+ // skip this non-terminal unless it corresponds to
+ // an embedded action production.
+ if (((non_terminal)s).is_embedded_action == false) continue;
+ // OK, it fits. Make a conditional assignment to RESULT.
+ int index = prod.rhs_length() - i - 1; // last rhs is on top.
+ out.println(" " + "// propagate RESULT from " +
+ s.name());
+ out.println(" " + "if ( " +
+ "((java_cup.runtime.Symbol) " + emit.pre("stack") + ".elementAt("
+ + emit.pre("top") + "-" + index + ")).value != null )");
+ out.println(" " + "RESULT = " +
+ "(" + prod.lhs().the_symbol().stack_type() + ") " +
+ "((java_cup.runtime.Symbol) " + emit.pre("stack") + ".elementAt("
+ + emit.pre("top") + "-" + index + ")).value;");
+ }
+
+ /* if there is an action string, emit it */
+ if (prod.action() != null && prod.action().code_string() != null &&
+ !prod.action().equals(""))
+ out.println(prod.action().code_string());
+
+ /* here we have the left and right values being propagated.
+ must make this a command line option.
+ frankf 6/18/96 */
+
+ /* Create the code that assigns the left and right values of
+ the new Symbol that the production is reducing to */
+ if (emit.lr_values()) {
+ int loffset;
+ String leftstring, rightstring;
+ int roffset = 0;
+ rightstring = "((java_cup.runtime.Symbol)" + emit.pre("stack") + ".elementAt(" +
+ emit.pre("top") + "-" + roffset + ")).right";
+ if (prod.rhs_length() == 0)
+ leftstring = rightstring;
+ else {
+ loffset = prod.rhs_length() - 1;
+ leftstring = "((java_cup.runtime.Symbol)" + emit.pre("stack") + ".elementAt(" +
+ emit.pre("top") + "-" + loffset + ")).left";
+ }
+ out.println(" " + pre("result") + " = new java_cup.runtime.Symbol(" +
+ prod.lhs().the_symbol().index() + "/*" +
+ prod.lhs().the_symbol().name() + "*/" +
+ ", " + leftstring + ", " + rightstring + ", RESULT);");
+ } else {
+ out.println(" " + pre("result") + " = new java_cup.runtime.Symbol(" +
+ prod.lhs().the_symbol().index() + "/*" +
+ prod.lhs().the_symbol().name() + "*/" +
+ ", RESULT);");
+ }
+
+ /* end of their block */
+ out.println(" }");
+
+ /* if this was the start production, do action for accept */
+ if (prod == start_prod)
+ {
+ out.println(" /* ACCEPT */");
+ out.println(" " + pre("parser") + ".done_parsing();");
+ }
+
+ /* code to return lhs symbol */
+ out.println(" return " + pre("result") + ";");
+ out.println();
+ }
+
+ /* end of switch */
+ out.println(" /* . . . . . .*/");
+ out.println(" default:");
+ out.println(" throw new Exception(");
+ out.println(" \"Invalid action number found in " +
+ "internal parse table\");");
+ out.println();
+ out.println(" }");
+
+ /* end of method */
+ out.println(" }");
+
+ /* end of class */
+ out.println("}");
+ out.println();
+
+ action_code_time = System.currentTimeMillis() - start_time;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Emit the production table.
+ * @param out stream to produce output on.
+ */
+ protected static void emit_production_table(PrintWriter out)
+ {
+ production all_prods[];
+ production prod;
+
+ long start_time = System.currentTimeMillis();
+
+ /* collect up the productions in order */
+ all_prods = new production[production.number()];
+ for (Enumeration p = production.all(); p.hasMoreElements(); )
+ {
+ prod = (production)p.nextElement();
+ all_prods[prod.index()] = prod;
+ }
+
+ // make short[][]
+ short[][] prod_table = new short[production.number()][2];
+ for (int i = 0; i<production.number(); i++)
+ {
+ prod = all_prods[i];
+ // { lhs symbol , rhs size }
+ prod_table[i][0] = (short) prod.lhs().the_symbol().index();
+ prod_table[i][1] = (short) prod.rhs_length();
+ }
+ /* do the top of the table */
+ out.println();
+ out.println(" /** Production table. */");
+ out.println(" protected static final short _production_table[][] = ");
+ out.print (" unpackFromStrings(");
+ do_table_as_string(out, prod_table);
+ out.println(");");
+
+ /* do the public accessor method */
+ out.println();
+ out.println(" /** Access to production table. */");
+ out.println(" public short[][] production_table() " +
+ "{return _production_table;}");
+
+ production_table_time = System.currentTimeMillis() - start_time;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Emit the action table.
+ * @param out stream to produce output on.
+ * @param act_tab the internal representation of the action table.
+ * @param compact_reduces do we use the most frequent reduce as default?
+ */
+ protected static void do_action_table(
+ PrintWriter out,
+ parse_action_table act_tab,
+ boolean compact_reduces)
+ throws internal_error
+ {
+ parse_action_row row;
+ parse_action act;
+ int red;
+
+ long start_time = System.currentTimeMillis();
+
+ /* collect values for the action table */
+ short[][] action_table = new short[act_tab.num_states()][];
+ /* do each state (row) of the action table */
+ for (int i = 0; i < act_tab.num_states(); i++)
+ {
+ /* get the row */
+ row = act_tab.under_state[i];
+
+ /* determine the default for the row */
+ if (compact_reduces)
+ row.compute_default();
+ else
+ row.default_reduce = -1;
+
+ /* make temporary table for the row. */
+ short[] temp_table = new short[2*row.size()];
+ int nentries = 0;
+
+ /* do each column */
+ for (int j = 0; j < row.size(); j++)
+ {
+ /* extract the action from the table */
+ act = row.under_term[j];
+
+ /* skip error entries these are all defaulted out */
+ if (act.kind() != parse_action.ERROR)
+ {
+ /* first put in the symbol index, then the actual entry */
+
+ /* shifts get positive entries of state number + 1 */
+ if (act.kind() == parse_action.SHIFT)
+ {
+ /* make entry */
+ temp_table[nentries++] = (short) j;
+ temp_table[nentries++] = (short)
+ (((shift_action)act).shift_to().index() + 1);
+ }
+
+ /* reduce actions get negated entries of production# + 1 */
+ else if (act.kind() == parse_action.REDUCE)
+ {
+ /* if its the default entry let it get defaulted out */
+ red = ((reduce_action)act).reduce_with().index();
+ if (red != row.default_reduce) {
+ /* make entry */
+ temp_table[nentries++] = (short) j;
+ temp_table[nentries++] = (short) (-(red+1));
+ }
+ } else if (act.kind() == parse_action.NONASSOC)
+ {
+ /* do nothing, since we just want a syntax error */
+ }
+ /* shouldn't be anything else */
+ else
+ throw new internal_error("Unrecognized action code " +
+ act.kind() + " found in parse table");
+ }
+ }
+
+ /* now we know how big to make the row */
+ action_table[i] = new short[nentries + 2];
+ System.arraycopy(temp_table, 0, action_table[i], 0, nentries);
+
+ /* finish off the row with a default entry */
+ action_table[i][nentries++] = -1;
+ if (row.default_reduce != -1)
+ action_table[i][nentries++] = (short) (-(row.default_reduce+1));
+ else
+ action_table[i][nentries++] = 0;
+ }
+
+ /* finish off the init of the table */
+ out.println();
+ out.println(" /** Parse-action table. */");
+ out.println(" protected static final short[][] _action_table = ");
+ out.print (" unpackFromStrings(");
+ do_table_as_string(out, action_table);
+ out.println(");");
+
+ /* do the public accessor method */
+ out.println();
+ out.println(" /** Access to parse-action table. */");
+ out.println(" public short[][] action_table() {return _action_table;}");
+
+ action_table_time = System.currentTimeMillis() - start_time;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Emit the reduce-goto table.
+ * @param out stream to produce output on.
+ * @param red_tab the internal representation of the reduce-goto table.
+ */
+ protected static void do_reduce_table(
+ PrintWriter out,
+ parse_reduce_table red_tab)
+ {
+ lalr_state goto_st;
+ parse_action act;
+
+ long start_time = System.currentTimeMillis();
+
+ /* collect values for reduce-goto table */
+ short[][] reduce_goto_table = new short[red_tab.num_states()][];
+ /* do each row of the reduce-goto table */
+ for (int i=0; i<red_tab.num_states(); i++)
+ {
+ /* make temporary table for the row. */
+ short[] temp_table = new short[2*red_tab.under_state[i].size()];
+ int nentries = 0;
+ /* do each entry in the row */
+ for (int j=0; j<red_tab.under_state[i].size(); j++)
+ {
+ /* get the entry */
+ goto_st = red_tab.under_state[i].under_non_term[j];
+
+ /* if we have none, skip it */
+ if (goto_st != null)
+ {
+ /* make entries for the index and the value */
+ temp_table[nentries++] = (short) j;
+ temp_table[nentries++] = (short) goto_st.index();
+ }
+ }
+ /* now we know how big to make the row. */
+ reduce_goto_table[i] = new short[nentries+2];
+ System.arraycopy(temp_table, 0, reduce_goto_table[i], 0, nentries);
+
+ /* end row with default value */
+ reduce_goto_table[i][nentries++] = -1;
+ reduce_goto_table[i][nentries++] = -1;
+ }
+
+ /* emit the table. */
+ out.println();
+ out.println(" /** <code>reduce_goto</code> table. */");
+ out.println(" protected static final short[][] _reduce_table = ");
+ out.print (" unpackFromStrings(");
+ do_table_as_string(out, reduce_goto_table);
+ out.println(");");
+
+ /* do the public accessor method */
+ out.println();
+ out.println(" /** Access to <code>reduce_goto</code> table. */");
+ out.println(" public short[][] reduce_table() {return _reduce_table;}");
+ out.println();
+
+ goto_table_time = System.currentTimeMillis() - start_time;
+ }
+
+ // print a string array encoding the given short[][] array.
+ protected static void do_table_as_string(PrintWriter out, short[][] sa) {
+ out.println("new String[] {");
+ out.print(" \"");
+ int nchar=0, nbytes=0;
+ nbytes+=do_escaped(out, (char)(sa.length>>16));
+ nchar =do_newline(out, nchar, nbytes);
+ nbytes+=do_escaped(out, (char)(sa.length&0xFFFF));
+ nchar =do_newline(out, nchar, nbytes);
+ for (int i=0; i<sa.length; i++) {
+ nbytes+=do_escaped(out, (char)(sa[i].length>>16));
+ nchar =do_newline(out, nchar, nbytes);
+ nbytes+=do_escaped(out, (char)(sa[i].length&0xFFFF));
+ nchar =do_newline(out, nchar, nbytes);
+ for (int j=0; j<sa[i].length; j++) {
+ // contents of string are (value+2) to allow for common -1, 0 cases
+ // (UTF-8 encoding is most efficient for 0<c<0x80)
+ nbytes+=do_escaped(out, (char)(2+sa[i][j]));
+ nchar =do_newline(out, nchar, nbytes);
+ }
+ }
+ out.print("\" }");
+ }
+ // split string if it is very long; start new line occasionally for neatness
+ protected static int do_newline(PrintWriter out, int nchar, int nbytes) {
+ if (nbytes > 65500) { out.println("\", "); out.print(" \""); }
+ else if (nchar > 11) { out.println("\" +"); out.print(" \""); }
+ else return nchar+1;
+ return 0;
+ }
+ // output an escape sequence for the given character code.
+ protected static int do_escaped(PrintWriter out, char c) {
+ StringBuffer escape = new StringBuffer();
+ if (c <= 0xFF) {
+ escape.append(Integer.toOctalString(c));
+ while(escape.length() < 3) escape.insert(0, '0');
+ } else {
+ escape.append(Integer.toHexString(c));
+ while(escape.length() < 4) escape.insert(0, '0');
+ escape.insert(0, 'u');
+ }
+ escape.insert(0, '\\');
+ out.print(escape.toString());
+
+ // return number of bytes this takes up in UTF-8 encoding.
+ if (c == 0) return 2;
+ if (c >= 0x01 && c <= 0x7F) return 1;
+ if (c >= 0x80 && c <= 0x7FF) return 2;
+ return 3;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Emit the parser subclass with embedded tables.
+ * @param out stream to produce output on.
+ * @param action_table internal representation of the action table.
+ * @param reduce_table internal representation of the reduce-goto table.
+ * @param start_st start state of the parse machine.
+ * @param start_prod start production of the grammar.
+ * @param compact_reduces do we use most frequent reduce as default?
+ * @param suppress_scanner should scanner be suppressed for compatibility?
+ */
+ public static void parser(
+ PrintWriter out,
+ parse_action_table action_table,
+ parse_reduce_table reduce_table,
+ int start_st,
+ production start_prod,
+ boolean compact_reduces,
+ boolean suppress_scanner)
+ throws internal_error
+ {
+ long start_time = System.currentTimeMillis();
+
+ /* top of file */
+ out.println();
+ out.println("//----------------------------------------------------");
+ out.println("// The following code was generated by " +
+ version.title_str);
+ out.println("// " + new Date());
+ out.println("//----------------------------------------------------");
+ out.println();
+ emit_package(out);
+
+ /* user supplied imports */
+ for (int i = 0; i < import_list.size(); i++)
+ out.println("import " + import_list.elementAt(i) + ";");
+
+ /* class header */
+ out.println();
+ out.println("/** "+version.title_str+" generated parser.");
+ out.println(" * @version " + new Date());
+ out.println(" */");
+ out.println("public class " + parser_class_name +
+ " extends java_cup.runtime.lr_parser {");
+
+ /* constructors [CSA/davidm, 24-jul-99] */
+ out.println();
+ out.println(" /** Default constructor. */");
+ out.println(" public " + parser_class_name + "() {super();}");
+ if (!suppress_scanner) {
+ out.println();
+ out.println(" /** Constructor which sets the default scanner. */");
+ out.println(" public " + parser_class_name +
+ "(java_cup.runtime.Scanner s) {super(s);}");
+ }
+
+ /* emit the various tables */
+ emit_production_table(out);
+ do_action_table(out, action_table, compact_reduces);
+ do_reduce_table(out, reduce_table);
+
+ /* instance of the action encapsulation class */
+ out.println(" /** Instance of action encapsulation class. */");
+ out.println(" protected " + pre("actions") + " action_obj;");
+ out.println();
+
+ /* action object initializer */
+ out.println(" /** Action encapsulation object initializer. */");
+ out.println(" protected void init_actions()");
+ out.println(" {");
+ out.println(" action_obj = new " + pre("actions") + "(this);");
+ out.println(" }");
+ out.println();
+
+ /* access to action code */
+ out.println(" /** Invoke a user supplied parse action. */");
+ out.println(" public java_cup.runtime.Symbol do_action(");
+ out.println(" int act_num,");
+ out.println(" java_cup.runtime.lr_parser parser,");
+ out.println(" java.util.Stack stack,");
+ out.println(" int top)");
+ out.println(" throws java.lang.Exception");
+ out.println(" {");
+ out.println(" /* call code in generated class */");
+ out.println(" return action_obj." + pre("do_action(") +
+ "act_num, parser, stack, top);");
+ out.println(" }");
+ out.println("");
+
+
+ /* method to tell the parser about the start state */
+ out.println(" /** Indicates start state. */");
+ out.println(" public int start_state() {return " + start_st + ";}");
+
+ /* method to indicate start production */
+ out.println(" /** Indicates start production. */");
+ out.println(" public int start_production() {return " +
+ start_production.index() + ";}");
+ out.println();
+
+ /* methods to indicate EOF and error symbol indexes */
+ out.println(" /** <code>EOF</code> Symbol index. */");
+ out.println(" public int EOF_sym() {return " + terminal.EOF.index() +
+ ";}");
+ out.println();
+ out.println(" /** <code>error</code> Symbol index. */");
+ out.println(" public int error_sym() {return " + terminal.error.index() +
+ ";}");
+ out.println();
+
+ /* user supplied code for user_init() */
+ if (init_code != null)
+ {
+ out.println();
+ out.println(" /** User initialization code. */");
+ out.println(" public void user_init() throws java.lang.Exception");
+ out.println(" {");
+ out.println(init_code);
+ out.println(" }");
+ }
+
+ /* user supplied code for scan */
+ if (scan_code != null)
+ {
+ out.println();
+ out.println(" /** Scan to get the next Symbol. */");
+ out.println(" public java_cup.runtime.Symbol scan()");
+ out.println(" throws java.lang.Exception");
+ out.println(" {");
+ out.println(scan_code);
+ out.println(" }");
+ }
+
+ /* user supplied code */
+ if (parser_code != null)
+ {
+ out.println();
+ out.println(parser_code);
+ }
+
+ /* end of class */
+ out.println("}");
+
+ /* put out the action code class */
+ emit_action_code(out, start_prod);
+
+ parser_time = System.currentTimeMillis() - start_time;
+ }
+
+ /*-----------------------------------------------------------*/
+}
diff --git a/src/syntaxParser/java_cup/internal_error.class b/src/syntaxParser/java_cup/internal_error.class
new file mode 100644
index 0000000..77c69e1
--- /dev/null
+++ b/src/syntaxParser/java_cup/internal_error.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/internal_error.java b/src/syntaxParser/java_cup/internal_error.java
new file mode 100644
index 0000000..4d3e7c2
--- /dev/null
+++ b/src/syntaxParser/java_cup/internal_error.java
@@ -0,0 +1,22 @@
+
+package java_cup;
+
+/** Exception subclass for reporting internal errors in JavaCup. */
+public class internal_error extends Exception
+ {
+ /** Constructor with a message */
+ public internal_error(String msg)
+ {
+ super(msg);
+ }
+
+ /** Method called to do a forced error exit on an internal error
+ for cases when we can't actually throw the exception. */
+ public void crash()
+ {
+ System.err.println("JavaCUP Fatal Internal Error Detected");
+ System.err.println(getMessage());
+ printStackTrace();
+ System.exit(-1);
+ }
+ }
diff --git a/src/syntaxParser/java_cup/lalr_item.class b/src/syntaxParser/java_cup/lalr_item.class
new file mode 100644
index 0000000..2d539f9
--- /dev/null
+++ b/src/syntaxParser/java_cup/lalr_item.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/lalr_item.java b/src/syntaxParser/java_cup/lalr_item.java
new file mode 100644
index 0000000..fe92054
--- /dev/null
+++ b/src/syntaxParser/java_cup/lalr_item.java
@@ -0,0 +1,330 @@
+package java_cup;
+
+import java.util.Stack;
+import java.util.Enumeration;
+
+/** This class represents an LALR item. Each LALR item consists of
+ * a production, a "dot" at a position within that production, and
+ * a set of lookahead symbols (terminal). (The first two of these parts
+ * are provide by the super class). An item is designed to represent a
+ * configuration that the parser may be in. For example, an item of the
+ * form: <pre>
+ * [A ::= B * C d E , {a,b,c}]
+ * </pre>
+ * indicates that the parser is in the middle of parsing the production <pre>
+ * A ::= B C d E
+ * </pre>
+ * that B has already been parsed, and that we will expect to see a lookahead
+ * of either a, b, or c once the complete RHS of this production has been
+ * found.<p>
+ *
+ * Items may initially be missing some items from their lookahead sets.
+ * Links are maintained from each item to the set of items that would need
+ * to be updated if symbols are added to its lookahead set. During
+ * "lookahead propagation", we add symbols to various lookahead sets and
+ * propagate these changes across these dependency links as needed.
+ *
+ * @see java_cup.lalr_item_set
+ * @see java_cup.lalr_state
+ * @version last updated: 11/25/95
+ * @author Scott Hudson
+ */
+public class lalr_item extends lr_item_core {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Full constructor.
+ * @param prod the production for the item.
+ * @param pos the position of the "dot" within the production.
+ * @param look the set of lookahead symbols.
+ */
+ public lalr_item(production prod, int pos, terminal_set look)
+ throws internal_error
+ {
+ super(prod, pos);
+ _lookahead = look;
+ _propagate_items = new Stack();
+ needs_propagation = true;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Constructor with default position (dot at start).
+ * @param prod the production for the item.
+ * @param look the set of lookahead symbols.
+ */
+ public lalr_item(production prod, terminal_set look) throws internal_error
+ {
+ this(prod,0,look);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Constructor with default position and empty lookahead set.
+ * @param prod the production for the item.
+ */
+ public lalr_item(production prod) throws internal_error
+ {
+ this(prod,0,new terminal_set());
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** The lookahead symbols of the item. */
+ protected terminal_set _lookahead;
+
+ /** The lookahead symbols of the item. */
+ public terminal_set lookahead() {return _lookahead;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Links to items that the lookahead needs to be propagated to. */
+ protected Stack _propagate_items;
+
+ /** Links to items that the lookahead needs to be propagated to */
+ public Stack propagate_items() {return _propagate_items;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Flag to indicate that this item needs to propagate its lookahead
+ * (whether it has changed or not).
+ */
+ protected boolean needs_propagation;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Add a new item to the set of items we propagate to. */
+ public void add_propagate(lalr_item prop_to)
+ {
+ _propagate_items.push(prop_to);
+ needs_propagation = true;
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Propagate incoming lookaheads through this item to others need to
+ * be changed.
+ * @params incoming symbols to potentially be added to lookahead of this item.
+ */
+ public void propagate_lookaheads(terminal_set incoming) throws internal_error
+ {
+ boolean change = false;
+
+ /* if we don't need to propagate, then bail out now */
+ if (!needs_propagation && (incoming == null || incoming.empty()))
+ return;
+
+ /* if we have null incoming, treat as an empty set */
+ if (incoming != null)
+ {
+ /* add the incoming to the lookahead of this item */
+ change = lookahead().add(incoming);
+ }
+
+ /* if we changed or need it anyway, propagate across our links */
+ if (change || needs_propagation)
+ {
+ /* don't need to propagate again */
+ needs_propagation = false;
+
+ /* propagate our lookahead into each item we are linked to */
+ for (int i = 0; i < propagate_items().size(); i++)
+ ((lalr_item)propagate_items().elementAt(i))
+ .propagate_lookaheads(lookahead());
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Produce the new lalr_item that results from shifting the dot one position
+ * to the right.
+ */
+ public lalr_item shift() throws internal_error
+ {
+ lalr_item result;
+
+ /* can't shift if we have dot already at the end */
+ if (dot_at_end())
+ throw new internal_error("Attempt to shift past end of an lalr_item");
+
+ /* create the new item w/ the dot shifted by one */
+ result = new lalr_item(the_production(), dot_pos()+1,
+ new terminal_set(lookahead()));
+
+ /* change in our lookahead needs to be propagated to this item */
+ add_propagate(result);
+
+ return result;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Calculate lookahead representing symbols that could appear after the
+ * symbol that the dot is currently in front of. Note: this routine must
+ * not be invoked before first sets and nullability has been calculated
+ * for all non terminals.
+ */
+ public terminal_set calc_lookahead(terminal_set lookahead_after)
+ throws internal_error
+ {
+ terminal_set result;
+ int pos;
+ production_part part;
+ symbol sym;
+
+ /* sanity check */
+ if (dot_at_end())
+ throw new internal_error(
+ "Attempt to calculate a lookahead set with a completed item");
+
+ /* start with an empty result */
+ result = new terminal_set();
+
+ /* consider all nullable symbols after the one to the right of the dot */
+ for (pos = dot_pos()+1; pos < the_production().rhs_length(); pos++)
+ {
+ part = the_production().rhs(pos);
+
+ /* consider what kind of production part it is -- skip actions */
+ if (!part.is_action())
+ {
+ sym = ((symbol_part)part).the_symbol();
+
+ /* if its a terminal add it in and we are done */
+ if (!sym.is_non_term())
+ {
+ result.add((terminal)sym);
+ return result;
+ }
+ else
+ {
+ /* otherwise add in first set of the non terminal */
+ result.add(((non_terminal)sym).first_set());
+
+ /* if its nullable we continue adding, if not, we are done */
+ if (!((non_terminal)sym).nullable())
+ return result;
+ }
+ }
+ }
+
+ /* if we get here everything past the dot was nullable
+ we add in the lookahead for after the production and we are done */
+ result.add(lookahead_after);
+ return result;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Determine if everything from the symbol one beyond the dot all the
+ * way to the end of the right hand side is nullable. This would indicate
+ * that the lookahead of this item must be included in the lookaheads of
+ * all items produced as a closure of this item. Note: this routine should
+ * not be invoked until after first sets and nullability have been
+ * calculated for all non terminals.
+ */
+ public boolean lookahead_visible() throws internal_error
+ {
+ production_part part;
+ symbol sym;
+
+ /* if the dot is at the end, we have a problem, but the cleanest thing
+ to do is just return true. */
+ if (dot_at_end()) return true;
+
+ /* walk down the rhs and bail if we get a non-nullable symbol */
+ for (int pos = dot_pos() + 1; pos < the_production().rhs_length(); pos++)
+ {
+ part = the_production().rhs(pos);
+
+ /* skip actions */
+ if (!part.is_action())
+ {
+ sym = ((symbol_part)part).the_symbol();
+
+ /* if its a terminal we fail */
+ if (!sym.is_non_term()) return false;
+
+ /* if its not nullable we fail */
+ if (!((non_terminal)sym).nullable()) return false;
+ }
+ }
+
+ /* if we get here its all nullable */
+ return true;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Equality comparison -- here we only require the cores to be equal since
+ * we need to do sets of items based only on core equality (ignoring
+ * lookahead sets).
+ */
+ public boolean equals(lalr_item other)
+ {
+ if (other == null) return false;
+ return super.equals(other);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Generic equality comparison. */
+ public boolean equals(Object other)
+ {
+ if (!(other instanceof lalr_item))
+ return false;
+ else
+ return equals((lalr_item)other);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Return a hash code -- here we only hash the core since we only test core
+ * matching in LALR items.
+ */
+ public int hashCode()
+ {
+ return super.hashCode();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to string. */
+ public String toString()
+ {
+ String result = "";
+
+ // additional output for debugging:
+ // result += "(" + obj_hash() + ")";
+ result += "[";
+ result += super.toString();
+ result += ", ";
+ if (lookahead() != null)
+ {
+ result += "{";
+ for (int t = 0; t < terminal.number(); t++)
+ if (lookahead().contains(t))
+ result += terminal.find(t).name() + " ";
+ result += "}";
+ }
+ else
+ result += "NULL LOOKAHEAD!!";
+ result += "]";
+
+ // additional output for debugging:
+ // result += " -> ";
+ // for (int i = 0; i<propagate_items().size(); i++)
+ // result+=((lalr_item)(propagate_items().elementAt(i))).obj_hash()+" ";
+ //
+ // if (needs_propagation) result += " NP";
+
+ return result;
+ }
+ /*-----------------------------------------------------------*/
+}
diff --git a/src/syntaxParser/java_cup/lalr_item_set.class b/src/syntaxParser/java_cup/lalr_item_set.class
new file mode 100644
index 0000000..ff55488
--- /dev/null
+++ b/src/syntaxParser/java_cup/lalr_item_set.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/lalr_item_set.java b/src/syntaxParser/java_cup/lalr_item_set.java
new file mode 100644
index 0000000..233a68f
--- /dev/null
+++ b/src/syntaxParser/java_cup/lalr_item_set.java
@@ -0,0 +1,371 @@
+
+package java_cup;
+
+import java.util.Hashtable;
+import java.util.Enumeration;
+
+/** This class represents a set of LALR items. For purposes of building
+ * these sets, items are considered unique only if they have unique cores
+ * (i.e., ignoring differences in their lookahead sets).<p>
+ *
+ * This class provides fairly conventional set oriented operations (union,
+ * sub/super-set tests, etc.), as well as an LALR "closure" operation (see
+ * compute_closure()).
+ *
+ * @see java_cup.lalr_item
+ * @see java_cup.lalr_state
+ * @version last updated: 3/6/96
+ * @author Scott Hudson
+ */
+
+public class lalr_item_set {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Constructor for an empty set. */
+ public lalr_item_set() { }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Constructor for cloning from another set.
+ * @param other indicates set we should copy from.
+ */
+ public lalr_item_set(lalr_item_set other)
+ throws internal_error
+ {
+ not_null(other);
+ _all = (Hashtable)other._all.clone();
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** A hash table to implement the set. We store the items using themselves
+ * as keys.
+ */
+ protected Hashtable _all = new Hashtable(11);
+
+ /** Access to all elements of the set. */
+ public Enumeration all() {return _all.elements();}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Cached hashcode for this set. */
+ protected Integer hashcode_cache = null;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Size of the set */
+ public int size() {return _all.size();}
+
+ /*-----------------------------------------------------------*/
+ /*--- Set Operation Methods ---------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Does the set contain a particular item?
+ * @param itm the item in question.
+ */
+ public boolean contains(lalr_item itm) {return _all.containsKey(itm);}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Return the item in the set matching a particular item (or null if not
+ * found)
+ * @param itm the item we are looking for.
+ */
+ public lalr_item find(lalr_item itm) {return (lalr_item)_all.get(itm);}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Is this set an (improper) subset of another?
+ * @param other the other set in question.
+ */
+ public boolean is_subset_of(lalr_item_set other) throws internal_error
+ {
+ not_null(other);
+
+ /* walk down our set and make sure every element is in the other */
+ for (Enumeration e = all(); e.hasMoreElements(); )
+ if (!other.contains((lalr_item)e.nextElement()))
+ return false;
+
+ /* they were all there */
+ return true;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Is this set an (improper) superset of another?
+ * @param other the other set in question.
+ */
+ public boolean is_superset_of(lalr_item_set other) throws internal_error
+ {
+ not_null(other);
+ return other.is_subset_of(this);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Add a singleton item, merging lookahead sets if the item is already
+ * part of the set. returns the element of the set that was added or
+ * merged into.
+ * @param itm the item being added.
+ */
+ public lalr_item add(lalr_item itm) throws internal_error
+ {
+ lalr_item other;
+
+ not_null(itm);
+
+ /* see if an item with a matching core is already there */
+ other = (lalr_item)_all.get(itm);
+
+ /* if so, merge this lookahead into the original and leave it */
+ if (other != null)
+ {
+ other.lookahead().add(itm.lookahead());
+ return other;
+ }
+ /* otherwise we just go in the set */
+ else
+ {
+ /* invalidate cached hashcode */
+ hashcode_cache = null;
+
+ _all.put(itm,itm);
+ return itm;
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Remove a single item if it is in the set.
+ * @param itm the item to remove.
+ */
+ public void remove(lalr_item itm) throws internal_error
+ {
+ not_null(itm);
+
+ /* invalidate cached hashcode */
+ hashcode_cache = null;
+
+ /* remove it from hash table implementing set */
+ _all.remove(itm);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Add a complete set, merging lookaheads where items are already in
+ * the set
+ * @param other the set to be added.
+ */
+ public void add(lalr_item_set other) throws internal_error
+ {
+ not_null(other);
+
+ /* walk down the other set and do the adds individually */
+ for (Enumeration e = other.all(); e.hasMoreElements(); )
+ add((lalr_item)e.nextElement());
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Remove (set subtract) a complete set.
+ * @param other the set to remove.
+ */
+ public void remove(lalr_item_set other) throws internal_error
+ {
+ not_null(other);
+
+ /* walk down the other set and do the removes individually */
+ for (Enumeration e = other.all(); e.hasMoreElements(); )
+ remove((lalr_item)e.nextElement());
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Remove and return one item from the set (done in hash order). */
+ public lalr_item get_one() throws internal_error
+ {
+ Enumeration the_set;
+ lalr_item result;
+
+ the_set = all();
+ if (the_set.hasMoreElements())
+ {
+ result = (lalr_item)the_set.nextElement();
+ remove(result);
+ return result;
+ }
+ else
+ return null;
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Helper function for null test. Throws an interal_error exception if its
+ * parameter is null.
+ * @param obj the object we are testing.
+ */
+ protected void not_null(Object obj) throws internal_error
+ {
+ if (obj == null)
+ throw new internal_error("Null object used in set operation");
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Compute the closure of the set using the LALR closure rules. Basically
+ * for every item of the form: <pre>
+ * [L ::= a *N alpha, l]
+ * </pre>
+ * (where N is a a non terminal and alpha is a string of symbols) make
+ * sure there are also items of the form: <pre>
+ * [N ::= *beta, first(alpha l)]
+ * </pre>
+ * corresponding to each production of N. Items with identical cores but
+ * differing lookahead sets are merged by creating a new item with the same
+ * core and the union of the lookahead sets (the LA in LALR stands for
+ * "lookahead merged" and this is where the merger is). This routine
+ * assumes that nullability and first sets have been computed for all
+ * productions before it is called.
+ */
+ public void compute_closure()
+ throws internal_error
+ {
+ lalr_item_set consider;
+ lalr_item itm, new_itm, add_itm;
+ non_terminal nt;
+ terminal_set new_lookaheads;
+ Enumeration p;
+ production prod;
+ boolean need_prop;
+
+
+
+ /* invalidate cached hashcode */
+ hashcode_cache = null;
+
+ /* each current element needs to be considered */
+ consider = new lalr_item_set(this);
+
+ /* repeat this until there is nothing else to consider */
+ while (consider.size() > 0)
+ {
+ /* get one item to consider */
+ itm = consider.get_one();
+
+ /* do we have a dot before a non terminal */
+ nt = itm.dot_before_nt();
+ if (nt != null)
+ {
+ /* create the lookahead set based on first after dot */
+ new_lookaheads = itm.calc_lookahead(itm.lookahead());
+
+ /* are we going to need to propagate our lookahead to new item */
+ need_prop = itm.lookahead_visible();
+
+ /* create items for each production of that non term */
+ for (p = nt.productions(); p.hasMoreElements(); )
+ {
+ prod = (production)p.nextElement();
+
+ /* create new item with dot at start and that lookahead */
+ new_itm = new lalr_item(prod,
+ new terminal_set(new_lookaheads));
+
+ /* add/merge item into the set */
+ add_itm = add(new_itm);
+ /* if propagation is needed link to that item */
+ if (need_prop)
+ itm.add_propagate(add_itm);
+
+ /* was this was a new item*/
+ if (add_itm == new_itm)
+ {
+ /* that may need further closure, consider it also */
+ consider.add(new_itm);
+ }
+ }
+ }
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Equality comparison. */
+ public boolean equals(lalr_item_set other)
+ {
+ if (other == null || other.size() != size()) return false;
+
+ /* once we know they are the same size, then improper subset does test */
+ try {
+ return is_subset_of(other);
+ } catch (internal_error e) {
+ /* can't throw error from here (because superclass doesn't) so crash */
+ e.crash();
+ return false;
+ }
+
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Generic equality comparison. */
+ public boolean equals(Object other)
+ {
+ if (!(other instanceof lalr_item_set))
+ return false;
+ else
+ return equals((lalr_item_set)other);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Return hash code. */
+ public int hashCode()
+ {
+ int result = 0;
+ Enumeration e;
+ int cnt;
+
+ /* only compute a new one if we don't have it cached */
+ if (hashcode_cache == null)
+ {
+ /* hash together codes from at most first 5 elements */
+ // CSA fix! we'd *like* to hash just a few elements, but
+ // that means equal sets will have inequal hashcodes, which
+ // we're not allowed (by contract) to do. So hash them all.
+ for (e = all(), cnt=0 ; e.hasMoreElements() /*&& cnt<5*/; cnt++)
+ result ^= ((lalr_item)e.nextElement()).hashCode();
+
+ hashcode_cache = new Integer(result);
+ }
+
+ return hashcode_cache.intValue();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to string. */
+ public String toString()
+ {
+ StringBuffer result = new StringBuffer();
+
+ result.append("{\n");
+ for (Enumeration e=all(); e.hasMoreElements(); )
+ {
+ result.append(" " + (lalr_item)e.nextElement() + "\n");
+ }
+ result.append("}");
+
+ return result.toString();
+ }
+ /*-----------------------------------------------------------*/
+}
+
diff --git a/src/syntaxParser/java_cup/lalr_state.class b/src/syntaxParser/java_cup/lalr_state.class
new file mode 100644
index 0000000..ce9b2bd
--- /dev/null
+++ b/src/syntaxParser/java_cup/lalr_state.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/lalr_state.java b/src/syntaxParser/java_cup/lalr_state.java
new file mode 100644
index 0000000..5298e87
--- /dev/null
+++ b/src/syntaxParser/java_cup/lalr_state.java
@@ -0,0 +1,884 @@
+
+package java_cup;
+
+import java.util.Hashtable;
+import java.util.Enumeration;
+import java.util.Stack;
+
+/** This class represents a state in the LALR viable prefix recognition machine.
+ * A state consists of an LALR item set and a set of transitions to other
+ * states under terminal and non-terminal symbols. Each state represents
+ * a potential configuration of the parser. If the item set of a state
+ * includes an item such as: <pre>
+ * [A ::= B * C d E , {a,b,c}]
+ * </pre>
+ * this indicates that when the parser is in this state it is currently
+ * looking for an A of the given form, has already seen the B, and would
+ * expect to see an a, b, or c after this sequence is complete. Note that
+ * the parser is normally looking for several things at once (represented
+ * by several items). In our example above, the state would also include
+ * items such as: <pre>
+ * [C ::= * X e Z, {d}]
+ * [X ::= * f, {e}]
+ * </pre>
+ * to indicate that it was currently looking for a C followed by a d (which
+ * would be reduced into a C, matching the first symbol in our production
+ * above), and the terminal f followed by e.<p>
+ *
+ * At runtime, the parser uses a viable prefix recognition machine made up
+ * of these states to parse. The parser has two operations, shift and reduce.
+ * In a shift, it consumes one Symbol and makes a transition to a new state.
+ * This corresponds to "moving the dot past" a terminal in one or more items
+ * in the state (these new shifted items will then be found in the state at
+ * the end of the transition). For a reduce operation, the parser is
+ * signifying that it is recognizing the RHS of some production. To do this
+ * it first "backs up" by popping a stack of previously saved states. It
+ * pops off the same number of states as are found in the RHS of the
+ * production. This leaves the machine in the same state is was in when the
+ * parser first attempted to find the RHS. From this state it makes a
+ * transition based on the non-terminal on the LHS of the production. This
+ * corresponds to placing the parse in a configuration equivalent to having
+ * replaced all the symbols from the the input corresponding to the RHS with
+ * the symbol on the LHS.
+ *
+ * @see java_cup.lalr_item
+ * @see java_cup.lalr_item_set
+ * @see java_cup.lalr_transition
+ * @version last updated: 7/3/96
+ * @author Frank Flannery
+ *
+ */
+
+public class lalr_state {
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Constructor for building a state from a set of items.
+ * @param itms the set of items that makes up this state.
+ */
+ public lalr_state(lalr_item_set itms) throws internal_error
+ {
+ /* don't allow null or duplicate item sets */
+ if (itms == null)
+ throw new internal_error(
+ "Attempt to construct an LALR state from a null item set");
+
+ if (find_state(itms) != null)
+ throw new internal_error(
+ "Attempt to construct a duplicate LALR state");
+
+ /* assign a unique index */
+ _index = next_index++;
+
+ /* store the items */
+ _items = itms;
+
+ /* add to the global collection, keyed with its item set */
+ _all.put(_items,this);
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Static (Class) Variables ------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Collection of all states. */
+ protected static Hashtable _all = new Hashtable();
+
+ /** Collection of all states. */
+ public static Enumeration all() {return _all.elements();}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Indicate total number of states there are. */
+ public static int number() {return _all.size();}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Hash table to find states by their kernels (i.e, the original,
+ * unclosed, set of items -- which uniquely define the state). This table
+ * stores state objects using (a copy of) their kernel item sets as keys.
+ */
+ protected static Hashtable _all_kernels = new Hashtable();
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Find and return state with a given a kernel item set (or null if not
+ * found). The kernel item set is the subset of items that were used to
+ * originally create the state. These items are formed by "shifting the
+ * dot" within items of other states that have a transition to this one.
+ * The remaining elements of this state's item set are added during closure.
+ * @param itms the kernel set of the state we are looking for.
+ */
+ public static lalr_state find_state(lalr_item_set itms)
+ {
+ if (itms == null)
+ return null;
+ else
+ return (lalr_state)_all.get(itms);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Static counter for assigning unique state indexes. */
+ protected static int next_index = 0;
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** The item set for this state. */
+ protected lalr_item_set _items;
+
+ /** The item set for this state. */
+ public lalr_item_set items() {return _items;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** List of transitions out of this state. */
+ protected lalr_transition _transitions = null;
+
+ /** List of transitions out of this state. */
+ public lalr_transition transitions() {return _transitions;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Index of this state in the parse tables */
+ protected int _index;
+
+ /** Index of this state in the parse tables */
+ public int index() {return _index;}
+
+ /*-----------------------------------------------------------*/
+ /*--- Static Methods ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Helper routine for debugging -- produces a dump of the given state
+ * onto System.out.
+ */
+ protected static void dump_state(lalr_state st) throws internal_error
+ {
+ lalr_item_set itms;
+ lalr_item itm;
+ production_part part;
+
+ if (st == null)
+ {
+ System.out.println("NULL lalr_state");
+ return;
+ }
+
+ System.out.println("lalr_state [" + st.index() + "] {");
+ itms = st.items();
+ for (Enumeration e = itms.all(); e.hasMoreElements(); )
+ {
+ itm = (lalr_item)e.nextElement();
+ System.out.print(" [");
+ System.out.print(itm.the_production().lhs().the_symbol().name());
+ System.out.print(" ::= ");
+ for (int i = 0; i<itm.the_production().rhs_length(); i++)
+ {
+ if (i == itm.dot_pos()) System.out.print("(*) ");
+ part = itm.the_production().rhs(i);
+ if (part.is_action())
+ System.out.print("{action} ");
+ else
+ System.out.print(((symbol_part)part).the_symbol().name() + " ");
+ }
+ if (itm.dot_at_end()) System.out.print("(*) ");
+ System.out.println("]");
+ }
+ System.out.println("}");
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Propagate lookahead sets through the constructed viable prefix
+ * recognizer. When the machine is constructed, each item that results
+ in the creation of another such that its lookahead is included in the
+ other's will have a propagate link set up for it. This allows additions
+ to the lookahead of one item to be included in other items that it
+ was used to directly or indirectly create.
+ */
+ protected static void propagate_all_lookaheads() throws internal_error
+ {
+ /* iterate across all states */
+ for (Enumeration st = all(); st.hasMoreElements(); )
+ {
+ /* propagate lookaheads out of that state */
+ ((lalr_state)st.nextElement()).propagate_lookaheads();
+ }
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Add a transition out of this state to another.
+ * @param on_sym the symbol the transition is under.
+ * @param to_st the state the transition goes to.
+ */
+ public void add_transition(symbol on_sym, lalr_state to_st)
+ throws internal_error
+ {
+ lalr_transition trans;
+
+ /* create a new transition object and put it in our list */
+ trans = new lalr_transition(on_sym, to_st, _transitions);
+ _transitions = trans;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Build an LALR viable prefix recognition machine given a start
+ * production. This method operates by first building a start state
+ * from the start production (based on a single item with the dot at
+ * the beginning and EOF as expected lookahead). Then for each state
+ * it attempts to extend the machine by creating transitions out of
+ * the state to new or existing states. When considering extension
+ * from a state we make a transition on each symbol that appears before
+ * the dot in some item. For example, if we have the items: <pre>
+ * [A ::= a b * X c, {d,e}]
+ * [B ::= a b * X d, {a,b}]
+ * </pre>
+ * in some state, then we would be making a transition under X to a new
+ * state. This new state would be formed by a "kernel" of items
+ * corresponding to moving the dot past the X. In this case: <pre>
+ * [A ::= a b X * c, {d,e}]
+ * [B ::= a b X * Y, {a,b}]
+ * </pre>
+ * The full state would then be formed by "closing" this kernel set of
+ * items so that it included items that represented productions of things
+ * the parser was now looking for. In this case we would items
+ * corresponding to productions of Y, since various forms of Y are expected
+ * next when in this state (see lalr_item_set.compute_closure() for details
+ * on closure). <p>
+ *
+ * The process of building the viable prefix recognizer terminates when no
+ * new states can be added. However, in order to build a smaller number of
+ * states (i.e., corresponding to LALR rather than canonical LR) the state
+ * building process does not maintain full loookaheads in all items.
+ * Consequently, after the machine is built, we go back and propagate
+ * lookaheads through the constructed machine using a call to
+ * propagate_all_lookaheads(). This makes use of propagation links
+ * constructed during the closure and transition process.
+ *
+ * @param start_prod the start production of the grammar
+ * @see java_cup.lalr_item_set#compute_closure
+ * @see java_cup.lalr_state#propagate_all_lookaheads
+ */
+
+ public static lalr_state build_machine(production start_prod)
+ throws internal_error
+ {
+ lalr_state start_state;
+ lalr_item_set start_items;
+ lalr_item_set new_items;
+ lalr_item_set linked_items;
+ lalr_item_set kernel;
+ Stack work_stack = new Stack();
+ lalr_state st, new_st;
+ symbol_set outgoing;
+ lalr_item itm, new_itm, existing, fix_itm;
+ symbol sym, sym2;
+ Enumeration i, s, fix;
+
+ /* sanity check */
+ if (start_prod == null)
+ throw new internal_error(
+ "Attempt to build viable prefix recognizer using a null production");
+
+ /* build item with dot at front of start production and EOF lookahead */
+ start_items = new lalr_item_set();
+
+ itm = new lalr_item(start_prod);
+ itm.lookahead().add(terminal.EOF);
+
+ start_items.add(itm);
+
+ /* create copy the item set to form the kernel */
+ kernel = new lalr_item_set(start_items);
+
+ /* create the closure from that item set */
+ start_items.compute_closure();
+
+ /* build a state out of that item set and put it in our work set */
+ start_state = new lalr_state(start_items);
+ work_stack.push(start_state);
+
+ /* enter the state using the kernel as the key */
+ _all_kernels.put(kernel, start_state);
+
+ /* continue looking at new states until we have no more work to do */
+ while (!work_stack.empty())
+ {
+ /* remove a state from the work set */
+ st = (lalr_state)work_stack.pop();
+
+ /* gather up all the symbols that appear before dots */
+ outgoing = new symbol_set();
+ for (i = st.items().all(); i.hasMoreElements(); )
+ {
+ itm = (lalr_item)i.nextElement();
+
+ /* add the symbol before the dot (if any) to our collection */
+ sym = itm.symbol_after_dot();
+ if (sym != null) outgoing.add(sym);
+ }
+
+ /* now create a transition out for each individual symbol */
+ for (s = outgoing.all(); s.hasMoreElements(); )
+ {
+ sym = (symbol)s.nextElement();
+
+ /* will be keeping the set of items with propagate links */
+ linked_items = new lalr_item_set();
+
+ /* gather up shifted versions of all the items that have this
+ symbol before the dot */
+ new_items = new lalr_item_set();
+ for (i = st.items().all(); i.hasMoreElements();)
+ {
+ itm = (lalr_item)i.nextElement();
+
+ /* if this is the symbol we are working on now, add to set */
+ sym2 = itm.symbol_after_dot();
+ if (sym.equals(sym2))
+ {
+ /* add to the kernel of the new state */
+ new_items.add(itm.shift());
+
+ /* remember that itm has propagate link to it */
+ linked_items.add(itm);
+ }
+ }
+
+ /* use new items as state kernel */
+ kernel = new lalr_item_set(new_items);
+
+ /* have we seen this one already? */
+ new_st = (lalr_state)_all_kernels.get(kernel);
+
+ /* if we haven't, build a new state out of the item set */
+ if (new_st == null)
+ {
+ /* compute closure of the kernel for the full item set */
+ new_items.compute_closure();
+
+ /* build the new state */
+ new_st = new lalr_state(new_items);
+
+ /* add the new state to our work set */
+ work_stack.push(new_st);
+
+ /* put it in our kernel table */
+ _all_kernels.put(kernel, new_st);
+ }
+ /* otherwise relink propagation to items in existing state */
+ else
+ {
+ /* walk through the items that have links to the new state */
+ for (fix = linked_items.all(); fix.hasMoreElements(); )
+ {
+ fix_itm = (lalr_item)fix.nextElement();
+
+ /* look at each propagate link out of that item */
+ for (int l =0; l < fix_itm.propagate_items().size(); l++)
+ {
+ /* pull out item linked to in the new state */
+ new_itm =
+ (lalr_item)fix_itm.propagate_items().elementAt(l);
+
+ /* find corresponding item in the existing state */
+ existing = new_st.items().find(new_itm);
+
+ /* fix up the item so it points to the existing set */
+ if (existing != null)
+ fix_itm.propagate_items().setElementAt(existing ,l);
+ }
+ }
+ }
+
+ /* add a transition from current state to that state */
+ st.add_transition(sym, new_st);
+ }
+ }
+
+ /* all done building states */
+
+ /* propagate complete lookahead sets throughout the states */
+ propagate_all_lookaheads();
+
+ return start_state;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Propagate lookahead sets out of this state. This recursively
+ * propagates to all items that have propagation links from some item
+ * in this state.
+ */
+ protected void propagate_lookaheads() throws internal_error
+ {
+ /* recursively propagate out from each item in the state */
+ for (Enumeration itm = items().all(); itm.hasMoreElements(); )
+ ((lalr_item)itm.nextElement()).propagate_lookaheads(null);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Fill in the parse table entries for this state. There are two
+ * parse tables that encode the viable prefix recognition machine, an
+ * action table and a reduce-goto table. The rows in each table
+ * correspond to states of the machine. The columns of the action table
+ * are indexed by terminal symbols and correspond to either transitions
+ * out of the state (shift entries) or reductions from the state to some
+ * previous state saved on the stack (reduce entries). All entries in the
+ * action table that are not shifts or reduces, represent errors. The
+ * reduce-goto table is indexed by non terminals and represents transitions
+ * out of a state on that non-terminal.<p>
+ * Conflicts occur if more than one action needs to go in one entry of the
+ * action table (this cannot happen with the reduce-goto table). Conflicts
+ * are resolved by always shifting for shift/reduce conflicts and choosing
+ * the lowest numbered production (hence the one that appeared first in
+ * the specification) in reduce/reduce conflicts. All conflicts are
+ * reported and if more conflicts are detected than were declared by the
+ * user, code generation is aborted.
+ *
+ * @param act_table the action table to put entries in.
+ * @param reduce_table the reduce-goto table to put entries in.
+ */
+ public void build_table_entries(
+ parse_action_table act_table,
+ parse_reduce_table reduce_table)
+ throws internal_error
+ {
+ parse_action_row our_act_row;
+ parse_reduce_row our_red_row;
+ lalr_item itm;
+ parse_action act, other_act;
+ symbol sym;
+ terminal_set conflict_set = new terminal_set();
+
+ /* pull out our rows from the tables */
+ our_act_row = act_table.under_state[index()];
+ our_red_row = reduce_table.under_state[index()];
+
+ /* consider each item in our state */
+ for (Enumeration i = items().all(); i.hasMoreElements(); )
+ {
+ itm = (lalr_item)i.nextElement();
+
+
+ /* if its completed (dot at end) then reduce under the lookahead */
+ if (itm.dot_at_end())
+ {
+ act = new reduce_action(itm.the_production());
+
+ /* consider each lookahead symbol */
+ for (int t = 0; t < terminal.number(); t++)
+ {
+ /* skip over the ones not in the lookahead */
+ if (!itm.lookahead().contains(t)) continue;
+
+ /* if we don't already have an action put this one in */
+ if (our_act_row.under_term[t].kind() ==
+ parse_action.ERROR)
+ {
+ our_act_row.under_term[t] = act;
+ }
+ else
+ {
+ /* we now have at least one conflict */
+ terminal term = terminal.find(t);
+ other_act = our_act_row.under_term[t];
+
+ /* if the other act was not a shift */
+ if ((other_act.kind() != parse_action.SHIFT) &&
+ (other_act.kind() != parse_action.NONASSOC))
+ {
+ /* if we have lower index hence priority, replace it*/
+ if (itm.the_production().index() <
+ ((reduce_action)other_act).reduce_with().index())
+ {
+ /* replace the action */
+ our_act_row.under_term[t] = act;
+ }
+ } else {
+ /* Check precedences,see if problem is correctable */
+ if(fix_with_precedence(itm.the_production(),
+ t, our_act_row, act)) {
+ term = null;
+ }
+ }
+ if(term!=null) {
+
+ conflict_set.add(term);
+ }
+ }
+ }
+ }
+ }
+
+ /* consider each outgoing transition */
+ for (lalr_transition trans=transitions(); trans!=null; trans=trans.next())
+ {
+ /* if its on an terminal add a shift entry */
+ sym = trans.on_symbol();
+ if (!sym.is_non_term())
+ {
+ act = new shift_action(trans.to_state());
+
+ /* if we don't already have an action put this one in */
+ if ( our_act_row.under_term[sym.index()].kind() ==
+ parse_action.ERROR)
+ {
+ our_act_row.under_term[sym.index()] = act;
+ }
+ else
+ {
+ /* we now have at least one conflict */
+ production p = ((reduce_action)our_act_row.under_term[sym.index()]).reduce_with();
+
+ /* shift always wins */
+ if (!fix_with_precedence(p, sym.index(), our_act_row, act)) {
+ our_act_row.under_term[sym.index()] = act;
+ conflict_set.add(terminal.find(sym.index()));
+ }
+ }
+ }
+ else
+ {
+ /* for non terminals add an entry to the reduce-goto table */
+ our_red_row.under_non_term[sym.index()] = trans.to_state();
+ }
+ }
+
+ /* if we end up with conflict(s), report them */
+ if (!conflict_set.empty())
+ report_conflicts(conflict_set);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+
+ /** Procedure that attempts to fix a shift/reduce error by using
+ * precedences. --frankf 6/26/96
+ *
+ * if a production (also called rule) or the lookahead terminal
+ * has a precedence, then the table can be fixed. if the rule
+ * has greater precedence than the terminal, a reduce by that rule
+ * in inserted in the table. If the terminal has a higher precedence,
+ * it is shifted. if they have equal precedence, then the associativity
+ * of the precedence is used to determine what to put in the table:
+ * if the precedence is left associative, the action is to reduce.
+ * if the precedence is right associative, the action is to shift.
+ * if the precedence is non associative, then it is a syntax error.
+ *
+ * @param p the production
+ * @param term_index the index of the lokahead terminal
+ * @param parse_action_row a row of the action table
+ * @param act the rule in conflict with the table entry
+ */
+
+ protected boolean fix_with_precedence(
+ production p,
+ int term_index,
+ parse_action_row table_row,
+ parse_action act)
+
+ throws internal_error {
+
+ terminal term = terminal.find(term_index);
+
+ /* if the production has a precedence number, it can be fixed */
+ if (p.precedence_num() > assoc.no_prec) {
+
+ /* if production precedes terminal, put reduce in table */
+ if (p.precedence_num() > term.precedence_num()) {
+ table_row.under_term[term_index] =
+ insert_reduce(table_row.under_term[term_index],act);
+ return true;
+ }
+
+ /* if terminal precedes rule, put shift in table */
+ else if (p.precedence_num() < term.precedence_num()) {
+ table_row.under_term[term_index] =
+ insert_shift(table_row.under_term[term_index],act);
+ return true;
+ }
+ else { /* they are == precedence */
+
+ /* equal precedences have equal sides, so only need to
+ look at one: if it is right, put shift in table */
+ if (term.precedence_side() == assoc.right) {
+ table_row.under_term[term_index] =
+ insert_shift(table_row.under_term[term_index],act);
+ return true;
+ }
+
+ /* if it is left, put reduce in table */
+ else if (term.precedence_side() == assoc.left) {
+ table_row.under_term[term_index] =
+ insert_reduce(table_row.under_term[term_index],act);
+ return true;
+ }
+
+ /* if it is nonassoc, we're not allowed to have two nonassocs
+ of equal precedence in a row, so put in NONASSOC */
+ else if (term.precedence_side() == assoc.nonassoc) {
+ table_row.under_term[term_index] = new nonassoc_action();
+ return true;
+ } else {
+ /* something really went wrong */
+ throw new internal_error("Unable to resolve conflict correctly");
+ }
+ }
+ }
+ /* check if terminal has precedence, if so, shift, since
+ rule does not have precedence */
+ else if (term.precedence_num() > assoc.no_prec) {
+ table_row.under_term[term_index] =
+ insert_shift(table_row.under_term[term_index],act);
+ return true;
+ }
+
+ /* otherwise, neither the rule nor the terminal has a precedence,
+ so it can't be fixed. */
+ return false;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+
+ /* given two actions, and an action type, return the
+ action of that action type. give an error if they are of
+ the same action, because that should never have tried
+ to be fixed
+
+ */
+ protected parse_action insert_action(
+ parse_action a1,
+ parse_action a2,
+ int act_type)
+ throws internal_error
+ {
+ if ((a1.kind() == act_type) && (a2.kind() == act_type)) {
+ throw new internal_error("Conflict resolution of bogus actions");
+ } else if (a1.kind() == act_type) {
+ return a1;
+ } else if (a2.kind() == act_type) {
+ return a2;
+ } else {
+ throw new internal_error("Conflict resolution of bogus actions");
+ }
+ }
+
+ /* find the shift in the two actions */
+ protected parse_action insert_shift(
+ parse_action a1,
+ parse_action a2)
+ throws internal_error
+ {
+ return insert_action(a1, a2, parse_action.SHIFT);
+ }
+
+ /* find the reduce in the two actions */
+ protected parse_action insert_reduce(
+ parse_action a1,
+ parse_action a2)
+ throws internal_error
+ {
+ return insert_action(a1, a2, parse_action.REDUCE);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Produce warning messages for all conflicts found in this state. */
+ protected void report_conflicts(terminal_set conflict_set)
+ throws internal_error
+ {
+ lalr_item itm, compare;
+ symbol shift_sym;
+
+ boolean after_itm;
+
+ /* consider each element */
+ for (Enumeration itms = items().all(); itms.hasMoreElements(); )
+ {
+ itm = (lalr_item)itms.nextElement();
+
+ /* clear the S/R conflict set for this item */
+
+ /* if it results in a reduce, it could be a conflict */
+ if (itm.dot_at_end())
+ {
+ /* not yet after itm */
+ after_itm = false;
+
+ /* compare this item against all others looking for conflicts */
+ for (Enumeration comps = items().all(); comps.hasMoreElements(); )
+ {
+ compare = (lalr_item)comps.nextElement();
+
+ /* if this is the item, next one is after it */
+ if (itm == compare) after_itm = true;
+
+ /* only look at it if its not the same item */
+ if (itm != compare)
+ {
+ /* is it a reduce */
+ if (compare.dot_at_end())
+ {
+ /* only look at reduces after itm */
+ if (after_itm)
+ /* does the comparison item conflict? */
+ if (compare.lookahead().intersects(itm.lookahead()))
+ /* report a reduce/reduce conflict */
+ report_reduce_reduce(itm, compare);
+ }
+ }
+ }
+ /* report S/R conflicts under all the symbols we conflict under */
+ for (int t = 0; t < terminal.number(); t++)
+ if (conflict_set.contains(t))
+ report_shift_reduce(itm,t);
+ }
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Produce a warning message for one reduce/reduce conflict.
+ *
+ * @param itm1 first item in conflict.
+ * @param itm2 second item in conflict.
+ */
+ protected void report_reduce_reduce(lalr_item itm1, lalr_item itm2)
+ throws internal_error
+ {
+ boolean comma_flag = false;
+
+ System.err.println("*** Reduce/Reduce conflict found in state #"+index());
+ System.err.print (" between ");
+ System.err.println(itm1.to_simple_string());
+ System.err.print (" and ");
+ System.err.println(itm2.to_simple_string());
+ System.err.print(" under symbols: {" );
+ for (int t = 0; t < terminal.number(); t++)
+ {
+ if (itm1.lookahead().contains(t) && itm2.lookahead().contains(t))
+ {
+ if (comma_flag) System.err.print(", "); else comma_flag = true;
+ System.err.print(terminal.find(t).name());
+ }
+ }
+ System.err.println("}");
+ System.err.print(" Resolved in favor of ");
+ if (itm1.the_production().index() < itm2.the_production().index())
+ System.err.println("the first production.\n");
+ else
+ System.err.println("the second production.\n");
+
+ /* count the conflict */
+ emit.num_conflicts++;
+ lexer.warning_count++;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Produce a warning message for one shift/reduce conflict.
+ *
+ * @param red_itm the item with the reduce.
+ * @param conflict_sym the index of the symbol conflict occurs under.
+ */
+ protected void report_shift_reduce(
+ lalr_item red_itm,
+ int conflict_sym)
+ throws internal_error
+ {
+ lalr_item itm;
+ symbol shift_sym;
+
+ /* emit top part of message including the reduce item */
+ System.err.println("*** Shift/Reduce conflict found in state #"+index());
+ System.err.print (" between ");
+ System.err.println(red_itm.to_simple_string());
+
+ /* find and report on all items that shift under our conflict symbol */
+ for (Enumeration itms = items().all(); itms.hasMoreElements(); )
+ {
+ itm = (lalr_item)itms.nextElement();
+
+ /* only look if its not the same item and not a reduce */
+ if (itm != red_itm && !itm.dot_at_end())
+ {
+ /* is it a shift on our conflicting terminal */
+ shift_sym = itm.symbol_after_dot();
+ if (!shift_sym.is_non_term() && shift_sym.index() == conflict_sym)
+ {
+ /* yes, report on it */
+ System.err.println(" and " + itm.to_simple_string());
+ }
+ }
+ }
+ System.err.println(" under symbol "+ terminal.find(conflict_sym).name());
+ System.err.println(" Resolved in favor of shifting.\n");
+
+ /* count the conflict */
+ emit.num_conflicts++;
+ lexer.warning_count++;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Equality comparison. */
+ public boolean equals(lalr_state other)
+ {
+ /* we are equal if our item sets are equal */
+ return other != null && items().equals(other.items());
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Generic equality comparison. */
+ public boolean equals(Object other)
+ {
+ if (!(other instanceof lalr_state))
+ return false;
+ else
+ return equals((lalr_state)other);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Produce a hash code. */
+ public int hashCode()
+ {
+ /* just use the item set hash code */
+ return items().hashCode();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to a string. */
+ public String toString()
+ {
+ String result;
+ lalr_transition tr;
+
+ /* dump the item set */
+ result = "lalr_state [" + index() + "]: " + _items + "\n";
+
+ /* do the transitions */
+ for (tr = transitions(); tr != null; tr = tr.next())
+ {
+ result += tr;
+ result += "\n";
+ }
+
+ return result;
+ }
+
+ /*-----------------------------------------------------------*/
+}
diff --git a/src/syntaxParser/java_cup/lalr_transition.class b/src/syntaxParser/java_cup/lalr_transition.class
new file mode 100644
index 0000000..4d33e8d
--- /dev/null
+++ b/src/syntaxParser/java_cup/lalr_transition.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/lalr_transition.java b/src/syntaxParser/java_cup/lalr_transition.java
new file mode 100644
index 0000000..1c941bd
--- /dev/null
+++ b/src/syntaxParser/java_cup/lalr_transition.java
@@ -0,0 +1,93 @@
+package java_cup;
+
+/** This class represents a transition in an LALR viable prefix recognition
+ * machine. Transitions can be under terminals for non-terminals. They are
+ * internally linked together into singly linked lists containing all the
+ * transitions out of a single state via the _next field.
+ *
+ * @see java_cup.lalr_state
+ * @version last updated: 11/25/95
+ * @author Scott Hudson
+ *
+ */
+public class lalr_transition {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Full constructor.
+ * @param on_sym symbol we are transitioning on.
+ * @param to_st state we transition to.
+ * @param nxt next transition in linked list.
+ */
+ public lalr_transition(symbol on_sym, lalr_state to_st, lalr_transition nxt)
+ throws internal_error
+ {
+ /* sanity checks */
+ if (on_sym == null)
+ throw new internal_error("Attempt to create transition on null symbol");
+ if (to_st == null)
+ throw new internal_error("Attempt to create transition to null state");
+
+ /* initialize */
+ _on_symbol = on_sym;
+ _to_state = to_st;
+ _next = nxt;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Constructor with null next.
+ * @param on_sym symbol we are transitioning on.
+ * @param to_st state we transition to.
+ */
+ public lalr_transition(symbol on_sym, lalr_state to_st) throws internal_error
+ {
+ this(on_sym, to_st, null);
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** The symbol we make the transition on. */
+ protected symbol _on_symbol;
+
+ /** The symbol we make the transition on. */
+ public symbol on_symbol() {return _on_symbol;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** The state we transition to. */
+ protected lalr_state _to_state;
+
+ /** The state we transition to. */
+ public lalr_state to_state() {return _to_state;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Next transition in linked list of transitions out of a state */
+ protected lalr_transition _next;
+
+ /** Next transition in linked list of transitions out of a state */
+ public lalr_transition next() {return _next;}
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Convert to a string. */
+ public String toString()
+ {
+ String result;
+
+ result = "transition on " + on_symbol().name() + " to state [";
+ result += _to_state.index();
+ result += "]";
+
+ return result;
+ }
+
+ /*-----------------------------------------------------------*/
+}
diff --git a/src/syntaxParser/java_cup/lexer.class b/src/syntaxParser/java_cup/lexer.class
new file mode 100644
index 0000000..87e0073
--- /dev/null
+++ b/src/syntaxParser/java_cup/lexer.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/lexer.java b/src/syntaxParser/java_cup/lexer.java
new file mode 100644
index 0000000..2230d12
--- /dev/null
+++ b/src/syntaxParser/java_cup/lexer.java
@@ -0,0 +1,543 @@
+package java_cup;
+
+import java_cup.runtime.Symbol;
+import java.util.Hashtable;
+
+/** This class implements a small scanner (aka lexical analyzer or lexer) for
+ * the JavaCup specification. This scanner reads characters from standard
+ * input (System.in) and returns integers corresponding to the terminal
+ * number of the next Symbol. Once end of input is reached the EOF Symbol is
+ * returned on every subsequent call.<p>
+ * Symbols currently returned include: <pre>
+ * Symbol Constant Returned Symbol Constant Returned
+ * ------ ----------------- ------ -----------------
+ * "package" PACKAGE "import" IMPORT
+ * "code" CODE "action" ACTION
+ * "parser" PARSER "terminal" TERMINAL
+ * "non" NON "init" INIT
+ * "scan" SCAN "with" WITH
+ * "start" START "precedence" PRECEDENCE
+ * "left" LEFT "right" RIGHT
+ * "nonassoc" NONASSOC "%prec PRECENT_PREC
+ * [ LBRACK ] RBRACK
+ * ; SEMI
+ * , COMMA * STAR
+ * . DOT : COLON
+ * ::= COLON_COLON_EQUALS | BAR
+ * identifier ID {:...:} CODE_STRING
+ * "nonterminal" NONTERMINAL
+ * </pre>
+ * All symbol constants are defined in sym.java which is generated by
+ * JavaCup from parser.cup.<p>
+ *
+ * In addition to the scanner proper (called first via init() then with
+ * next_token() to get each Symbol) this class provides simple error and
+ * warning routines and keeps a count of errors and warnings that is
+ * publicly accessible.<p>
+ *
+ * This class is "static" (i.e., it has only static members and methods).
+ *
+ * @version last updated: 7/3/96
+ * @author Frank Flannery
+ */
+public class lexer {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** The only constructor is private, so no instances can be created. */
+ private lexer() { }
+
+ /*-----------------------------------------------------------*/
+ /*--- Static (Class) Variables ------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** First character of lookahead. */
+ protected static int next_char;
+
+ /** Second character of lookahead. */
+ protected static int next_char2;
+
+ /** Second character of lookahead. */
+ protected static int next_char3;
+
+ /** Second character of lookahead. */
+ protected static int next_char4;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** EOF constant. */
+ protected static final int EOF_CHAR = -1;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Table of keywords. Keywords are initially treated as identifiers.
+ * Just before they are returned we look them up in this table to see if
+ * they match one of the keywords. The string of the name is the key here,
+ * which indexes Integer objects holding the symbol number.
+ */
+ protected static Hashtable keywords = new Hashtable(23);
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Table of single character symbols. For ease of implementation, we
+ * store all unambiguous single character Symbols in this table of Integer
+ * objects keyed by Integer objects with the numerical value of the
+ * appropriate char (currently Character objects have a bug which precludes
+ * their use in tables).
+ */
+ protected static Hashtable char_symbols = new Hashtable(11);
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Current line number for use in error messages. */
+ protected static int current_line = 1;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Character position in current line. */
+ protected static int current_position = 1;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Character position in current line. */
+ protected static int absolute_position = 1;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Count of total errors detected so far. */
+ public static int error_count = 0;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Count of warnings issued so far */
+ public static int warning_count = 0;
+
+ /*-----------------------------------------------------------*/
+ /*--- Static Methods ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Initialize the scanner. This sets up the keywords and char_symbols
+ * tables and reads the first two characters of lookahead.
+ */
+ public static void init() throws java.io.IOException
+ {
+ /* set up the keyword table */
+ keywords.put("package", new Integer(sym.PACKAGE));
+ keywords.put("import", new Integer(sym.IMPORT));
+ keywords.put("code", new Integer(sym.CODE));
+ keywords.put("action", new Integer(sym.ACTION));
+ keywords.put("parser", new Integer(sym.PARSER));
+ keywords.put("terminal", new Integer(sym.TERMINAL));
+ keywords.put("non", new Integer(sym.NON));
+ keywords.put("nonterminal",new Integer(sym.NONTERMINAL));// [CSA]
+ keywords.put("init", new Integer(sym.INIT));
+ keywords.put("scan", new Integer(sym.SCAN));
+ keywords.put("with", new Integer(sym.WITH));
+ keywords.put("start", new Integer(sym.START));
+ keywords.put("precedence", new Integer(sym.PRECEDENCE));
+ keywords.put("left", new Integer(sym.LEFT));
+ keywords.put("right", new Integer(sym.RIGHT));
+ keywords.put("nonassoc", new Integer(sym.NONASSOC));
+
+ /* set up the table of single character symbols */
+ char_symbols.put(new Integer(';'), new Integer(sym.SEMI));
+ char_symbols.put(new Integer(','), new Integer(sym.COMMA));
+ char_symbols.put(new Integer('*'), new Integer(sym.STAR));
+ char_symbols.put(new Integer('.'), new Integer(sym.DOT));
+ char_symbols.put(new Integer('|'), new Integer(sym.BAR));
+ char_symbols.put(new Integer('['), new Integer(sym.LBRACK));
+ char_symbols.put(new Integer(']'), new Integer(sym.RBRACK));
+
+ /* read two characters of lookahead */
+ next_char = System.in.read();
+ if (next_char == EOF_CHAR) {
+ next_char2 = EOF_CHAR;
+ next_char3 = EOF_CHAR;
+ next_char4 = EOF_CHAR;
+ } else {
+ next_char2 = System.in.read();
+ if (next_char2 == EOF_CHAR) {
+ next_char3 = EOF_CHAR;
+ next_char4 = EOF_CHAR;
+ } else {
+ next_char3 = System.in.read();
+ if (next_char3 == EOF_CHAR) {
+ next_char4 = EOF_CHAR;
+ } else {
+ next_char4 = System.in.read();
+ }
+ }
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Advance the scanner one character in the input stream. This moves
+ * next_char2 to next_char and then reads a new next_char2.
+ */
+ protected static void advance() throws java.io.IOException
+ {
+ int old_char;
+
+ old_char = next_char;
+ next_char = next_char2;
+ if (next_char == EOF_CHAR) {
+ next_char2 = EOF_CHAR;
+ next_char3 = EOF_CHAR;
+ next_char4 = EOF_CHAR;
+ } else {
+ next_char2 = next_char3;
+ if (next_char2 == EOF_CHAR) {
+ next_char3 = EOF_CHAR;
+ next_char4 = EOF_CHAR;
+ } else {
+ next_char3 = next_char4;
+ if (next_char3 == EOF_CHAR) {
+ next_char4 = EOF_CHAR;
+ } else {
+ next_char4 = System.in.read();
+ }
+ }
+ }
+
+ /* count this */
+ absolute_position++;
+ current_position++;
+ if (old_char == '\n' || (old_char == '\r' && next_char!='\n'))
+ {
+ current_line++;
+ current_position = 1;
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Emit an error message. The message will be marked with both the
+ * current line number and the position in the line. Error messages
+ * are printed on standard error (System.err).
+ * @param message the message to print.
+ */
+ public static void emit_error(String message)
+ {
+ System.err.println("Error at " + current_line + "(" + current_position +
+ "): " + message);
+ error_count++;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Emit a warning message. The message will be marked with both the
+ * current line number and the position in the line. Messages are
+ * printed on standard error (System.err).
+ * @param message the message to print.
+ */
+ public static void emit_warn(String message)
+ {
+ System.err.println("Warning at " + current_line + "(" + current_position +
+ "): " + message);
+ warning_count++;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Determine if a character is ok to start an id.
+ * @param ch the character in question.
+ */
+ protected static boolean id_start_char(int ch)
+ {
+ /* allow for % in identifiers. a hack to allow my
+ %prec in. Should eventually make lex spec for this
+ frankf */
+ return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') ||
+ (ch == '_');
+
+ // later need to deal with non-8-bit chars here
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Determine if a character is ok for the middle of an id.
+ * @param ch the character in question.
+ */
+ protected static boolean id_char(int ch)
+ {
+ return id_start_char(ch) || (ch >= '0' && ch <= '9');
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Try to look up a single character symbol, returns -1 for not found.
+ * @param ch the character in question.
+ */
+ protected static int find_single_char(int ch)
+ {
+ Integer result;
+
+ result = (Integer)char_symbols.get(new Integer((char)ch));
+ if (result == null)
+ return -1;
+ else
+ return result.intValue();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Handle swallowing up a comment. Both old style C and new style C++
+ * comments are handled.
+ */
+ protected static void swallow_comment() throws java.io.IOException
+ {
+ /* next_char == '/' at this point */
+
+ /* is it a traditional comment */
+ if (next_char2 == '*')
+ {
+ /* swallow the opener */
+ advance(); advance();
+
+ /* swallow the comment until end of comment or EOF */
+ for (;;)
+ {
+ /* if its EOF we have an error */
+ if (next_char == EOF_CHAR)
+ {
+ emit_error("Specification file ends inside a comment");
+ return;
+ }
+
+ /* if we can see the closer we are done */
+ if (next_char == '*' && next_char2 == '/')
+ {
+ advance();
+ advance();
+ return;
+ }
+
+ /* otherwise swallow char and move on */
+ advance();
+ }
+ }
+
+ /* is its a new style comment */
+ if (next_char2 == '/')
+ {
+ /* swallow the opener */
+ advance(); advance();
+
+ /* swallow to '\n', '\r', '\f', or EOF */
+ while (next_char != '\n' && next_char != '\r' &&
+ next_char != '\f' && next_char!=EOF_CHAR)
+ advance();
+
+ return;
+
+ }
+
+ /* shouldn't get here, but... if we get here we have an error */
+ emit_error("Malformed comment in specification -- ignored");
+ advance();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Swallow up a code string. Code strings begin with "{:" and include
+ all characters up to the first occurrence of ":}" (there is no way to
+ include ":}" inside a code string). The routine returns a String
+ object suitable for return by the scanner.
+ */
+ protected static Symbol do_code_string() throws java.io.IOException
+ {
+ StringBuffer result = new StringBuffer();
+
+ /* at this point we have lookahead of "{:" -- swallow that */
+ advance(); advance();
+
+ /* save chars until we see ":}" */
+ while (!(next_char == ':' && next_char2 == '}'))
+ {
+ /* if we have run off the end issue a message and break out of loop */
+ if (next_char == EOF_CHAR)
+ {
+ emit_error("Specification file ends inside a code string");
+ break;
+ }
+
+ /* otherwise record the char and move on */
+ result.append(new Character((char)next_char));
+ advance();
+ }
+
+ /* advance past the closer and build a return Symbol */
+ advance(); advance();
+ return new Symbol(sym.CODE_STRING, result.toString());
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Process an identifier. Identifiers begin with a letter, underscore,
+ * or dollar sign, which is followed by zero or more letters, numbers,
+ * underscores or dollar signs. This routine returns a String suitable
+ * for return by the scanner.
+ */
+ protected static Symbol do_id() throws java.io.IOException
+ {
+ StringBuffer result = new StringBuffer();
+ String result_str;
+ Integer keyword_num;
+ char buffer[] = new char[1];
+
+ /* next_char holds first character of id */
+ buffer[0] = (char)next_char;
+ result.append(buffer,0,1);
+ advance();
+
+ /* collect up characters while they fit in id */
+ while(id_char(next_char))
+ {
+ buffer[0] = (char)next_char;
+ result.append(buffer,0,1);
+ advance();
+ }
+
+ /* extract a string and try to look it up as a keyword */
+ result_str = result.toString();
+ keyword_num = (Integer)keywords.get(result_str);
+
+ /* if we found something, return that keyword */
+ if (keyword_num != null)
+ return new Symbol(keyword_num.intValue());
+
+ /* otherwise build and return an id Symbol with an attached string */
+ return new Symbol(sym.ID, result_str);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Return one Symbol. This is the main external interface to the scanner.
+ * It consumes sufficient characters to determine the next input Symbol
+ * and returns it. To help with debugging, this routine actually calls
+ * real_next_token() which does the work. If you need to debug the
+ * parser, this can be changed to call debug_next_token() which prints
+ * a debugging message before returning the Symbol.
+ */
+ public static Symbol next_token() throws java.io.IOException
+ {
+ return real_next_token();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Debugging version of next_token(). This routine calls the real scanning
+ * routine, prints a message on System.out indicating what the Symbol is,
+ * then returns it.
+ */
+ public static Symbol debug_next_token() throws java.io.IOException
+ {
+ Symbol result = real_next_token();
+ System.out.println("# next_Symbol() => " + result.sym);
+ return result;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** The actual routine to return one Symbol. This is normally called from
+ * next_token(), but for debugging purposes can be called indirectly from
+ * debug_next_token().
+ */
+ protected static Symbol real_next_token() throws java.io.IOException
+ {
+ int sym_num;
+
+ for (;;)
+ {
+ /* look for white space */
+ if (next_char == ' ' || next_char == '\t' || next_char == '\n' ||
+ next_char == '\f' || next_char == '\r')
+ {
+ /* advance past it and try the next character */
+ advance();
+ continue;
+ }
+
+ /* look for a single character symbol */
+ sym_num = find_single_char(next_char);
+ if (sym_num != -1)
+ {
+ /* found one -- advance past it and return a Symbol for it */
+ advance();
+ return new Symbol(sym_num);
+ }
+
+ /* look for : or ::= */
+ if (next_char == ':')
+ {
+ /* if we don't have a second ':' return COLON */
+ if (next_char2 != ':')
+ {
+ advance();
+ return new Symbol(sym.COLON);
+ }
+
+ /* move forward and look for the '=' */
+ advance();
+ if (next_char2 == '=')
+ {
+ advance(); advance();
+ return new Symbol(sym.COLON_COLON_EQUALS);
+ }
+ else
+ {
+ /* return just the colon (already consumed) */
+ return new Symbol(sym.COLON);
+ }
+ }
+
+ /* find a "%prec" string and return it. otherwise, a '%' was found,
+ which has no right being in the specification otherwise */
+ if (next_char == '%') {
+ advance();
+ if ((next_char == 'p') && (next_char2 == 'r') && (next_char3 == 'e') &&
+ (next_char4 == 'c')) {
+ advance();
+ advance();
+ advance();
+ advance();
+ return new Symbol(sym.PERCENT_PREC);
+ } else {
+ emit_error("Found extraneous percent sign");
+ }
+ }
+
+ /* look for a comment */
+ if (next_char == '/' && (next_char2 == '*' || next_char2 == '/'))
+ {
+ /* swallow then continue the scan */
+ swallow_comment();
+ continue;
+ }
+
+ /* look for start of code string */
+ if (next_char == '{' && next_char2 == ':')
+ return do_code_string();
+
+ /* look for an id or keyword */
+ if (id_start_char(next_char)) return do_id();
+
+ /* look for EOF */
+ if (next_char == EOF_CHAR) return new Symbol(sym.EOF);
+
+ /* if we get here, we have an unrecognized character */
+ emit_warn("Unrecognized character '" +
+ new Character((char)next_char) + "'(" + next_char +
+ ") -- ignored");
+
+ /* advance past it */
+ advance();
+ }
+ }
+
+ /*-----------------------------------------------------------*/
+}
+
diff --git a/src/syntaxParser/java_cup/lr_item_core.class b/src/syntaxParser/java_cup/lr_item_core.class
new file mode 100644
index 0000000..047e002
--- /dev/null
+++ b/src/syntaxParser/java_cup/lr_item_core.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/lr_item_core.java b/src/syntaxParser/java_cup/lr_item_core.java
new file mode 100644
index 0000000..c0fa656
--- /dev/null
+++ b/src/syntaxParser/java_cup/lr_item_core.java
@@ -0,0 +1,280 @@
+
+package java_cup;
+
+/** The "core" of an LR item. This includes a production and the position
+ * of a marker (the "dot") within the production. Typically item cores
+ * are written using a production with an embedded "dot" to indicate their
+ * position. For example: <pre>
+ * A ::= B * C d E
+ * </pre>
+ * This represents a point in a parse where the parser is trying to match
+ * the given production, and has succeeded in matching everything before the
+ * "dot" (and hence is expecting to see the symbols after the dot next). See
+ * lalr_item, lalr_item_set, and lalr_start for full details on the meaning
+ * and use of items.
+ *
+ * @see java_cup.lalr_item
+ * @see java_cup.lalr_item_set
+ * @see java_cup.lalr_state
+ * @version last updated: 11/25/95
+ * @author Scott Hudson
+*/
+
+public class lr_item_core {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Full constructor.
+ * @param prod production this item uses.
+ * @param pos position of the "dot" within the item.
+ */
+ public lr_item_core(production prod, int pos) throws internal_error
+ {
+ symbol after_dot = null;
+ production_part part;
+
+ if (prod == null)
+ throw new internal_error(
+ "Attempt to create an lr_item_core with a null production");
+
+ _the_production = prod;
+
+ if (pos < 0 || pos > _the_production.rhs_length())
+ throw new internal_error(
+ "Attempt to create an lr_item_core with a bad dot position");
+
+ _dot_pos = pos;
+
+ /* compute and cache hash code now */
+ _core_hash_cache = 13*_the_production.hashCode() + pos;
+
+ /* cache the symbol after the dot */
+ if (_dot_pos < _the_production.rhs_length())
+ {
+ part = _the_production.rhs(_dot_pos);
+ if (!part.is_action())
+ _symbol_after_dot = ((symbol_part)part).the_symbol();
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Constructor for dot at start of right hand side.
+ * @param prod production this item uses.
+ */
+ public lr_item_core(production prod) throws internal_error
+ {
+ this(prod,0);
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** The production for the item. */
+ protected production _the_production;
+
+ /** The production for the item. */
+ public production the_production() {return _the_production;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** The position of the "dot" -- this indicates the part of the production
+ * that the marker is before, so 0 indicates a dot at the beginning of
+ * the RHS.
+ */
+ protected int _dot_pos;
+
+ /** The position of the "dot" -- this indicates the part of the production
+ * that the marker is before, so 0 indicates a dot at the beginning of
+ * the RHS.
+ */
+ public int dot_pos() {return _dot_pos;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Cache of the hash code. */
+ protected int _core_hash_cache;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Cache of symbol after the dot. */
+ protected symbol _symbol_after_dot = null;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Is the dot at the end of the production? */
+ public boolean dot_at_end()
+ {
+ return _dot_pos >= _the_production.rhs_length();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Return the symbol after the dot. If there is no symbol after the dot
+ * we return null. */
+ public symbol symbol_after_dot()
+ {
+ /* use the cached symbol */
+ return _symbol_after_dot;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Determine if we have a dot before a non terminal, and if so which one
+ * (return null or the non terminal).
+ */
+ public non_terminal dot_before_nt()
+ {
+ symbol sym;
+
+ /* get the symbol after the dot */
+ sym = symbol_after_dot();
+
+ /* if it exists and is a non terminal, return it */
+ if (sym != null && sym.is_non_term())
+ return (non_terminal)sym;
+ else
+ return null;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Produce a new lr_item_core that results from shifting the dot one
+ * position to the right.
+ */
+ public lr_item_core shift_core() throws internal_error
+ {
+ if (dot_at_end())
+ throw new internal_error(
+ "Attempt to shift past end of an lr_item_core");
+
+ return new lr_item_core(_the_production, _dot_pos+1);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Equality comparison for the core only. This is separate out because we
+ * need separate access in a super class.
+ */
+ public boolean core_equals(lr_item_core other)
+ {
+ return other != null &&
+ _the_production.equals(other._the_production) &&
+ _dot_pos == other._dot_pos;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Equality comparison. */
+ public boolean equals(lr_item_core other) {return core_equals(other);}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Generic equality comparison. */
+ public boolean equals(Object other)
+ {
+ if (!(other instanceof lr_item_core))
+ return false;
+ else
+ return equals((lr_item_core)other);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Hash code for the core (separated so we keep non overridden version). */
+ public int core_hashCode()
+ {
+ return _core_hash_cache;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Hash code for the item. */
+ public int hashCode()
+ {
+ return _core_hash_cache;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Return the hash code that object would have provided for us so we have
+ * a (nearly) unique id for debugging.
+ */
+ protected int obj_hash()
+ {
+ return super.hashCode();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to a string (separated out from toString() so we can call it
+ * from subclass that overrides toString()).
+ */
+ public String to_simple_string() throws internal_error
+ {
+ String result;
+ production_part part;
+
+ if (_the_production.lhs() != null &&
+ _the_production.lhs().the_symbol() != null &&
+ _the_production.lhs().the_symbol().name() != null)
+ result = _the_production.lhs().the_symbol().name();
+ else
+ result = "$$NULL$$";
+
+ result += " ::= ";
+
+ for (int i = 0; i<_the_production.rhs_length(); i++)
+ {
+ /* do we need the dot before this one? */
+ if (i == _dot_pos)
+ result += "(*) ";
+
+ /* print the name of the part */
+ if (_the_production.rhs(i) == null)
+ {
+ result += "$$NULL$$ ";
+ }
+ else
+ {
+ part = _the_production.rhs(i);
+ if (part == null)
+ result += "$$NULL$$ ";
+ else if (part.is_action())
+ result += "{ACTION} ";
+ else if (((symbol_part)part).the_symbol() != null &&
+ ((symbol_part)part).the_symbol().name() != null)
+ result += ((symbol_part)part).the_symbol().name() + " ";
+ else
+ result += "$$NULL$$ ";
+ }
+ }
+
+ /* put the dot after if needed */
+ if (_dot_pos == _the_production.rhs_length())
+ result += "(*) ";
+
+ return result;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to a string */
+ public String toString()
+ {
+ /* can't throw here since super class doesn't, so we crash instead */
+ try {
+ return to_simple_string();
+ } catch(internal_error e) {
+ e.crash();
+ return null;
+ }
+ }
+
+ /*-----------------------------------------------------------*/
+
+}
+
diff --git a/src/syntaxParser/java_cup/non_terminal.class b/src/syntaxParser/java_cup/non_terminal.class
new file mode 100644
index 0000000..ba6079c
--- /dev/null
+++ b/src/syntaxParser/java_cup/non_terminal.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/non_terminal.java b/src/syntaxParser/java_cup/non_terminal.java
new file mode 100644
index 0000000..9354a7f
--- /dev/null
+++ b/src/syntaxParser/java_cup/non_terminal.java
@@ -0,0 +1,301 @@
+package java_cup;
+
+import java.util.Hashtable;
+import java.util.Enumeration;
+
+/** This class represents a non-terminal symbol in the grammar. Each
+ * non terminal has a textual name, an index, and a string which indicates
+ * the type of object it will be implemented with at runtime (i.e. the class
+ * of object that will be pushed on the parse stack to represent it).
+ *
+ * @version last updated: 11/25/95
+ * @author Scott Hudson
+ */
+
+public class non_terminal extends symbol {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Full constructor.
+ * @param nm the name of the non terminal.
+ * @param tp the type string for the non terminal.
+ */
+ public non_terminal(String nm, String tp)
+ {
+ /* super class does most of the work */
+ super(nm, tp);
+
+ /* add to set of all non terminals and check for duplicates */
+ Object conflict = _all.put(nm,this);
+ if (conflict != null)
+ // can't throw an exception here because these are used in static
+ // initializers, so we crash instead
+ // was:
+ // throw new internal_error("Duplicate non-terminal ("+nm+") created");
+ (new internal_error("Duplicate non-terminal ("+nm+") created")).crash();
+
+ /* assign a unique index */
+ _index = next_index++;
+
+ /* add to by_index set */
+ _all_by_index.put(new Integer(_index), this);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Constructor with default type.
+ * @param nm the name of the non terminal.
+ */
+ public non_terminal(String nm)
+ {
+ this(nm, null);
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Static (Class) Variables ------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Table of all non-terminals -- elements are stored using name strings
+ * as the key
+ */
+ protected static Hashtable _all = new Hashtable();
+
+ /** Access to all non-terminals. */
+ public static Enumeration all() {return _all.elements();}
+
+ /** lookup a non terminal by name string */
+ public static non_terminal find(String with_name)
+ {
+ if (with_name == null)
+ return null;
+ else
+ return (non_terminal)_all.get(with_name);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Table of all non terminals indexed by their index number. */
+ protected static Hashtable _all_by_index = new Hashtable();
+
+ /** Lookup a non terminal by index. */
+ public static non_terminal find(int indx)
+ {
+ Integer the_indx = new Integer(indx);
+
+ return (non_terminal)_all_by_index.get(the_indx);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Total number of non-terminals. */
+ public static int number() {return _all.size();}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Static counter to assign unique indexes. */
+ protected static int next_index = 0;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Static counter for creating unique non-terminal names */
+ static protected int next_nt = 0;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** special non-terminal for start symbol */
+ public static final non_terminal START_nt = new non_terminal("$START");
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** flag non-terminals created to embed action productions */
+ public boolean is_embedded_action = false; /* added 24-Mar-1998, CSA */
+
+ /*-----------------------------------------------------------*/
+ /*--- Static Methods ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Method for creating a new uniquely named hidden non-terminal using
+ * the given string as a base for the name (or "NT$" if null is passed).
+ * @param prefix base name to construct unique name from.
+ */
+ static non_terminal create_new(String prefix) throws internal_error
+ {
+ if (prefix == null) prefix = "NT$";
+ return new non_terminal(prefix + next_nt++);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** static routine for creating a new uniquely named hidden non-terminal */
+ static non_terminal create_new() throws internal_error
+ {
+ return create_new(null);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Compute nullability of all non-terminals. */
+ public static void compute_nullability() throws internal_error
+ {
+ boolean change = true;
+ non_terminal nt;
+ Enumeration e;
+ production prod;
+
+ /* repeat this process until there is no change */
+ while (change)
+ {
+ /* look for a new change */
+ change = false;
+
+ /* consider each non-terminal */
+ for (e=all(); e.hasMoreElements(); )
+ {
+ nt = (non_terminal)e.nextElement();
+
+ /* only look at things that aren't already marked nullable */
+ if (!nt.nullable())
+ {
+ if (nt.looks_nullable())
+ {
+ nt._nullable = true;
+ change = true;
+ }
+ }
+ }
+ }
+
+ /* do one last pass over the productions to finalize all of them */
+ for (e=production.all(); e.hasMoreElements(); )
+ {
+ prod = (production)e.nextElement();
+ prod.set_nullable(prod.check_nullable());
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Compute first sets for all non-terminals. This assumes nullability has
+ * already computed.
+ */
+ public static void compute_first_sets() throws internal_error
+ {
+ boolean change = true;
+ Enumeration n;
+ Enumeration p;
+ non_terminal nt;
+ production prod;
+ terminal_set prod_first;
+
+ /* repeat this process until we have no change */
+ while (change)
+ {
+ /* look for a new change */
+ change = false;
+
+ /* consider each non-terminal */
+ for (n = all(); n.hasMoreElements(); )
+ {
+ nt = (non_terminal)n.nextElement();
+
+ /* consider every production of that non terminal */
+ for (p = nt.productions(); p.hasMoreElements(); )
+ {
+ prod = (production)p.nextElement();
+
+ /* get the updated first of that production */
+ prod_first = prod.check_first_set();
+
+ /* if this going to add anything, add it */
+ if (!prod_first.is_subset_of(nt._first_set))
+ {
+ change = true;
+ nt._first_set.add(prod_first);
+ }
+ }
+ }
+ }
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Table of all productions with this non terminal on the LHS. */
+ protected Hashtable _productions = new Hashtable(11);
+
+ /** Access to productions with this non terminal on the LHS. */
+ public Enumeration productions() {return _productions.elements();}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Total number of productions with this non terminal on the LHS. */
+ public int num_productions() {return _productions.size();}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Add a production to our set of productions. */
+ public void add_production(production prod) throws internal_error
+ {
+ /* catch improper productions */
+ if (prod == null || prod.lhs() == null || prod.lhs().the_symbol() != this)
+ throw new internal_error(
+ "Attempt to add invalid production to non terminal production table");
+
+ /* add it to the table, keyed with itself */
+ _productions.put(prod,prod);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Nullability of this non terminal. */
+ protected boolean _nullable;
+
+ /** Nullability of this non terminal. */
+ public boolean nullable() {return _nullable;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** First set for this non-terminal. */
+ protected terminal_set _first_set = new terminal_set();
+
+ /** First set for this non-terminal. */
+ public terminal_set first_set() {return _first_set;}
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Indicate that this symbol is a non-terminal. */
+ public boolean is_non_term()
+ {
+ return true;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Test to see if this non terminal currently looks nullable. */
+ protected boolean looks_nullable() throws internal_error
+ {
+ /* look and see if any of the productions now look nullable */
+ for (Enumeration e = productions(); e.hasMoreElements(); )
+ /* if the production can go to empty, we are nullable */
+ if (((production)e.nextElement()).check_nullable())
+ return true;
+
+ /* none of the productions can go to empty, so we are not nullable */
+ return false;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** convert to string */
+ public String toString()
+ {
+ return super.toString() + "[" + index() + "]" + (nullable() ? "*" : "");
+ }
+
+ /*-----------------------------------------------------------*/
+}
diff --git a/src/syntaxParser/java_cup/nonassoc_action.class b/src/syntaxParser/java_cup/nonassoc_action.class
new file mode 100644
index 0000000..fcb75a7
--- /dev/null
+++ b/src/syntaxParser/java_cup/nonassoc_action.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/nonassoc_action.java b/src/syntaxParser/java_cup/nonassoc_action.java
new file mode 100644
index 0000000..3882324
--- /dev/null
+++ b/src/syntaxParser/java_cup/nonassoc_action.java
@@ -0,0 +1,71 @@
+
+package java_cup;
+
+/** This class represents a shift/reduce nonassociative error within the
+ * parse table. If action_table element is assign to type
+ * nonassoc_action, it cannot be changed, and signifies that there
+ * is a conflict between shifting and reducing a production and a
+ * terminal that shouldn't be next to each other.
+ *
+ * @version last updated: 7/2/96
+ * @author Frank Flannery
+ */
+public class nonassoc_action extends parse_action {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Simple constructor.
+ */
+ public nonassoc_action() throws internal_error
+ {
+ /* don't need to set anything, since it signifies error */
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Quick access to type of action. */
+ public int kind() {return NONASSOC;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Equality test. */
+ public boolean equals(parse_action other)
+ {
+ return other != null && other.kind() == NONASSOC;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Generic equality test. */
+ public boolean equals(Object other)
+ {
+ if (other instanceof parse_action)
+ return equals((parse_action)other);
+ else
+ return false;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Compute a hash code. */
+ public int hashCode()
+ {
+ /* all objects of this class hash together */
+ return 0xCafe321;
+ }
+
+
+
+ /** Convert to string. */
+ public String toString()
+ {
+ return "NONASSOC";
+ }
+
+ /*-----------------------------------------------------------*/
+
+}
diff --git a/src/syntaxParser/java_cup/parse_action.class b/src/syntaxParser/java_cup/parse_action.class
new file mode 100644
index 0000000..63c0ffa
--- /dev/null
+++ b/src/syntaxParser/java_cup/parse_action.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/parse_action.java b/src/syntaxParser/java_cup/parse_action.java
new file mode 100644
index 0000000..9228663
--- /dev/null
+++ b/src/syntaxParser/java_cup/parse_action.java
@@ -0,0 +1,92 @@
+
+package java_cup;
+
+/** This class serves as the base class for entries in a parse action table.
+ * Full entries will either be SHIFT(state_num), REDUCE(production), NONASSOC,
+ * or ERROR. Objects of this base class will default to ERROR, while
+ * the other three types will be represented by subclasses.
+ *
+ * @see java_cup.reduce_action
+ * @see java_cup.shift_action
+ * @version last updated: 7/2/96
+ * @author Frank Flannery
+ */
+
+public class parse_action {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Simple constructor. */
+ public parse_action()
+ {
+ /* nothing to do in the base class */
+ }
+
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Static (Class) Variables ------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Constant for action type -- error action. */
+ public static final int ERROR = 0;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Constant for action type -- shift action. */
+ public static final int SHIFT = 1;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Constants for action type -- reduce action. */
+ public static final int REDUCE = 2;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Constants for action type -- reduce action. */
+ public static final int NONASSOC = 3;
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Quick access to the type -- base class defaults to error. */
+ public int kind() {return ERROR;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Equality test. */
+ public boolean equals(parse_action other)
+ {
+ /* we match all error actions */
+ return other != null && other.kind() == ERROR;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Generic equality test. */
+ public boolean equals(Object other)
+ {
+ if (other instanceof parse_action)
+ return equals((parse_action)other);
+ else
+ return false;
+ }
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Compute a hash code. */
+ public int hashCode()
+ {
+ /* all objects of this class hash together */
+ return 0xCafe123;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to string. */
+ public String toString() {return "ERROR";}
+
+ /*-----------------------------------------------------------*/
+}
+
diff --git a/src/syntaxParser/java_cup/parse_action_row.class b/src/syntaxParser/java_cup/parse_action_row.class
new file mode 100644
index 0000000..5c407fb
--- /dev/null
+++ b/src/syntaxParser/java_cup/parse_action_row.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/parse_action_row.java b/src/syntaxParser/java_cup/parse_action_row.java
new file mode 100644
index 0000000..817b8c5
--- /dev/null
+++ b/src/syntaxParser/java_cup/parse_action_row.java
@@ -0,0 +1,106 @@
+
+package java_cup;
+
+/** This class represents one row (corresponding to one machine state) of the
+ * parse action table.
+ */
+public class parse_action_row {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Simple constructor. Note: this should not be used until the number of
+ * terminals in the grammar has been established.
+ */
+ public parse_action_row()
+ {
+ /* make sure the size is set */
+ if (_size <= 0 ) _size = terminal.number();
+
+ /* allocate the array */
+ under_term = new parse_action[size()];
+
+ /* set each element to an error action */
+ for (int i=0; i<_size; i++)
+ under_term[i] = new parse_action();
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Static (Class) Variables ------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Number of columns (terminals) in every row. */
+ protected static int _size = 0;
+
+ /** Number of columns (terminals) in every row. */
+ public static int size() {return _size;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Table of reduction counts (reused by compute_default()). */
+ protected static int reduction_count[] = null;
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Actual action entries for the row. */
+ public parse_action under_term[];
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Default (reduce) action for this row. -1 will represent default
+ * of error.
+ */
+ public int default_reduce;
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Compute the default (reduce) action for this row and store it in
+ * default_reduce. In the case of non-zero default we will have the
+ * effect of replacing all errors by that reduction. This may cause
+ * us to do erroneous reduces, but will never cause us to shift past
+ * the point of the error and never cause an incorrect parse. -1 will
+ * be used to encode the fact that no reduction can be used as a
+ * default (in which case error will be used).
+ */
+ public void compute_default()
+ {
+ int i, prod, max_prod, max_red;
+
+ /* if we haven't allocated the count table, do so now */
+ if (reduction_count == null)
+ reduction_count = new int[production.number()];
+
+ /* clear the reduction count table and maximums */
+ for (i = 0; i < production.number(); i++)
+ reduction_count[i] = 0;
+ max_prod = -1;
+ max_red = 0;
+
+ /* walk down the row and look at the reduces */
+ for (i = 0; i < size(); i++)
+ if (under_term[i].kind() == parse_action.REDUCE)
+ {
+ /* count the reduce in the proper production slot and keep the
+ max up to date */
+ prod = ((reduce_action)under_term[i]).reduce_with().index();
+ reduction_count[prod]++;
+ if (reduction_count[prod] > max_red)
+ {
+ max_red = reduction_count[prod];
+ max_prod = prod;
+ }
+ }
+
+ /* record the max as the default (or -1 for not found) */
+ default_reduce = max_prod;
+ }
+
+ /*-----------------------------------------------------------*/
+
+}
+
diff --git a/src/syntaxParser/java_cup/parse_action_table.class b/src/syntaxParser/java_cup/parse_action_table.class
new file mode 100644
index 0000000..43bfea8
--- /dev/null
+++ b/src/syntaxParser/java_cup/parse_action_table.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/parse_action_table.java b/src/syntaxParser/java_cup/parse_action_table.java
new file mode 100644
index 0000000..1e0edb2
--- /dev/null
+++ b/src/syntaxParser/java_cup/parse_action_table.java
@@ -0,0 +1,143 @@
+
+package java_cup;
+
+import java.util.Enumeration;
+
+/** This class represents the complete "action" table of the parser.
+ * It has one row for each state in the parse machine, and a column for
+ * each terminal symbol. Each entry in the table represents a shift,
+ * reduce, or an error.
+ *
+ * @see java_cup.parse_action
+ * @see java_cup.parse_action_row
+ * @version last updated: 11/25/95
+ * @author Scott Hudson
+ */
+public class parse_action_table {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Simple constructor. All terminals, non-terminals, and productions must
+ * already have been entered, and the viable prefix recognizer should
+ * have been constructed before this is called.
+ */
+ public parse_action_table()
+ {
+ /* determine how many states we are working with */
+ _num_states = lalr_state.number();
+
+ /* allocate the array and fill it in with empty rows */
+ under_state = new parse_action_row[_num_states];
+ for (int i=0; i<_num_states; i++)
+ under_state[i] = new parse_action_row();
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** How many rows/states are in the machine/table. */
+ protected int _num_states;
+
+ /** How many rows/states are in the machine/table. */
+ public int num_states() {return _num_states;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Actual array of rows, one per state. */
+ public parse_action_row[] under_state;
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Check the table to ensure that all productions have been reduced.
+ * Issue a warning message (to System.err) for each production that
+ * is never reduced.
+ */
+ public void check_reductions()
+ throws internal_error
+ {
+ parse_action act;
+ production prod;
+
+ /* tabulate reductions -- look at every table entry */
+ for (int row = 0; row < num_states(); row++)
+ {
+ for (int col = 0; col < under_state[row].size(); col++)
+ {
+ /* look at the action entry to see if its a reduce */
+ act = under_state[row].under_term[col];
+ if (act != null && act.kind() == parse_action.REDUCE)
+ {
+ /* tell production that we used it */
+ ((reduce_action)act).reduce_with().note_reduction_use();
+ }
+ }
+ }
+
+ /* now go across every production and make sure we hit it */
+ for (Enumeration p = production.all(); p.hasMoreElements(); )
+ {
+ prod = (production)p.nextElement();
+
+ /* if we didn't hit it give a warning */
+ if (prod.num_reductions() == 0)
+ {
+ /* count it *
+ emit.not_reduced++;
+
+ /* give a warning if they haven't been turned off */
+ if (!emit.nowarn)
+ {
+ System.err.println("*** Production \"" +
+ prod.to_simple_string() + "\" never reduced");
+ lexer.warning_count++;
+ }
+ }
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*
+
+ /** Convert to a string. */
+ public String toString()
+ {
+ String result;
+ int cnt;
+
+ result = "-------- ACTION_TABLE --------\n";
+ for (int row = 0; row < num_states(); row++)
+ {
+ result += "From state #" + row + "\n";
+ cnt = 0;
+ for (int col = 0; col < under_state[row].size(); col++)
+ {
+ /* if the action is not an error print it */
+ if (under_state[row].under_term[col].kind() != parse_action.ERROR)
+ {
+ result += " [term " + col + ":" + under_state[row].under_term[col] + "]";
+
+ /* end the line after the 2nd one */
+ cnt++;
+ if (cnt == 2)
+ {
+ result += "\n";
+ cnt = 0;
+ }
+ }
+ }
+ /* finish the line if we haven't just done that */
+ if (cnt != 0) result += "\n";
+ }
+ result += "------------------------------";
+
+ return result;
+ }
+
+ /*-----------------------------------------------------------*/
+
+}
+
diff --git a/src/syntaxParser/java_cup/parse_reduce_row.class b/src/syntaxParser/java_cup/parse_reduce_row.class
new file mode 100644
index 0000000..f62f13a
--- /dev/null
+++ b/src/syntaxParser/java_cup/parse_reduce_row.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/parse_reduce_row.java b/src/syntaxParser/java_cup/parse_reduce_row.java
new file mode 100644
index 0000000..57d978e
--- /dev/null
+++ b/src/syntaxParser/java_cup/parse_reduce_row.java
@@ -0,0 +1,41 @@
+
+package java_cup;
+
+/** This class represents one row (corresponding to one machine state) of the
+ * reduce-goto parse table.
+ */
+public class parse_reduce_row {
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Simple constructor. Note: this should not be used until the number
+ * of terminals in the grammar has been established.
+ */
+ public parse_reduce_row()
+ {
+ /* make sure the size is set */
+ if (_size <= 0 ) _size = non_terminal.number();
+
+ /* allocate the array */
+ under_non_term = new lalr_state[size()];
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Static (Class) Variables ------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Number of columns (non terminals) in every row. */
+ protected static int _size = 0;
+
+ /** Number of columns (non terminals) in every row. */
+ public static int size() {return _size;}
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Actual entries for the row. */
+ public lalr_state under_non_term[];
+}
+
diff --git a/src/syntaxParser/java_cup/parse_reduce_table.class b/src/syntaxParser/java_cup/parse_reduce_table.class
new file mode 100644
index 0000000..44211d2
--- /dev/null
+++ b/src/syntaxParser/java_cup/parse_reduce_table.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/parse_reduce_table.java b/src/syntaxParser/java_cup/parse_reduce_table.java
new file mode 100644
index 0000000..9ac1b11
--- /dev/null
+++ b/src/syntaxParser/java_cup/parse_reduce_table.java
@@ -0,0 +1,99 @@
+
+package java_cup;
+
+import java.util.Enumeration;
+
+/** This class represents the complete "reduce-goto" table of the parser.
+ * It has one row for each state in the parse machines, and a column for
+ * each terminal symbol. Each entry contains a state number to shift to
+ * as the last step of a reduce.
+ *
+ * @see java_cup.parse_reduce_row
+ * @version last updated: 11/25/95
+ * @author Scott Hudson
+ */
+public class parse_reduce_table {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Simple constructor. Note: all terminals, non-terminals, and productions
+ * must already have been entered, and the viable prefix recognizer should
+ * have been constructed before this is called.
+ */
+ public parse_reduce_table()
+ {
+ /* determine how many states we are working with */
+ _num_states = lalr_state.number();
+
+ /* allocate the array and fill it in with empty rows */
+ under_state = new parse_reduce_row[_num_states];
+ for (int i=0; i<_num_states; i++)
+ under_state[i] = new parse_reduce_row();
+ }
+
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** How many rows/states in the machine/table. */
+ protected int _num_states;
+
+ /** How many rows/states in the machine/table. */
+ public int num_states() {return _num_states;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Actual array of rows, one per state */
+ public parse_reduce_row[] under_state;
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Convert to a string. */
+ public String toString()
+ {
+ String result;
+ lalr_state goto_st;
+ int cnt;
+
+ result = "-------- REDUCE_TABLE --------\n";
+ for (int row = 0; row < num_states(); row++)
+ {
+ result += "From state #" + row + "\n";
+ cnt = 0;
+ for (int col = 0; col < under_state[row].size(); col++)
+ {
+ /* pull out the table entry */
+ goto_st = under_state[row].under_non_term[col];
+
+ /* if it has action in it, print it */
+ if (goto_st != null)
+ {
+ result += " [non term " + col + "->";
+ result += "state " + goto_st.index() + "]";
+
+ /* end the line after the 3rd one */
+ cnt++;
+ if (cnt == 3)
+ {
+ result += "\n";
+ cnt = 0;
+ }
+ }
+ }
+ /* finish the line if we haven't just done that */
+ if (cnt != 0) result += "\n";
+ }
+ result += "-----------------------------";
+
+ return result;
+ }
+
+ /*-----------------------------------------------------------*/
+
+}
+
diff --git a/src/syntaxParser/java_cup/parser.class b/src/syntaxParser/java_cup/parser.class
new file mode 100644
index 0000000..05af393
--- /dev/null
+++ b/src/syntaxParser/java_cup/parser.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/parser.cup b/src/syntaxParser/java_cup/parser.cup
new file mode 100644
index 0000000..8af0d05
--- /dev/null
+++ b/src/syntaxParser/java_cup/parser.cup
@@ -0,0 +1,863 @@
+
+/*================================================================*/
+/*
+ JavaCup Specification for the JavaCup Specification Language
+ by Scott Hudson, GVU Center, Georgia Tech, August 1995
+ and Frank Flannery, Department of Computer Science, Princeton Univ,
+ July 1996
+ Bug Fixes: C. Scott Ananian, Dept of Electrical Engineering, Princeton
+ University, October 1996. [later Massachusetts Institute of Technology]
+
+
+ This JavaCup specification is used to implement JavaCup itself.
+ It specifies the parser for the JavaCup specification language.
+ (It also serves as a reasonable example of what a typical JavaCup
+ spec looks like).
+
+ The specification has the following parts:
+ Package and import declarations
+ These serve the same purpose as in a normal Java source file
+ (and will appear in the generated code for the parser). In this
+ case we are part of the java_cup package and we import both the
+ java_cup runtime system and Hashtable from the standard Java
+ utilities package.
+
+ Action code
+ This section provides code that is included with the class encapsulating
+ the various pieces of user code embedded in the grammar (i.e., the
+ semantic actions). This provides a series of helper routines and
+ data structures that the semantic actions use.
+
+ Parser code
+ This section provides code included in the parser class itself. In
+ this case we override the default error reporting routines.
+
+ Init with and scan with
+ These sections provide small bits of code that initialize, then
+ indicate how to invoke the scanner.
+
+ Symbols and grammar
+ These sections declare all the terminal and non terminal symbols
+ and the types of objects that they will be represented by at runtime,
+ then indicate the start symbol of the grammar (), and finally provide
+ the grammar itself (with embedded actions).
+
+ Operation of the parser
+ The parser acts primarily by accumulating data structures representing
+ various parts of the specification. Various small parts (e.g., single
+ code strings) are stored as static variables of the emit class and
+ in a few cases as variables declared in the action code section.
+ Terminals, non terminals, and productions, are maintained as collection
+ accessible via static methods of those classes. In addition, two
+ symbol tables are kept:
+ symbols maintains the name to object mapping for all symbols
+ non_terms maintains a separate mapping containing only the non terms
+
+ Several intermediate working structures are also declared in the action
+ code section. These include: rhs_parts, rhs_pos, and lhs_nt which
+ build up parts of the current production while it is being parsed.
+
+ Author(s)
+ Scott Hudson, GVU Center, Georgia Tech.
+ Frank Flannery, Department of Computer Science, Princeton Univ.
+ C. Scott Ananian, Department of Electrical Engineering, Princeton Univ.
+
+ Revisions
+ v0.9a First released version [SEH] 8/29/95
+ v0.9b Updated for beta language (throws clauses) [SEH] 11/25/95
+ v0.10a Made many improvements/changes. now offers:
+ return value
+ left/right positions and propagations
+ cleaner label references
+ precedence and associativity for terminals
+ contextual precedence for productions
+ [FF] 7/3/96
+ v0.10b Fixed %prec directive so it works like it's supposed to.
+ [CSA] 10/10/96
+ v0.10g Added support for array types on symbols.
+ [CSA] 03/23/98
+ v0.10i Broaden set of IDs allowed in multipart_id and label_id so
+ that only java reserved words (and not CUP reserved words like
+ 'parser' and 'start') are prohibited. Allow reordering of
+ action code, parser code, init code, and scan with sections,
+ and made closing semicolon optional for these sections.
+ Added 'nonterminal' as a terminal symbol, finally fixing a
+ spelling mistake that's been around since the beginning.
+ For backwards compatibility, you can still misspell the
+ word if you like.
+*/
+/*================================================================*/
+
+package java_cup;
+import java_cup.runtime.*;
+import java.util.Hashtable;
+
+/*----------------------------------------------------------------*/
+
+action code {:
+ /** helper routine to clone a new production part adding a given label */
+ protected production_part add_lab(production_part part, String lab)
+ throws internal_error
+ {
+ /* if there is no label, or this is an action, just return the original */
+ if (lab == null || part.is_action()) return part;
+
+ /* otherwise build a new one with the given label attached */
+ return new symbol_part(((symbol_part)part).the_symbol(),lab);
+ }
+
+ /** max size of right hand side we will support */
+ protected final int MAX_RHS = 200;
+
+ /** array for accumulating right hand side parts */
+ protected production_part[] rhs_parts = new production_part[MAX_RHS];
+
+ /** where we are currently in building a right hand side */
+ protected int rhs_pos = 0;
+
+ /** start a new right hand side */
+ protected void new_rhs() {rhs_pos = 0; }
+
+ /** add a new right hand side part */
+ protected void add_rhs_part(production_part part) throws java.lang.Exception
+ {
+ if (rhs_pos >= MAX_RHS)
+ throw new Exception("Internal Error: Productions limited to " +
+ MAX_RHS + " symbols and actions");
+
+ rhs_parts[rhs_pos] = part;
+ rhs_pos++;
+ }
+
+ /** string to build up multiple part names */
+ protected String multipart_name = new String();
+
+ /** append a new name segment to the accumulated multipart name */
+ protected void append_multipart(String name)
+ {
+ String dot = "";
+
+ /* if we aren't just starting out, put on a dot */
+ if (multipart_name.length() != 0) dot = ".";
+
+ multipart_name = multipart_name.concat(dot + name);
+ }
+
+ /** table of declared symbols -- contains production parts indexed by name */
+ protected Hashtable symbols = new Hashtable();
+
+ /** table of just non terminals -- contains non_terminals indexed by name */
+ protected Hashtable non_terms = new Hashtable();
+
+ /** declared start non_terminal */
+ protected non_terminal start_nt = null;
+
+ /** left hand side non terminal of the current production */
+ protected non_terminal lhs_nt;
+
+ /** Current precedence number */
+ int _cur_prec = 0;
+
+ /** Current precedence side */
+ int _cur_side = assoc.no_prec;
+
+ /** update the precedences we are declaring */
+ protected void update_precedence(int p) {
+ _cur_side = p;
+ _cur_prec++;
+ }
+ /** add relevant data to terminals */
+ protected void add_precedence(String term) {
+ if (term == null) {
+ System.err.println("Unable to add precedence to nonexistent terminal");
+ } else {
+ symbol_part sp = (symbol_part)symbols.get(term);
+ if (sp == null) {
+ System.err.println("Could find terminal " + term + " while declaring precedence");
+ } else {
+ java_cup.symbol sym = sp.the_symbol();
+ if (sym instanceof terminal)
+ ((terminal)sym).set_precedence(_cur_side, _cur_prec);
+ else System.err.println("Precedence declaration: Can't find terminal " + term);
+ }
+ }
+ }
+:};
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+parser code {:
+
+ /* override error routines */
+
+ public void report_fatal_error(
+ String message,
+ Object info)
+ {
+ done_parsing();
+ lexer.emit_error(message);
+ System.err.println("Can't recover from previous error(s), giving up.");
+ System.exit(1);
+ }
+
+ public void report_error(String message, Object info)
+ {
+ lexer.emit_error(message);
+ }
+:};
+
+/*----------------------------------------------------------------*/
+
+init with {: lexer.init(); :};
+scan with {: return lexer.next_token(); :};
+
+/*----------------------------------------------------------------*/
+
+terminal
+ PACKAGE, IMPORT, CODE, ACTION, PARSER, TERMINAL, NON, INIT, SCAN, WITH,
+ START, SEMI, COMMA, STAR, DOT, COLON, COLON_COLON_EQUALS, BAR, PRECEDENCE,
+ LEFT, RIGHT, NONASSOC, PERCENT_PREC, LBRACK, RBRACK, NONTERMINAL;
+
+terminal String ID, CODE_STRING;
+
+non terminal
+ spec, package_spec, import_list, action_code_part,
+ code_parts, code_part, opt_semi, non_terminal,
+ parser_code_part, symbol_list, start_spec, production_list,
+ multipart_id, import_spec, import_id, init_code, scan_code, symbol,
+ type_id, term_name_list, non_term_name_list, production, prod_part_list,
+ prod_part, new_term_id, new_non_term_id, rhs_list, rhs, empty,
+ precedence_list, preced, terminal_list, precedence_l, declares_term,
+ declares_non_term;
+
+non terminal String nt_id, symbol_id, label_id, opt_label, terminal_id,
+ term_id, robust_id;
+
+/*----------------------------------------------------------------*/
+
+start with spec;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+spec ::=
+ {:
+ /* declare "error" as a terminal */
+ symbols.put("error", new symbol_part(terminal.error));
+
+ /* declare start non terminal */
+ non_terms.put("$START", non_terminal.START_nt);
+ :}
+ package_spec
+ import_list
+ code_parts
+ symbol_list
+ precedence_list
+ start_spec
+ production_list
+ |
+ /* error recovery assuming something went wrong before symbols
+ and we have TERMINAL or NON TERMINAL to sync on. if we get
+ an error after that, we recover inside symbol_list or
+ production_list
+ */
+ error
+ symbol_list
+ precedence_list
+ start_spec
+ production_list
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+package_spec ::=
+ PACKAGE
+ multipart_id
+ {:
+ /* save the package name */
+ emit.package_name = multipart_name;
+
+ /* reset the accumulated multipart name */
+ multipart_name = new String();
+ :}
+ SEMI
+ |
+ empty
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+import_list ::=
+ import_list
+ import_spec
+ |
+ empty
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+import_spec ::=
+ IMPORT
+ import_id
+ {:
+ /* save this import on the imports list */
+ emit.import_list.push(multipart_name);
+
+ /* reset the accumulated multipart name */
+ multipart_name = new String();
+ :}
+ SEMI
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+// allow any order; all parts are optional. [CSA, 23-Jul-1999]
+// (we check in the part action to make sure we don't have 2 of any part)
+code_part ::=
+ action_code_part | parser_code_part | init_code | scan_code ;
+code_parts ::=
+ | code_parts code_part;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+action_code_part ::=
+ ACTION CODE CODE_STRING:user_code opt_semi
+ {:
+ if (emit.action_code!=null)
+ lexer.emit_error("Redundant action code (skipping)");
+ else /* save the user included code string */
+ emit.action_code = user_code;
+ :}
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+parser_code_part ::=
+ PARSER CODE CODE_STRING:user_code opt_semi
+ {:
+ if (emit.parser_code!=null)
+ lexer.emit_error("Redundant parser code (skipping)");
+ else /* save the user included code string */
+ emit.parser_code = user_code;
+ :}
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+init_code ::=
+ INIT WITH CODE_STRING:user_code opt_semi
+ {:
+ if (emit.init_code!=null)
+ lexer.emit_error("Redundant init code (skipping)");
+ else /* save the user code */
+ emit.init_code = user_code;
+ :}
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+scan_code ::=
+ SCAN WITH CODE_STRING:user_code opt_semi
+ {:
+ if (emit.scan_code!=null)
+ lexer.emit_error("Redundant scan code (skipping)");
+ else /* save the user code */
+ emit.scan_code = user_code;
+ :}
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+symbol_list ::= symbol_list symbol | symbol;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+symbol ::=
+ TERMINAL
+ type_id
+ declares_term
+ |
+ TERMINAL
+ declares_term
+ |
+ non_terminal
+ type_id
+ declares_non_term
+ |
+ non_terminal
+ declares_non_term
+ |
+ /* error recovery productions -- sync on semicolon */
+
+ TERMINAL
+ error
+ {:
+ /* reset the accumulated multipart name */
+ multipart_name = new String();
+ :}
+ SEMI
+ |
+ non_terminal
+ error
+ {:
+ /* reset the accumulated multipart name */
+ multipart_name = new String();
+ :}
+ SEMI
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+declares_term ::=
+ term_name_list
+ {:
+ /* reset the accumulated multipart name */
+ multipart_name = new String();
+ :}
+ SEMI
+ ;
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+declares_non_term ::=
+ non_term_name_list
+ {:
+ /* reset the accumulated multipart name */
+ multipart_name = new String();
+ :}
+ SEMI
+ ;
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+term_name_list ::= term_name_list COMMA new_term_id | new_term_id;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+non_term_name_list ::=
+ non_term_name_list
+ COMMA
+ new_non_term_id
+ |
+ new_non_term_id
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+
+precedence_list ::= precedence_l | empty;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+precedence_l ::= precedence_l preced | preced;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+preced ::=
+ PRECEDENCE LEFT
+ {:
+ update_precedence(assoc.left);
+ :}
+ terminal_list SEMI
+ |
+ PRECEDENCE RIGHT
+ {:
+ update_precedence(assoc.right);
+ :}
+ terminal_list SEMI
+ |
+ PRECEDENCE NONASSOC
+ {:
+ update_precedence(assoc.nonassoc);
+ :}
+ terminal_list SEMI
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+terminal_list ::= terminal_list COMMA terminal_id
+ |
+ terminal_id
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+terminal_id ::= term_id:sym
+ {:
+ add_precedence(sym);
+ RESULT = sym;
+ :};
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+term_id ::= symbol_id:sym
+ {:
+ /* check that the symbol_id is a terminal */
+ if (symbols.get(sym) == null)
+ {
+ /* issue a message */
+ lexer.emit_error("Terminal \"" + sym +
+ "\" has not been declared");
+ }
+ RESULT = sym;
+ :};
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+start_spec ::=
+ START WITH nt_id:start_name
+ {:
+ /* verify that the name has been declared as a non terminal */
+ non_terminal nt = (non_terminal)non_terms.get(start_name);
+ if (nt == null)
+ {
+ lexer.emit_error( "Start non terminal \"" + start_name +
+ "\" has not been declared");
+ }
+ else
+ {
+ /* remember the non-terminal for later */
+ start_nt = nt;
+
+ /* build a special start production */
+ new_rhs();
+ add_rhs_part(add_lab(new symbol_part(start_nt), "start_val"));
+ add_rhs_part(new symbol_part(terminal.EOF));
+ add_rhs_part(new action_part("RESULT = start_val;"));
+ emit.start_production =
+ new production(non_terminal.START_nt, rhs_parts, rhs_pos);
+ new_rhs();
+ }
+ :}
+ SEMI
+ |
+ empty
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+production_list ::= production_list production | production;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+production ::=
+ nt_id:lhs_id
+ {:
+ /* lookup the lhs nt */
+ lhs_nt = (non_terminal)non_terms.get(lhs_id);
+
+ /* if it wasn't declared, emit a message */
+ if (lhs_nt == null)
+ {
+ if (lexer.error_count == 0)
+ lexer.emit_error("LHS non terminal \"" + lhs_id +
+ "\" has not been declared");
+ }
+
+ /* reset the rhs accumulation */
+ new_rhs();
+ :}
+ COLON_COLON_EQUALS
+ {: :}
+ rhs_list
+ SEMI
+ |
+ error
+ {: lexer.emit_error("Syntax Error"); :}
+ SEMI
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+rhs_list ::= rhs_list BAR rhs | rhs;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+rhs ::=
+ prod_part_list PERCENT_PREC term_id:term_name
+ {:
+ java_cup.symbol sym = null;
+ if (lhs_nt != null)
+ {
+ /* Find the precedence symbol */
+ if (term_name == null) {
+ System.err.println("No terminal for contextual precedence");
+ sym = null;
+ } else {
+ sym = ((symbol_part)symbols.get(term_name)).the_symbol();
+ }
+ /* build the production */
+ production p;
+ if ((sym!=null) && (sym instanceof terminal)) {
+ p = new production(lhs_nt, rhs_parts, rhs_pos,
+ ((terminal)sym).precedence_num(),
+ ((terminal)sym).precedence_side());
+ ((symbol_part)symbols.get(term_name)).the_symbol().note_use();
+ } else {
+ System.err.println("Invalid terminal " + term_name +
+ " for contextual precedence assignment");
+ p = new production(lhs_nt, rhs_parts, rhs_pos);
+ }
+
+ /* if we have no start non-terminal declared and this is
+ the first production, make its lhs nt the start_nt
+ and build a special start production for it. */
+ if (start_nt == null)
+ {
+ start_nt = lhs_nt;
+
+ /* build a special start production */
+ new_rhs();
+ add_rhs_part(add_lab(new symbol_part(start_nt),"start_val"));
+ add_rhs_part(new symbol_part(terminal.EOF));
+ add_rhs_part(new action_part("RESULT = start_val;"));
+ if ((sym!=null) && (sym instanceof terminal)) {
+ emit.start_production =
+ new production(non_terminal.START_nt, rhs_parts,
+ rhs_pos, ((terminal)sym).precedence_num(),
+ ((terminal)sym).precedence_side());
+ } else {
+ emit.start_production =
+ new production(non_terminal.START_nt, rhs_parts, rhs_pos);
+ }
+ new_rhs();
+ }
+ }
+
+ /* reset the rhs accumulation in any case */
+ new_rhs();
+ :}
+ |
+ prod_part_list
+ {:
+ if (lhs_nt != null)
+ {
+ /* build the production */
+ production p = new production(lhs_nt, rhs_parts, rhs_pos);
+
+ /* if we have no start non-terminal declared and this is
+ the first production, make its lhs nt the start_nt
+ and build a special start production for it. */
+ if (start_nt == null)
+ {
+ start_nt = lhs_nt;
+
+ /* build a special start production */
+ new_rhs();
+ add_rhs_part(add_lab(new symbol_part(start_nt),"start_val"));
+ add_rhs_part(new symbol_part(terminal.EOF));
+ add_rhs_part(new action_part("RESULT = start_val;"));
+ emit.start_production =
+ new production(non_terminal.START_nt, rhs_parts, rhs_pos);
+
+ new_rhs();
+ }
+ }
+
+ /* reset the rhs accumulation in any case */
+ new_rhs();
+ :}
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+prod_part_list ::= prod_part_list prod_part | empty;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+prod_part ::=
+ symbol_id:symid opt_label:labid
+ {:
+ /* try to look up the id */
+ production_part symb = (production_part)symbols.get(symid);
+
+ /* if that fails, symbol is undeclared */
+ if (symb == null)
+ {
+ if (lexer.error_count == 0)
+ lexer.emit_error("java_cup.runtime.Symbol \"" + symid +
+ "\" has not been declared");
+ }
+ else
+ {
+ /* add a labeled production part */
+ add_rhs_part(add_lab(symb, labid));
+ }
+ :}
+ |
+ CODE_STRING:code_str
+ {:
+ /* add a new production part */
+ add_rhs_part(new action_part(code_str));
+ :}
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+opt_label ::=
+ COLON label_id:labid
+ {: RESULT = labid; :}
+ |
+ empty
+ {: RESULT = null; :}
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+multipart_id ::=
+ multipart_id DOT robust_id:another_id
+ {: append_multipart(another_id); :}
+ |
+ robust_id:an_id
+ {: append_multipart(an_id); :}
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+import_id ::=
+ multipart_id DOT STAR
+ {: append_multipart("*"); :}
+ |
+ multipart_id
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+type_id ::= multipart_id
+ | type_id LBRACK RBRACK
+ {: multipart_name = multipart_name.concat("[]"); :}
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+new_term_id ::=
+ ID:term_id
+ {:
+ /* see if this terminal has been declared before */
+ if (symbols.get(term_id) != null)
+ {
+ /* issue a message */
+ lexer.emit_error("java_cup.runtime.Symbol \"" + term_id +
+ "\" has already been declared");
+ }
+ else
+ {
+ /* if no type declared, declare one */
+ if (multipart_name.equals("")) {
+ append_multipart("Object");
+ }
+ /* build a production_part and put it in the table */
+ symbols.put(term_id,
+ new symbol_part(new terminal(term_id, multipart_name)));
+ }
+ :}
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+new_non_term_id ::=
+ ID:non_term_id
+ {:
+ /* see if this non terminal has been declared before */
+ if (symbols.get(non_term_id) != null)
+ {
+ /* issue a message */
+ lexer.emit_error( "java_cup.runtime.Symbol \"" + non_term_id +
+ "\" has already been declared");
+ }
+ else
+ {
+ if (multipart_name.equals("")) {
+ append_multipart("Object");
+ }
+ /* build the non terminal object */
+ non_terminal this_nt =
+ new non_terminal(non_term_id, multipart_name);
+
+ /* put it in the non_terms table */
+ non_terms.put(non_term_id, this_nt);
+
+ /* build a production_part and put it in the symbols table */
+ symbols.put(non_term_id, new symbol_part(this_nt));
+ }
+ :}
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+nt_id ::=
+ ID:the_id
+ {: RESULT = the_id; :}
+ | error
+ {:
+ lexer.emit_error("Illegal use of reserved word");
+ RESULT="ILLEGAL";
+ :}
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+symbol_id ::=
+ ID:the_id
+ {: RESULT = the_id; :}
+ | error
+ {:
+ lexer.emit_error("Illegal use of reserved word");
+ RESULT="ILLEGAL";
+ :}
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+label_id ::=
+ robust_id:the_id
+ {: RESULT = the_id; :}
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+robust_id ::= /* all ids that aren't reserved words in Java */
+ ID:the_id {: RESULT = the_id; :}
+ /* package is reserved. */
+ /* import is reserved. */
+ | CODE {: RESULT = "code"; :}
+ | ACTION {: RESULT = "action"; :}
+ | PARSER {: RESULT = "parser"; :}
+ | TERMINAL {: RESULT = "terminal"; :}
+ | NON {: RESULT = "non"; :}
+ | NONTERMINAL {: RESULT = "nonterminal"; :}
+ | INIT {: RESULT = "init"; :}
+ | SCAN {: RESULT = "scan"; :}
+ | WITH {: RESULT = "with"; :}
+ | START {: RESULT = "start"; :}
+ | PRECEDENCE {: RESULT = "precedence"; :}
+ | LEFT {: RESULT = "left"; :}
+ | RIGHT {: RESULT = "right"; :}
+ | NONASSOC {: RESULT = "nonassoc"; :}
+ | error
+ {:
+ lexer.emit_error("Illegal use of reserved word");
+ RESULT="ILLEGAL";
+ :}
+ ;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+non_terminal ::= NON TERMINAL | NONTERMINAL;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+opt_semi ::= /* nothing */
+ | SEMI;
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+empty ::= /* nothing */;
+
+/*----------------------------------------------------------------*/
+
+
+
+
+
+
+
+
+
diff --git a/src/syntaxParser/java_cup/parser.java b/src/syntaxParser/java_cup/parser.java
new file mode 100644
index 0000000..163968e
--- /dev/null
+++ b/src/syntaxParser/java_cup/parser.java
@@ -0,0 +1,1849 @@
+
+//----------------------------------------------------
+// The following code was generated by CUP v0.10k
+// Sun Jul 25 13:35:26 EDT 1999
+//----------------------------------------------------
+
+package java_cup;
+
+import java_cup.runtime.*;
+import java.util.Hashtable;
+
+/** CUP v0.10k generated parser.
+ * @version Sun Jul 25 13:35:26 EDT 1999
+ */
+public class parser extends java_cup.runtime.lr_parser {
+
+ /** Default constructor. */
+ public parser() {super();}
+
+ /** Constructor which sets the default scanner. */
+ public parser(java_cup.runtime.Scanner s) {super(s);}
+
+ /** Production table. */
+ protected static final short _production_table[][] =
+ unpackFromStrings(new String[] {
+ "\000\153\000\002\002\004\000\002\055\002\000\002\003" +
+ "\012\000\002\003\007\000\002\056\002\000\002\004\006" +
+ "\000\002\004\003\000\002\005\004\000\002\005\003\000" +
+ "\002\057\002\000\002\020\006\000\002\010\003\000\002" +
+ "\010\003\000\002\010\003\000\002\010\003\000\002\007" +
+ "\002\000\002\007\004\000\002\006\006\000\002\013\006" +
+ "\000\002\022\006\000\002\023\006\000\002\014\004\000" +
+ "\002\014\003\000\002\024\005\000\002\024\004\000\002" +
+ "\024\005\000\002\024\004\000\002\060\002\000\002\024" +
+ "\006\000\002\061\002\000\002\024\006\000\002\062\002" +
+ "\000\002\044\005\000\002\063\002\000\002\045\005\000" +
+ "\002\026\005\000\002\026\003\000\002\027\005\000\002" +
+ "\027\003\000\002\040\003\000\002\040\003\000\002\043" +
+ "\004\000\002\043\003\000\002\064\002\000\002\041\007" +
+ "\000\002\065\002\000\002\041\007\000\002\066\002\000" +
+ "\002\041\007\000\002\042\005\000\002\042\003\000\002" +
+ "\052\003\000\002\053\003\000\002\067\002\000\002\015" +
+ "\007\000\002\015\003\000\002\016\004\000\002\016\003" +
+ "\000\002\070\002\000\002\071\002\000\002\030\010\000" +
+ "\002\072\002\000\002\030\005\000\002\035\005\000\002" +
+ "\035\003\000\002\036\005\000\002\036\003\000\002\031" +
+ "\004\000\002\031\003\000\002\032\004\000\002\032\003" +
+ "\000\002\051\004\000\002\051\003\000\002\017\005\000" +
+ "\002\017\003\000\002\021\005\000\002\021\003\000\002" +
+ "\025\003\000\002\025\005\000\002\033\003\000\002\034" +
+ "\003\000\002\046\003\000\002\046\003\000\002\047\003" +
+ "\000\002\047\003\000\002\050\003\000\002\054\003\000" +
+ "\002\054\003\000\002\054\003\000\002\054\003\000\002" +
+ "\054\003\000\002\054\003\000\002\054\003\000\002\054" +
+ "\003\000\002\054\003\000\002\054\003\000\002\054\003" +
+ "\000\002\054\003\000\002\054\003\000\002\054\003\000" +
+ "\002\054\003\000\002\054\003\000\002\012\004\000\002" +
+ "\012\003\000\002\011\002\000\002\011\003\000\002\037" +
+ "\002" });
+
+ /** Access to production table. */
+ public short[][] production_table() {return _production_table;}
+
+ /** Parse-action table. */
+ protected static final short[][] _action_table =
+ unpackFromStrings(new String[] {
+ "\000\247\000\026\003\006\004\000\005\000\007\000\010" +
+ "\000\011\000\012\000\013\000\014\000\035\000\001\002" +
+ "\000\004\002\251\001\002\000\024\004\200\005\uff97\007" +
+ "\uff97\010\uff97\011\uff97\012\uff97\013\uff97\014\uff97\035\uff97" +
+ "\001\002\000\010\011\007\012\012\035\014\001\002\000" +
+ "\042\003\163\006\026\007\027\010\040\011\036\012\022" +
+ "\013\042\014\030\015\017\016\015\026\033\027\023\030" +
+ "\035\031\041\035\025\036\160\001\002\000\020\003\uffeb" +
+ "\011\uffeb\012\uffeb\016\uffeb\026\uffeb\035\uffeb\036\uffeb\001" +
+ "\002\000\020\003\uff97\011\007\012\012\016\uff97\026\065" +
+ "\035\014\036\uff97\001\002\000\004\011\061\001\002\000" +
+ "\042\003\034\006\026\007\027\010\040\011\036\012\022" +
+ "\013\042\014\030\015\017\016\015\026\033\027\023\030" +
+ "\035\031\041\035\025\036\016\001\002\000\042\003\uff9a" +
+ "\006\uff9a\007\uff9a\010\uff9a\011\uff9a\012\uff9a\013\uff9a\014" +
+ "\uff9a\015\uff9a\016\uff9a\026\uff9a\027\uff9a\030\uff9a\031\uff9a" +
+ "\035\uff9a\036\uff9a\001\002\000\022\003\uffa1\017\uffa1\022" +
+ "\uffa1\025\uffa1\032\uffa1\033\uffa1\036\uffa1\037\uffa1\001\002" +
+ "\000\014\017\uffb1\020\uffb1\022\uffab\033\uffab\036\uffab\001" +
+ "\002\000\022\003\uffa2\017\uffa2\022\uffa2\025\uffa2\032\uffa2" +
+ "\033\uffa2\036\uffa2\037\uffa2\001\002\000\006\017\uffe0\020" +
+ "\055\001\002\000\010\022\051\033\uffb4\036\uffb4\001\002" +
+ "\000\022\003\uffa6\017\uffa6\022\uffa6\025\uffa6\032\uffa6\033" +
+ "\uffa6\036\uffa6\037\uffa6\001\002\000\022\003\uff9f\017\uff9f" +
+ "\022\uff9f\025\uff9f\032\uff9f\033\uff9f\036\uff9f\037\uff9f\001" +
+ "\002\000\006\033\047\036\045\001\002\000\022\003\uffa5" +
+ "\017\uffa5\022\uffa5\025\uffa5\032\uffa5\033\uffa5\036\uffa5\037" +
+ "\uffa5\001\002\000\022\003\uffaa\017\uffaa\022\uffaa\025\uffaa" +
+ "\032\uffaa\033\uffaa\036\uffaa\037\uffaa\001\002\000\022\003" +
+ "\uffa9\017\uffa9\022\uffa9\025\uffa9\032\uffa9\033\uffa9\036\uffa9" +
+ "\037\uffa9\001\002\000\022\003\uffa3\017\uffa3\022\uffa3\025" +
+ "\uffa3\032\uffa3\033\uffa3\036\uffa3\037\uffa3\001\002\000\012" +
+ "\017\uffb7\022\uffb7\033\uffb7\036\uffb7\001\002\000\020\003" +
+ "\uffe7\011\uffe7\012\uffe7\016\uffe7\026\uffe7\035\uffe7\036\uffe7" +
+ "\001\002\000\022\003\uffa0\017\uffa0\022\uffa0\025\uffa0\032" +
+ "\uffa0\033\uffa0\036\uffa0\037\uffa0\001\002\000\012\017\uffe4" +
+ "\022\uff9c\033\uff9c\036\uff9c\001\002\000\022\003\uff9e\017" +
+ "\uff9e\022\uff9e\025\uff9e\032\uff9e\033\uff9e\036\uff9e\037\uff9e" +
+ "\001\002\000\022\003\uffa7\017\uffa7\022\uffa7\025\uffa7\032" +
+ "\uffa7\033\uffa7\036\uffa7\037\uffa7\001\002\000\006\017\uffdb" +
+ "\020\uffdb\001\002\000\022\003\uffa8\017\uffa8\022\uffa8\025" +
+ "\uffa8\032\uffa8\033\uffa8\036\uffa8\037\uffa8\001\002\000\022" +
+ "\003\uff9d\017\uff9d\022\uff9d\025\uff9d\032\uff9d\033\uff9d\036" +
+ "\uff9d\037\uff9d\001\002\000\022\003\uffa4\017\uffa4\022\uffa4" +
+ "\025\uffa4\032\uffa4\033\uffa4\036\uffa4\037\uffa4\001\002\000" +
+ "\004\017\044\001\002\000\020\003\uffe3\011\uffe3\012\uffe3" +
+ "\016\uffe3\026\uffe3\035\uffe3\036\uffe3\001\002\000\006\017" +
+ "\uffb1\020\uffb1\001\002\000\020\003\uffe8\011\uffe8\012\uffe8" +
+ "\016\uffe8\026\uffe8\035\uffe8\036\uffe8\001\002\000\004\034" +
+ "\050\001\002\000\006\033\uffb3\036\uffb3\001\002\000\042" +
+ "\003\054\006\026\007\027\010\040\011\036\012\022\013" +
+ "\042\014\030\015\017\016\015\026\033\027\023\030\035" +
+ "\031\041\035\025\036\053\001\002\000\012\017\uffb8\022" +
+ "\uffb8\033\uffb8\036\uffb8\001\002\000\022\003\uffab\017\uffab" +
+ "\022\uffab\025\uffab\032\uffab\033\uffab\036\uffab\037\uffab\001" +
+ "\002\000\022\003\uff9c\017\uff9c\022\uff9c\025\uff9c\032\uff9c" +
+ "\033\uff9c\036\uff9c\037\uff9c\001\002\000\004\036\045\001" +
+ "\002\000\004\017\057\001\002\000\020\003\uffdf\011\uffdf" +
+ "\012\uffdf\016\uffdf\026\uffdf\035\uffdf\036\uffdf\001\002\000" +
+ "\006\017\uffdc\020\uffdc\001\002\000\042\003\uff9b\006\uff9b" +
+ "\007\uff9b\010\uff9b\011\uff9b\012\uff9b\013\uff9b\014\uff9b\015" +
+ "\uff9b\016\uff9b\026\uff9b\027\uff9b\030\uff9b\031\uff9b\035\uff9b" +
+ "\036\uff9b\001\002\000\010\003\uff97\016\116\036\uff97\001" +
+ "\002\000\012\003\uffda\016\uffda\026\065\036\uffda\001\002" +
+ "\000\010\003\uffd9\016\uffd9\036\uffd9\001\002\000\010\027" +
+ "\071\030\072\031\070\001\002\000\020\003\uffec\011\uffec" +
+ "\012\uffec\016\uffec\026\uffec\035\uffec\036\uffec\001\002\000" +
+ "\012\003\uffd7\016\uffd7\026\uffd7\036\uffd7\001\002\000\006" +
+ "\003\uffd2\036\uffd2\001\002\000\006\003\uffd6\036\uffd6\001" +
+ "\002\000\006\003\uffd4\036\uffd4\001\002\000\006\003\077" +
+ "\036\074\001\002\000\022\003\uffae\017\uffae\020\uffae\023" +
+ "\uffae\025\uffae\032\uffae\036\uffae\037\uffae\001\002\000\010" +
+ "\017\uffcd\020\uffcd\025\uffcd\001\002\000\006\017\uffce\020" +
+ "\uffce\001\002\000\022\003\uffad\017\uffad\020\uffad\023\uffad" +
+ "\025\uffad\032\uffad\036\uffad\037\uffad\001\002\000\006\017" +
+ "\102\020\103\001\002\000\006\017\uffcf\020\uffcf\001\002" +
+ "\000\012\003\uffd3\016\uffd3\026\uffd3\036\uffd3\001\002\000" +
+ "\006\003\077\036\074\001\002\000\006\017\uffd0\020\uffd0" +
+ "\001\002\000\006\003\077\036\074\001\002\000\006\017" +
+ "\107\020\103\001\002\000\012\003\uffd5\016\uffd5\026\uffd5" +
+ "\036\uffd5\001\002\000\006\003\077\036\074\001\002\000" +
+ "\006\017\112\020\103\001\002\000\012\003\uffd1\016\uffd1" +
+ "\026\uffd1\036\uffd1\001\002\000\012\003\uffd8\016\uffd8\026" +
+ "\uffd8\036\uffd8\001\002\000\006\003\uffca\036\uffca\001\002" +
+ "\000\006\003\126\036\120\001\002\000\004\015\117\001" +
+ "\002\000\006\003\122\036\120\001\002\000\006\017\uffb0" +
+ "\024\uffb0\001\002\000\004\017\uffcc\001\002\000\004\017" +
+ "\uffaf\001\002\000\004\017\124\001\002\000\006\003\uffcb" +
+ "\036\uffcb\001\002\000\004\024\uffc7\001\002\000\006\017" +
+ "\uffc4\024\uffaf\001\002\000\010\002\ufffe\003\126\036\120" +
+ "\001\002\000\010\002\uffc8\003\uffc8\036\uffc8\001\002\000" +
+ "\010\002\uffc9\003\uffc9\036\uffc9\001\002\000\004\017\133" +
+ "\001\002\000\010\002\uffc3\003\uffc3\036\uffc3\001\002\000" +
+ "\004\024\135\001\002\000\016\003\uffc6\017\uffc6\025\uffc6" +
+ "\032\uffc6\036\uffc6\037\uffc6\001\002\000\016\003\uff97\017" +
+ "\uff97\025\uff97\032\uff97\036\uff97\037\uff97\001\002\000\016" +
+ "\003\uffbd\017\uffbd\025\uffbd\032\uffbd\036\uffbd\037\uffbd\001" +
+ "\002\000\016\003\077\017\uffbf\025\uffbf\032\147\036\074" +
+ "\037\146\001\002\000\006\017\uffc1\025\uffc1\001\002\000" +
+ "\006\017\143\025\144\001\002\000\010\002\uffc5\003\uffc5" +
+ "\036\uffc5\001\002\000\016\003\uff97\017\uff97\025\uff97\032" +
+ "\uff97\036\uff97\037\uff97\001\002\000\006\017\uffc2\025\uffc2" +
+ "\001\002\000\016\003\uffbb\017\uffbb\025\uffbb\032\uffbb\036" +
+ "\uffbb\037\uffbb\001\002\000\006\003\077\036\074\001\002" +
+ "\000\020\003\uff97\017\uff97\023\154\025\uff97\032\uff97\036" +
+ "\uff97\037\uff97\001\002\000\016\003\uffbe\017\uffbe\025\uffbe" +
+ "\032\uffbe\036\uffbe\037\uffbe\001\002\000\016\003\uffb9\017" +
+ "\uffb9\025\uffb9\032\uffb9\036\uffb9\037\uffb9\001\002\000\016" +
+ "\003\uffbc\017\uffbc\025\uffbc\032\uffbc\036\uffbc\037\uffbc\001" +
+ "\002\000\042\003\054\006\026\007\027\010\040\011\036" +
+ "\012\022\013\042\014\030\015\017\016\015\026\033\027" +
+ "\023\030\035\031\041\035\025\036\053\001\002\000\016" +
+ "\003\uffba\017\uffba\025\uffba\032\uffba\036\uffba\037\uffba\001" +
+ "\002\000\016\003\uffac\017\uffac\025\uffac\032\uffac\036\uffac" +
+ "\037\uffac\001\002\000\006\017\uffc0\025\uffc0\001\002\000" +
+ "\014\017\uffb2\020\uffb2\022\uffab\033\uffab\036\uffab\001\002" +
+ "\000\006\033\047\036\170\001\002\000\006\017\uffdd\020" +
+ "\uffdd\001\002\000\012\017\uffe6\022\uff9c\033\uff9c\036\uff9c" +
+ "\001\002\000\020\003\uffe9\011\uffe9\012\uffe9\016\uffe9\026" +
+ "\uffe9\035\uffe9\036\uffe9\001\002\000\006\017\uffe2\020\167" +
+ "\001\002\000\004\017\172\001\002\000\004\036\170\001" +
+ "\002\000\006\017\uffb2\020\uffb2\001\002\000\006\017\uffde" +
+ "\020\uffde\001\002\000\020\003\uffe1\011\uffe1\012\uffe1\016" +
+ "\uffe1\026\uffe1\035\uffe1\036\uffe1\001\002\000\004\017\174" +
+ "\001\002\000\020\003\uffe5\011\uffe5\012\uffe5\016\uffe5\026" +
+ "\uffe5\035\uffe5\036\uffe5\001\002\000\020\003\uffea\011\uffea" +
+ "\012\uffea\016\uffea\026\uffea\035\uffea\036\uffea\001\002\000" +
+ "\022\005\ufffb\007\ufffb\010\ufffb\011\ufffb\012\ufffb\013\ufffb" +
+ "\014\ufffb\035\ufffb\001\002\000\022\005\uff97\007\uff97\010" +
+ "\uff97\011\uff97\012\uff97\013\uff97\014\uff97\035\uff97\001\002" +
+ "\000\042\003\054\006\026\007\027\010\040\011\036\012" +
+ "\022\013\042\014\030\015\017\016\015\026\033\027\023" +
+ "\030\035\031\041\035\025\036\053\001\002\000\006\017" +
+ "\ufffd\022\051\001\002\000\004\017\203\001\002\000\022" +
+ "\005\ufffc\007\ufffc\010\ufffc\011\ufffc\012\ufffc\013\ufffc\014" +
+ "\ufffc\035\ufffc\001\002\000\022\005\210\007\ufff2\010\ufff2" +
+ "\011\ufff2\012\ufff2\013\ufff2\014\ufff2\035\ufff2\001\002\000" +
+ "\022\005\ufff9\007\ufff9\010\ufff9\011\ufff9\012\ufff9\013\ufff9" +
+ "\014\ufff9\035\ufff9\001\002\000\020\007\223\010\224\011" +
+ "\007\012\012\013\227\014\225\035\014\001\002\000\022" +
+ "\005\ufffa\007\ufffa\010\ufffa\011\ufffa\012\ufffa\013\ufffa\014" +
+ "\ufffa\035\ufffa\001\002\000\042\003\054\006\026\007\027" +
+ "\010\040\011\036\012\022\013\042\014\030\015\017\016" +
+ "\015\026\033\027\023\030\035\031\041\035\025\036\053" +
+ "\001\002\000\006\017\uffb5\022\215\001\002\000\004\017" +
+ "\ufff8\001\002\000\004\017\214\001\002\000\022\005\ufff7" +
+ "\007\ufff7\010\ufff7\011\ufff7\012\ufff7\013\ufff7\014\ufff7\035" +
+ "\ufff7\001\002\000\044\003\054\006\026\007\027\010\040" +
+ "\011\036\012\022\013\042\014\030\015\017\016\015\021" +
+ "\216\026\033\027\023\030\035\031\041\035\025\036\053" +
+ "\001\002\000\004\017\uffb6\001\002\000\020\007\ufff3\010" +
+ "\ufff3\011\ufff3\012\ufff3\013\ufff3\014\ufff3\035\ufff3\001\002" +
+ "\000\020\007\ufff5\010\ufff5\011\ufff5\012\ufff5\013\ufff5\014" +
+ "\ufff5\035\ufff5\001\002\000\020\007\ufff1\010\ufff1\011\ufff1" +
+ "\012\ufff1\013\ufff1\014\ufff1\035\ufff1\001\002\000\020\007" +
+ "\ufff4\010\ufff4\011\ufff4\012\ufff4\013\ufff4\014\ufff4\035\ufff4" +
+ "\001\002\000\004\006\246\001\002\000\004\006\243\001" +
+ "\002\000\004\015\240\001\002\000\020\007\ufff6\010\ufff6" +
+ "\011\ufff6\012\ufff6\013\ufff6\014\ufff6\035\ufff6\001\002\000" +
+ "\004\015\234\001\002\000\020\003\uff97\011\007\012\012" +
+ "\016\uff97\026\065\035\014\036\uff97\001\002\000\010\003" +
+ "\uff97\016\116\036\uff97\001\002\000\006\003\126\036\120" +
+ "\001\002\000\010\002\uffff\003\126\036\120\001\002\000" +
+ "\004\037\235\001\002\000\022\007\uff99\010\uff99\011\uff99" +
+ "\012\uff99\013\uff99\014\uff99\017\236\035\uff99\001\002\000" +
+ "\020\007\uff98\010\uff98\011\uff98\012\uff98\013\uff98\014\uff98" +
+ "\035\uff98\001\002\000\020\007\uffee\010\uffee\011\uffee\012" +
+ "\uffee\013\uffee\014\uffee\035\uffee\001\002\000\004\037\241" +
+ "\001\002\000\022\007\uff99\010\uff99\011\uff99\012\uff99\013" +
+ "\uff99\014\uff99\017\236\035\uff99\001\002\000\020\007\uffed" +
+ "\010\uffed\011\uffed\012\uffed\013\uffed\014\uffed\035\uffed\001" +
+ "\002\000\004\037\244\001\002\000\022\007\uff99\010\uff99" +
+ "\011\uff99\012\uff99\013\uff99\014\uff99\017\236\035\uff99\001" +
+ "\002\000\020\007\uffef\010\uffef\011\uffef\012\uffef\013\uffef" +
+ "\014\uffef\035\uffef\001\002\000\004\037\247\001\002\000" +
+ "\022\007\uff99\010\uff99\011\uff99\012\uff99\013\uff99\014\uff99" +
+ "\017\236\035\uff99\001\002\000\020\007\ufff0\010\ufff0\011" +
+ "\ufff0\012\ufff0\013\ufff0\014\ufff0\035\ufff0\001\002\000\004" +
+ "\002\001\001\002" });
+
+ /** Access to parse-action table. */
+ public short[][] action_table() {return _action_table;}
+
+ /** <code>reduce_goto</code> table. */
+ protected static final short[][] _reduce_table =
+ unpackFromStrings(new String[] {
+ "\000\247\000\006\003\003\055\004\001\001\000\002\001" +
+ "\001\000\006\004\176\037\175\001\001\000\010\012\012" +
+ "\014\010\024\007\001\001\000\016\017\020\025\160\026" +
+ "\164\033\161\044\163\054\030\001\001\000\002\001\001" +
+ "\000\016\012\012\024\065\037\063\040\061\041\066\043" +
+ "\062\001\001\000\002\001\001\000\016\017\020\025\023" +
+ "\027\017\034\036\045\031\054\030\001\001\000\002\001" +
+ "\001\000\002\001\001\000\002\001\001\000\002\001\001" +
+ "\000\004\063\055\001\001\000\002\001\001\000\002\001" +
+ "\001\000\002\001\001\000\010\027\017\034\036\045\045" +
+ "\001\001\000\002\001\001\000\002\001\001\000\002\001" +
+ "\001\000\002\001\001\000\002\001\001\000\002\001\001" +
+ "\000\002\001\001\000\004\061\042\001\001\000\002\001" +
+ "\001\000\002\001\001\000\002\001\001\000\002\001\001" +
+ "\000\002\001\001\000\002\001\001\000\002\001\001\000" +
+ "\002\001\001\000\002\001\001\000\002\001\001\000\002" +
+ "\001\001\000\002\001\001\000\004\054\051\001\001\000" +
+ "\002\001\001\000\002\001\001\000\002\001\001\000\004" +
+ "\034\057\001\001\000\002\001\001\000\002\001\001\000" +
+ "\002\001\001\000\002\001\001\000\006\015\114\037\113" +
+ "\001\001\000\004\041\112\001\001\000\002\001\001\000" +
+ "\002\001\001\000\002\001\001\000\002\001\001\000\004" +
+ "\066\107\001\001\000\004\064\104\001\001\000\004\065" +
+ "\072\001\001\000\012\042\077\047\074\052\100\053\075" +
+ "\001\001\000\002\001\001\000\002\001\001\000\002\001" +
+ "\001\000\002\001\001\000\002\001\001\000\002\001\001" +
+ "\000\002\001\001\000\010\047\074\052\103\053\075\001" +
+ "\001\000\002\001\001\000\012\042\105\047\074\052\100" +
+ "\053\075\001\001\000\002\001\001\000\002\001\001\000" +
+ "\012\042\110\047\074\052\100\053\075\001\001\000\002" +
+ "\001\001\000\002\001\001\000\002\001\001\000\002\001" +
+ "\001\000\010\016\126\030\127\046\124\001\001\000\002" +
+ "\001\001\000\004\046\120\001\001\000\002\001\001\000" +
+ "\004\067\122\001\001\000\002\001\001\000\002\001\001" +
+ "\000\002\001\001\000\004\070\133\001\001\000\004\072" +
+ "\131\001\001\000\006\030\130\046\124\001\001\000\002" +
+ "\001\001\000\002\001\001\000\002\001\001\000\002\001" +
+ "\001\000\002\001\001\000\004\071\135\001\001\000\012" +
+ "\031\137\035\141\036\140\037\136\001\001\000\002\001" +
+ "\001\000\006\032\150\047\147\001\001\000\002\001\001" +
+ "\000\002\001\001\000\002\001\001\000\010\031\137\036" +
+ "\144\037\136\001\001\000\002\001\001\000\002\001\001" +
+ "\000\006\047\074\053\156\001\001\000\006\037\151\051" +
+ "\152\001\001\000\002\001\001\000\002\001\001\000\002" +
+ "\001\001\000\006\050\154\054\155\001\001\000\002\001" +
+ "\001\000\002\001\001\000\002\001\001\000\002\001\001" +
+ "\000\010\026\164\033\161\044\174\001\001\000\002\001" +
+ "\001\000\004\060\172\001\001\000\002\001\001\000\004" +
+ "\062\165\001\001\000\002\001\001\000\004\033\170\001" +
+ "\001\000\002\001\001\000\002\001\001\000\002\001\001" +
+ "\000\002\001\001\000\002\001\001\000\002\001\001\000" +
+ "\002\001\001\000\006\005\203\037\204\001\001\000\006" +
+ "\017\200\054\030\001\001\000\004\056\201\001\001\000" +
+ "\002\001\001\000\002\001\001\000\006\007\205\020\206" +
+ "\001\001\000\002\001\001\000\022\006\225\010\220\012" +
+ "\012\013\217\014\227\022\221\023\216\024\007\001\001" +
+ "\000\002\001\001\000\010\017\210\021\211\054\030\001" +
+ "\001\000\002\001\001\000\004\057\212\001\001\000\002" +
+ "\001\001\000\002\001\001\000\004\054\051\001\001\000" +
+ "\002\001\001\000\002\001\001\000\002\001\001\000\002" +
+ "\001\001\000\002\001\001\000\002\001\001\000\002\001" +
+ "\001\000\002\001\001\000\002\001\001\000\002\001\001" +
+ "\000\016\012\012\024\065\037\063\040\230\041\066\043" +
+ "\062\001\001\000\006\015\231\037\113\001\001\000\010" +
+ "\016\232\030\127\046\124\001\001\000\006\030\130\046" +
+ "\124\001\001\000\002\001\001\000\004\011\236\001\001" +
+ "\000\002\001\001\000\002\001\001\000\002\001\001\000" +
+ "\004\011\241\001\001\000\002\001\001\000\002\001\001" +
+ "\000\004\011\244\001\001\000\002\001\001\000\002\001" +
+ "\001\000\004\011\247\001\001\000\002\001\001\000\002" +
+ "\001\001" });
+
+ /** Access to <code>reduce_goto</code> table. */
+ public short[][] reduce_table() {return _reduce_table;}
+
+ /** Instance of action encapsulation class. */
+ protected CUP$parser$actions action_obj;
+
+ /** Action encapsulation object initializer. */
+ protected void init_actions()
+ {
+ action_obj = new CUP$parser$actions(this);
+ }
+
+ /** Invoke a user supplied parse action. */
+ public java_cup.runtime.Symbol do_action(
+ int act_num,
+ java_cup.runtime.lr_parser parser,
+ java.util.Stack stack,
+ int top)
+ throws java.lang.Exception
+ {
+ /* call code in generated class */
+ return action_obj.CUP$parser$do_action(act_num, parser, stack, top);
+ }
+
+ /** Indicates start state. */
+ public int start_state() {return 0;}
+ /** Indicates start production. */
+ public int start_production() {return 0;}
+
+ /** <code>EOF</code> Symbol index. */
+ public int EOF_sym() {return 0;}
+
+ /** <code>error</code> Symbol index. */
+ public int error_sym() {return 1;}
+
+
+ /** User initialization code. */
+ public void user_init() throws java.lang.Exception
+ {
+ lexer.init();
+ }
+
+ /** Scan to get the next Symbol. */
+ public java_cup.runtime.Symbol scan()
+ throws java.lang.Exception
+ {
+ return lexer.next_token();
+ }
+
+
+
+ /* override error routines */
+
+ public void report_fatal_error(
+ String message,
+ Object info)
+ {
+ done_parsing();
+ lexer.emit_error(message);
+ System.err.println("Can't recover from previous error(s), giving up.");
+ System.exit(1);
+ }
+
+ public void report_error(String message, Object info)
+ {
+ lexer.emit_error(message);
+ }
+
+}
+
+/** Cup generated class to encapsulate user supplied action code.*/
+class CUP$parser$actions {
+
+
+ /** helper routine to clone a new production part adding a given label */
+ protected production_part add_lab(production_part part, String lab)
+ throws internal_error
+ {
+ /* if there is no label, or this is an action, just return the original */
+ if (lab == null || part.is_action()) return part;
+
+ /* otherwise build a new one with the given label attached */
+ return new symbol_part(((symbol_part)part).the_symbol(),lab);
+ }
+
+ /** max size of right hand side we will support */
+ protected final int MAX_RHS = 200;
+
+ /** array for accumulating right hand side parts */
+ protected production_part[] rhs_parts = new production_part[MAX_RHS];
+
+ /** where we are currently in building a right hand side */
+ protected int rhs_pos = 0;
+
+ /** start a new right hand side */
+ protected void new_rhs() {rhs_pos = 0; }
+
+ /** add a new right hand side part */
+ protected void add_rhs_part(production_part part) throws java.lang.Exception
+ {
+ if (rhs_pos >= MAX_RHS)
+ throw new Exception("Internal Error: Productions limited to " +
+ MAX_RHS + " symbols and actions");
+
+ rhs_parts[rhs_pos] = part;
+ rhs_pos++;
+ }
+
+ /** string to build up multiple part names */
+ protected String multipart_name = new String();
+
+ /** append a new name segment to the accumulated multipart name */
+ protected void append_multipart(String name)
+ {
+ String dot = "";
+
+ /* if we aren't just starting out, put on a dot */
+ if (multipart_name.length() != 0) dot = ".";
+
+ multipart_name = multipart_name.concat(dot + name);
+ }
+
+ /** table of declared symbols -- contains production parts indexed by name */
+ protected Hashtable symbols = new Hashtable();
+
+ /** table of just non terminals -- contains non_terminals indexed by name */
+ protected Hashtable non_terms = new Hashtable();
+
+ /** declared start non_terminal */
+ protected non_terminal start_nt = null;
+
+ /** left hand side non terminal of the current production */
+ protected non_terminal lhs_nt;
+
+ /** Current precedence number */
+ int _cur_prec = 0;
+
+ /** Current precedence side */
+ int _cur_side = assoc.no_prec;
+
+ /** update the precedences we are declaring */
+ protected void update_precedence(int p) {
+ _cur_side = p;
+ _cur_prec++;
+ }
+ /** add relevant data to terminals */
+ protected void add_precedence(String term) {
+ if (term == null) {
+ System.err.println("Unable to add precedence to nonexistent terminal");
+ } else {
+ symbol_part sp = (symbol_part)symbols.get(term);
+ if (sp == null) {
+ System.err.println("Could find terminal " + term + " while declaring precedence");
+ } else {
+ java_cup.symbol sym = sp.the_symbol();
+ if (sym instanceof terminal)
+ ((terminal)sym).set_precedence(_cur_side, _cur_prec);
+ else System.err.println("Precedence declaration: Can't find terminal " + term);
+ }
+ }
+ }
+
+ private final parser parser;
+
+ /** Constructor */
+ CUP$parser$actions(parser parser) {
+ this.parser = parser;
+ }
+
+ /** Method with the actual generated action code. */
+ public final java_cup.runtime.Symbol CUP$parser$do_action(
+ int CUP$parser$act_num,
+ java_cup.runtime.lr_parser CUP$parser$parser,
+ java.util.Stack CUP$parser$stack,
+ int CUP$parser$top)
+ throws java.lang.Exception
+ {
+ /* Symbol object for return from actions */
+ java_cup.runtime.Symbol CUP$parser$result;
+
+ /* select the action based on the action number */
+ switch (CUP$parser$act_num)
+ {
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 106: // empty ::=
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(29/*empty*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 105: // opt_semi ::= SEMI
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(7/*opt_semi*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 104: // opt_semi ::=
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(7/*opt_semi*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 103: // non_terminal ::= NONTERMINAL
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(8/*non_terminal*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 102: // non_terminal ::= NON TERMINAL
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(8/*non_terminal*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 101: // robust_id ::= error
+ {
+ String RESULT = null;
+
+ lexer.emit_error("Illegal use of reserved word");
+ RESULT="ILLEGAL";
+
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 100: // robust_id ::= NONASSOC
+ {
+ String RESULT = null;
+ RESULT = "nonassoc";
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 99: // robust_id ::= RIGHT
+ {
+ String RESULT = null;
+ RESULT = "right";
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 98: // robust_id ::= LEFT
+ {
+ String RESULT = null;
+ RESULT = "left";
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 97: // robust_id ::= PRECEDENCE
+ {
+ String RESULT = null;
+ RESULT = "precedence";
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 96: // robust_id ::= START
+ {
+ String RESULT = null;
+ RESULT = "start";
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 95: // robust_id ::= WITH
+ {
+ String RESULT = null;
+ RESULT = "with";
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 94: // robust_id ::= SCAN
+ {
+ String RESULT = null;
+ RESULT = "scan";
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 93: // robust_id ::= INIT
+ {
+ String RESULT = null;
+ RESULT = "init";
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 92: // robust_id ::= NONTERMINAL
+ {
+ String RESULT = null;
+ RESULT = "nonterminal";
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 91: // robust_id ::= NON
+ {
+ String RESULT = null;
+ RESULT = "non";
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 90: // robust_id ::= TERMINAL
+ {
+ String RESULT = null;
+ RESULT = "terminal";
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 89: // robust_id ::= PARSER
+ {
+ String RESULT = null;
+ RESULT = "parser";
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 88: // robust_id ::= ACTION
+ {
+ String RESULT = null;
+ RESULT = "action";
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 87: // robust_id ::= CODE
+ {
+ String RESULT = null;
+ RESULT = "code";
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 86: // robust_id ::= ID
+ {
+ String RESULT = null;
+ int the_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int the_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String the_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+ RESULT = the_id;
+ CUP$parser$result = new java_cup.runtime.Symbol(42/*robust_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 85: // label_id ::= robust_id
+ {
+ String RESULT = null;
+ int the_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int the_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String the_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+ RESULT = the_id;
+ CUP$parser$result = new java_cup.runtime.Symbol(38/*label_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 84: // symbol_id ::= error
+ {
+ String RESULT = null;
+
+ lexer.emit_error("Illegal use of reserved word");
+ RESULT="ILLEGAL";
+
+ CUP$parser$result = new java_cup.runtime.Symbol(37/*symbol_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 83: // symbol_id ::= ID
+ {
+ String RESULT = null;
+ int the_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int the_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String the_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+ RESULT = the_id;
+ CUP$parser$result = new java_cup.runtime.Symbol(37/*symbol_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 82: // nt_id ::= error
+ {
+ String RESULT = null;
+
+ lexer.emit_error("Illegal use of reserved word");
+ RESULT="ILLEGAL";
+
+ CUP$parser$result = new java_cup.runtime.Symbol(36/*nt_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 81: // nt_id ::= ID
+ {
+ String RESULT = null;
+ int the_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int the_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String the_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+ RESULT = the_id;
+ CUP$parser$result = new java_cup.runtime.Symbol(36/*nt_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 80: // new_non_term_id ::= ID
+ {
+ Object RESULT = null;
+ int non_term_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int non_term_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String non_term_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+
+ /* see if this non terminal has been declared before */
+ if (symbols.get(non_term_id) != null)
+ {
+ /* issue a message */
+ lexer.emit_error( "java_cup.runtime.Symbol \"" + non_term_id +
+ "\" has already been declared");
+ }
+ else
+ {
+ if (multipart_name.equals("")) {
+ append_multipart("Object");
+ }
+ /* build the non terminal object */
+ non_terminal this_nt =
+ new non_terminal(non_term_id, multipart_name);
+
+ /* put it in the non_terms table */
+ non_terms.put(non_term_id, this_nt);
+
+ /* build a production_part and put it in the symbols table */
+ symbols.put(non_term_id, new symbol_part(this_nt));
+ }
+
+ CUP$parser$result = new java_cup.runtime.Symbol(26/*new_non_term_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 79: // new_term_id ::= ID
+ {
+ Object RESULT = null;
+ int term_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int term_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String term_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+
+ /* see if this terminal has been declared before */
+ if (symbols.get(term_id) != null)
+ {
+ /* issue a message */
+ lexer.emit_error("java_cup.runtime.Symbol \"" + term_id +
+ "\" has already been declared");
+ }
+ else
+ {
+ /* if no type declared, declare one */
+ if (multipart_name.equals("")) {
+ append_multipart("Object");
+ }
+ /* build a production_part and put it in the table */
+ symbols.put(term_id,
+ new symbol_part(new terminal(term_id, multipart_name)));
+ }
+
+ CUP$parser$result = new java_cup.runtime.Symbol(25/*new_term_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 78: // type_id ::= type_id LBRACK RBRACK
+ {
+ Object RESULT = null;
+ multipart_name = multipart_name.concat("[]");
+ CUP$parser$result = new java_cup.runtime.Symbol(19/*type_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 77: // type_id ::= multipart_id
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(19/*type_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 76: // import_id ::= multipart_id
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(15/*import_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 75: // import_id ::= multipart_id DOT STAR
+ {
+ Object RESULT = null;
+ append_multipart("*");
+ CUP$parser$result = new java_cup.runtime.Symbol(15/*import_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 74: // multipart_id ::= robust_id
+ {
+ Object RESULT = null;
+ int an_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int an_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String an_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+ append_multipart(an_id);
+ CUP$parser$result = new java_cup.runtime.Symbol(13/*multipart_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 73: // multipart_id ::= multipart_id DOT robust_id
+ {
+ Object RESULT = null;
+ int another_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int another_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String another_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+ append_multipart(another_id);
+ CUP$parser$result = new java_cup.runtime.Symbol(13/*multipart_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 72: // opt_label ::= empty
+ {
+ String RESULT = null;
+ RESULT = null;
+ CUP$parser$result = new java_cup.runtime.Symbol(39/*opt_label*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 71: // opt_label ::= COLON label_id
+ {
+ String RESULT = null;
+ int labidleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int labidright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String labid = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+ RESULT = labid;
+ CUP$parser$result = new java_cup.runtime.Symbol(39/*opt_label*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 70: // prod_part ::= CODE_STRING
+ {
+ Object RESULT = null;
+ int code_strleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int code_strright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String code_str = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+
+ /* add a new production part */
+ add_rhs_part(new action_part(code_str));
+
+ CUP$parser$result = new java_cup.runtime.Symbol(24/*prod_part*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 69: // prod_part ::= symbol_id opt_label
+ {
+ Object RESULT = null;
+ int symidleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left;
+ int symidright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).right;
+ String symid = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+ int labidleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int labidright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String labid = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+
+ /* try to look up the id */
+ production_part symb = (production_part)symbols.get(symid);
+
+ /* if that fails, symbol is undeclared */
+ if (symb == null)
+ {
+ if (lexer.error_count == 0)
+ lexer.emit_error("java_cup.runtime.Symbol \"" + symid +
+ "\" has not been declared");
+ }
+ else
+ {
+ /* add a labeled production part */
+ add_rhs_part(add_lab(symb, labid));
+ }
+
+ CUP$parser$result = new java_cup.runtime.Symbol(24/*prod_part*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 68: // prod_part_list ::= empty
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(23/*prod_part_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 67: // prod_part_list ::= prod_part_list prod_part
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(23/*prod_part_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 66: // rhs ::= prod_part_list
+ {
+ Object RESULT = null;
+
+ if (lhs_nt != null)
+ {
+ /* build the production */
+ production p = new production(lhs_nt, rhs_parts, rhs_pos);
+
+ /* if we have no start non-terminal declared and this is
+ the first production, make its lhs nt the start_nt
+ and build a special start production for it. */
+ if (start_nt == null)
+ {
+ start_nt = lhs_nt;
+
+ /* build a special start production */
+ new_rhs();
+ add_rhs_part(add_lab(new symbol_part(start_nt),"start_val"));
+ add_rhs_part(new symbol_part(terminal.EOF));
+ add_rhs_part(new action_part("RESULT = start_val;"));
+ emit.start_production =
+ new production(non_terminal.START_nt, rhs_parts, rhs_pos);
+
+ new_rhs();
+ }
+ }
+
+ /* reset the rhs accumulation in any case */
+ new_rhs();
+
+ CUP$parser$result = new java_cup.runtime.Symbol(28/*rhs*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 65: // rhs ::= prod_part_list PERCENT_PREC term_id
+ {
+ Object RESULT = null;
+ int term_nameleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int term_nameright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String term_name = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+
+ java_cup.symbol sym = null;
+ if (lhs_nt != null)
+ {
+ /* Find the precedence symbol */
+ if (term_name == null) {
+ System.err.println("No terminal for contextual precedence");
+ sym = null;
+ } else {
+ sym = ((symbol_part)symbols.get(term_name)).the_symbol();
+ }
+ /* build the production */
+ production p;
+ if ((sym!=null) && (sym instanceof terminal)) {
+ p = new production(lhs_nt, rhs_parts, rhs_pos,
+ ((terminal)sym).precedence_num(),
+ ((terminal)sym).precedence_side());
+ ((symbol_part)symbols.get(term_name)).the_symbol().note_use();
+ } else {
+ System.err.println("Invalid terminal " + term_name +
+ " for contextual precedence assignment");
+ p = new production(lhs_nt, rhs_parts, rhs_pos);
+ }
+
+ /* if we have no start non-terminal declared and this is
+ the first production, make its lhs nt the start_nt
+ and build a special start production for it. */
+ if (start_nt == null)
+ {
+ start_nt = lhs_nt;
+
+ /* build a special start production */
+ new_rhs();
+ add_rhs_part(add_lab(new symbol_part(start_nt),"start_val"));
+ add_rhs_part(new symbol_part(terminal.EOF));
+ add_rhs_part(new action_part("RESULT = start_val;"));
+ if ((sym!=null) && (sym instanceof terminal)) {
+ emit.start_production =
+ new production(non_terminal.START_nt, rhs_parts,
+ rhs_pos, ((terminal)sym).precedence_num(),
+ ((terminal)sym).precedence_side());
+ } else {
+ emit.start_production =
+ new production(non_terminal.START_nt, rhs_parts, rhs_pos);
+ }
+ new_rhs();
+ }
+ }
+
+ /* reset the rhs accumulation in any case */
+ new_rhs();
+
+ CUP$parser$result = new java_cup.runtime.Symbol(28/*rhs*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 64: // rhs_list ::= rhs
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(27/*rhs_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 63: // rhs_list ::= rhs_list BAR rhs
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(27/*rhs_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 62: // production ::= error NT$13 SEMI
+ {
+ Object RESULT = null;
+ // propagate RESULT from NT$13
+ if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value != null )
+ RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(22/*production*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 61: // NT$13 ::=
+ {
+ Object RESULT = null;
+ lexer.emit_error("Syntax Error");
+ CUP$parser$result = new java_cup.runtime.Symbol(56/*NT$13*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 60: // production ::= nt_id NT$11 COLON_COLON_EQUALS NT$12 rhs_list SEMI
+ {
+ Object RESULT = null;
+ // propagate RESULT from NT$11
+ if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-4)).value != null )
+ RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-4)).value;
+ // propagate RESULT from NT$12
+ if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value != null )
+ RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
+ int lhs_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-5)).left;
+ int lhs_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-5)).right;
+ String lhs_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-5)).value;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(22/*production*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-5)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 59: // NT$12 ::=
+ {
+ Object RESULT = null;
+ int lhs_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left;
+ int lhs_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).right;
+ String lhs_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(55/*NT$12*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 58: // NT$11 ::=
+ {
+ Object RESULT = null;
+ int lhs_idleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int lhs_idright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String lhs_id = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+
+ /* lookup the lhs nt */
+ lhs_nt = (non_terminal)non_terms.get(lhs_id);
+
+ /* if it wasn't declared, emit a message */
+ if (lhs_nt == null)
+ {
+ if (lexer.error_count == 0)
+ lexer.emit_error("LHS non terminal \"" + lhs_id +
+ "\" has not been declared");
+ }
+
+ /* reset the rhs accumulation */
+ new_rhs();
+
+ CUP$parser$result = new java_cup.runtime.Symbol(54/*NT$11*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 57: // production_list ::= production
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(12/*production_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 56: // production_list ::= production_list production
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(12/*production_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 55: // start_spec ::= empty
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(11/*start_spec*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 54: // start_spec ::= START WITH nt_id NT$10 SEMI
+ {
+ Object RESULT = null;
+ // propagate RESULT from NT$10
+ if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value != null )
+ RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+ int start_nameleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left;
+ int start_nameright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).right;
+ String start_name = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(11/*start_spec*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-4)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 53: // NT$10 ::=
+ {
+ Object RESULT = null;
+ int start_nameleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int start_nameright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String start_name = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+
+ /* verify that the name has been declared as a non terminal */
+ non_terminal nt = (non_terminal)non_terms.get(start_name);
+ if (nt == null)
+ {
+ lexer.emit_error( "Start non terminal \"" + start_name +
+ "\" has not been declared");
+ }
+ else
+ {
+ /* remember the non-terminal for later */
+ start_nt = nt;
+
+ /* build a special start production */
+ new_rhs();
+ add_rhs_part(add_lab(new symbol_part(start_nt), "start_val"));
+ add_rhs_part(new symbol_part(terminal.EOF));
+ add_rhs_part(new action_part("RESULT = start_val;"));
+ emit.start_production =
+ new production(non_terminal.START_nt, rhs_parts, rhs_pos);
+ new_rhs();
+ }
+
+ CUP$parser$result = new java_cup.runtime.Symbol(53/*NT$10*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 52: // term_id ::= symbol_id
+ {
+ String RESULT = null;
+ int symleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int symright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String sym = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+
+ /* check that the symbol_id is a terminal */
+ if (symbols.get(sym) == null)
+ {
+ /* issue a message */
+ lexer.emit_error("Terminal \"" + sym +
+ "\" has not been declared");
+ }
+ RESULT = sym;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(41/*term_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 51: // terminal_id ::= term_id
+ {
+ String RESULT = null;
+ int symleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int symright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ String sym = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+
+ add_precedence(sym);
+ RESULT = sym;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(40/*terminal_id*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 50: // terminal_list ::= terminal_id
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(32/*terminal_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 49: // terminal_list ::= terminal_list COMMA terminal_id
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(32/*terminal_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 48: // preced ::= PRECEDENCE NONASSOC NT$9 terminal_list SEMI
+ {
+ Object RESULT = null;
+ // propagate RESULT from NT$9
+ if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value != null )
+ RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(31/*preced*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-4)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 47: // NT$9 ::=
+ {
+ Object RESULT = null;
+
+ update_precedence(assoc.nonassoc);
+
+ CUP$parser$result = new java_cup.runtime.Symbol(52/*NT$9*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 46: // preced ::= PRECEDENCE RIGHT NT$8 terminal_list SEMI
+ {
+ Object RESULT = null;
+ // propagate RESULT from NT$8
+ if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value != null )
+ RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(31/*preced*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-4)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 45: // NT$8 ::=
+ {
+ Object RESULT = null;
+
+ update_precedence(assoc.right);
+
+ CUP$parser$result = new java_cup.runtime.Symbol(51/*NT$8*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 44: // preced ::= PRECEDENCE LEFT NT$7 terminal_list SEMI
+ {
+ Object RESULT = null;
+ // propagate RESULT from NT$7
+ if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value != null )
+ RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(31/*preced*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-4)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 43: // NT$7 ::=
+ {
+ Object RESULT = null;
+
+ update_precedence(assoc.left);
+
+ CUP$parser$result = new java_cup.runtime.Symbol(50/*NT$7*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 42: // precedence_l ::= preced
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(33/*precedence_l*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 41: // precedence_l ::= precedence_l preced
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(33/*precedence_l*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 40: // precedence_list ::= empty
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(30/*precedence_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 39: // precedence_list ::= precedence_l
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(30/*precedence_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 38: // non_term_name_list ::= new_non_term_id
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(21/*non_term_name_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 37: // non_term_name_list ::= non_term_name_list COMMA new_non_term_id
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(21/*non_term_name_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 36: // term_name_list ::= new_term_id
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(20/*term_name_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 35: // term_name_list ::= term_name_list COMMA new_term_id
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(20/*term_name_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 34: // declares_non_term ::= non_term_name_list NT$6 SEMI
+ {
+ Object RESULT = null;
+ // propagate RESULT from NT$6
+ if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value != null )
+ RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(35/*declares_non_term*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 33: // NT$6 ::=
+ {
+ Object RESULT = null;
+
+ /* reset the accumulated multipart name */
+ multipart_name = new String();
+
+ CUP$parser$result = new java_cup.runtime.Symbol(49/*NT$6*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 32: // declares_term ::= term_name_list NT$5 SEMI
+ {
+ Object RESULT = null;
+ // propagate RESULT from NT$5
+ if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value != null )
+ RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(34/*declares_term*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 31: // NT$5 ::=
+ {
+ Object RESULT = null;
+
+ /* reset the accumulated multipart name */
+ multipart_name = new String();
+
+ CUP$parser$result = new java_cup.runtime.Symbol(48/*NT$5*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 30: // symbol ::= non_terminal error NT$4 SEMI
+ {
+ Object RESULT = null;
+ // propagate RESULT from NT$4
+ if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value != null )
+ RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(18/*symbol*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-3)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 29: // NT$4 ::=
+ {
+ Object RESULT = null;
+
+ /* reset the accumulated multipart name */
+ multipart_name = new String();
+
+ CUP$parser$result = new java_cup.runtime.Symbol(47/*NT$4*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 28: // symbol ::= TERMINAL error NT$3 SEMI
+ {
+ Object RESULT = null;
+ // propagate RESULT from NT$3
+ if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value != null )
+ RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(18/*symbol*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-3)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 27: // NT$3 ::=
+ {
+ Object RESULT = null;
+
+ /* reset the accumulated multipart name */
+ multipart_name = new String();
+
+ CUP$parser$result = new java_cup.runtime.Symbol(46/*NT$3*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 26: // symbol ::= non_terminal declares_non_term
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(18/*symbol*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 25: // symbol ::= non_terminal type_id declares_non_term
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(18/*symbol*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 24: // symbol ::= TERMINAL declares_term
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(18/*symbol*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 23: // symbol ::= TERMINAL type_id declares_term
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(18/*symbol*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 22: // symbol_list ::= symbol
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(10/*symbol_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 21: // symbol_list ::= symbol_list symbol
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(10/*symbol_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 20: // scan_code ::= SCAN WITH CODE_STRING opt_semi
+ {
+ Object RESULT = null;
+ int user_codeleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left;
+ int user_coderight = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).right;
+ String user_code = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+
+ if (emit.scan_code!=null)
+ lexer.emit_error("Redundant scan code (skipping)");
+ else /* save the user code */
+ emit.scan_code = user_code;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(17/*scan_code*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-3)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 19: // init_code ::= INIT WITH CODE_STRING opt_semi
+ {
+ Object RESULT = null;
+ int user_codeleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left;
+ int user_coderight = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).right;
+ String user_code = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+
+ if (emit.init_code!=null)
+ lexer.emit_error("Redundant init code (skipping)");
+ else /* save the user code */
+ emit.init_code = user_code;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(16/*init_code*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-3)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 18: // parser_code_part ::= PARSER CODE CODE_STRING opt_semi
+ {
+ Object RESULT = null;
+ int user_codeleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left;
+ int user_coderight = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).right;
+ String user_code = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+
+ if (emit.parser_code!=null)
+ lexer.emit_error("Redundant parser code (skipping)");
+ else /* save the user included code string */
+ emit.parser_code = user_code;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(9/*parser_code_part*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-3)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 17: // action_code_part ::= ACTION CODE CODE_STRING opt_semi
+ {
+ Object RESULT = null;
+ int user_codeleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left;
+ int user_coderight = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).right;
+ String user_code = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+
+ if (emit.action_code!=null)
+ lexer.emit_error("Redundant action code (skipping)");
+ else /* save the user included code string */
+ emit.action_code = user_code;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(4/*action_code_part*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-3)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 16: // code_parts ::= code_parts code_part
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(5/*code_parts*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 15: // code_parts ::=
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(5/*code_parts*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 14: // code_part ::= scan_code
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(6/*code_part*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 13: // code_part ::= init_code
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(6/*code_part*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 12: // code_part ::= parser_code_part
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(6/*code_part*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 11: // code_part ::= action_code_part
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(6/*code_part*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 10: // import_spec ::= IMPORT import_id NT$2 SEMI
+ {
+ Object RESULT = null;
+ // propagate RESULT from NT$2
+ if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value != null )
+ RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(14/*import_spec*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-3)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 9: // NT$2 ::=
+ {
+ Object RESULT = null;
+
+ /* save this import on the imports list */
+ emit.import_list.push(multipart_name);
+
+ /* reset the accumulated multipart name */
+ multipart_name = new String();
+
+ CUP$parser$result = new java_cup.runtime.Symbol(45/*NT$2*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 8: // import_list ::= empty
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(3/*import_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 7: // import_list ::= import_list import_spec
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(3/*import_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 6: // package_spec ::= empty
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(2/*package_spec*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 5: // package_spec ::= PACKAGE multipart_id NT$1 SEMI
+ {
+ Object RESULT = null;
+ // propagate RESULT from NT$1
+ if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value != null )
+ RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(2/*package_spec*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-3)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 4: // NT$1 ::=
+ {
+ Object RESULT = null;
+
+ /* save the package name */
+ emit.package_name = multipart_name;
+
+ /* reset the accumulated multipart name */
+ multipart_name = new String();
+
+ CUP$parser$result = new java_cup.runtime.Symbol(44/*NT$1*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 3: // spec ::= error symbol_list precedence_list start_spec production_list
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(1/*spec*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-4)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 2: // spec ::= NT$0 package_spec import_list code_parts symbol_list precedence_list start_spec production_list
+ {
+ Object RESULT = null;
+ // propagate RESULT from NT$0
+ if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-7)).value != null )
+ RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-7)).value;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(1/*spec*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-7)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 1: // NT$0 ::=
+ {
+ Object RESULT = null;
+
+ /* declare "error" as a terminal */
+ symbols.put("error", new symbol_part(terminal.error));
+
+ /* declare start non terminal */
+ non_terms.put("$START", non_terminal.START_nt);
+
+ CUP$parser$result = new java_cup.runtime.Symbol(43/*NT$0*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 0: // $START ::= spec EOF
+ {
+ Object RESULT = null;
+ int start_valleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left;
+ int start_valright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).right;
+ Object start_val = (Object)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+ RESULT = start_val;
+ CUP$parser$result = new java_cup.runtime.Symbol(0/*$START*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ /* ACCEPT */
+ CUP$parser$parser.done_parsing();
+ return CUP$parser$result;
+
+ /* . . . . . .*/
+ default:
+ throw new Exception(
+ "Invalid action number found in internal parse table");
+
+ }
+ }
+}
+
diff --git a/src/syntaxParser/java_cup/production.class b/src/syntaxParser/java_cup/production.class
new file mode 100644
index 0000000..eb46236
--- /dev/null
+++ b/src/syntaxParser/java_cup/production.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/production.java b/src/syntaxParser/java_cup/production.java
new file mode 100644
index 0000000..5a41287
--- /dev/null
+++ b/src/syntaxParser/java_cup/production.java
@@ -0,0 +1,756 @@
+
+package java_cup;
+
+import java.util.Hashtable;
+import java.util.Enumeration;
+
+/** This class represents a production in the grammar. It contains
+ * a LHS non terminal, and an array of RHS symbols. As various
+ * transformations are done on the RHS of the production, it may shrink.
+ * As a result a separate length is always maintained to indicate how much
+ * of the RHS array is still valid.<p>
+ *
+ * I addition to construction and manipulation operations, productions provide
+ * methods for factoring out actions (see remove_embedded_actions()), for
+ * computing the nullability of the production (i.e., can it derive the empty
+ * string, see check_nullable()), and operations for computing its first
+ * set (i.e., the set of terminals that could appear at the beginning of some
+ * string derived from the production, see check_first_set()).
+ *
+ * @see java_cup.production_part
+ * @see java_cup.symbol_part
+ * @see java_cup.action_part
+ * @version last updated: 7/3/96
+ * @author Frank Flannery
+ */
+
+public class production {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Full constructor. This constructor accepts a LHS non terminal,
+ * an array of RHS parts (including terminals, non terminals, and
+ * actions), and a string for a final reduce action. It does several
+ * manipulations in the process of creating a production object.
+ * After some validity checking it translates labels that appear in
+ * actions into code for accessing objects on the runtime parse stack.
+ * It them merges adjacent actions if they appear and moves any trailing
+ * action into the final reduce actions string. Next it removes any
+ * embedded actions by factoring them out with new action productions.
+ * Finally it assigns a unique index to the production.<p>
+ *
+ * Factoring out of actions is accomplished by creating new "hidden"
+ * non terminals. For example if the production was originally: <pre>
+ * A ::= B {action} C D
+ * </pre>
+ * then it is factored into two productions:<pre>
+ * A ::= B X C D
+ * X ::= {action}
+ * </pre>
+ * (where X is a unique new non terminal). This has the effect of placing
+ * all actions at the end where they can be handled as part of a reduce by
+ * the parser.
+ */
+ public production(
+ non_terminal lhs_sym,
+ production_part rhs_parts[],
+ int rhs_l,
+ String action_str)
+ throws internal_error
+ {
+ int i;
+ action_part tail_action;
+ String declare_str;
+ int rightlen = rhs_l;
+
+ /* remember the length */
+ if (rhs_l >= 0)
+ _rhs_length = rhs_l;
+ else if (rhs_parts != null)
+ _rhs_length = rhs_parts.length;
+ else
+ _rhs_length = 0;
+
+ /* make sure we have a valid left-hand-side */
+ if (lhs_sym == null)
+ throw new internal_error(
+ "Attempt to construct a production with a null LHS");
+
+ /* I'm not translating labels anymore, I'm adding code to declare
+ labels as valid variables. This way, the users code string is
+ untouched
+ 6/96 frankf */
+
+ /* check if the last part of the right hand side is an action. If
+ it is, it won't be on the stack, so we don't want to count it
+ in the rightlen. Then when we search down the stack for a
+ Symbol, we don't try to search past action */
+
+ if (rhs_l > 0) {
+ if (rhs_parts[rhs_l - 1].is_action()) {
+ rightlen = rhs_l - 1;
+ } else {
+ rightlen = rhs_l;
+ }
+ }
+
+ /* get the generated declaration code for the necessary labels. */
+ declare_str = declare_labels(
+ rhs_parts, rightlen, action_str);
+
+ if (action_str == null)
+ action_str = declare_str;
+ else
+ action_str = declare_str + action_str;
+
+ /* count use of lhs */
+ lhs_sym.note_use();
+
+ /* create the part for left-hand-side */
+ _lhs = new symbol_part(lhs_sym);
+
+ /* merge adjacent actions (if any) */
+ _rhs_length = merge_adjacent_actions(rhs_parts, _rhs_length);
+
+ /* strip off any trailing action */
+ tail_action = strip_trailing_action(rhs_parts, _rhs_length);
+ if (tail_action != null) _rhs_length--;
+
+ /* Why does this run through the right hand side happen
+ over and over? here a quick combination of two
+ prior runs plus one I wanted of my own
+ frankf 6/25/96 */
+ /* allocate and copy over the right-hand-side */
+ /* count use of each rhs symbol */
+ _rhs = new production_part[_rhs_length];
+ for (i=0; i<_rhs_length; i++) {
+ _rhs[i] = rhs_parts[i];
+ if (!_rhs[i].is_action()) {
+ ((symbol_part)_rhs[i]).the_symbol().note_use();
+ if (((symbol_part)_rhs[i]).the_symbol() instanceof terminal) {
+ _rhs_prec =
+ ((terminal)((symbol_part)_rhs[i]).the_symbol()).precedence_num();
+ _rhs_assoc =
+ ((terminal)((symbol_part)_rhs[i]).the_symbol()).precedence_side();
+ }
+ }
+ }
+
+ /*now action string is really declaration string, so put it in front!
+ 6/14/96 frankf */
+ if (action_str == null) action_str = "";
+ if (tail_action != null && tail_action.code_string() != null)
+ action_str = action_str + "\t\t" + tail_action.code_string();
+
+ /* stash the action */
+ _action = new action_part(action_str);
+
+ /* rewrite production to remove any embedded actions */
+ remove_embedded_actions();
+
+ /* assign an index */
+ _index = next_index++;
+
+ /* put us in the global collection of productions */
+ _all.put(new Integer(_index),this);
+
+ /* put us in the production list of the lhs non terminal */
+ lhs_sym.add_production(this);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Constructor with no action string. */
+ public production(
+ non_terminal lhs_sym,
+ production_part rhs_parts[],
+ int rhs_l)
+ throws internal_error
+ {
+ this(lhs_sym,rhs_parts,rhs_l,null);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /* Constructor with precedence and associativity of production
+ contextually define */
+ public production(
+ non_terminal lhs_sym,
+ production_part rhs_parts[],
+ int rhs_l,
+ String action_str,
+ int prec_num,
+ int prec_side)
+ throws internal_error
+ {
+ this(lhs_sym,rhs_parts,rhs_l,action_str);
+
+ /* set the precedence */
+ set_precedence_num(prec_num);
+ set_precedence_side(prec_side);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /* Constructor w/ no action string and contextual precedence
+ defined */
+ public production(
+ non_terminal lhs_sym,
+ production_part rhs_parts[],
+ int rhs_l,
+ int prec_num,
+ int prec_side)
+ throws internal_error
+ {
+ this(lhs_sym,rhs_parts,rhs_l,null);
+ /* set the precedence */
+ set_precedence_num(prec_num);
+ set_precedence_side(prec_side);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Static (Class) Variables ------------------*/
+ /*-----------------------------------------------------------*/
+
+
+ /** Table of all productions. Elements are stored using their index as
+ * the key.
+ */
+ protected static Hashtable _all = new Hashtable();
+
+ /** Access to all productions. */
+ public static Enumeration all() {return _all.elements();}
+
+ /** Lookup a production by index. */
+ public static production find(int indx) {
+ return (production) _all.get(new Integer(indx));
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Total number of productions. */
+ public static int number() {return _all.size();}
+
+ /** Static counter for assigning unique index numbers. */
+ protected static int next_index;
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** The left hand side non-terminal. */
+ protected symbol_part _lhs;
+
+ /** The left hand side non-terminal. */
+ public symbol_part lhs() {return _lhs;}
+
+
+ /** The precedence of the rule */
+ protected int _rhs_prec = -1;
+ protected int _rhs_assoc = -1;
+
+ /** Access to the precedence of the rule */
+ public int precedence_num() { return _rhs_prec; }
+ public int precedence_side() { return _rhs_assoc; }
+
+ /** Setting the precedence of a rule */
+ public void set_precedence_num(int prec_num) {
+ _rhs_prec = prec_num;
+ }
+ public void set_precedence_side(int prec_side) {
+ _rhs_assoc = prec_side;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** A collection of parts for the right hand side. */
+ protected production_part _rhs[];
+
+ /** Access to the collection of parts for the right hand side. */
+ public production_part rhs(int indx) throws internal_error
+ {
+ if (indx >= 0 && indx < _rhs_length)
+ return _rhs[indx];
+ else
+ throw new internal_error(
+ "Index out of range for right hand side of production");
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** How much of the right hand side array we are presently using. */
+ protected int _rhs_length;
+
+ /** How much of the right hand side array we are presently using. */
+ public int rhs_length() {return _rhs_length;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** An action_part containing code for the action to be performed when we
+ * reduce with this production.
+ */
+ protected action_part _action;
+
+ /** An action_part containing code for the action to be performed when we
+ * reduce with this production.
+ */
+ public action_part action() {return _action;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Index number of the production. */
+ protected int _index;
+
+ /** Index number of the production. */
+ public int index() {return _index;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Count of number of reductions using this production. */
+ protected int _num_reductions = 0;
+
+ /** Count of number of reductions using this production. */
+ public int num_reductions() {return _num_reductions;}
+
+ /** Increment the count of reductions with this non-terminal */
+ public void note_reduction_use() {_num_reductions++;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Is the nullability of the production known or unknown? */
+ protected boolean _nullable_known = false;
+
+ /** Is the nullability of the production known or unknown? */
+ public boolean nullable_known() {return _nullable_known;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Nullability of the production (can it derive the empty string). */
+ protected boolean _nullable = false;
+
+ /** Nullability of the production (can it derive the empty string). */
+ public boolean nullable() {return _nullable;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** First set of the production. This is the set of terminals that
+ * could appear at the front of some string derived from this production.
+ */
+ protected terminal_set _first_set = new terminal_set();
+
+ /** First set of the production. This is the set of terminals that
+ * could appear at the front of some string derived from this production.
+ */
+ public terminal_set first_set() {return _first_set;}
+
+ /*-----------------------------------------------------------*/
+ /*--- Static Methods ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Determine if a given character can be a label id starter.
+ * @param c the character in question.
+ */
+ protected static boolean is_id_start(char c)
+ {
+ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_');
+
+ //later need to handle non-8-bit chars here
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Determine if a character can be in a label id.
+ * @param c the character in question.
+ */
+ protected static boolean is_id_char(char c)
+ {
+ return is_id_start(c) || (c >= '0' && c <= '9');
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+
+ /** Return label declaration code
+ * @param labelname the label name
+ * @param stack_type the stack type of label?
+ * @author frankf
+ */
+ protected String make_declaration(
+ String labelname,
+ String stack_type,
+ int offset)
+ {
+ String ret;
+
+ /* Put in the left/right value labels */
+ if (emit.lr_values())
+ ret = "\t\tint " + labelname + "left = ((java_cup.runtime.Symbol)" +
+ emit.pre("stack") + ".elementAt(" + emit.pre("top") +
+ "-" + offset + ")).left;\n" +
+ "\t\tint " + labelname + "right = ((java_cup.runtime.Symbol)" +
+ emit.pre("stack") + ".elementAt(" + emit.pre("top") +
+ "-" + offset + ")).right;\n";
+ else ret = "";
+
+ /* otherwise, just declare label. */
+ return ret + "\t\t" + stack_type + " " + labelname + " = (" + stack_type +
+ ")((" + "java_cup.runtime.Symbol) " + emit.pre("stack") + ".elementAt(" + emit.pre("top")
+ + "-" + offset + ")).value;\n";
+
+ }
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Declare label names as valid variables within the action string
+ * @param rhs array of RHS parts.
+ * @param rhs_len how much of rhs to consider valid.
+ * @param final_action the final action string of the production.
+ * @param lhs_type the object type associated with the LHS symbol.
+ */
+ protected String declare_labels(
+ production_part rhs[],
+ int rhs_len,
+ String final_action)
+ {
+ String declaration = "";
+
+ symbol_part part;
+ action_part act_part;
+ int pos;
+
+ /* walk down the parts and extract the labels */
+ for (pos = 0; pos < rhs_len; pos++)
+ {
+ if (!rhs[pos].is_action())
+ {
+ part = (symbol_part)rhs[pos];
+
+ /* if it has a label, make declaration! */
+ if (part.label() != null)
+ {
+ declaration = declaration +
+ make_declaration(part.label(), part.the_symbol().stack_type(),
+ rhs_len-pos-1);
+ }
+ }
+ }
+ return declaration;
+ }
+
+
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Helper routine to merge adjacent actions in a set of RHS parts
+ * @param rhs_parts array of RHS parts.
+ * @param len amount of that array that is valid.
+ * @return remaining valid length.
+ */
+ protected int merge_adjacent_actions(production_part rhs_parts[], int len)
+ {
+ int from_loc, to_loc, merge_cnt;
+
+ /* bail out early if we have no work to do */
+ if (rhs_parts == null || len == 0) return 0;
+
+ merge_cnt = 0;
+ to_loc = -1;
+ for (from_loc=0; from_loc<len; from_loc++)
+ {
+ /* do we go in the current position or one further */
+ if (to_loc < 0 || !rhs_parts[to_loc].is_action()
+ || !rhs_parts[from_loc].is_action())
+ {
+ /* next one */
+ to_loc++;
+
+ /* clear the way for it */
+ if (to_loc != from_loc) rhs_parts[to_loc] = null;
+ }
+
+ /* if this is not trivial? */
+ if (to_loc != from_loc)
+ {
+ /* do we merge or copy? */
+ if (rhs_parts[to_loc] != null && rhs_parts[to_loc].is_action() &&
+ rhs_parts[from_loc].is_action())
+ {
+ /* merge */
+ rhs_parts[to_loc] = new action_part(
+ ((action_part)rhs_parts[to_loc]).code_string() +
+ ((action_part)rhs_parts[from_loc]).code_string());
+ merge_cnt++;
+ }
+ else
+ {
+ /* copy */
+ rhs_parts[to_loc] = rhs_parts[from_loc];
+ }
+ }
+ }
+
+ /* return the used length */
+ return len - merge_cnt;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Helper routine to strip a trailing action off rhs and return it
+ * @param rhs_parts array of RHS parts.
+ * @param len how many of those are valid.
+ * @return the removed action part.
+ */
+ protected action_part strip_trailing_action(
+ production_part rhs_parts[],
+ int len)
+ {
+ action_part result;
+
+ /* bail out early if we have nothing to do */
+ if (rhs_parts == null || len == 0) return null;
+
+ /* see if we have a trailing action */
+ if (rhs_parts[len-1].is_action())
+ {
+ /* snip it out and return it */
+ result = (action_part)rhs_parts[len-1];
+ rhs_parts[len-1] = null;
+ return result;
+ }
+ else
+ return null;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Remove all embedded actions from a production by factoring them
+ * out into individual action production using new non terminals.
+ * if the original production was: <pre>
+ * A ::= B {action1} C {action2} D
+ * </pre>
+ * then it will be factored into: <pre>
+ * A ::= B NT$1 C NT$2 D
+ * NT$1 ::= {action1}
+ * NT$2 ::= {action2}
+ * </pre>
+ * where NT$1 and NT$2 are new system created non terminals.
+ */
+
+ /* the declarations added to the parent production are also passed along,
+ as they should be perfectly valid in this code string, since it
+ was originally a code string in the parent, not on its own.
+ frank 6/20/96 */
+ protected void remove_embedded_actions(
+
+ ) throws internal_error
+ {
+ non_terminal new_nt;
+ production new_prod;
+ String declare_str;
+
+ /* walk over the production and process each action */
+ for (int act_loc = 0; act_loc < rhs_length(); act_loc++)
+ if (rhs(act_loc).is_action())
+ {
+
+
+ declare_str = declare_labels(
+ _rhs, act_loc, "");
+ /* create a new non terminal for the action production */
+ new_nt = non_terminal.create_new();
+ new_nt.is_embedded_action = true; /* 24-Mar-1998, CSA */
+
+ /* create a new production with just the action */
+ new_prod = new action_production(this, new_nt, null, 0,
+ declare_str + ((action_part)rhs(act_loc)).code_string());
+
+ /* replace the action with the generated non terminal */
+ _rhs[act_loc] = new symbol_part(new_nt);
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Check to see if the production (now) appears to be nullable.
+ * A production is nullable if its RHS could derive the empty string.
+ * This results when the RHS is empty or contains only non terminals
+ * which themselves are nullable.
+ */
+ public boolean check_nullable() throws internal_error
+ {
+ production_part part;
+ symbol sym;
+ int pos;
+
+ /* if we already know bail out early */
+ if (nullable_known()) return nullable();
+
+ /* if we have a zero size RHS we are directly nullable */
+ if (rhs_length() == 0)
+ {
+ /* stash and return the result */
+ return set_nullable(true);
+ }
+
+ /* otherwise we need to test all of our parts */
+ for (pos=0; pos<rhs_length(); pos++)
+ {
+ part = rhs(pos);
+
+ /* only look at non-actions */
+ if (!part.is_action())
+ {
+ sym = ((symbol_part)part).the_symbol();
+
+ /* if its a terminal we are definitely not nullable */
+ if (!sym.is_non_term())
+ return set_nullable(false);
+ /* its a non-term, is it marked nullable */
+ else if (!((non_terminal)sym).nullable())
+ /* this one not (yet) nullable, so we aren't */
+ return false;
+ }
+ }
+
+ /* if we make it here all parts are nullable */
+ return set_nullable(true);
+ }
+
+ /** set (and return) nullability */
+ boolean set_nullable(boolean v)
+ {
+ _nullable_known = true;
+ _nullable = v;
+ return v;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Update (and return) the first set based on current NT firsts.
+ * This assumes that nullability has already been computed for all non
+ * terminals and productions.
+ */
+ public terminal_set check_first_set() throws internal_error
+ {
+ int part;
+ symbol sym;
+
+ /* walk down the right hand side till we get past all nullables */
+ for (part=0; part<rhs_length(); part++)
+ {
+ /* only look at non-actions */
+ if (!rhs(part).is_action())
+ {
+ sym = ((symbol_part)rhs(part)).the_symbol();
+
+ /* is it a non-terminal?*/
+ if (sym.is_non_term())
+ {
+ /* add in current firsts from that NT */
+ _first_set.add(((non_terminal)sym).first_set());
+
+ /* if its not nullable, we are done */
+ if (!((non_terminal)sym).nullable())
+ break;
+ }
+ else
+ {
+ /* its a terminal -- add that to the set */
+ _first_set.add((terminal)sym);
+
+ /* we are done */
+ break;
+ }
+ }
+ }
+
+ /* return our updated first set */
+ return first_set();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Equality comparison. */
+ public boolean equals(production other)
+ {
+ if (other == null) return false;
+ return other._index == _index;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Generic equality comparison. */
+ public boolean equals(Object other)
+ {
+ if (!(other instanceof production))
+ return false;
+ else
+ return equals((production)other);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Produce a hash code. */
+ public int hashCode()
+ {
+ /* just use a simple function of the index */
+ return _index*13;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to a string. */
+ public String toString()
+ {
+ String result;
+
+ /* catch any internal errors */
+ try {
+ result = "production [" + index() + "]: ";
+ result += ((lhs() != null) ? lhs().toString() : "$$NULL-LHS$$");
+ result += " :: = ";
+ for (int i = 0; i<rhs_length(); i++)
+ result += rhs(i) + " ";
+ result += ";";
+ if (action() != null && action().code_string() != null)
+ result += " {" + action().code_string() + "}";
+
+ if (nullable_known())
+ if (nullable())
+ result += "[NULLABLE]";
+ else
+ result += "[NOT NULLABLE]";
+ } catch (internal_error e) {
+ /* crash on internal error since we can't throw it from here (because
+ superclass does not throw anything. */
+ e.crash();
+ result = null;
+ }
+
+ return result;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to a simpler string. */
+ public String to_simple_string() throws internal_error
+ {
+ String result;
+
+ result = ((lhs() != null) ? lhs().the_symbol().name() : "NULL_LHS");
+ result += " ::= ";
+ for (int i = 0; i < rhs_length(); i++)
+ if (!rhs(i).is_action())
+ result += ((symbol_part)rhs(i)).the_symbol().name() + " ";
+
+ return result;
+ }
+
+ /*-----------------------------------------------------------*/
+
+}
diff --git a/src/syntaxParser/java_cup/production_part.class b/src/syntaxParser/java_cup/production_part.class
new file mode 100644
index 0000000..80e74a5
--- /dev/null
+++ b/src/syntaxParser/java_cup/production_part.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/production_part.java b/src/syntaxParser/java_cup/production_part.java
new file mode 100644
index 0000000..a790ec0
--- /dev/null
+++ b/src/syntaxParser/java_cup/production_part.java
@@ -0,0 +1,94 @@
+package java_cup;
+
+/** This class represents one part (either a symbol or an action) of a
+ * production. In this base class it contains only an optional label
+ * string that the user can use to refer to the part within actions.<p>
+ *
+ * This is an abstract class.
+ *
+ * @see java_cup.production
+ * @version last updated: 11/25/95
+ * @author Scott Hudson
+ */
+public abstract class production_part {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Simple constructor. */
+ public production_part(String lab)
+ {
+ _label = lab;
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Optional label for referring to the part within an action (null for
+ * no label).
+ */
+ protected String _label;
+
+ /** Optional label for referring to the part within an action (null for
+ * no label).
+ */
+ public String label() {return _label;}
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Indicate if this is an action (rather than a symbol). Here in the
+ * base class, we don't this know yet, so its an abstract method.
+ */
+ public abstract boolean is_action();
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Equality comparison. */
+ public boolean equals(production_part other)
+ {
+ if (other == null) return false;
+
+ /* compare the labels */
+ if (label() != null)
+ return label().equals(other.label());
+ else
+ return other.label() == null;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Generic equality comparison. */
+ public boolean equals(Object other)
+ {
+ if (!(other instanceof production_part))
+ return false;
+ else
+ return equals((production_part)other);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Produce a hash code. */
+ public int hashCode()
+ {
+ return label()==null ? 0 : label().hashCode();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to a string. */
+ public String toString()
+ {
+ if (label() != null)
+ return label() + ":";
+ else
+ return " ";
+ }
+
+ /*-----------------------------------------------------------*/
+
+}
diff --git a/src/syntaxParser/java_cup/reduce_action.class b/src/syntaxParser/java_cup/reduce_action.class
new file mode 100644
index 0000000..14379c2
--- /dev/null
+++ b/src/syntaxParser/java_cup/reduce_action.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/reduce_action.java b/src/syntaxParser/java_cup/reduce_action.java
new file mode 100644
index 0000000..e8f4c84
--- /dev/null
+++ b/src/syntaxParser/java_cup/reduce_action.java
@@ -0,0 +1,84 @@
+
+package java_cup;
+
+/** This class represents a reduce action within the parse table.
+ * The action simply stores the production that it reduces with and
+ * responds to queries about its type.
+ *
+ * @version last updated: 11/25/95
+ * @author Scott Hudson
+ */
+public class reduce_action extends parse_action {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Simple constructor.
+ * @param prod the production this action reduces with.
+ */
+ public reduce_action(production prod ) throws internal_error
+ {
+ /* sanity check */
+ if (prod == null)
+ throw new internal_error(
+ "Attempt to create a reduce_action with a null production");
+
+ _reduce_with = prod;
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** The production we reduce with. */
+ protected production _reduce_with;
+
+ /** The production we reduce with. */
+ public production reduce_with() {return _reduce_with;}
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Quick access to type of action. */
+ public int kind() {return REDUCE;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Equality test. */
+ public boolean equals(reduce_action other)
+ {
+ return other != null && other.reduce_with() == reduce_with();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Generic equality test. */
+ public boolean equals(Object other)
+ {
+ if (other instanceof reduce_action)
+ return equals((reduce_action)other);
+ else
+ return false;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Compute a hash code. */
+ public int hashCode()
+ {
+ /* use the hash code of the production we are reducing with */
+ return reduce_with().hashCode();
+ }
+
+
+ /** Convert to string. */
+ public String toString()
+ {
+ return "REDUCE(with prod " + reduce_with().index() + ")";
+ }
+
+ /*-----------------------------------------------------------*/
+
+}
diff --git a/src/syntaxParser/java_cup/runtime/Scanner.class b/src/syntaxParser/java_cup/runtime/Scanner.class
new file mode 100644
index 0000000..29ef66b
--- /dev/null
+++ b/src/syntaxParser/java_cup/runtime/Scanner.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/runtime/Scanner.java b/src/syntaxParser/java_cup/runtime/Scanner.java
new file mode 100644
index 0000000..3233551
--- /dev/null
+++ b/src/syntaxParser/java_cup/runtime/Scanner.java
@@ -0,0 +1,25 @@
+package java_cup.runtime;
+
+/**
+ * Defines the Scanner interface, which CUP uses in the default
+ * implementation of <code>lr_parser.scan()</code>. Integration
+ * of scanners implementing <code>Scanner</code> is facilitated.
+ *
+ * @version last updated 23-Jul-1999
+ * @author David MacMahon <davidm@smartsc.com>
+ */
+
+/* *************************************************
+ Interface Scanner
+
+ Declares the next_token() method that should be
+ implemented by scanners. This method is typically
+ called by lr_parser.scan(). End-of-file can be
+ indicated either by returning
+ <code>new Symbol(lr_parser.EOF_sym())</code> or
+ <code>null</code>.
+ ***************************************************/
+public interface Scanner {
+ /** Return the next token, or <code>null</code> on end-of-file. */
+ public Symbol next_token() throws java.lang.Exception;
+}
diff --git a/src/syntaxParser/java_cup/runtime/Symbol.class b/src/syntaxParser/java_cup/runtime/Symbol.class
new file mode 100644
index 0000000..4831d12
--- /dev/null
+++ b/src/syntaxParser/java_cup/runtime/Symbol.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/runtime/Symbol.java b/src/syntaxParser/java_cup/runtime/Symbol.java
new file mode 100644
index 0000000..eeb6a0b
--- /dev/null
+++ b/src/syntaxParser/java_cup/runtime/Symbol.java
@@ -0,0 +1,105 @@
+package java_cup.runtime;
+
+/**
+ * Defines the Symbol class, which is used to represent all terminals
+ * and nonterminals while parsing. The lexer should pass CUP Symbols
+ * and CUP returns a Symbol.
+ *
+ * @version last updated: 7/3/96
+ * @author Frank Flannery
+ */
+
+/* ****************************************************************
+ Class Symbol
+ what the parser expects to receive from the lexer.
+ the token is identified as follows:
+ sym: the symbol type
+ parse_state: the parse state.
+ value: is the lexical value of type Object
+ left : is the left position in the original input file
+ right: is the right position in the original input file
+******************************************************************/
+
+public class Symbol {
+
+/*******************************
+ Constructor for l,r values
+ *******************************/
+
+ public Symbol(int id, int l, int r, Object o) {
+ this(id);
+ left = l;
+ right = r;
+ value = o;
+ }
+
+/*******************************
+ Constructor for no l,r values
+********************************/
+
+ public Symbol(int id, Object o) {
+ this(id, -1, -1, o);
+ }
+
+/*****************************
+ Constructor for no value
+ ***************************/
+
+ public Symbol(int id, int l, int r) {
+ this(id, l, r, null);
+ }
+
+/***********************************
+ Constructor for no value or l,r
+***********************************/
+
+ public Symbol(int sym_num) {
+ this(sym_num, -1);
+ left = -1;
+ right = -1;
+ value = null;
+ }
+
+/***********************************
+ Constructor to give a start state
+***********************************/
+ Symbol(int sym_num, int state)
+ {
+ sym = sym_num;
+ parse_state = state;
+ }
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** The symbol number of the terminal or non terminal being represented */
+ public int sym;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** The parse state to be recorded on the parse stack with this symbol.
+ * This field is for the convenience of the parser and shouldn't be
+ * modified except by the parser.
+ */
+ public int parse_state;
+ /** This allows us to catch some errors caused by scanners recycling
+ * symbols. For the use of the parser only. [CSA, 23-Jul-1999] */
+ boolean used_by_parser = false;
+
+/*******************************
+ The data passed to parser
+ *******************************/
+
+ public int left, right;
+ public Object value;
+
+ /*****************************
+ Printing this token out. (Override for pretty-print).
+ ****************************/
+ public String toString() { return "#"+sym; }
+}
+
+
+
+
+
+
diff --git a/src/syntaxParser/java_cup/runtime/lr_parser.class b/src/syntaxParser/java_cup/runtime/lr_parser.class
new file mode 100644
index 0000000..338bdd8
--- /dev/null
+++ b/src/syntaxParser/java_cup/runtime/lr_parser.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/runtime/lr_parser.java b/src/syntaxParser/java_cup/runtime/lr_parser.java
new file mode 100644
index 0000000..3c8335c
--- /dev/null
+++ b/src/syntaxParser/java_cup/runtime/lr_parser.java
@@ -0,0 +1,1238 @@
+
+package java_cup.runtime;
+
+import java.util.Stack;
+
+/** This class implements a skeleton table driven LR parser. In general,
+ * LR parsers are a form of bottom up shift-reduce parsers. Shift-reduce
+ * parsers act by shifting input onto a parse stack until the Symbols
+ * matching the right hand side of a production appear on the top of the
+ * stack. Once this occurs, a reduce is performed. This involves removing
+ * the Symbols corresponding to the right hand side of the production
+ * (the so called "handle") and replacing them with the non-terminal from
+ * the left hand side of the production. <p>
+ *
+ * To control the decision of whether to shift or reduce at any given point,
+ * the parser uses a state machine (the "viable prefix recognition machine"
+ * built by the parser generator). The current state of the machine is placed
+ * on top of the parse stack (stored as part of a Symbol object representing
+ * a terminal or non terminal). The parse action table is consulted
+ * (using the current state and the current lookahead Symbol as indexes) to
+ * determine whether to shift or to reduce. When the parser shifts, it
+ * changes to a new state by pushing a new Symbol (containing a new state)
+ * onto the stack. When the parser reduces, it pops the handle (right hand
+ * side of a production) off the stack. This leaves the parser in the state
+ * it was in before any of those Symbols were matched. Next the reduce-goto
+ * table is consulted (using the new state and current lookahead Symbol as
+ * indexes) to determine a new state to go to. The parser then shifts to
+ * this goto state by pushing the left hand side Symbol of the production
+ * (also containing the new state) onto the stack.<p>
+ *
+ * This class actually provides four LR parsers. The methods parse() and
+ * debug_parse() provide two versions of the main parser (the only difference
+ * being that debug_parse() emits debugging trace messages as it parses).
+ * In addition to these main parsers, the error recovery mechanism uses two
+ * more. One of these is used to simulate "parsing ahead" in the input
+ * without carrying out actions (to verify that a potential error recovery
+ * has worked), and the other is used to parse through buffered "parse ahead"
+ * input in order to execute all actions and re-synchronize the actual parser
+ * configuration.<p>
+ *
+ * This is an abstract class which is normally filled out by a subclass
+ * generated by the JavaCup parser generator. In addition to supplying
+ * the actual parse tables, generated code also supplies methods which
+ * invoke various pieces of user supplied code, provide access to certain
+ * special Symbols (e.g., EOF and error), etc. Specifically, the following
+ * abstract methods are normally supplied by generated code:
+ * <dl compact>
+ * <dt> short[][] production_table()
+ * <dd> Provides a reference to the production table (indicating the index of
+ * the left hand side non terminal and the length of the right hand side
+ * for each production in the grammar).
+ * <dt> short[][] action_table()
+ * <dd> Provides a reference to the parse action table.
+ * <dt> short[][] reduce_table()
+ * <dd> Provides a reference to the reduce-goto table.
+ * <dt> int start_state()
+ * <dd> Indicates the index of the start state.
+ * <dt> int start_production()
+ * <dd> Indicates the index of the starting production.
+ * <dt> int EOF_sym()
+ * <dd> Indicates the index of the EOF Symbol.
+ * <dt> int error_sym()
+ * <dd> Indicates the index of the error Symbol.
+ * <dt> Symbol do_action()
+ * <dd> Executes a piece of user supplied action code. This always comes at
+ * the point of a reduce in the parse, so this code also allocates and
+ * fills in the left hand side non terminal Symbol object that is to be
+ * pushed onto the stack for the reduce.
+ * <dt> void init_actions()
+ * <dd> Code to initialize a special object that encapsulates user supplied
+ * actions (this object is used by do_action() to actually carry out the
+ * actions).
+ * </dl>
+ *
+ * In addition to these routines that <i>must</i> be supplied by the
+ * generated subclass there are also a series of routines that <i>may</i>
+ * be supplied. These include:
+ * <dl>
+ * <dt> Symbol scan()
+ * <dd> Used to get the next input Symbol from the scanner.
+ * <dt> Scanner getScanner()
+ * <dd> Used to provide a scanner for the default implementation of
+ * scan().
+ * <dt> int error_sync_size()
+ * <dd> This determines how many Symbols past the point of an error
+ * must be parsed without error in order to consider a recovery to
+ * be valid. This defaults to 3. Values less than 2 are not
+ * recommended.
+ * <dt> void report_error(String message, Object info)
+ * <dd> This method is called to report an error. The default implementation
+ * simply prints a message to System.err and where the error occurred.
+ * This method is often replaced in order to provide a more sophisticated
+ * error reporting mechanism.
+ * <dt> void report_fatal_error(String message, Object info)
+ * <dd> This method is called when a fatal error that cannot be recovered from
+ * is encountered. In the default implementation, it calls
+ * report_error() to emit a message, then throws an exception.
+ * <dt> void syntax_error(Symbol cur_token)
+ * <dd> This method is called as soon as syntax error is detected (but
+ * before recovery is attempted). In the default implementation it
+ * invokes: report_error("Syntax error", null);
+ * <dt> void unrecovered_syntax_error(Symbol cur_token)
+ * <dd> This method is called if syntax error recovery fails. In the default
+ * implementation it invokes:<br>
+ * report_fatal_error("Couldn't repair and continue parse", null);
+ * </dl>
+ *
+ * @see java_cup.runtime.Symbol
+ * @see java_cup.runtime.Symbol
+ * @see java_cup.runtime.virtual_parse_stack
+ * @version last updated: 7/3/96
+ * @author Frank Flannery
+ */
+
+public abstract class lr_parser {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Simple constructor. */
+ public lr_parser()
+ {
+ /* nothing to do here */
+ }
+
+ /** Constructor that sets the default scanner. [CSA/davidm] */
+ public lr_parser(Scanner s) {
+ this(); /* in case default constructor someday does something */
+ setScanner(s);
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Static (Class) Variables ------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** The default number of Symbols after an error we much match to consider
+ * it recovered from.
+ */
+ protected final static int _error_sync_size = 3;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** The number of Symbols after an error we much match to consider it
+ * recovered from.
+ */
+ protected int error_sync_size() {return _error_sync_size; }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Table of production information (supplied by generated subclass).
+ * This table contains one entry per production and is indexed by
+ * the negative-encoded values (reduce actions) in the action_table.
+ * Each entry has two parts, the index of the non-terminal on the
+ * left hand side of the production, and the number of Symbols
+ * on the right hand side.
+ */
+ public abstract short[][] production_table();
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** The action table (supplied by generated subclass). This table is
+ * indexed by state and terminal number indicating what action is to
+ * be taken when the parser is in the given state (i.e., the given state
+ * is on top of the stack) and the given terminal is next on the input.
+ * States are indexed using the first dimension, however, the entries for
+ * a given state are compacted and stored in adjacent index, value pairs
+ * which are searched for rather than accessed directly (see get_action()).
+ * The actions stored in the table will be either shifts, reduces, or
+ * errors. Shifts are encoded as positive values (one greater than the
+ * state shifted to). Reduces are encoded as negative values (one less
+ * than the production reduced by). Error entries are denoted by zero.
+ *
+ * @see java_cup.runtime.lr_parser#get_action
+ */
+ public abstract short[][] action_table();
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** The reduce-goto table (supplied by generated subclass). This
+ * table is indexed by state and non-terminal number and contains
+ * state numbers. States are indexed using the first dimension, however,
+ * the entries for a given state are compacted and stored in adjacent
+ * index, value pairs which are searched for rather than accessed
+ * directly (see get_reduce()). When a reduce occurs, the handle
+ * (corresponding to the RHS of the matched production) is popped off
+ * the stack. The new top of stack indicates a state. This table is
+ * then indexed by that state and the LHS of the reducing production to
+ * indicate where to "shift" to.
+ *
+ * @see java_cup.runtime.lr_parser#get_reduce
+ */
+ public abstract short[][] reduce_table();
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** The index of the start state (supplied by generated subclass). */
+ public abstract int start_state();
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** The index of the start production (supplied by generated subclass). */
+ public abstract int start_production();
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** The index of the end of file terminal Symbol (supplied by generated
+ * subclass).
+ */
+ public abstract int EOF_sym();
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** The index of the special error Symbol (supplied by generated subclass). */
+ public abstract int error_sym();
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Internal flag to indicate when parser should quit. */
+ protected boolean _done_parsing = false;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** This method is called to indicate that the parser should quit. This is
+ * normally called by an accept action, but can be used to cancel parsing
+ * early in other circumstances if desired.
+ */
+ public void done_parsing()
+ {
+ _done_parsing = true;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+ /* Global parse state shared by parse(), error recovery, and
+ * debugging routines */
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Indication of the index for top of stack (for use by actions). */
+ protected int tos;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** The current lookahead Symbol. */
+ protected Symbol cur_token;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** The parse stack itself. */
+ protected Stack stack = new Stack();
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Direct reference to the production table. */
+ protected short[][] production_tab;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Direct reference to the action table. */
+ protected short[][] action_tab;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Direct reference to the reduce-goto table. */
+ protected short[][] reduce_tab;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** This is the scanner object used by the default implementation
+ * of scan() to get Symbols. To avoid name conflicts with existing
+ * code, this field is private. [CSA/davidm] */
+ private Scanner _scanner;
+
+ /**
+ * Simple accessor method to set the default scanner.
+ */
+ public void setScanner(Scanner s) { _scanner = s; }
+
+ /**
+ * Simple accessor method to get the default scanner.
+ */
+ public Scanner getScanner() { return _scanner; }
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Perform a bit of user supplied action code (supplied by generated
+ * subclass). Actions are indexed by an internal action number assigned
+ * at parser generation time.
+ *
+ * @param act_num the internal index of the action to be performed.
+ * @param parser the parser object we are acting for.
+ * @param stack the parse stack of that object.
+ * @param top the index of the top element of the parse stack.
+ */
+ public abstract Symbol do_action(
+ int act_num,
+ lr_parser parser,
+ Stack stack,
+ int top)
+ throws java.lang.Exception;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** User code for initialization inside the parser. Typically this
+ * initializes the scanner. This is called before the parser requests
+ * the first Symbol. Here this is just a placeholder for subclasses that
+ * might need this and we perform no action. This method is normally
+ * overridden by the generated code using this contents of the "init with"
+ * clause as its body.
+ */
+ public void user_init() throws java.lang.Exception { }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Initialize the action object. This is called before the parser does
+ * any parse actions. This is filled in by generated code to create
+ * an object that encapsulates all action code.
+ */
+ protected abstract void init_actions() throws java.lang.Exception;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Get the next Symbol from the input (supplied by generated subclass).
+ * Once end of file has been reached, all subsequent calls to scan
+ * should return an EOF Symbol (which is Symbol number 0). By default
+ * this method returns getScanner().next_token(); this implementation
+ * can be overriden by the generated parser using the code declared in
+ * the "scan with" clause. Do not recycle objects; every call to
+ * scan() should return a fresh object.
+ */
+ public Symbol scan() throws java.lang.Exception {
+ Symbol sym = getScanner().next_token();
+ return (sym!=null) ? sym : new Symbol(EOF_sym());
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Report a fatal error. This method takes a message string and an
+ * additional object (to be used by specializations implemented in
+ * subclasses). Here in the base class a very simple implementation
+ * is provided which reports the error then throws an exception.
+ *
+ * @param message an error message.
+ * @param info an extra object reserved for use by specialized subclasses.
+ */
+ public void report_fatal_error(
+ String message,
+ Object info)
+ throws java.lang.Exception
+ {
+ /* stop parsing (not really necessary since we throw an exception, but) */
+ done_parsing();
+
+ /* use the normal error message reporting to put out the message */
+ report_error(message, info);
+
+ /* throw an exception */
+ throw new Exception("Can't recover from previous error(s)");
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Report a non fatal error (or warning). This method takes a message
+ * string and an additional object (to be used by specializations
+ * implemented in subclasses). Here in the base class a very simple
+ * implementation is provided which simply prints the message to
+ * System.err.
+ *
+ * @param message an error message.
+ * @param info an extra object reserved for use by specialized subclasses.
+ */
+ public void report_error(String message, Object info)
+ {
+ System.err.print(message);
+ if (info instanceof Symbol)
+ if (((Symbol)info).left != -1)
+ System.err.println(" at character " + ((Symbol)info).left +
+ " of input");
+ else System.err.println("");
+ else System.err.println("");
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** This method is called when a syntax error has been detected and recovery
+ * is about to be invoked. Here in the base class we just emit a
+ * "Syntax error" error message.
+ *
+ * @param cur_token the current lookahead Symbol.
+ */
+ public void syntax_error(Symbol cur_token)
+ {
+ report_error("Syntax error", cur_token);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** This method is called if it is determined that syntax error recovery
+ * has been unsuccessful. Here in the base class we report a fatal error.
+ *
+ * @param cur_token the current lookahead Symbol.
+ */
+ public void unrecovered_syntax_error(Symbol cur_token)
+ throws java.lang.Exception
+ {
+ report_fatal_error("Couldn't repair and continue parse", cur_token);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Fetch an action from the action table. The table is broken up into
+ * rows, one per state (rows are indexed directly by state number).
+ * Within each row, a list of index, value pairs are given (as sequential
+ * entries in the table), and the list is terminated by a default entry
+ * (denoted with a Symbol index of -1). To find the proper entry in a row
+ * we do a linear or binary search (depending on the size of the row).
+ *
+ * @param state the state index of the action being accessed.
+ * @param sym the Symbol index of the action being accessed.
+ */
+ protected final short get_action(int state, int sym)
+ {
+ short tag;
+ int first, last, probe;
+ short[] row = action_tab[state];
+
+ /* linear search if we are < 10 entries */
+ if (row.length < 20)
+ for (probe = 0; probe < row.length; probe++)
+ {
+ /* is this entry labeled with our Symbol or the default? */
+ tag = row[probe++];
+ if (tag == sym || tag == -1)
+ {
+ /* return the next entry */
+ return row[probe];
+ }
+ }
+ /* otherwise binary search */
+ else
+ {
+ first = 0;
+ last = (row.length-1)/2 - 1; /* leave out trailing default entry */
+ while (first <= last)
+ {
+ probe = (first+last)/2;
+ if (sym == row[probe*2])
+ return row[probe*2+1];
+ else if (sym > row[probe*2])
+ first = probe+1;
+ else
+ last = probe-1;
+ }
+
+ /* not found, use the default at the end */
+ return row[row.length-1];
+ }
+
+ /* shouldn't happened, but if we run off the end we return the
+ default (error == 0) */
+ return 0;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Fetch a state from the reduce-goto table. The table is broken up into
+ * rows, one per state (rows are indexed directly by state number).
+ * Within each row, a list of index, value pairs are given (as sequential
+ * entries in the table), and the list is terminated by a default entry
+ * (denoted with a Symbol index of -1). To find the proper entry in a row
+ * we do a linear search.
+ *
+ * @param state the state index of the entry being accessed.
+ * @param sym the Symbol index of the entry being accessed.
+ */
+ protected final short get_reduce(int state, int sym)
+ {
+ short tag;
+ short[] row = reduce_tab[state];
+
+ /* if we have a null row we go with the default */
+ if (row == null)
+ return -1;
+
+ for (int probe = 0; probe < row.length; probe++)
+ {
+ /* is this entry labeled with our Symbol or the default? */
+ tag = row[probe++];
+ if (tag == sym || tag == -1)
+ {
+ /* return the next entry */
+ return row[probe];
+ }
+ }
+ /* if we run off the end we return the default (error == -1) */
+ return -1;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** This method provides the main parsing routine. It returns only when
+ * done_parsing() has been called (typically because the parser has
+ * accepted, or a fatal error has been reported). See the header
+ * documentation for the class regarding how shift/reduce parsers operate
+ * and how the various tables are used.
+ */
+ public Symbol parse() throws java.lang.Exception
+ {
+ /* the current action code */
+ int act;
+
+ /* the Symbol/stack element returned by a reduce */
+ Symbol lhs_sym = null;
+
+ /* information about production being reduced with */
+ short handle_size, lhs_sym_num;
+
+ /* set up direct reference to tables to drive the parser */
+
+ production_tab = production_table();
+ action_tab = action_table();
+ reduce_tab = reduce_table();
+
+ /* initialize the action encapsulation object */
+ init_actions();
+
+ /* do user initialization */
+ user_init();
+
+ /* get the first token */
+ cur_token = scan();
+
+ /* push dummy Symbol with start state to get us underway */
+ stack.removeAllElements();
+ stack.push(new Symbol(0, start_state()));
+ tos = 0;
+
+ /* continue until we are told to stop */
+ for (_done_parsing = false; !_done_parsing; )
+ {
+ /* Check current token for freshness. */
+ if (cur_token.used_by_parser)
+ throw new Error("Symbol recycling detected (fix your scanner).");
+
+ /* current state is always on the top of the stack */
+
+ /* look up action out of the current state with the current input */
+ act = get_action(((Symbol)stack.peek()).parse_state, cur_token.sym);
+
+ /* decode the action -- > 0 encodes shift */
+ if (act > 0)
+ {
+ /* shift to the encoded state by pushing it on the stack */
+ cur_token.parse_state = act-1;
+ cur_token.used_by_parser = true;
+ stack.push(cur_token);
+ tos++;
+
+ /* advance to the next Symbol */
+ cur_token = scan();
+ }
+ /* if its less than zero, then it encodes a reduce action */
+ else if (act < 0)
+ {
+ /* perform the action for the reduce */
+ lhs_sym = do_action((-act)-1, this, stack, tos);
+
+ /* look up information about the production */
+ lhs_sym_num = production_tab[(-act)-1][0];
+ handle_size = production_tab[(-act)-1][1];
+
+ /* pop the handle off the stack */
+ for (int i = 0; i < handle_size; i++)
+ {
+ stack.pop();
+ tos--;
+ }
+
+ /* look up the state to go to from the one popped back to */
+ act = get_reduce(((Symbol)stack.peek()).parse_state, lhs_sym_num);
+
+ /* shift to that state */
+ lhs_sym.parse_state = act;
+ lhs_sym.used_by_parser = true;
+ stack.push(lhs_sym);
+ tos++;
+ }
+ /* finally if the entry is zero, we have an error */
+ else if (act == 0)
+ {
+ /* call user syntax error reporting routine */
+ syntax_error(cur_token);
+
+ /* try to error recover */
+ if (!error_recovery(false))
+ {
+ /* if that fails give up with a fatal syntax error */
+ unrecovered_syntax_error(cur_token);
+
+ /* just in case that wasn't fatal enough, end parse */
+ done_parsing();
+ } else {
+ lhs_sym = (Symbol)stack.peek();
+ }
+ }
+ }
+ return lhs_sym;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Write a debugging message to System.err for the debugging version
+ * of the parser.
+ *
+ * @param mess the text of the debugging message.
+ */
+ public void debug_message(String mess)
+ {
+ System.err.println(mess);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Dump the parse stack for debugging purposes. */
+ public void dump_stack()
+ {
+ if (stack == null)
+ {
+ debug_message("# Stack dump requested, but stack is null");
+ return;
+ }
+
+ debug_message("============ Parse Stack Dump ============");
+
+ /* dump the stack */
+ for (int i=0; i<stack.size(); i++)
+ {
+ debug_message("Symbol: " + ((Symbol)stack.elementAt(i)).sym +
+ " State: " + ((Symbol)stack.elementAt(i)).parse_state);
+ }
+ debug_message("==========================================");
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Do debug output for a reduce.
+ *
+ * @param prod_num the production we are reducing with.
+ * @param nt_num the index of the LHS non terminal.
+ * @param rhs_size the size of the RHS.
+ */
+ public void debug_reduce(int prod_num, int nt_num, int rhs_size)
+ {
+ debug_message("# Reduce with prod #" + prod_num + " [NT=" + nt_num +
+ ", " + "SZ=" + rhs_size + "]");
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Do debug output for shift.
+ *
+ * @param shift_tkn the Symbol being shifted onto the stack.
+ */
+ public void debug_shift(Symbol shift_tkn)
+ {
+ debug_message("# Shift under term #" + shift_tkn.sym +
+ " to state #" + shift_tkn.parse_state);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Do debug output for stack state. [CSA]
+ */
+ public void debug_stack() {
+ StringBuffer sb=new StringBuffer("## STACK:");
+ for (int i=0; i<stack.size(); i++) {
+ Symbol s = (Symbol) stack.elementAt(i);
+ sb.append(" <state "+s.parse_state+", sym "+s.sym+">");
+ if ((i%3)==2 || (i==(stack.size()-1))) {
+ debug_message(sb.toString());
+ sb = new StringBuffer(" ");
+ }
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Perform a parse with debugging output. This does exactly the
+ * same things as parse(), except that it calls debug_shift() and
+ * debug_reduce() when shift and reduce moves are taken by the parser
+ * and produces various other debugging messages.
+ */
+ public Symbol debug_parse()
+ throws java.lang.Exception
+ {
+ /* the current action code */
+ int act;
+
+ /* the Symbol/stack element returned by a reduce */
+ Symbol lhs_sym = null;
+
+ /* information about production being reduced with */
+ short handle_size, lhs_sym_num;
+
+ /* set up direct reference to tables to drive the parser */
+ production_tab = production_table();
+ action_tab = action_table();
+ reduce_tab = reduce_table();
+
+ debug_message("# Initializing parser");
+
+ /* initialize the action encapsulation object */
+ init_actions();
+
+ /* do user initialization */
+ user_init();
+
+ /* the current Symbol */
+ cur_token = scan();
+
+ debug_message("# Current Symbol is #" + cur_token.sym);
+
+ /* push dummy Symbol with start state to get us underway */
+ stack.removeAllElements();
+ stack.push(new Symbol(0, start_state()));
+ tos = 0;
+
+ /* continue until we are told to stop */
+ for (_done_parsing = false; !_done_parsing; )
+ {
+ /* Check current token for freshness. */
+ if (cur_token.used_by_parser)
+ throw new Error("Symbol recycling detected (fix your scanner).");
+
+ /* current state is always on the top of the stack */
+ //debug_stack();
+
+ /* look up action out of the current state with the current input */
+ act = get_action(((Symbol)stack.peek()).parse_state, cur_token.sym);
+
+ /* decode the action -- > 0 encodes shift */
+ if (act > 0)
+ {
+ /* shift to the encoded state by pushing it on the stack */
+ cur_token.parse_state = act-1;
+ cur_token.used_by_parser = true;
+ debug_shift(cur_token);
+ stack.push(cur_token);
+ tos++;
+
+ /* advance to the next Symbol */
+ cur_token = scan();
+ debug_message("# Current token is " + cur_token);
+ }
+ /* if its less than zero, then it encodes a reduce action */
+ else if (act < 0)
+ {
+ /* perform the action for the reduce */
+ lhs_sym = do_action((-act)-1, this, stack, tos);
+
+ /* look up information about the production */
+ lhs_sym_num = production_tab[(-act)-1][0];
+ handle_size = production_tab[(-act)-1][1];
+
+ debug_reduce((-act)-1, lhs_sym_num, handle_size);
+
+ /* pop the handle off the stack */
+ for (int i = 0; i < handle_size; i++)
+ {
+ stack.pop();
+ tos--;
+ }
+
+ /* look up the state to go to from the one popped back to */
+ act = get_reduce(((Symbol)stack.peek()).parse_state, lhs_sym_num);
+ debug_message("# Reduce rule: top state " +
+ ((Symbol)stack.peek()).parse_state +
+ ", lhs sym " + lhs_sym_num + " -> state " + act);
+
+ /* shift to that state */
+ lhs_sym.parse_state = act;
+ lhs_sym.used_by_parser = true;
+ stack.push(lhs_sym);
+ tos++;
+
+ debug_message("# Goto state #" + act);
+ }
+ /* finally if the entry is zero, we have an error */
+ else if (act == 0)
+ {
+ /* call user syntax error reporting routine */
+ syntax_error(cur_token);
+
+ /* try to error recover */
+ if (!error_recovery(true))
+ {
+ /* if that fails give up with a fatal syntax error */
+ unrecovered_syntax_error(cur_token);
+
+ /* just in case that wasn't fatal enough, end parse */
+ done_parsing();
+ } else {
+ lhs_sym = (Symbol)stack.peek();
+ }
+ }
+ }
+ return lhs_sym;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+ /* Error recovery code */
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Attempt to recover from a syntax error. This returns false if recovery
+ * fails, true if it succeeds. Recovery happens in 4 steps. First we
+ * pop the parse stack down to a point at which we have a shift out
+ * of the top-most state on the error Symbol. This represents the
+ * initial error recovery configuration. If no such configuration is
+ * found, then we fail. Next a small number of "lookahead" or "parse
+ * ahead" Symbols are read into a buffer. The size of this buffer is
+ * determined by error_sync_size() and determines how many Symbols beyond
+ * the error must be matched to consider the recovery a success. Next,
+ * we begin to discard Symbols in attempt to get past the point of error
+ * to a point where we can continue parsing. After each Symbol, we attempt
+ * to "parse ahead" though the buffered lookahead Symbols. The "parse ahead"
+ * process simulates that actual parse, but does not modify the real
+ * parser's configuration, nor execute any actions. If we can parse all
+ * the stored Symbols without error, then the recovery is considered a
+ * success. Once a successful recovery point is determined, we do an
+ * actual parse over the stored input -- modifying the real parse
+ * configuration and executing all actions. Finally, we return the the
+ * normal parser to continue with the overall parse.
+ *
+ * @param debug should we produce debugging messages as we parse.
+ */
+ protected boolean error_recovery(boolean debug)
+ throws java.lang.Exception
+ {
+ if (debug) debug_message("# Attempting error recovery");
+
+ /* first pop the stack back into a state that can shift on error and
+ do that shift (if that fails, we fail) */
+ if (!find_recovery_config(debug))
+ {
+ if (debug) debug_message("# Error recovery fails");
+ return false;
+ }
+
+ /* read ahead to create lookahead we can parse multiple times */
+ read_lookahead();
+
+ /* repeatedly try to parse forward until we make it the required dist */
+ for (;;)
+ {
+ /* try to parse forward, if it makes it, bail out of loop */
+ if (debug) debug_message("# Trying to parse ahead");
+ if (try_parse_ahead(debug))
+ {
+ break;
+ }
+
+ /* if we are now at EOF, we have failed */
+ if (lookahead[0].sym == EOF_sym())
+ {
+ if (debug) debug_message("# Error recovery fails at EOF");
+ return false;
+ }
+
+ /* otherwise, we consume another Symbol and try again */
+ // BUG FIX by Bruce Hutton
+ // Computer Science Department, University of Auckland,
+ // Auckland, New Zealand.
+ // It is the first token that is being consumed, not the one
+ // we were up to parsing
+ if (debug)
+ debug_message("# Consuming Symbol #" + lookahead[ 0 ].sym);
+ restart_lookahead();
+ }
+
+ /* we have consumed to a point where we can parse forward */
+ if (debug) debug_message("# Parse-ahead ok, going back to normal parse");
+
+ /* do the real parse (including actions) across the lookahead */
+ parse_lookahead(debug);
+
+ /* we have success */
+ return true;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Determine if we can shift under the special error Symbol out of the
+ * state currently on the top of the (real) parse stack.
+ */
+ protected boolean shift_under_error()
+ {
+ /* is there a shift under error Symbol */
+ return get_action(((Symbol)stack.peek()).parse_state, error_sym()) > 0;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Put the (real) parse stack into error recovery configuration by
+ * popping the stack down to a state that can shift on the special
+ * error Symbol, then doing the shift. If no suitable state exists on
+ * the stack we return false
+ *
+ * @param debug should we produce debugging messages as we parse.
+ */
+ protected boolean find_recovery_config(boolean debug)
+ {
+ Symbol error_token;
+ int act;
+
+ if (debug) debug_message("# Finding recovery state on stack");
+
+ /* Remember the right-position of the top symbol on the stack */
+ int right_pos = ((Symbol)stack.peek()).right;
+ int left_pos = ((Symbol)stack.peek()).left;
+
+ /* pop down until we can shift under error Symbol */
+ while (!shift_under_error())
+ {
+ /* pop the stack */
+ if (debug)
+ debug_message("# Pop stack by one, state was # " +
+ ((Symbol)stack.peek()).parse_state);
+ left_pos = ((Symbol)stack.pop()).left;
+ tos--;
+
+ /* if we have hit bottom, we fail */
+ if (stack.empty())
+ {
+ if (debug) debug_message("# No recovery state found on stack");
+ return false;
+ }
+ }
+
+ /* state on top of the stack can shift under error, find the shift */
+ act = get_action(((Symbol)stack.peek()).parse_state, error_sym());
+ if (debug)
+ {
+ debug_message("# Recover state found (#" +
+ ((Symbol)stack.peek()).parse_state + ")");
+ debug_message("# Shifting on error to state #" + (act-1));
+ }
+
+ /* build and shift a special error Symbol */
+ error_token = new Symbol(error_sym(), left_pos, right_pos);
+ error_token.parse_state = act-1;
+ error_token.used_by_parser = true;
+ stack.push(error_token);
+ tos++;
+
+ return true;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Lookahead Symbols used for attempting error recovery "parse aheads". */
+ protected Symbol lookahead[];
+
+ /** Position in lookahead input buffer used for "parse ahead". */
+ protected int lookahead_pos;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Read from input to establish our buffer of "parse ahead" lookahead
+ * Symbols.
+ */
+ protected void read_lookahead() throws java.lang.Exception
+ {
+ /* create the lookahead array */
+ lookahead = new Symbol[error_sync_size()];
+
+ /* fill in the array */
+ for (int i = 0; i < error_sync_size(); i++)
+ {
+ lookahead[i] = cur_token;
+ cur_token = scan();
+ }
+
+ /* start at the beginning */
+ lookahead_pos = 0;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Return the current lookahead in our error "parse ahead" buffer. */
+ protected Symbol cur_err_token() { return lookahead[lookahead_pos]; }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Advance to next "parse ahead" input Symbol. Return true if we have
+ * input to advance to, false otherwise.
+ */
+ protected boolean advance_lookahead()
+ {
+ /* advance the input location */
+ lookahead_pos++;
+
+ /* return true if we didn't go off the end */
+ return lookahead_pos < error_sync_size();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Reset the parse ahead input to one Symbol past where we started error
+ * recovery (this consumes one new Symbol from the real input).
+ */
+ protected void restart_lookahead() throws java.lang.Exception
+ {
+ /* move all the existing input over */
+ for (int i = 1; i < error_sync_size(); i++)
+ lookahead[i-1] = lookahead[i];
+
+ /* read a new Symbol into the last spot */
+ // BUG Fix by Bruce Hutton
+ // Computer Science Department, University of Auckland,
+ // Auckland, New Zealand. [applied 5-sep-1999 by csa]
+ // The following two lines were out of order!!
+ lookahead[error_sync_size()-1] = cur_token;
+ cur_token = scan();
+
+ /* reset our internal position marker */
+ lookahead_pos = 0;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Do a simulated parse forward (a "parse ahead") from the current
+ * stack configuration using stored lookahead input and a virtual parse
+ * stack. Return true if we make it all the way through the stored
+ * lookahead input without error. This basically simulates the action of
+ * parse() using only our saved "parse ahead" input, and not executing any
+ * actions.
+ *
+ * @param debug should we produce debugging messages as we parse.
+ */
+ protected boolean try_parse_ahead(boolean debug)
+ throws java.lang.Exception
+ {
+ int act;
+ short lhs, rhs_size;
+
+ /* create a virtual stack from the real parse stack */
+ virtual_parse_stack vstack = new virtual_parse_stack(stack);
+
+ /* parse until we fail or get past the lookahead input */
+ for (;;)
+ {
+ /* look up the action from the current state (on top of stack) */
+ act = get_action(vstack.top(), cur_err_token().sym);
+
+ /* if its an error, we fail */
+ if (act == 0) return false;
+
+ /* > 0 encodes a shift */
+ if (act > 0)
+ {
+ /* push the new state on the stack */
+ vstack.push(act-1);
+
+ if (debug) debug_message("# Parse-ahead shifts Symbol #" +
+ cur_err_token().sym + " into state #" + (act-1));
+
+ /* advance simulated input, if we run off the end, we are done */
+ if (!advance_lookahead()) return true;
+ }
+ /* < 0 encodes a reduce */
+ else
+ {
+ /* if this is a reduce with the start production we are done */
+ if ((-act)-1 == start_production())
+ {
+ if (debug) debug_message("# Parse-ahead accepts");
+ return true;
+ }
+
+ /* get the lhs Symbol and the rhs size */
+ lhs = production_tab[(-act)-1][0];
+ rhs_size = production_tab[(-act)-1][1];
+
+ /* pop handle off the stack */
+ for (int i = 0; i < rhs_size; i++)
+ vstack.pop();
+
+ if (debug)
+ debug_message("# Parse-ahead reduces: handle size = " +
+ rhs_size + " lhs = #" + lhs + " from state #" + vstack.top());
+
+ /* look up goto and push it onto the stack */
+ vstack.push(get_reduce(vstack.top(), lhs));
+ if (debug)
+ debug_message("# Goto state #" + vstack.top());
+ }
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Parse forward using stored lookahead Symbols. In this case we have
+ * already verified that parsing will make it through the stored lookahead
+ * Symbols and we are now getting back to the point at which we can hand
+ * control back to the normal parser. Consequently, this version of the
+ * parser performs all actions and modifies the real parse configuration.
+ * This returns once we have consumed all the stored input or we accept.
+ *
+ * @param debug should we produce debugging messages as we parse.
+ */
+ protected void parse_lookahead(boolean debug)
+ throws java.lang.Exception
+ {
+ /* the current action code */
+ int act;
+
+ /* the Symbol/stack element returned by a reduce */
+ Symbol lhs_sym = null;
+
+ /* information about production being reduced with */
+ short handle_size, lhs_sym_num;
+
+ /* restart the saved input at the beginning */
+ lookahead_pos = 0;
+
+ if (debug)
+ {
+ debug_message("# Reparsing saved input with actions");
+ debug_message("# Current Symbol is #" + cur_err_token().sym);
+ debug_message("# Current state is #" +
+ ((Symbol)stack.peek()).parse_state);
+ }
+
+ /* continue until we accept or have read all lookahead input */
+ while(!_done_parsing)
+ {
+ /* current state is always on the top of the stack */
+
+ /* look up action out of the current state with the current input */
+ act =
+ get_action(((Symbol)stack.peek()).parse_state, cur_err_token().sym);
+
+ /* decode the action -- > 0 encodes shift */
+ if (act > 0)
+ {
+ /* shift to the encoded state by pushing it on the stack */
+ cur_err_token().parse_state = act-1;
+ cur_err_token().used_by_parser = true;
+ if (debug) debug_shift(cur_err_token());
+ stack.push(cur_err_token());
+ tos++;
+
+ /* advance to the next Symbol, if there is none, we are done */
+ if (!advance_lookahead())
+ {
+ if (debug) debug_message("# Completed reparse");
+
+ /* scan next Symbol so we can continue parse */
+ // BUGFIX by Chris Harris <ckharris@ucsd.edu>:
+ // correct a one-off error by commenting out
+ // this next line.
+ /*cur_token = scan();*/
+
+ /* go back to normal parser */
+ return;
+ }
+
+ if (debug)
+ debug_message("# Current Symbol is #" + cur_err_token().sym);
+ }
+ /* if its less than zero, then it encodes a reduce action */
+ else if (act < 0)
+ {
+ /* perform the action for the reduce */
+ lhs_sym = do_action((-act)-1, this, stack, tos);
+
+ /* look up information about the production */
+ lhs_sym_num = production_tab[(-act)-1][0];
+ handle_size = production_tab[(-act)-1][1];
+
+ if (debug) debug_reduce((-act)-1, lhs_sym_num, handle_size);
+
+ /* pop the handle off the stack */
+ for (int i = 0; i < handle_size; i++)
+ {
+ stack.pop();
+ tos--;
+ }
+
+ /* look up the state to go to from the one popped back to */
+ act = get_reduce(((Symbol)stack.peek()).parse_state, lhs_sym_num);
+
+ /* shift to that state */
+ lhs_sym.parse_state = act;
+ lhs_sym.used_by_parser = true;
+ stack.push(lhs_sym);
+ tos++;
+
+ if (debug) debug_message("# Goto state #" + act);
+
+ }
+ /* finally if the entry is zero, we have an error
+ (shouldn't happen here, but...)*/
+ else if (act == 0)
+ {
+ report_fatal_error("Syntax error", lhs_sym);
+ return;
+ }
+ }
+
+
+ }
+
+ /*-----------------------------------------------------------*/
+
+ /** Utility function: unpacks parse tables from strings */
+ protected static short[][] unpackFromStrings(String[] sa)
+ {
+ // Concatanate initialization strings.
+ StringBuffer sb = new StringBuffer(sa[0]);
+ for (int i=1; i<sa.length; i++)
+ sb.append(sa[i]);
+ int n=0; // location in initialization string
+ int size1 = (((int)sb.charAt(n))<<16) | ((int)sb.charAt(n+1)); n+=2;
+ short[][] result = new short[size1][];
+ for (int i=0; i<size1; i++) {
+ int size2 = (((int)sb.charAt(n))<<16) | ((int)sb.charAt(n+1)); n+=2;
+ result[i] = new short[size2];
+ for (int j=0; j<size2; j++)
+ result[i][j] = (short) (sb.charAt(n++)-2);
+ }
+ return result;
+ }
+}
+
diff --git a/src/syntaxParser/java_cup/runtime/virtual_parse_stack.class b/src/syntaxParser/java_cup/runtime/virtual_parse_stack.class
new file mode 100644
index 0000000..1c3435c
--- /dev/null
+++ b/src/syntaxParser/java_cup/runtime/virtual_parse_stack.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/runtime/virtual_parse_stack.java b/src/syntaxParser/java_cup/runtime/virtual_parse_stack.java
new file mode 100644
index 0000000..a4386aa
--- /dev/null
+++ b/src/syntaxParser/java_cup/runtime/virtual_parse_stack.java
@@ -0,0 +1,145 @@
+
+package java_cup.runtime;
+
+import java.util.Stack;
+
+/** This class implements a temporary or "virtual" parse stack that
+ * replaces the top portion of the actual parse stack (the part that
+ * has been changed by some set of operations) while maintaining its
+ * original contents. This data structure is used when the parse needs
+ * to "parse ahead" to determine if a given error recovery attempt will
+ * allow the parse to continue far enough to consider it successful. Once
+ * success or failure of parse ahead is determined the system then
+ * reverts to the original parse stack (which has not actually been
+ * modified). Since parse ahead does not execute actions, only parse
+ * state is maintained on the virtual stack, not full Symbol objects.
+ *
+ * @see java_cup.runtime.lr_parser
+ * @version last updated: 7/3/96
+ * @author Frank Flannery
+ */
+
+public class virtual_parse_stack {
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Constructor to build a virtual stack out of a real stack. */
+ public virtual_parse_stack(Stack shadowing_stack) throws java.lang.Exception
+ {
+ /* sanity check */
+ if (shadowing_stack == null)
+ throw new Exception(
+ "Internal parser error: attempt to create null virtual stack");
+
+ /* set up our internals */
+ real_stack = shadowing_stack;
+ vstack = new Stack();
+ real_next = 0;
+
+ /* get one element onto the virtual portion of the stack */
+ get_from_real();
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** The real stack that we shadow. This is accessed when we move off
+ * the bottom of the virtual portion of the stack, but is always left
+ * unmodified.
+ */
+ protected Stack real_stack;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Top of stack indicator for where we leave off in the real stack.
+ * This is measured from top of stack, so 0 would indicate that no
+ * elements have been "moved" from the real to virtual stack.
+ */
+ protected int real_next;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** The virtual top portion of the stack. This stack contains Integer
+ * objects with state numbers. This stack shadows the top portion
+ * of the real stack within the area that has been modified (via operations
+ * on the virtual stack). When this portion of the stack becomes empty we
+ * transfer elements from the underlying stack onto this stack.
+ */
+ protected Stack vstack;
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Transfer an element from the real to the virtual stack. This assumes
+ * that the virtual stack is currently empty.
+ */
+ protected void get_from_real()
+ {
+ Symbol stack_sym;
+
+ /* don't transfer if the real stack is empty */
+ if (real_next >= real_stack.size()) return;
+
+ /* get a copy of the first Symbol we have not transfered */
+ stack_sym = (Symbol)real_stack.elementAt(real_stack.size()-1-real_next);
+
+ /* record the transfer */
+ real_next++;
+
+ /* put the state number from the Symbol onto the virtual stack */
+ vstack.push(new Integer(stack_sym.parse_state));
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Indicate whether the stack is empty. */
+ public boolean empty()
+ {
+ /* if vstack is empty then we were unable to transfer onto it and
+ the whole thing is empty. */
+ return vstack.empty();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Return value on the top of the stack (without popping it). */
+ public int top() throws java.lang.Exception
+ {
+ if (vstack.empty())
+ throw new Exception(
+ "Internal parser error: top() called on empty virtual stack");
+
+ return ((Integer)vstack.peek()).intValue();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Pop the stack. */
+ public void pop() throws java.lang.Exception
+ {
+ if (vstack.empty())
+ throw new Exception(
+ "Internal parser error: pop from empty virtual stack");
+
+ /* pop it */
+ vstack.pop();
+
+ /* if we are now empty transfer an element (if there is one) */
+ if (vstack.empty())
+ get_from_real();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Push a state number onto the stack. */
+ public void push(int state_num)
+ {
+ vstack.push(new Integer(state_num));
+ }
+
+ /*-----------------------------------------------------------*/
+
+}
diff --git a/src/syntaxParser/java_cup/shift_action.class b/src/syntaxParser/java_cup/shift_action.class
new file mode 100644
index 0000000..db961ff
--- /dev/null
+++ b/src/syntaxParser/java_cup/shift_action.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/shift_action.java b/src/syntaxParser/java_cup/shift_action.java
new file mode 100644
index 0000000..33fc17a
--- /dev/null
+++ b/src/syntaxParser/java_cup/shift_action.java
@@ -0,0 +1,82 @@
+
+package java_cup;
+
+/** This class represents a shift action within the parse table.
+ * The action simply stores the state that it shifts to and responds
+ * to queries about its type.
+ *
+ * @version last updated: 11/25/95
+ * @author Scott Hudson
+ */
+public class shift_action extends parse_action {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Simple constructor.
+ * @param shft_to the state that this action shifts to.
+ */
+ public shift_action(lalr_state shft_to) throws internal_error
+ {
+ /* sanity check */
+ if (shft_to == null)
+ throw new internal_error(
+ "Attempt to create a shift_action to a null state");
+
+ _shift_to = shft_to;
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** The state we shift to. */
+ protected lalr_state _shift_to;
+
+ /** The state we shift to. */
+ public lalr_state shift_to() {return _shift_to;}
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Quick access to type of action. */
+ public int kind() {return SHIFT;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Equality test. */
+ public boolean equals(shift_action other)
+ {
+ return other != null && other.shift_to() == shift_to();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Generic equality test. */
+ public boolean equals(Object other)
+ {
+ if (other instanceof shift_action)
+ return equals((shift_action)other);
+ else
+ return false;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Compute a hash code. */
+ public int hashCode()
+ {
+ /* use the hash code of the state we are shifting to */
+ return shift_to().hashCode();
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to a string. */
+ public String toString() {return "SHIFT(to state " + shift_to().index() + ")";}
+
+ /*-----------------------------------------------------------*/
+
+}
diff --git a/src/syntaxParser/java_cup/simple_calc/Main.java b/src/syntaxParser/java_cup/simple_calc/Main.java
new file mode 100644
index 0000000..21ff5aa
--- /dev/null
+++ b/src/syntaxParser/java_cup/simple_calc/Main.java
@@ -0,0 +1,32 @@
+// Driver for parser
+
+package java_cup.simple_calc;
+
+import java_cup.simple_calc.parser;
+import java_cup.runtime.Symbol;
+
+class Main {
+
+ static boolean do_debug_parse = false;
+
+ static public void main(String[] args) throws java.io.IOException {
+
+ /* create a parsing object */
+ parser parser_obj = new parser(new scanner());
+
+ /* open input files, etc. here */
+ Symbol parse_tree = null;
+
+ try {
+ if (do_debug_parse)
+ parse_tree = parser_obj.debug_parse();
+ else
+ parse_tree = parser_obj.parse();
+ } catch (Exception e) {
+ /* do cleanup here -- possibly rethrow e */
+ } finally {
+ /* do close out here */
+ }
+ }
+}
+
diff --git a/src/syntaxParser/java_cup/simple_calc/parser.cup b/src/syntaxParser/java_cup/simple_calc/parser.cup
new file mode 100644
index 0000000..a88d900
--- /dev/null
+++ b/src/syntaxParser/java_cup/simple_calc/parser.cup
@@ -0,0 +1,55 @@
+// JavaCup specification for a simple expression evaluator (w/ actions)
+
+package java_cup.simple_calc;
+
+import java_cup.runtime.*;
+
+/* Terminals (tokens returned by the scanner). */
+terminal SEMI, PLUS, MINUS, TIMES, DIVIDE, MOD;
+terminal UMINUS, LPAREN, RPAREN;
+terminal Integer NUMBER;
+
+/* Non terminals */
+non terminal Object expr_list, expr_part;
+non terminal Integer expr;
+
+/* Precedences */
+precedence left PLUS, MINUS;
+precedence left TIMES, DIVIDE, MOD;
+precedence left UMINUS, LPAREN;
+
+/* The grammar */
+expr_list ::= expr_list expr_part
+ |
+ expr_part;
+
+expr_part ::= expr:e
+ {: System.out.println("= " + e); :}
+ SEMI
+ ;
+
+expr ::= expr:e1 PLUS expr:e2
+ {: RESULT = new Integer(e1.intValue() + e2.intValue()); :}
+ |
+ expr:e1 MINUS expr:e2
+ {: RESULT = new Integer(e1.intValue() - e2.intValue()); :}
+ |
+ expr:e1 TIMES expr:e2
+ {: RESULT = new Integer(e1.intValue() * e2.intValue()); :}
+ |
+ expr:e1 DIVIDE expr:e2
+ {: RESULT = new Integer(e1.intValue() / e2.intValue()); :}
+ |
+ expr:e1 MOD expr:e2
+ {: RESULT = new Integer(e1.intValue() % e2.intValue()); :}
+ |
+ NUMBER:n
+ {: RESULT = n; :}
+ |
+ MINUS expr:e
+ {: RESULT = new Integer(0 - e.intValue()); :}
+ %prec UMINUS
+ |
+ LPAREN expr:e RPAREN
+ {: RESULT = e; :}
+ ;
diff --git a/src/syntaxParser/java_cup/simple_calc/parser.java b/src/syntaxParser/java_cup/simple_calc/parser.java
new file mode 100644
index 0000000..d6003c7
--- /dev/null
+++ b/src/syntaxParser/java_cup/simple_calc/parser.java
@@ -0,0 +1,318 @@
+
+//----------------------------------------------------
+// The following code was generated by CUP v0.10k
+// Sun Jul 25 13:36:02 EDT 1999
+//----------------------------------------------------
+
+package java_cup.simple_calc;
+
+import java_cup.runtime.*;
+
+/** CUP v0.10k generated parser.
+ * @version Sun Jul 25 13:36:02 EDT 1999
+ */
+public class parser extends java_cup.runtime.lr_parser {
+
+ /** Default constructor. */
+ public parser() {super();}
+
+ /** Constructor which sets the default scanner. */
+ public parser(java_cup.runtime.Scanner s) {super(s);}
+
+ /** Production table. */
+ protected static final short _production_table[][] =
+ unpackFromStrings(new String[] {
+ "\000\015\000\002\003\004\000\002\002\004\000\002\003" +
+ "\003\000\002\006\002\000\002\004\005\000\002\005\005" +
+ "\000\002\005\005\000\002\005\005\000\002\005\005\000" +
+ "\002\005\005\000\002\005\003\000\002\005\004\000\002" +
+ "\005\005" });
+
+ /** Access to production table. */
+ public short[][] production_table() {return _production_table;}
+
+ /** Parse-action table. */
+ protected static final short[][] _action_table =
+ unpackFromStrings(new String[] {
+ "\000\030\000\010\006\004\013\011\015\005\001\002\000" +
+ "\010\006\004\013\011\015\005\001\002\000\020\004\ufff7" +
+ "\005\ufff7\006\ufff7\007\ufff7\010\ufff7\011\ufff7\014\ufff7\001" +
+ "\002\000\012\002\uffff\006\uffff\013\uffff\015\uffff\001\002" +
+ "\000\016\004\ufffe\005\016\006\014\007\020\010\017\011" +
+ "\013\001\002\000\012\002\027\006\004\013\011\015\005" +
+ "\001\002\000\010\006\004\013\011\015\005\001\002\000" +
+ "\016\005\016\006\014\007\020\010\017\011\013\014\015" +
+ "\001\002\000\010\006\004\013\011\015\005\001\002\000" +
+ "\010\006\004\013\011\015\005\001\002\000\020\004\ufff5" +
+ "\005\ufff5\006\ufff5\007\ufff5\010\ufff5\011\ufff5\014\ufff5\001" +
+ "\002\000\010\006\004\013\011\015\005\001\002\000\010" +
+ "\006\004\013\011\015\005\001\002\000\010\006\004\013" +
+ "\011\015\005\001\002\000\020\004\ufffa\005\ufffa\006\ufffa" +
+ "\007\ufffa\010\ufffa\011\ufffa\014\ufffa\001\002\000\020\004" +
+ "\ufff9\005\ufff9\006\ufff9\007\ufff9\010\ufff9\011\ufff9\014\ufff9" +
+ "\001\002\000\020\004\ufffc\005\ufffc\006\ufffc\007\020\010" +
+ "\017\011\013\014\ufffc\001\002\000\020\004\ufffb\005\ufffb" +
+ "\006\ufffb\007\020\010\017\011\013\014\ufffb\001\002\000" +
+ "\020\004\ufff8\005\ufff8\006\ufff8\007\ufff8\010\ufff8\011\ufff8" +
+ "\014\ufff8\001\002\000\012\002\001\006\001\013\001\015" +
+ "\001\001\002\000\004\002\000\001\002\000\004\004\031" +
+ "\001\002\000\012\002\ufffd\006\ufffd\013\ufffd\015\ufffd\001" +
+ "\002\000\020\004\ufff6\005\ufff6\006\ufff6\007\ufff6\010\ufff6" +
+ "\011\ufff6\014\ufff6\001\002" });
+
+ /** Access to parse-action table. */
+ public short[][] action_table() {return _action_table;}
+
+ /** <code>reduce_goto</code> table. */
+ protected static final short[][] _reduce_table =
+ unpackFromStrings(new String[] {
+ "\000\030\000\010\003\007\004\005\005\006\001\001\000" +
+ "\004\005\031\001\001\000\002\001\001\000\002\001\001" +
+ "\000\004\006\027\001\001\000\006\004\025\005\006\001" +
+ "\001\000\004\005\011\001\001\000\002\001\001\000\004" +
+ "\005\024\001\001\000\004\005\023\001\001\000\002\001" +
+ "\001\000\004\005\022\001\001\000\004\005\021\001\001" +
+ "\000\004\005\020\001\001\000\002\001\001\000\002\001" +
+ "\001\000\002\001\001\000\002\001\001\000\002\001\001" +
+ "\000\002\001\001\000\002\001\001\000\002\001\001\000" +
+ "\002\001\001\000\002\001\001" });
+
+ /** Access to <code>reduce_goto</code> table. */
+ public short[][] reduce_table() {return _reduce_table;}
+
+ /** Instance of action encapsulation class. */
+ protected CUP$parser$actions action_obj;
+
+ /** Action encapsulation object initializer. */
+ protected void init_actions()
+ {
+ action_obj = new CUP$parser$actions(this);
+ }
+
+ /** Invoke a user supplied parse action. */
+ public java_cup.runtime.Symbol do_action(
+ int act_num,
+ java_cup.runtime.lr_parser parser,
+ java.util.Stack stack,
+ int top)
+ throws java.lang.Exception
+ {
+ /* call code in generated class */
+ return action_obj.CUP$parser$do_action(act_num, parser, stack, top);
+ }
+
+ /** Indicates start state. */
+ public int start_state() {return 0;}
+ /** Indicates start production. */
+ public int start_production() {return 1;}
+
+ /** <code>EOF</code> Symbol index. */
+ public int EOF_sym() {return 0;}
+
+ /** <code>error</code> Symbol index. */
+ public int error_sym() {return 1;}
+
+}
+
+/** Cup generated class to encapsulate user supplied action code.*/
+class CUP$parser$actions {
+ private final parser parser;
+
+ /** Constructor */
+ CUP$parser$actions(parser parser) {
+ this.parser = parser;
+ }
+
+ /** Method with the actual generated action code. */
+ public final java_cup.runtime.Symbol CUP$parser$do_action(
+ int CUP$parser$act_num,
+ java_cup.runtime.lr_parser CUP$parser$parser,
+ java.util.Stack CUP$parser$stack,
+ int CUP$parser$top)
+ throws java.lang.Exception
+ {
+ /* Symbol object for return from actions */
+ java_cup.runtime.Symbol CUP$parser$result;
+
+ /* select the action based on the action number */
+ switch (CUP$parser$act_num)
+ {
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 12: // expr ::= LPAREN expr RPAREN
+ {
+ Integer RESULT = null;
+ int eleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left;
+ int eright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).right;
+ Integer e = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+ RESULT = e;
+ CUP$parser$result = new java_cup.runtime.Symbol(3/*expr*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 11: // expr ::= MINUS expr
+ {
+ Integer RESULT = null;
+ int eleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int eright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ Integer e = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+ RESULT = new Integer(0 - e.intValue());
+ CUP$parser$result = new java_cup.runtime.Symbol(3/*expr*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 10: // expr ::= NUMBER
+ {
+ Integer RESULT = null;
+ int nleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int nright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ Integer n = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+ RESULT = n;
+ CUP$parser$result = new java_cup.runtime.Symbol(3/*expr*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 9: // expr ::= expr MOD expr
+ {
+ Integer RESULT = null;
+ int e1left = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left;
+ int e1right = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).right;
+ Integer e1 = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
+ int e2left = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int e2right = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ Integer e2 = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+ RESULT = new Integer(e1.intValue() % e2.intValue());
+ CUP$parser$result = new java_cup.runtime.Symbol(3/*expr*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 8: // expr ::= expr DIVIDE expr
+ {
+ Integer RESULT = null;
+ int e1left = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left;
+ int e1right = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).right;
+ Integer e1 = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
+ int e2left = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int e2right = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ Integer e2 = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+ RESULT = new Integer(e1.intValue() / e2.intValue());
+ CUP$parser$result = new java_cup.runtime.Symbol(3/*expr*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 7: // expr ::= expr TIMES expr
+ {
+ Integer RESULT = null;
+ int e1left = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left;
+ int e1right = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).right;
+ Integer e1 = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
+ int e2left = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int e2right = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ Integer e2 = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+ RESULT = new Integer(e1.intValue() * e2.intValue());
+ CUP$parser$result = new java_cup.runtime.Symbol(3/*expr*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 6: // expr ::= expr MINUS expr
+ {
+ Integer RESULT = null;
+ int e1left = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left;
+ int e1right = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).right;
+ Integer e1 = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
+ int e2left = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int e2right = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ Integer e2 = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+ RESULT = new Integer(e1.intValue() - e2.intValue());
+ CUP$parser$result = new java_cup.runtime.Symbol(3/*expr*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 5: // expr ::= expr PLUS expr
+ {
+ Integer RESULT = null;
+ int e1left = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left;
+ int e1right = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).right;
+ Integer e1 = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
+ int e2left = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int e2right = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ Integer e2 = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+ RESULT = new Integer(e1.intValue() + e2.intValue());
+ CUP$parser$result = new java_cup.runtime.Symbol(3/*expr*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 4: // expr_part ::= expr NT$0 SEMI
+ {
+ Object RESULT = null;
+ // propagate RESULT from NT$0
+ if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value != null )
+ RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+ int eleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left;
+ int eright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).right;
+ Integer e = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(2/*expr_part*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 3: // NT$0 ::=
+ {
+ Object RESULT = null;
+ int eleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+ int eright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+ Integer e = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+ System.out.println("= " + e);
+ CUP$parser$result = new java_cup.runtime.Symbol(4/*NT$0*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 2: // expr_list ::= expr_part
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(1/*expr_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 1: // $START ::= expr_list EOF
+ {
+ Object RESULT = null;
+ int start_valleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left;
+ int start_valright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).right;
+ Object start_val = (Object)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+ RESULT = start_val;
+ CUP$parser$result = new java_cup.runtime.Symbol(0/*$START*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ /* ACCEPT */
+ CUP$parser$parser.done_parsing();
+ return CUP$parser$result;
+
+ /*. . . . . . . . . . . . . . . . . . . .*/
+ case 0: // expr_list ::= expr_list expr_part
+ {
+ Object RESULT = null;
+
+ CUP$parser$result = new java_cup.runtime.Symbol(1/*expr_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+ }
+ return CUP$parser$result;
+
+ /* . . . . . .*/
+ default:
+ throw new Exception(
+ "Invalid action number found in internal parse table");
+
+ }
+ }
+}
+
diff --git a/src/syntaxParser/java_cup/simple_calc/scanner.java b/src/syntaxParser/java_cup/simple_calc/scanner.java
new file mode 100644
index 0000000..f8f850a
--- /dev/null
+++ b/src/syntaxParser/java_cup/simple_calc/scanner.java
@@ -0,0 +1,63 @@
+// Simple Example Scanner Class
+
+package java_cup.simple_calc;
+
+import java_cup.runtime.Symbol;
+
+public class scanner implements java_cup.runtime.Scanner {
+ final java.io.InputStream instream;
+
+ public scanner(java.io.InputStream is) throws java.io.IOException {
+ instream = is;
+ }
+ public scanner() throws java.io.IOException { this(System.in); }
+
+ /* single lookahead character */
+ protected int next_char = -2;
+
+ /* advance input by one character */
+ protected void advance()
+ throws java.io.IOException
+ { next_char = instream.read(); }
+
+ /* initialize the scanner */
+ private void init()
+ throws java.io.IOException
+ { advance(); }
+
+ /* recognize and return the next complete token */
+ public Symbol next_token()
+ throws java.io.IOException
+ {
+ if (next_char==-2) init(); // set stuff up first time we are called.
+ for (;;)
+ switch (next_char)
+ {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ /* parse a decimal integer */
+ int i_val = 0;
+ do {
+ i_val = i_val * 10 + (next_char - '0');
+ advance();
+ } while (next_char >= '0' && next_char <= '9');
+ return new Symbol(sym.NUMBER, new Integer(i_val));
+
+ case ';': advance(); return new Symbol(sym.SEMI);
+ case '+': advance(); return new Symbol(sym.PLUS);
+ case '-': advance(); return new Symbol(sym.MINUS);
+ case '*': advance(); return new Symbol(sym.TIMES);
+ case '/': advance(); return new Symbol(sym.DIVIDE);
+ case '%': advance(); return new Symbol(sym.MOD);
+ case '(': advance(); return new Symbol(sym.LPAREN);
+ case ')': advance(); return new Symbol(sym.RPAREN);
+
+ case -1: return new Symbol(sym.EOF);
+
+ default:
+ /* in this simple scanner we just ignore everything else */
+ advance();
+ break;
+ }
+ }
+};
diff --git a/src/syntaxParser/java_cup/simple_calc/sym.java b/src/syntaxParser/java_cup/simple_calc/sym.java
new file mode 100644
index 0000000..2584f2f
--- /dev/null
+++ b/src/syntaxParser/java_cup/simple_calc/sym.java
@@ -0,0 +1,25 @@
+
+//----------------------------------------------------
+// The following code was generated by CUP v0.10k
+// Sun Jul 25 13:36:02 EDT 1999
+//----------------------------------------------------
+
+package java_cup.simple_calc;
+
+/** CUP generated class containing symbol constants. */
+public class sym {
+ /* terminals */
+ public static final int SEMI = 2;
+ public static final int EOF = 0;
+ public static final int DIVIDE = 6;
+ public static final int NUMBER = 11;
+ public static final int error = 1;
+ public static final int UMINUS = 8;
+ public static final int MINUS = 4;
+ public static final int TIMES = 5;
+ public static final int LPAREN = 9;
+ public static final int RPAREN = 10;
+ public static final int MOD = 7;
+ public static final int PLUS = 3;
+}
+
diff --git a/src/syntaxParser/java_cup/sym.class b/src/syntaxParser/java_cup/sym.class
new file mode 100644
index 0000000..97397bd
--- /dev/null
+++ b/src/syntaxParser/java_cup/sym.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/sym.java b/src/syntaxParser/java_cup/sym.java
new file mode 100644
index 0000000..9810a3d
--- /dev/null
+++ b/src/syntaxParser/java_cup/sym.java
@@ -0,0 +1,43 @@
+
+//----------------------------------------------------
+// The following code was generated by CUP v0.10k
+// Sun Jul 25 13:35:26 EDT 1999
+//----------------------------------------------------
+
+package java_cup;
+
+/** CUP generated class containing symbol constants. */
+public class sym {
+ /* terminals */
+ public static final int NON = 8;
+ public static final int NONTERMINAL = 27;
+ public static final int STAR = 15;
+ public static final int SEMI = 13;
+ public static final int CODE = 4;
+ public static final int EOF = 0;
+ public static final int NONASSOC = 23;
+ public static final int LEFT = 21;
+ public static final int PACKAGE = 2;
+ public static final int COLON = 17;
+ public static final int WITH = 11;
+ public static final int IMPORT = 3;
+ public static final int error = 1;
+ public static final int COLON_COLON_EQUALS = 18;
+ public static final int COMMA = 14;
+ public static final int DOT = 16;
+ public static final int SCAN = 10;
+ public static final int ID = 28;
+ public static final int INIT = 9;
+ public static final int PARSER = 6;
+ public static final int TERMINAL = 7;
+ public static final int PRECEDENCE = 20;
+ public static final int LBRACK = 25;
+ public static final int RBRACK = 26;
+ public static final int PERCENT_PREC = 24;
+ public static final int START = 12;
+ public static final int RIGHT = 22;
+ public static final int BAR = 19;
+ public static final int ACTION = 5;
+ public static final int CODE_STRING = 29;
+}
+
diff --git a/src/syntaxParser/java_cup/symbol.class b/src/syntaxParser/java_cup/symbol.class
new file mode 100644
index 0000000..04d222d
--- /dev/null
+++ b/src/syntaxParser/java_cup/symbol.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/symbol.java b/src/syntaxParser/java_cup/symbol.java
new file mode 100644
index 0000000..94d8b7d
--- /dev/null
+++ b/src/syntaxParser/java_cup/symbol.java
@@ -0,0 +1,107 @@
+package java_cup;
+
+/** This abstract class serves as the base class for grammar symbols (i.e.,
+ * both terminals and non-terminals). Each symbol has a name string, and
+ * a string giving the type of object that the symbol will be represented by
+ * on the runtime parse stack. In addition, each symbol maintains a use count
+ * in order to detect symbols that are declared but never used, and an index
+ * number that indicates where it appears in parse tables (index numbers are
+ * unique within terminals or non terminals, but not across both).
+ *
+ * @see java_cup.terminal
+ * @see java_cup.non_terminal
+ * @version last updated: 7/3/96
+ * @author Frank Flannery
+ */
+public abstract class symbol {
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Full constructor.
+ * @param nm the name of the symbol.
+ * @param tp a string with the type name.
+ */
+ public symbol(String nm, String tp)
+ {
+ /* sanity check */
+ if (nm == null) nm = "";
+
+ /* apply default if no type given */
+ if (tp == null) tp = "Object";
+
+ _name = nm;
+ _stack_type = tp;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Constructor with default type.
+ * @param nm the name of the symbol.
+ */
+ public symbol(String nm)
+ {
+ this(nm, null);
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** String for the human readable name of the symbol. */
+ protected String _name;
+
+ /** String for the human readable name of the symbol. */
+ public String name() {return _name;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** String for the type of object used for the symbol on the parse stack. */
+ protected String _stack_type;
+
+ /** String for the type of object used for the symbol on the parse stack. */
+ public String stack_type() {return _stack_type;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Count of how many times the symbol appears in productions. */
+ protected int _use_count = 0;
+
+ /** Count of how many times the symbol appears in productions. */
+ public int use_count() {return _use_count;}
+
+ /** Increment the use count. */
+ public void note_use() {_use_count++;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Index of this symbol (terminal or non terminal) in the parse tables.
+ * Note: indexes are unique among terminals and unique among non terminals,
+ * however, a terminal may have the same index as a non-terminal, etc.
+ */
+ protected int _index;
+
+ /** Index of this symbol (terminal or non terminal) in the parse tables.
+ * Note: indexes are unique among terminals and unique among non terminals,
+ * however, a terminal may have the same index as a non-terminal, etc.
+ */
+ public int index() {return _index;}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Indicate if this is a non-terminal. Here in the base class we
+ * don't know, so this is abstract.
+ */
+ public abstract boolean is_non_term();
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to a string. */
+ public String toString()
+ {
+ return name();
+ }
+
+ /*-----------------------------------------------------------*/
+
+}
diff --git a/src/syntaxParser/java_cup/symbol_part.class b/src/syntaxParser/java_cup/symbol_part.class
new file mode 100644
index 0000000..1b81faa
--- /dev/null
+++ b/src/syntaxParser/java_cup/symbol_part.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/symbol_part.java b/src/syntaxParser/java_cup/symbol_part.java
new file mode 100644
index 0000000..9142b5f
--- /dev/null
+++ b/src/syntaxParser/java_cup/symbol_part.java
@@ -0,0 +1,100 @@
+package java_cup;
+
+/** This class represents a part of a production which is a symbol (terminal
+ * or non terminal). This simply maintains a reference to the symbol in
+ * question.
+ *
+ * @see java_cup.production
+ * @version last updated: 11/25/95
+ * @author Scott Hudson
+ */
+public class symbol_part extends production_part {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Full constructor.
+ * @param sym the symbol that this part is made up of.
+ * @param lab an optional label string for the part.
+ */
+ public symbol_part(symbol sym, String lab) throws internal_error
+ {
+ super(lab);
+
+ if (sym == null)
+ throw new internal_error(
+ "Attempt to construct a symbol_part with a null symbol");
+ _the_symbol = sym;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Constructor with no label.
+ * @param sym the symbol that this part is made up of.
+ */
+ public symbol_part(symbol sym) throws internal_error
+ {
+ this(sym,null);
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** The symbol that this part is made up of. */
+ protected symbol _the_symbol;
+
+ /** The symbol that this part is made up of. */
+ public symbol the_symbol() {return _the_symbol;}
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Respond that we are not an action part. */
+ public boolean is_action() { return false; }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Equality comparison. */
+ public boolean equals(symbol_part other)
+ {
+ return other != null && super.equals(other) &&
+ the_symbol().equals(other.the_symbol());
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Generic equality comparison. */
+ public boolean equals(Object other)
+ {
+ if (!(other instanceof symbol_part))
+ return false;
+ else
+ return equals((symbol_part)other);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Produce a hash code. */
+ public int hashCode()
+ {
+ return super.hashCode() ^
+ (the_symbol()==null ? 0 : the_symbol().hashCode());
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to a string. */
+ public String toString()
+ {
+ if (the_symbol() != null)
+ return super.toString() + the_symbol();
+ else
+ return super.toString() + "$$MISSING-SYMBOL$$";
+ }
+
+ /*-----------------------------------------------------------*/
+
+}
diff --git a/src/syntaxParser/java_cup/symbol_set.class b/src/syntaxParser/java_cup/symbol_set.class
new file mode 100644
index 0000000..903718d
--- /dev/null
+++ b/src/syntaxParser/java_cup/symbol_set.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/symbol_set.java b/src/syntaxParser/java_cup/symbol_set.java
new file mode 100644
index 0000000..a1aec10
--- /dev/null
+++ b/src/syntaxParser/java_cup/symbol_set.java
@@ -0,0 +1,231 @@
+
+package java_cup;
+
+import java.util.Hashtable;
+import java.util.Enumeration;
+
+/** This class represents a set of symbols and provides a series of
+ * set operations to manipulate them.
+ *
+ * @see java_cup.symbol
+ * @version last updated: 11/25/95
+ * @author Scott Hudson
+ */
+public class symbol_set {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Constructor for an empty set. */
+ public symbol_set() { }
+
+ /** Constructor for cloning from another set.
+ * @param other the set we are cloning from.
+ */
+ public symbol_set(symbol_set other) throws internal_error
+ {
+ not_null(other);
+ _all = (Hashtable)other._all.clone();
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** A hash table to hold the set. Symbols are keyed using their name string.
+ */
+ protected Hashtable _all = new Hashtable(11);
+
+ /** Access to all elements of the set. */
+ public Enumeration all() {return _all.elements();}
+
+ /** size of the set */
+ public int size() {return _all.size();}
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Helper function to test for a null object and throw an exception
+ * if one is found.
+ * @param obj the object we are testing.
+ */
+ protected void not_null(Object obj) throws internal_error
+ {
+ if (obj == null)
+ throw new internal_error("Null object used in set operation");
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Determine if the set contains a particular symbol.
+ * @param sym the symbol we are looking for.
+ */
+ public boolean contains(symbol sym) {return _all.containsKey(sym.name());}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Determine if this set is an (improper) subset of another.
+ * @param other the set we are testing against.
+ */
+ public boolean is_subset_of(symbol_set other) throws internal_error
+ {
+ not_null(other);
+
+ /* walk down our set and make sure every element is in the other */
+ for (Enumeration e = all(); e.hasMoreElements(); )
+ if (!other.contains((symbol)e.nextElement()))
+ return false;
+
+ /* they were all there */
+ return true;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Determine if this set is an (improper) superset of another.
+ * @param other the set we are are testing against.
+ */
+ public boolean is_superset_of(symbol_set other) throws internal_error
+ {
+ not_null(other);
+ return other.is_subset_of(this);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Add a single symbol to the set.
+ * @param sym the symbol we are adding.
+ * @return true if this changes the set.
+ */
+ public boolean add(symbol sym) throws internal_error
+ {
+ Object previous;
+
+ not_null(sym);
+
+ /* put the object in */
+ previous = _all.put(sym.name(),sym);
+
+ /* if we had a previous, this is no change */
+ return previous == null;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Remove a single symbol if it is in the set.
+ * @param sym the symbol we are removing.
+ */
+ public void remove(symbol sym) throws internal_error
+ {
+ not_null(sym);
+ _all.remove(sym.name());
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Add (union) in a complete set.
+ * @param other the set we are adding in.
+ * @return true if this changes the set.
+ */
+ public boolean add(symbol_set other) throws internal_error
+ {
+ boolean result = false;
+
+ not_null(other);
+
+ /* walk down the other set and do the adds individually */
+ for (Enumeration e = other.all(); e.hasMoreElements(); )
+ result = add((symbol)e.nextElement()) || result;
+
+ return result;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Remove (set subtract) a complete set.
+ * @param other the set we are removing.
+ */
+ public void remove(symbol_set other) throws internal_error
+ {
+ not_null(other);
+
+ /* walk down the other set and do the removes individually */
+ for (Enumeration e = other.all(); e.hasMoreElements(); )
+ remove((symbol)e.nextElement());
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Equality comparison. */
+ public boolean equals(symbol_set other)
+ {
+ if (other == null || other.size() != size()) return false;
+
+ /* once we know they are the same size, then improper subset does test */
+ try {
+ return is_subset_of(other);
+ } catch (internal_error e) {
+ /* can't throw the error (because super class doesn't), so we crash */
+ e.crash();
+ return false;
+ }
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Generic equality comparison. */
+ public boolean equals(Object other)
+ {
+ if (!(other instanceof symbol_set))
+ return false;
+ else
+ return equals((symbol_set)other);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Compute a hash code. */
+ public int hashCode()
+ {
+ int result = 0;
+ int cnt;
+ Enumeration e;
+
+ /* hash together codes from at most first 5 elements */
+ for (e = all(), cnt=0 ; e.hasMoreElements() && cnt<5; cnt++)
+ result ^= ((symbol)e.nextElement()).hashCode();
+
+ return result;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to a string. */
+ public String toString()
+ {
+ String result;
+ boolean comma_flag;
+
+ result = "{";
+ comma_flag = false;
+ for (Enumeration e = all(); e.hasMoreElements(); )
+ {
+ if (comma_flag)
+ result += ", ";
+ else
+ comma_flag = true;
+
+ result += ((symbol)e.nextElement()).name();
+ }
+ result += "}";
+
+ return result;
+ }
+
+ /*-----------------------------------------------------------*/
+
+}
+
+
diff --git a/src/syntaxParser/java_cup/terminal.class b/src/syntaxParser/java_cup/terminal.class
new file mode 100644
index 0000000..8f9b423
--- /dev/null
+++ b/src/syntaxParser/java_cup/terminal.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/terminal.java b/src/syntaxParser/java_cup/terminal.java
new file mode 100644
index 0000000..e1a40aa
--- /dev/null
+++ b/src/syntaxParser/java_cup/terminal.java
@@ -0,0 +1,169 @@
+package java_cup;
+
+import java_cup.assoc;
+import java.util.Hashtable;
+import java.util.Enumeration;
+
+/** This class represents a terminal symbol in the grammar. Each terminal
+ * has a textual name, an index, and a string which indicates the type of
+ * object it will be implemented with at runtime (i.e. the class of object
+ * that will be returned by the scanner and pushed on the parse stack to
+ * represent it).
+ *
+ * @version last updated: 7/3/96
+ * @author Frank Flannery
+ */
+public class terminal extends symbol {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Full constructor.
+ * @param nm the name of the terminal.
+ * @param tp the type of the terminal.
+ */
+ public terminal(String nm, String tp, int precedence_side, int precedence_num)
+ {
+ /* superclass does most of the work */
+ super(nm, tp);
+
+ /* add to set of all terminals and check for duplicates */
+ Object conflict = _all.put(nm,this);
+ if (conflict != null)
+ // can't throw an execption here because this is used in static
+ // initializers, so we do a crash instead
+ // was:
+ // throw new internal_error("Duplicate terminal (" + nm + ") created");
+ (new internal_error("Duplicate terminal (" + nm + ") created")).crash();
+
+ /* assign a unique index */
+ _index = next_index++;
+
+ /* set the precedence */
+ _precedence_num = precedence_num;
+ _precedence_side = precedence_side;
+
+ /* add to by_index set */
+ _all_by_index.put(new Integer(_index), this);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Constructor for non-precedented terminal
+ */
+
+ public terminal(String nm, String tp)
+ {
+ this(nm, tp, assoc.no_prec, -1);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Constructor with default type.
+ * @param nm the name of the terminal.
+ */
+ public terminal(String nm)
+ {
+ this(nm, null);
+ }
+
+ /*-----------------------------------------------------------*/
+ /*------------------- Class Variables ---------------------*/
+ /*-----------------------------------------------------------*/
+
+ private int _precedence_num;
+ private int _precedence_side;
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Static (Class) Variables ------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Table of all terminals. Elements are stored using name strings as
+ * the key
+ */
+ protected static Hashtable _all = new Hashtable();
+
+ /** Access to all terminals. */
+ public static Enumeration all() {return _all.elements();}
+
+ /** Lookup a terminal by name string. */
+ public static terminal find(String with_name)
+ {
+ if (with_name == null)
+ return null;
+ else
+ return (terminal)_all.get(with_name);
+ }
+
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Table of all terminals indexed by their index number. */
+ protected static Hashtable _all_by_index = new Hashtable();
+
+ /** Lookup a terminal by index. */
+ public static terminal find(int indx)
+ {
+ Integer the_indx = new Integer(indx);
+
+ return (terminal)_all_by_index.get(the_indx);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Total number of terminals. */
+ public static int number() {return _all.size();}
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Static counter to assign unique index. */
+ protected static int next_index = 0;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Special terminal for end of input. */
+ public static final terminal EOF = new terminal("EOF");
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** special terminal used for error recovery */
+ public static final terminal error = new terminal("error");
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ---------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Report this symbol as not being a non-terminal. */
+ public boolean is_non_term()
+ {
+ return false;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to a string. */
+ public String toString()
+ {
+ return super.toString() + "[" + index() + "]";
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** get the precedence of a terminal */
+ public int precedence_num() {
+ return _precedence_num;
+ }
+ public int precedence_side() {
+ return _precedence_side;
+ }
+
+ /** set the precedence of a terminal */
+ public void set_precedence(int p, int new_prec) {
+ _precedence_side = p;
+ _precedence_num = new_prec;
+ }
+
+ /*-----------------------------------------------------------*/
+
+}
diff --git a/src/syntaxParser/java_cup/terminal_set.class b/src/syntaxParser/java_cup/terminal_set.class
new file mode 100644
index 0000000..fd0453e
--- /dev/null
+++ b/src/syntaxParser/java_cup/terminal_set.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/terminal_set.java b/src/syntaxParser/java_cup/terminal_set.java
new file mode 100644
index 0000000..e921cb5
--- /dev/null
+++ b/src/syntaxParser/java_cup/terminal_set.java
@@ -0,0 +1,253 @@
+
+package java_cup;
+
+import java.util.BitSet;
+
+/** A set of terminals implemented as a bitset.
+ * @version last updated: 11/25/95
+ * @author Scott Hudson
+ */
+public class terminal_set {
+
+ /*-----------------------------------------------------------*/
+ /*--- Constructor(s) ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Constructor for an empty set. */
+ public terminal_set()
+ {
+ /* allocate the bitset at what is probably the right size */
+ _elements = new BitSet(terminal.number());
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Constructor for cloning from another set.
+ * @param other the set we are cloning from.
+ */
+ public terminal_set(terminal_set other)
+ throws internal_error
+ {
+ not_null(other);
+ _elements = (BitSet)other._elements.clone();
+ }
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Static (Class) Variables ------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Constant for the empty set. */
+ public static final terminal_set EMPTY = new terminal_set();
+
+ /*-----------------------------------------------------------*/
+ /*--- (Access to) Instance Variables ------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Bitset to implement the actual set. */
+ protected BitSet _elements;
+
+ /*-----------------------------------------------------------*/
+ /*--- General Methods ----------------------------------------*/
+ /*-----------------------------------------------------------*/
+
+ /** Helper function to test for a null object and throw an exception if
+ * one is found.
+ * @param obj the object we are testing.
+ */
+ protected void not_null(Object obj) throws internal_error
+ {
+ if (obj == null)
+ throw new internal_error("Null object used in set operation");
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Determine if the set is empty. */
+ public boolean empty()
+ {
+ return equals(EMPTY);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Determine if the set contains a particular terminal.
+ * @param sym the terminal symbol we are looking for.
+ */
+ public boolean contains(terminal sym)
+ throws internal_error
+ {
+ not_null(sym);
+ return _elements.get(sym.index());
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Given its index determine if the set contains a particular terminal.
+ * @param indx the index of the terminal in question.
+ */
+ public boolean contains(int indx)
+ {
+ return _elements.get(indx);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Determine if this set is an (improper) subset of another.
+ * @param other the set we are testing against.
+ */
+ public boolean is_subset_of(terminal_set other)
+ throws internal_error
+ {
+ not_null(other);
+
+ /* make a copy of the other set */
+ BitSet copy_other = (BitSet)other._elements.clone();
+
+ /* and or in */
+ copy_other.or(_elements);
+
+ /* if it hasn't changed, we were a subset */
+ return copy_other.equals(other._elements);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Determine if this set is an (improper) superset of another.
+ * @param other the set we are testing against.
+ */
+ public boolean is_superset_of(terminal_set other)
+ throws internal_error
+ {
+ not_null(other);
+ return other.is_subset_of(this);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Add a single terminal to the set.
+ * @param sym the terminal being added.
+ * @return true if this changes the set.
+ */
+ public boolean add(terminal sym)
+ throws internal_error
+ {
+ boolean result;
+
+ not_null(sym);
+
+ /* see if we already have this */
+ result = _elements.get(sym.index());
+
+ /* if not we add it */
+ if (!result)
+ _elements.set(sym.index());
+
+ return result;
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Remove a terminal if it is in the set.
+ * @param sym the terminal being removed.
+ */
+ public void remove(terminal sym)
+ throws internal_error
+ {
+ not_null(sym);
+ _elements.clear(sym.index());
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Add (union) in a complete set.
+ * @param other the set being added.
+ * @return true if this changes the set.
+ */
+ public boolean add(terminal_set other)
+ throws internal_error
+ {
+ not_null(other);
+
+ /* make a copy */
+ BitSet copy = (BitSet)_elements.clone();
+
+ /* or in the other set */
+ _elements.or(other._elements);
+
+ /* changed if we are not the same as the copy */
+ return !_elements.equals(copy);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Determine if this set intersects another.
+ * @param other the other set in question.
+ */
+ public boolean intersects(terminal_set other)
+ throws internal_error
+ {
+ not_null(other);
+
+ /* make a copy of the other set */
+ BitSet copy = (BitSet)other._elements.clone();
+
+ /* xor out our values */
+ copy.xor(this._elements);
+
+ /* see if its different */
+ return !copy.equals(other._elements);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Equality comparison. */
+ public boolean equals(terminal_set other)
+ {
+ if (other == null)
+ return false;
+ else
+ return _elements.equals(other._elements);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Generic equality comparison. */
+ public boolean equals(Object other)
+ {
+ if (!(other instanceof terminal_set))
+ return false;
+ else
+ return equals((terminal_set)other);
+ }
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Convert to string. */
+ public String toString()
+ {
+ String result;
+ boolean comma_flag;
+
+ result = "{";
+ comma_flag = false;
+ for (int t = 0; t < terminal.number(); t++)
+ {
+ if (_elements.get(t))
+ {
+ if (comma_flag)
+ result += ", ";
+ else
+ comma_flag = true;
+
+ result += terminal.find(t).name();
+ }
+ }
+ result += "}";
+
+ return result;
+ }
+
+ /*-----------------------------------------------------------*/
+
+}
+
diff --git a/src/syntaxParser/java_cup/version.class b/src/syntaxParser/java_cup/version.class
new file mode 100644
index 0000000..336e099
--- /dev/null
+++ b/src/syntaxParser/java_cup/version.class
Binary files differ
diff --git a/src/syntaxParser/java_cup/version.java b/src/syntaxParser/java_cup/version.java
new file mode 100644
index 0000000..06600b5
--- /dev/null
+++ b/src/syntaxParser/java_cup/version.java
@@ -0,0 +1,55 @@
+
+package java_cup;
+
+/** This class contains version and authorship information.
+ * It contains only static data elements and basically just a central
+ * place to put this kind of information so it can be updated easily
+ * for each release.
+ *
+ * Version numbers used here are broken into 3 parts: major, minor, and
+ * update, and are written as v<major>.<minor>.<update> (e.g. v0.10a).
+ * Major numbers will change at the time of major reworking of some
+ * part of the system. Minor numbers for each public release or
+ * change big enough to cause incompatibilities. Finally update
+ * letter will be incremented for small bug fixes and changes that
+ * probably wouldn't be noticed by a user.
+ *
+ * @version last updated: 12/22/97 [CSA]
+ * @author Frank Flannery
+ */
+
+public class version {
+ /** The major version number. */
+ public static final int major = 0;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** The minor version number. */
+ public static final int minor = 10;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** The update letter. */
+ public static final char update = 'k';
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** String for the current version. */
+ public static final String version_str = "v" + major + "." + minor + update;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Full title of the system */
+ public static final String title_str = "CUP " + version_str;
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** Name of the author */
+ public static final String author_str =
+ "Scott E. Hudson, Frank Flannery, and C. Scott Ananian";
+
+ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+ /** The command name normally used to invoke this program */
+ public static final String program_name = "java_cup";
+}
diff --git a/src/syntaxParser/processcoverage.xsd b/src/syntaxParser/processcoverage.xsd
new file mode 100644
index 0000000..77fbb93
--- /dev/null
+++ b/src/syntaxParser/processcoverage.xsd
@@ -0,0 +1,189 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:gml="http://www.opengis.net/gml" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified" version="0.0.1" xml:lang="en">
+
+
+
+
+
+
+
+
+
+
+
+ <!-- REMOVE EVERYTHING ALREADY IMPLEMENTED FOR VISUAL SIMPLICITY -->
+
+
+
+
+
+
+
+
+
+ <xs:complexType name="CoverageAxisType">
+ <xs:annotation>
+ <xs:documentation/>
+ </xs:annotation>
+ <xs:choice>
+ <xs:element name="coverageExpr" type="CoverageExprType"/>
+ <xs:element name="axis" type="xs:integer"/>
+ </xs:choice>
+ </xs:complexType>
+
+
+
+
+
+
+ <!-- =========================================================== -->
+ <xs:complexType name="CondenseExprType">
+ <xs:annotation>
+ <xs:documentation/>
+ </xs:annotation>
+ <xs:choice>
+ <xs:element name="generalCondenseExpr" type="GeneralCondenseExprType"/>
+ </xs:choice>
+ </xs:complexType>
+
+
+
+
+ <xs:complexType name="GeneralCondenseExprType">
+ <xs:annotation>
+ <xs:documentation/>
+ </xs:annotation>
+ <xs:sequence>
+ <!-- FIXME: tbd -->
+ <xs:element name="condenseVar" type="NameType"/>
+ <xs:element name="condenseOp" type="CondenseOpType"/>
+ <xs:element name="coverageExpr" type="CoverageExprType"/>
+ </xs:sequence>
+ </xs:complexType>
+
+
+ <!-- =========================================================== -->
+ <xs:simpleType name="CondenseOpType">
+ <xs:annotation>
+ <xs:documentation/>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="plus"/>
+ <xs:enumeration value="max"/>
+ <xs:enumeration value="min"/>
+ <xs:enumeration value="and"/>
+ <xs:enumeration value="or"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+
+ <!-- =========================================================== -->
+ <xs:complexType name="CoordinateTransformExprType">
+ <xs:annotation>
+ <xs:documentation/>
+ </xs:annotation>
+ <xs:choice>
+ <xs:element name="spatialTransformExpr" type="SpatialTransformExprType"/>
+ <xs:element name="temporalTransformExpr" type="TemporalTransformExprType"/>
+ </xs:choice>
+ </xs:complexType>
+
+
+
+ <!-- =========================================================== -->
+ <xs:complexType name="SpatialTransformExprType">
+ <xs:annotation>
+ <xs:documentation/>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="coverageExpr" type="CoverageExprType"/>
+ <xs:element name="point" type="SpatialPointType"/>
+ <!-- FIXME: ref="gml:Point" -->
+ <xs:element name="crsName" type="xs:string"/>
+ <!-- FIXME: gml:CodeListType -->
+ </xs:sequence>
+ </xs:complexType>
+
+
+ <!-- =========================================================== -->
+ <xs:complexType name="TemporalTransformExprType">
+ <xs:annotation>
+ <xs:documentation/>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="coverageExpr" type="CoverageExprType"/>
+ <xs:element name="point" type="xs:string"/>
+ </xs:sequence>
+ </xs:complexType>
+ <!-- =========================================================== -->
+
+
+
+
+
+
+
+ <!-- FIXME: should use ows:Point; have scratched something, TBR -->
+ <xs:complexType name="GridPointType">
+ <xs:annotation>
+ <xs:documentation/>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element type="GridCoordinateElementType" maxOccurs="unbounded" name="coordinate"/>
+ </xs:sequence>
+ </xs:complexType>
+ <!-- =========================================================== -->
+ <!-- FIXME: TBR -->
+ <xs:complexType name="GridCoordinateElementType">
+ <xs:annotation>
+ <xs:documentation/>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="axisName" type="NameType"/>
+ <xs:element name="value" type="xs:integer"/>
+ </xs:sequence>
+ </xs:complexType>
+ <!-- =========================================================== -->
+ <!-- FIXME: should use ows:Point; have scratched something, TBR -->
+ <xs:complexType name="SpatialPointType">
+ <xs:annotation>
+ <xs:documentation/>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element type="SpatialCoordinateElementType" maxOccurs="unbounded" name="coordinate"/>
+ </xs:sequence>
+ </xs:complexType>
+ <!-- =========================================================== -->
+ <!-- FIXME: TBR -->
+ <xs:complexType name="SpatialCoordinateElementType">
+ <xs:annotation>
+ <xs:documentation/>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="axisName" type="NameType"/>
+ <xs:element name="value" type="xs:double"/>
+ </xs:sequence>
+ </xs:complexType>
+ <!-- =========================================================== -->
+ <!-- FIXME: TBR -->
+ <!-- note that we don't need the above sequence as there is always at most 1 time axis -->
+ <xs:complexType name="TemporalCoordinateType">
+ <xs:annotation>
+ <xs:documentation/>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="axisName" type="NameType"/>
+ <xs:element name="value" type="xs:string"/>
+ <!-- FIXME: ows:time or so -->
+ </xs:sequence>
+ </xs:complexType>
+
+
+
+
+
+
+
+
+
+</xs:schema>
diff --git a/src/syntaxParser/request.wcps b/src/syntaxParser/request.wcps
new file mode 100644
index 0000000..a38e04a
--- /dev/null
+++ b/src/syntaxParser/request.wcps
@@ -0,0 +1 @@
+for m in (climate_temperature) return encode ( m , png )
diff --git a/src/syntaxParser/run.bat b/src/syntaxParser/run.bat
new file mode 100644
index 0000000..3e61552
--- /dev/null
+++ b/src/syntaxParser/run.bat
@@ -0,0 +1,8 @@
+java JLex.Main wcps.lex
+java java_cup.Main -parser WCPSParser -symbols WCPSSymbol <wcps.cup
+javac wcps.lex.java
+javac WCPSParser.java WCPSSymbol.java WCPSRequestProcessor.java
+java WCPSRequestProcessor
+
+
+
diff --git a/src/syntaxParser/test_requests.txt b/src/syntaxParser/test_requests.txt
new file mode 100644
index 0000000..4cd3050
--- /dev/null
+++ b/src/syntaxParser/test_requests.txt
@@ -0,0 +1,101 @@
+for F in (CD, C) return encode( A, B)
+
+for F in (CD, C), C in (Q,S,R) return encode( A, B)
+
+for F in (CD, C), C in (Q,S,R) return encode( A, B, blah)
+
+
+
+for F in (CD, C), C in (Q,S,R) return res( simple )
+
+for F in (CD, C), C in (Q,S,R) return dim( simple )
+
+for F in (CD, C), C in (Q,S,R) return null( simple )
+
+for F in (CD, C), C in (Q,S,R) return cellType( simple )
+
+for F in (CD, C), C in (Q,S,R) return crs( simple )
+
+
+
+
+for F in (CD, C), C in (Q,S,R) return crs( encode( A, B) )
+
+for F in (CD, C), C in (Q,S,R) return crs( encode( A, B, param) )
+
+
+
+
+for F in (CD, C), C in (Q,S,R) return ( crs( encode( A, B) ) )
+
+for F in (CD, C), C in (Q,S,R) return (( crs( encode( A, B) ) ))
+
+
+
+
+
+
+
+for F in (CD, C), C in (Q,S,R) return crs( setNull( simple, 454 ) )
+
+for F in (CD, C), C in (Q,S,R) return crs( setNull( simple, 41.6666 ) )
+
+for F in (CD, C), C in (Q,S,R) return crs( setNull( simple, TRUE ) )
+
+
+
+
+for F in (CD, C), C in (Q,S,R) return crs( setInterpolation( simple, nearest-neighbor ) )
+
+for F in (CD, C), C in (Q,S,R) return crs( setInterpolation( simple, bilinear ) )
+
+for F in (CD, C), C in (Q,S,R) return crs( setInterpolation( simple, lost-area ) )
+
+for F in (CD, C), C in (Q,S,R) return crs( setInterpolation( simple, bicubic ) )
+
+for F in (CD, C), C in (Q,S,R) return crs( setInterpolation( simple, barycentric ) )
+
+for F in (CD, C), C in (Q,S,R) return crs( setInterpolation( setNull( simple, 41.6666 ), barycentric ) )
+
+
+
+
+
+// wont take it now because of the crsName given as a simple String
+for F in (CD, C), C in (Q,S,R) return crs( setCrs( tan(angle), WGS:84 )
+
+// instead (plain String)
+for F in (CD, C), C in (Q,S,R) return crs( setCrs( tan(angle), CRSNAME )
+
+
+
+for F in (CD, C), C in (Q,S,R) return crs( setAxis( tan(angle), x, 3.3, 5.5432 ) )
+
+for F in (CD, C), C in (Q,S,R) return crs( setAxis( tan(angle), y, 345.3, 12.5432 ) )
+
+
+
+
+for F in (CD, C), C in (Q,S,R) return crs( setAxis( tan(cos(sin(arctan(arccos(arcsin(sinh(tanh(cosh(angle))))))))), x, 3.3, 5.5432 ) )
+
+
+for F in (CD, C), C in (Q,S,R) return crs( setAxis( ln(exp(log(valuevalue))), y, 345.3, 12.5432 ) )
+
+
+
+
+for F in (CD, C), C in (Q,S,R) return encode ( FGF + A * WE, format)
+
+for F in (CD, C), C in (Q,S,R) return encode ( FGF + A * WE and this or that xor those, format)
+
+
+
+
+
+for F in (CD, C), C in (Q,S,R) return encode ( trim(FGF + A * WE, z,4,78888), format)
+
+for F in (CD, C), C in (Q,S,R) return encode ( sect(FGF + A * WE, y, 4), format, extraP)
+
+
+
+
diff --git a/src/syntaxParser/tmp/META-INF/MANIFEST.MF b/src/syntaxParser/tmp/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..8ade325
--- /dev/null
+++ b/src/syntaxParser/tmp/META-INF/MANIFEST.MF
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+Ant-Version: Apache Ant 1.6.2
+Created-By: 1.5.0_07-b03 (Sun Microsystems Inc.)
+Main-Class: java_cup/Main
+Class-Path: java-cup-11a-runtime.jar
+
diff --git a/src/syntaxParser/wcps.cup b/src/syntaxParser/wcps.cup
new file mode 100644
index 0000000..a6dfb95
--- /dev/null
+++ b/src/syntaxParser/wcps.cup
@@ -0,0 +1,415 @@
+/*
+Author: *, Sorin Stancu-Mara
+Date (last update): 7 Feb 2007
+History:
+07 02 2007 smsorin Updated to WCPS 1.0.0
+This file contains the Java CUP implementation for the WCPS language parser and ProcessCoverage XML request
+generator.
+Sections include:
+ * Terminal symbols declaration from the JLex Lexycal declaration file
+ * Non Terminal symbols definitions
+ * Precedence rules to avoid Shift/Reduce conflicts in the grammar projections
+ * The grammar specification itself
+
+
+
+things to check / todo :
+ * crsName production : its now just as a simple string; CRS NAMES have certain formats, eg: EPSG:NNN
+ * axisName production : its now just as a simple integer; this was adapted from the example XML processCoverage request available for
+ testing.
+ * structSelection one item missing ????
+ * condende expression not specified in the grammar as current implementation in WCPS is not usable
+ * String are not specified by using "" characters ("string"). The parser will work anyways as a string with "" characters will
+ be recognized as a string anyway
+
+Terminals (tokens returned by the lexycal scanner). */
+package syntaxParser;
+import java_cup.runtime.*;
+import syntaxParser.SyntaxErrorException;
+
+parser code {:
+/* public void syntax_error(Symbol cur_token) {
+ report_error("Syntax error at line " + (cur_token.left+1) +
+ ", column " + cur_token.right,
+ new SyntaxErrorException(cur_token.left + 1, cur_token.right +1));
+ }*/
+ public void report_fatal_error(String message,
+ Object token) throws Exception {
+ report_error(message, null);
+ Symbol sym = (Symbol) token;
+ throw new SyntaxErrorException(sym.left + 1, sym.right + 1, message);
+ }
+:}
+
+terminal String ID, LPAREN, RPAREN, PLUS, MULTI, MINUS, DIVIDE, FOR, IN, RETURN, COMMA, ENCODE, STORE, CONDENSE, OVER, USING, MAX, MIN, AND, OR, COLON,
+STRUCT, LBRACE, RBRACE, NEAREST, CTRANSFORM,
+SIN , COS , TAN , SINH , COSH , TANH , ARCSIN , ARCCOS , ARCTAN,EXP , LOG , LN, ABS, SQRT, DOT, BOOL, CHAR,
+UNSIGNEDCHAR, SHORT, UNSIGNEDSHORT, LONG, UNSIGNEDLONG, FLOAT, DOUBLE, NOT, BIT, XOR, EQUALS, NOTEQUALS, OVERLAY, GT,LT,GTE,LTE, LBRACKET, RBRACKET, TRIM,
+SCALE, SOME, ADD, ALL, COUNT, AVG,TRUE, FALSE, WHERE, IDENTIFIER, IMAGECRS, IMAGECRSDOMAIN, CRSSET, GENERALDOMAIN, NULLDEFAULT, NULLSET,
+INTERPOLATIONDEFAULT, INTERPOLATIONSET, STRING, SETNULLDEFAULT, SETNULLSET, SETINTERPOLATIONDEFAULT, SETINTERPOLATIONSET, COMPLEX, COMPLEX2, SLICE, EXTEND,
+LINEAR, QUADRATIC, CUBIC, FULL, NONE, HALF, OTHER, COVERAGE, VALUES, X, Y, Z, TIME, ABSTRACT, SETCRSSET;
+
+terminal Integer NUMBER;
+terminal Float FLOATNUMBER;
+
+/* Non terminals */
+non terminal WCPSRequest wcpsRequest ;
+non terminal ForClause forClause;
+non terminal ForClauseElements forClauseElements;
+non terminal WhereClause whereClause;
+non terminal ReturnClause returnClause;
+non terminal CoverageList coverageList;
+non terminal ProcessingExpr processingExpr;
+non terminal EncodedCoverageExpr encodedCoverageExpr;
+non terminal StoreExpr storeExpr;
+non terminal ScalarExpr scalarExpr;
+non terminal GetMetaDataExpr getMetaDataExpr;
+non terminal BooleanScalarExpr booleanScalarExpr;
+non terminal String booleanLiteral;
+non terminal NumericScalarExpr numericScalarExpr;
+non terminal CoverageExpr coverageExpr;
+non terminal SetMetaDataExpr setMetaDataExpr;
+non terminal InducedExpr inducedExpr;
+non terminal UnaryInducedExpr unaryInducedExpr;
+non terminal UnaryArithMeticExpr unaryArithMeticExpr;
+non terminal ExponentialExpr exponentialExpr;
+non terminal TrigonometricExpr trigonometricExpr;
+non terminal BooleanExpr booleanExpr;
+non terminal CastExpr castExpr;
+non terminal SelectExpr fieldExpr;
+non terminal BinaryInducedExpr binaryInducedExpr;
+non terminal String binaryInducedOp;
+non terminal SubsetExpr subsetExpr;
+non terminal TrimExpr trimExpr;
+non terminal SliceExpr sliceExpr;
+non terminal ExtendExpr extendExpr;
+non terminal ScaleExpr scaleExpr;
+non terminal CrsTransformExpr crsTransformExpr;
+non terminal AxisIntervalList axisIntervalList;
+non terminal AxisIntervalElement axisIntervalElement;
+non terminal AxisPointList axisPointList;
+non terminal AxisPointList axisPointEnum;
+non terminal AxisPointElement axisPointElement;
+non terminal String axisPoint;
+non terminal AxisCrsList axisCrsList;
+non terminal AxisCrsList axisCrsEnum;
+non terminal AxisCrsElement axisCrsElement;
+non terminal FieldInterpolationList fieldInterpolationList;
+non terminal FieldInterpolationList fieldInterpolationEnum;
+non terminal FieldInterpolationElement fieldInterpolationElement;
+non terminal InterpolationMethodList interpolationMethodList;
+non terminal InterpolationMethodList interpolationMethodEnum;
+non terminal FieldInterpolationMethod interpolationMethod;
+non terminal String interpolationType;
+non terminal String nullResistence;
+non terminal CoverageConstructorExpr coverageConstructorExpr;
+non terminal VariableList variableList;
+non terminal String axisType;
+non terminal CondenseExpr condenseExpr;
+non terminal ReduceExpr reduceExpr;
+non terminal GeneralCondenseExpr generalCondenseExpr;
+non terminal String condenseOpType;
+non terminal RangeValue rangeValue;
+non terminal StructuredLiteral structuredLiteral;
+non terminal RangeValueList rangeValueList;
+non terminal String atomicLiteral;
+non terminal String complexLiteral;
+non terminal String fieldName;
+non terminal CrsList crsList;
+non terminal CrsList crsEnum;
+non terminal String cellType;
+non terminal String generalId;
+
+//non terminal CoverageConstExpr converageConstExpr; // TODO(smsorin): not defined in WCPS !!
+
+
+
+/* Precedence rules to avoid Shift/Reduce conflicts*/
+precedence left AND, OR, XOR;
+precedence left PLUS, MINUS;
+precedence left MULTI, DIVIDE;
+precedence nonassoc EQUALS, LT, GT, LTE, GTE, NOTEQUALS;
+precedence nonassoc NOT, DOT, OVERLAY;
+precedence left LBRACKET, LBRACE, COMMA, RBRACKET, RBRACE;
+
+/* The grammar specification */
+
+wcpsRequest ::= forClause:e1 returnClause:e2 {: RESULT = new WCPSRequest(e1,e2); :}
+ | forClause:e1 whereClause:e2 returnClause:e3 {: RESULT = new WCPSRequest(e1,e2,e3); :}
+ ;
+forClause ::= FOR forClauseElements:e1 {: RESULT = new ForClause(e1); :}
+ ;
+forClauseElements ::= ID:e1 IN LPAREN coverageList:e2 RPAREN {: RESULT = new ForClauseElements(e1,e2); :}
+ | ID:e1 IN LPAREN coverageList:e2 RPAREN COMMA forClauseElements:e3 {: RESULT = new ForClauseElements(e1,e2,e3); :}
+ ;
+whereClause ::= WHERE booleanScalarExpr:e1 {: RESULT = new WhereClause(e1); :}
+ ;
+returnClause ::= RETURN processingExpr:e1 {: RESULT = new ReturnClause(e1); :}
+ ;
+coverageList ::= ID:e1 {: RESULT = new CoverageList(e1); :}
+ | ID:e1 COMMA coverageList:e2 {: RESULT = new CoverageList(e1,e2); :}
+ ;
+processingExpr ::= encodedCoverageExpr:e1 {: RESULT = new ProcessingExpr(e1); :}
+ | storeExpr:e1 {: RESULT = new ProcessingExpr(e1); :}
+ | scalarExpr:e1 {: RESULT = new ProcessingExpr(e1); :}
+ ;
+encodedCoverageExpr ::= ENCODE LPAREN coverageExpr:e1 COMMA ID:e2 RPAREN {: RESULT = new EncodedCoverageExpr(e1,e2); :}
+ | ENCODE LPAREN coverageExpr:e1 COMMA ID:e2 COMMA ID:e3 RPAREN {: RESULT = new EncodedCoverageExpr(e1,e2,e3); :}
+ ;
+storeExpr ::= STORE LPAREN encodedCoverageExpr:e1 RPAREN {: RESULT = new StoreExpr(e1); :}
+ ;
+scalarExpr ::= getMetaDataExpr:e1 {: RESULT = new ScalarExpr(e1); :}
+ | condenseExpr:e1 {: RESULT = new ScalarExpr(e1); :}
+ | booleanScalarExpr:e1 {: RESULT = new ScalarExpr(e1); :}
+ | numericScalarExpr:e1 {: RESULT = new ScalarExpr(e1); :}
+ | LPAREN scalarExpr:e1 RPAREN {: RESULT = new ScalarExpr(e1); :}
+ ;
+getMetaDataExpr ::= IDENTIFIER:op LPAREN coverageExpr:e1 RPAREN {: RESULT = new GetMetaDataExpr(op, e1); :}
+ | IMAGECRS:op LPAREN coverageExpr:e1 RPAREN {: RESULT = new GetMetaDataExpr(op, e1); :}
+ | IMAGECRSDOMAIN:op LPAREN coverageExpr:e1 RPAREN {: RESULT = new GetMetaDataExpr(op, e1); :}
+ | CRSSET:op LPAREN coverageExpr:e1 RPAREN {: RESULT = new GetMetaDataExpr(op, e1); :}
+ | GENERALDOMAIN:op LPAREN coverageExpr:e1 RPAREN {: RESULT = new GetMetaDataExpr(op, e1); :}
+ | NULLDEFAULT:op LPAREN coverageExpr:e1 RPAREN {: RESULT = new GetMetaDataExpr(op, e1); :}
+ | NULLSET:op LPAREN coverageExpr:e1 RPAREN {: RESULT = new GetMetaDataExpr(op,e1); :}
+ | INTERPOLATIONDEFAULT:op LPAREN coverageExpr:e1 COMMA fieldName:f1 RPAREN {: RESULT = new GetMetaDataExpr(op,e1,f1); :}
+ | INTERPOLATIONSET:op LPAREN coverageExpr:e1 COMMA fieldName:f1 RPAREN {: RESULT = new GetMetaDataExpr(op, e1,f1); :}
+ ;
+booleanScalarExpr ::= booleanLiteral:e {: RESULT = new BooleanScalarExpr(e); :}
+ | NOT:op booleanScalarExpr:e {: RESULT = new BooleanScalarExpr(op,e); :}
+ | booleanScalarExpr:e1 AND:op booleanScalarExpr:e2 {: RESULT = new BooleanScalarExpr(op,e1,e2); :}
+ | booleanScalarExpr:e1 OR:op booleanScalarExpr:e2 {: RESULT = new BooleanScalarExpr(op,e1,e2); :}
+ | booleanScalarExpr:e1 XOR:op booleanScalarExpr:e2 {: RESULT = new BooleanScalarExpr(op,e1,e2); :}
+ ;
+booleanLiteral ::= TRUE:e {: RESULT = new String(e); :}
+ | FALSE:e {: RESULT = new String(e); :}
+ ;
+
+numericScalarExpr ::= NUMBER:e {: RESULT = new NumericScalarExpr(e.toString()); :}
+ | FLOATNUMBER:e {: RESULT = new NumericScalarExpr(e.toString()); :}
+ | MINUS:op numericScalarExpr:e1 {: RESULT = new NumericScalarExpr(op, e1); :}
+ | PLUS:op numericScalarExpr:e1 {: RESULT = new NumericScalarExpr(op,e1); :}
+ | numericScalarExpr:e1 PLUS:op numericScalarExpr:e2 {: RESULT = new NumericScalarExpr(op,e1,e2); :}
+ | numericScalarExpr:e1 MINUS:op numericScalarExpr:e2 {: RESULT = new NumericScalarExpr(op,e1,e2); :}
+ | numericScalarExpr:e1 DIVIDE:op numericScalarExpr:e2 {: RESULT = new NumericScalarExpr(op,e1,e2); :}
+ | numericScalarExpr:e1 MULTI:op numericScalarExpr:e2 {: RESULT = new NumericScalarExpr(op,e1,e2); :}
+ | ABS:op LPAREN numericScalarExpr:e1 RPAREN {: RESULT = new NumericScalarExpr(op,e1); :}
+ ;
+coverageExpr ::= ID:e1 {: RESULT = new CoverageExpr(e1); :}
+ | setMetaDataExpr:e2 {: RESULT = new CoverageExpr(e2); :}
+ | inducedExpr:e2 {: RESULT = new CoverageExpr(e2); :}
+ | subsetExpr:e2 {: RESULT = new CoverageExpr(e2); :}
+ | crsTransformExpr:e2 {: RESULT = new CoverageExpr(e2); :}
+ | scaleExpr:e2 {: RESULT = new CoverageExpr(e2); :}
+// TODO(smsorin): Update once the definition is available. | coverageConstExpr:e1 {: RESULT = new CoverageExpr(e1); :}
+ | coverageConstructorExpr:e1 {: RESULT = new CoverageExpr(e1); :}
+ | LPAREN coverageExpr:e2 RPAREN {: RESULT = new CoverageExpr(e2); :}
+ ;
+setMetaDataExpr ::= SETNULLDEFAULT:op LPAREN coverageExpr:e1 COMMA rangeValue:r1 RPAREN {: RESULT = new SetMetaDataExpr(op, e1,r1); :}
+ | SETNULLSET:op LPAREN coverageExpr:e1 COMMA rangeValueList:r1 RPAREN {: RESULT = new SetMetaDataExpr(op,e1,r1); :}
+ | SETINTERPOLATIONDEFAULT:op LPAREN coverageExpr:e1 COMMA fieldName:f1 COMMA interpolationMethod:i1 RPAREN
+ {: RESULT = new SetMetaDataExpr(op, e1,(IParseTreeNode)i1, f1); :}
+ | SETINTERPOLATIONSET:op LPAREN coverageExpr:e1 COMMA fieldName:f1 COMMA interpolationMethodList:i1 RPAREN
+ {: RESULT = new SetMetaDataExpr(op, e1,(IParseTreeNode)i1, f1); :}
+ | SETCRSSET:op LPAREN coverageExpr:e1 COMMA crsList:cs1 RPAREN {: RESULT = new SetMetaDataExpr(op, e1,cs1); :}
+ ;
+crsList ::= LBRACE crsEnum:list RBRACE {: RESULT = list; :}
+ ;
+crsEnum ::= ID:crs {: RESULT = new CrsList(crs); :}
+ | ID:crs COMMA crsEnum:n {: RESULT = new CrsList(crs, n); :}
+ ;
+inducedExpr ::= unaryInducedExpr:e1 {: RESULT = new InducedExpr(e1); :}
+ | binaryInducedExpr:e1 {: RESULT = new InducedExpr(e1); :}
+ ;
+unaryInducedExpr ::= unaryArithMeticExpr:e1 {: RESULT = new UnaryInducedExpr(e1); :}
+ | exponentialExpr:e1 {: RESULT = new UnaryInducedExpr(e1); :}
+ | trigonometricExpr:e1 {: RESULT = new UnaryInducedExpr(e1); :}
+ | booleanExpr:e1 {: RESULT = new UnaryInducedExpr(e1); :}
+ | castExpr:e1 {: RESULT = new UnaryInducedExpr(e1); :}
+ | fieldExpr:e1 {: RESULT = new UnaryInducedExpr(e1); :}
+ ;
+unaryArithMeticExpr ::= PLUS:e coverageExpr:e1 {: RESULT = new UnaryArithMeticExpr(e1,e); :}
+ | MINUS:e coverageExpr:e1 {: RESULT = new UnaryArithMeticExpr(e1,e); :}
+ | SQRT:e LPAREN coverageExpr:e1 RPAREN {: RESULT = new UnaryArithMeticExpr(e1,e); :}
+ | ABS:e LPAREN coverageExpr:e1 RPAREN {: RESULT = new UnaryArithMeticExpr(e1,e); :}
+ ;
+exponentialExpr ::= EXP:e LPAREN coverageExpr:e1 RPAREN {: RESULT = new ExponentialExpr(e1,e); :}
+ | LOG:e LPAREN coverageExpr:e1 RPAREN {: RESULT = new ExponentialExpr(e1,e); :}
+ | LN:e LPAREN coverageExpr:e1 RPAREN {: RESULT = new ExponentialExpr(e1,e); :}
+ ;
+trigonometricExpr ::= SIN:e LPAREN coverageExpr:e1 RPAREN {: RESULT = new TrigonometricExpr(e1,e); :}
+ | COS:e LPAREN coverageExpr:e1 RPAREN {: RESULT = new TrigonometricExpr(e1,e); :}
+ | TAN:e LPAREN coverageExpr:e1 RPAREN {: RESULT = new TrigonometricExpr(e1,e); :}
+ | SINH:e LPAREN coverageExpr:e1 RPAREN {: RESULT = new TrigonometricExpr(e1,e); :}
+ | COSH:e LPAREN coverageExpr:e1 RPAREN {: RESULT = new TrigonometricExpr(e1,e); :}
+ | TANH:e LPAREN coverageExpr:e1 RPAREN {: RESULT = new TrigonometricExpr(e1,e); :}
+ | ARCSIN:e LPAREN coverageExpr:e1 RPAREN {: RESULT = new TrigonometricExpr(e1,e); :}
+ | ARCCOS:e LPAREN coverageExpr:e1 RPAREN {: RESULT = new TrigonometricExpr(e1,e); :}
+ | ARCTAN:e LPAREN coverageExpr:e1 RPAREN {: RESULT = new TrigonometricExpr(e1,e); :}
+ ;
+booleanExpr ::= NOT:e coverageExpr:e1 {: RESULT = new BooleanExpr(e1,e); :}
+ | BIT:e LPAREN coverageExpr:e1 COMMA NUMBER:e2 RPAREN {: RESULT = new BooleanExpr(e1,e2,e); :}
+ ;
+castExpr ::= LPAREN cellType:e1 RPAREN coverageExpr:e2 {: RESULT = new CastExpr(e2,e1); :}
+ ;
+cellType ::= BOOL:e {: RESULT = new String(e); :}
+ | CHAR:e {: RESULT = new String(e); :}
+ | UNSIGNEDCHAR:e {: RESULT = new String(e); :}
+ | SHORT:e {: RESULT = new String(e); :}
+ | UNSIGNEDSHORT:e {: RESULT = new String(e); :}
+ | LONG:e {: RESULT = new String(e); :}
+ | UNSIGNEDLONG:e {: RESULT = new String(e); :}
+ | FLOAT:e {: RESULT = e.toString(); :}
+ | DOUBLE:e {: RESULT = new String(e); :}
+ | COMPLEX:e {: RESULT = new String(e); :}
+ | COMPLEX2:e {: RESULT = new String(e); :}
+ ;
+fieldExpr ::= coverageExpr:e1 DOT fieldName:e2 {: RESULT = new SelectExpr(e1,e2); :}
+ ;
+fieldName ::= NUMBER:e {: RESULT = e.toString(); :}
+ | ID:e {: RESULT = new String(e); :}
+ ;
+binaryInducedExpr ::= coverageExpr:e1 binaryInducedOp:op coverageExpr:e2 {: RESULT = new BinaryInducedExpr(op, e1, e2); :}
+ | coverageExpr:e1 binaryInducedOp:op rangeValue:rv1 {: RESULT = new BinaryInducedExpr(op, e1, rv1, 1); :}
+ | rangeValue:rv1 binaryInducedOp:op coverageExpr:e1 {: RESULT = new BinaryInducedExpr(op, rv1, e1, -1); :}
+ ;
+binaryInducedOp ::= PLUS {: RESULT = new String("plus"); :}
+ | MINUS {: RESULT = new String("minus"); :}
+ | MULTI {: RESULT = new String("mult"); :}
+ | DIVIDE {: RESULT = new String("div"); :}
+ | AND {: RESULT = new String("and"); :}
+ | OR {: RESULT = new String("or"); :}
+ | XOR {: RESULT = new String("xor"); :}
+ | EQUALS {: RESULT = new String("equals"); :}
+ | LT {: RESULT = new String("lessThan"); :}
+ | GT {: RESULT = new String("greaterThan"); :}
+ | LTE {: RESULT = new String("lessOrEqual"); :}
+ | GTE {: RESULT = new String("greaterOrEqual"); :}
+ | NOTEQUALS {: RESULT = new String("notEqual"); :}
+ | OVERLAY {: RESULT = new String("overlay"); :}
+ ;
+subsetExpr ::= trimExpr:e1 {: RESULT = new SubsetExpr(e1); :}
+ | sliceExpr:e1 {: RESULT = new SubsetExpr(e1); :}
+ | extendExpr:e1 {: RESULT = new SubsetExpr(e1); :}
+ ;
+trimExpr ::= coverageExpr:e1 LBRACKET axisIntervalList:ail RBRACKET {: RESULT = new TrimExpr(e1, ail); :}
+ | TRIM LPAREN coverageExpr:e1 COMMA axisIntervalList:ail RPAREN {: RESULT = new TrimExpr(e1,ail); :}
+ ;
+sliceExpr ::= coverageExpr:e1 LBRACKET axisPointList:apl RBRACKET {: RESULT = new SliceExpr(e1, apl); :}
+ | SLICE LPAREN coverageExpr:e1 COMMA LBRACE axisPointList:apl RBRACE RPAREN {: RESULT = new SliceExpr(e1, apl); :}
+ ;
+extendExpr ::= EXTEND LPAREN coverageExpr:e1 COMMA axisIntervalList:ail RPAREN {: RESULT = new ExtendExpr(e1, ail); :}
+ ;
+scaleExpr ::= SCALE LPAREN coverageExpr:e1 COMMA axisIntervalList:ail COMMA fieldInterpolationList:fil RPAREN
+ {: RESULT = new ScaleExpr(e1,ail,fil); :}
+ ;
+crsTransformExpr ::= CTRANSFORM LPAREN coverageExpr:e1 COMMA axisCrsList:ail COMMA fieldInterpolationList:fil RPAREN
+ {: RESULT = new CrsTransformExpr(e1,ail,fil); :}
+ ;
+axisIntervalList ::= axisIntervalElement:elem COMMA axisIntervalList:n {: RESULT = new AxisIntervalList(elem, n); :}
+ | axisIntervalElement:elem {: RESULT = new AxisIntervalList(elem); :}
+ ;
+axisIntervalElement ::= generalId:name LPAREN axisPoint:lo COLON axisPoint:hi RPAREN {: RESULT = new AxisIntervalElement(name, lo, hi); :}
+ | generalId:name COLON ID:crsName LPAREN axisPoint:lo COLON axisPoint:hi RPAREN {: RESULT = new AxisIntervalElement(name, crsName, lo, hi); :}
+ ;
+axisPointList ::= axisPointElement:elem {: RESULT = new AxisPointList(elem); :}
+ | axisPointElement:elem COMMA axisPointList:n {: RESULT = new AxisPointList(elem, n); :}
+ ;
+axisPointElement ::= generalId:axisName LPAREN axisPoint:ap RPAREN {: RESULT = new AxisPointElement(axisName, ap); :}
+ | generalId:axisName COLON ID:crsName LPAREN axisPoint:ap RPAREN {: RESULT = new AxisPointElement(axisName, crsName, ap); :}
+ ;
+axisPoint ::= NUMBER:e {: RESULT = e.toString(); :}
+// numericScalarExpr:e {: RESULT = e.toXML(); :} The schema doesn't actually allow this
+// | STRING:e {: RESULT = new String(e); :}
+ ;
+
+axisCrsList ::= LBRACE axisCrsEnum:ace RBRACE {: RESULT = ace; :}
+ ;
+axisCrsEnum ::= axisCrsElement:elem {: RESULT = new AxisCrsList(elem); :}
+ | axisCrsElement:elem COMMA axisCrsEnum:n {: RESULT = new AxisCrsList(elem, n); :}
+ ;
+axisCrsElement ::= ID:axis COLON ID:crs {: RESULT = new AxisCrsElement(axis, crs); :}
+ ;
+fieldInterpolationList ::= LBRACE fieldInterpolationEnum:fie RBRACE {: RESULT = fie; :}
+ ;
+fieldInterpolationEnum ::= fieldInterpolationElement:elem {: RESULT = new FieldInterpolationList(elem); :}
+ | fieldInterpolationElement:elem COMMA fieldInterpolationEnum:n {: RESULT = new FieldInterpolationList(elem, n); :}
+ ;
+fieldInterpolationElement ::= fieldName:name COLON interpolationMethod:method {: RESULT = new FieldInterpolationElement(name, method); :}
+ ;
+interpolationMethodList ::= LBRACE interpolationMethodEnum:list RBRACE {: RESULT = list; :}
+ ;
+interpolationMethodEnum ::= interpolationMethod:elem {: RESULT = new InterpolationMethodList(elem); :}
+ | interpolationMethod:elem COMMA interpolationMethodEnum:n {: RESULT = new InterpolationMethodList(elem,n); :}
+ ;
+interpolationMethod ::= LPAREN interpolationType:type COLON nullResistence:resistence RPAREN {: RESULT = new FieldInterpolationMethod(type, resistence); :}
+ ;
+interpolationType ::= NEAREST:e {: RESULT = new String(e); :}
+ | LINEAR:e {: RESULT = new String(e); :}
+ | QUADRATIC:e {: RESULT = new String(e); :}
+ | CUBIC:e {: RESULT = new String(e); :}
+ ;
+nullResistence ::= FULL:e {: RESULT = new String(e); :}
+ | NONE:e {: RESULT = new String(e); :}
+ | HALF:e {: RESULT = new String(e); :}
+ | OTHER:e {: RESULT = new String(e); :}
+ ;
+coverageConstructorExpr ::= COVERAGE fieldName:f OVER variableList:vl VALUES scalarExpr:se {: RESULT = new CoverageConstructorExpr(f, vl, se); :}
+ ;
+variableList ::= axisType:at ID:varName IN LPAREN NUMBER:lo COLON NUMBER:hi RPAREN COMMA variableList:n
+ {: RESULT = new VariableList(at,varName, lo.toString(), hi.toString(), n); :}
+ | axisType:at ID:varName IN LPAREN NUMBER:lo COLON NUMBER:hi RPAREN
+ {: RESULT = new VariableList(at,varName, lo.toString(), hi.toString()); :}
+
+ ;
+axisType ::= X:t {: RESULT = new String(t); :}
+ | Y:t {: RESULT = new String(t); :}
+ | Z:t {: RESULT = new String(t); :}
+ | TIME:t {: RESULT = new String(t); :}
+ | ABSTRACT:t {: RESULT = new String(t); :}
+ ;
+condenseExpr ::= reduceExpr:e {: RESULT = new CondenseExpr(e); :}
+ | generalCondenseExpr:e {: RESULT = new CondenseExpr(e); :}
+ ;
+reduceExpr ::= ALL:e1 LPAREN coverageExpr:e RPAREN {: RESULT = new ReduceExpr(e,e1); :}
+ | SOME:e1 LPAREN coverageExpr:e RPAREN {: RESULT = new ReduceExpr(e,e1); :}
+ | ADD:e1 LPAREN coverageExpr:e RPAREN {: RESULT = new ReduceExpr(e,e1); :}
+ | COUNT:e1 LPAREN coverageExpr:e RPAREN {: RESULT = new ReduceExpr(e,e1); :}
+ | AVG:e1 LPAREN coverageExpr:e RPAREN {: RESULT = new ReduceExpr(e,e1); :}
+ | MIN:e1 LPAREN coverageExpr:e RPAREN {: RESULT = new ReduceExpr(e,e1); :}
+ | MAX:e1 LPAREN coverageExpr:e RPAREN {: RESULT = new ReduceExpr(e,e1); :}
+ ;
+generalCondenseExpr ::= CONDENSE condenseOpType:op OVER variableList:vl USING scalarExpr:se {: RESULT = new GeneralCondenseExpr(op, vl, se); :}
+ | CONDENSE condenseOpType:op OVER variableList:vl WHERE booleanScalarExpr:be USING scalarExpr:se
+ {: RESULT = new GeneralCondenseExpr(op, vl, be, se); :}
+ ;
+condenseOpType ::= PLUS:op {: RESULT = new String(op); :}
+ | MULTI:op {: RESULT = new String(op); :}
+ | MAX:op {: RESULT = new String(op); :}
+ | MIN:op {: RESULT = new String(op); :}
+ | AND:op {: RESULT = new String(op); :}
+ | OR:op {: RESULT = new String(op); :}
+ ;
+rangeValue ::= structuredLiteral:sl {: RESULT = new RangeValue(sl); :}
+ | atomicLiteral:al {: RESULT = new RangeValue(al); :}
+ ;
+structuredLiteral ::= LBRACE rangeValueList:rvl RBRACE {: RESULT = new StructuredLiteral(rvl); :}
+ | STRUCT LBRACE rangeValueList:rvl RBRACE {: RESULT = new StructuredLiteral(rvl); :}
+ ;
+rangeValueList ::= rangeValue:elem {: RESULT = new RangeValueList(elem); :}
+ | rangeValue:elem COMMA rangeValueList:next {: RESULT = new RangeValueList(elem, next); :}
+ ;
+atomicLiteral ::= booleanLiteral:e {: RESULT = new String(e); :}
+ | NUMBER:e {: RESULT = e.toString(); :}
+ | FLOATNUMBER:e {: RESULT = e.toString(); :}
+ | complexLiteral:e {: RESULT = new String(e); :}
+// | STRING:e {: RESULT = new String(e); :}
+ ;
+complexLiteral ::= COMPLEX LPAREN FLOATNUMBER:f1 COMMA FLOATNUMBER:f2 RPAREN {: RESULT = new String(f1 + " + " + f2 + "i"); :}
+ ;
+
+generalId ::= ID:s {: RESULT = new String(s); :}
+ | X:s {: RESULT = new String(s); :}
+ | Y:s {: RESULT = new String(s); :}
+ | Z:s {: RESULT = new String(s); :}
+ | TIME:s {: RESULT = new String(s); :}
+ ;
diff --git a/src/syntaxParser/wcps.lex b/src/syntaxParser/wcps.lex
new file mode 100644
index 0000000..94fad48
--- /dev/null
+++ b/src/syntaxParser/wcps.lex
@@ -0,0 +1,157 @@
+/*
+ WCPS JLex specification - author: Mattia Parigiani
+
+ This is the JLex specification file for the WCPS abstract grammar. The JLex executable produces a Scanner.java source file which encapsulated
+ all symbol and token definition and which is needed by the Java CUP parser
+
+ This file specifies all possible tokens / symbols that may appear in a WCPS request
+
+ New symbols may be added following the same syntax standard
+
+*/
+
+
+
+
+
+/*
+ Required declarations for source generator.
+ Make sure you know what you are doing if you wish to modify these declarations
+*/
+
+package syntaxParser;
+import java_cup.runtime.*;
+import java.io.*;
+%%
+%notunix
+%implements java_cup.runtime.Scanner
+%type Symbol
+%function next_token
+%public
+%class WCPSScanner
+%eofval{ return null;
+%eofval}
+%line
+%char
+
+IDENTIFIER = [a-zA-Z][a-zA-Z0-9_]*
+FLOATNUMBER = [-+]?[0-9]+[.]?[0-9]+
+NUMBER = [0-9]+
+STRING = [a-zA-Z]*
+
+
+%%
+"+" { return new Symbol(WCPSSymbol.PLUS, yyline, yychar, yytext()); }
+"*" { return new Symbol(WCPSSymbol.MULTI, yyline, yychar, yytext()); }
+"/" { return new Symbol(WCPSSymbol.DIVIDE, yyline, yychar, yytext()); }
+"-" { return new Symbol(WCPSSymbol.MINUS, yyline, yychar, yytext()); }
+"(" { return new Symbol(WCPSSymbol.LPAREN, yyline, yychar, yytext()); }
+")" { return new Symbol(WCPSSymbol.RPAREN, yyline, yychar, yytext()); }
+"{" { return new Symbol(WCPSSymbol.LBRACE, yyline, yychar, yytext()); }
+"}" { return new Symbol(WCPSSymbol.RBRACE, yyline, yychar, yytext()); }
+"struct" { return new Symbol(WCPSSymbol.STRUCT, yyline, yychar, yytext()); }
+"sin" { return new Symbol(WCPSSymbol.SIN, yyline, yychar, yytext()); }
+"cos" { return new Symbol(WCPSSymbol.COS, yyline, yychar, yytext()); }
+"tan" { return new Symbol(WCPSSymbol.TAN, yyline, yychar, yytext()); }
+"sinh" { return new Symbol(WCPSSymbol.SINH, yyline, yychar, yytext()); }
+"cosh" { return new Symbol(WCPSSymbol.COSH, yyline, yychar, yytext()); }
+"tanh" { return new Symbol(WCPSSymbol.TANH, yyline, yychar, yytext()); }
+"arcsin" { return new Symbol(WCPSSymbol.ARCSIN, yyline, yychar, yytext()); }
+"arccos" { return new Symbol(WCPSSymbol.ARCCOS, yyline, yychar, yytext()); }
+"arctan" { return new Symbol(WCPSSymbol.ARCTAN, yyline, yychar, yytext()); }
+"exp" { return new Symbol(WCPSSymbol.EXP, yyline, yychar, yytext()); }
+"log" { return new Symbol(WCPSSymbol.LOG, yyline, yychar, yytext()); }
+"ln" { return new Symbol(WCPSSymbol.LN, yyline, yychar, yytext()); }
+"abs" { return new Symbol(WCPSSymbol.ABS, yyline, yychar, yytext()); }
+"sqrt" { return new Symbol(WCPSSymbol.SQRT, yyline, yychar, yytext()); }
+":" { return new Symbol(WCPSSymbol.COLON, yyline, yychar, yytext()); }
+"." { return new Symbol(WCPSSymbol.DOT, yyline, yychar, yytext()); }
+"return" { return new Symbol(WCPSSymbol.RETURN, yyline, yychar, yytext()) ;}
+"for" { return new Symbol(WCPSSymbol.FOR, yyline, yychar, yytext()) ;}
+"in" { return new Symbol(WCPSSymbol.IN, yyline, yychar, yytext()) ; }
+"," { return new Symbol(WCPSSymbol.COMMA, yyline, yychar, yytext()); }
+"encode" { return new Symbol(WCPSSymbol.ENCODE, yyline, yychar, yytext()) ; }
+"condense" { return new Symbol(WCPSSymbol.CONDENSE, yyline, yychar, yytext()) ; }
+"over" { return new Symbol(WCPSSymbol.OVER, yyline, yychar, yytext()) ; }
+"using" { return new Symbol(WCPSSymbol.USING, yyline, yychar, yytext()) ; }
+"max" { return new Symbol(WCPSSymbol.MAX, yyline, yychar, yytext()) ; }
+"min" { return new Symbol(WCPSSymbol.MIN, yyline, yychar, yytext()) ; }
+"and" { return new Symbol(WCPSSymbol.AND, yyline, yychar, yytext()) ; }
+"or" { return new Symbol(WCPSSymbol.OR, yyline, yychar, yytext()) ; }
+"setCrsSet" { return new Symbol(WCPSSymbol.SETCRSSET, yyline, yychar, yytext()); }
+"nearest" { return new Symbol(WCPSSymbol.NEAREST, yyline, yychar, yytext()) ; }
+"cTransform" { return new Symbol(WCPSSymbol.CTRANSFORM, yyline, yychar, yytext()) ; }
+"scale" { return new Symbol(WCPSSymbol.SCALE, yyline, yychar, yytext()) ; }
+"count" { return new Symbol(WCPSSymbol.COUNT, yyline, yychar, yytext()) ; }
+"all" { return new Symbol(WCPSSymbol.ALL, yyline, yychar, yytext()) ; }
+"add" { return new Symbol(WCPSSymbol.ADD, yyline, yychar, yytext()) ; }
+"some" { return new Symbol(WCPSSymbol.SOME, yyline, yychar, yytext()) ; }
+"avg" { return new Symbol(WCPSSymbol.AVG, yyline, yychar, yytext()) ; }
+"bool" { return new Symbol(WCPSSymbol.BOOL, yyline, yychar, yytext()) ; }
+"char" { return new Symbol(WCPSSymbol.CHAR, yyline, yychar, yytext()) ; }
+"unsigned char" { return new Symbol(WCPSSymbol.UNSIGNEDCHAR, yyline, yychar, yytext()) ; }
+"unsigned short" { return new Symbol(WCPSSymbol.UNSIGNEDSHORT, yyline, yychar, yytext()) ; }
+"short" { return new Symbol(WCPSSymbol.SHORT, yyline, yychar, yytext()) ; }
+"long" { return new Symbol(WCPSSymbol.LONG, yyline, yychar, yytext()) ; }
+"unsigned long" { return new Symbol(WCPSSymbol.UNSIGNEDLONG, yyline, yychar, yytext()) ; }
+"float" { return new Symbol(WCPSSymbol.FLOAT, yyline, yychar, yytext()) ; }
+"double" { return new Symbol(WCPSSymbol.DOUBLE, yyline, yychar, yytext()) ; }
+"not" { return new Symbol(WCPSSymbol.NOT, yyline, yychar, yytext()) ; }
+"bit" { return new Symbol(WCPSSymbol.BIT, yyline, yychar, yytext()) ; }
+"xor" { return new Symbol(WCPSSymbol.XOR, yyline, yychar, yytext()) ; }
+"=" { return new Symbol(WCPSSymbol.EQUALS, yyline, yychar, yytext()) ; }
+"!=" { return new Symbol(WCPSSymbol.NOTEQUALS, yyline, yychar, yytext()) ; }
+"overlay" { return new Symbol(WCPSSymbol.OVERLAY, yyline, yychar, yytext()) ; }
+">" { return new Symbol(WCPSSymbol.GT, yyline, yychar, yytext()) ; }
+"<" { return new Symbol(WCPSSymbol.LT, yyline, yychar, yytext()) ; }
+"<=" { return new Symbol(WCPSSymbol.LTE, yyline, yychar, yytext()) ; }
+">=" { return new Symbol(WCPSSymbol.GTE, yyline, yychar, yytext()) ; }
+"[" { return new Symbol(WCPSSymbol.LBRACKET, yyline, yychar, yytext()) ; }
+"]" { return new Symbol(WCPSSymbol.RBRACKET, yyline, yychar, yytext()) ; }
+"trim" { return new Symbol(WCPSSymbol.TRIM, yyline, yychar, yytext()) ; }
+"true" { return new Symbol(WCPSSymbol.TRUE, yyline, yychar, yytext()) ; }
+"false" { return new Symbol(WCPSSymbol.FALSE, yyline, yychar, yytext()) ; }
+"where" { return new Symbol(WCPSSymbol.WHERE, yyline, yychar, yytext()); }
+"store" { return new Symbol(WCPSSymbol.STORE, yyline, yychar, yytext()); }
+"identifier" { return new Symbol(WCPSSymbol.IDENTIFIER, yyline, yychar, yytext()); }
+"imageCrs" { return new Symbol(WCPSSymbol.IMAGECRS, yyline, yychar, yytext()); }
+"imageCrsDomain" { return new Symbol(WCPSSymbol.IMAGECRSDOMAIN, yyline, yychar, yytext()); }
+"crsSet" { return new Symbol(WCPSSymbol.CRSSET, yyline, yychar, yytext()); }
+"generalDomain" { return new Symbol(WCPSSymbol.GENERALDOMAIN, yyline, yychar, yytext()); }
+"nullDefault" { return new Symbol(WCPSSymbol.NULLDEFAULT, yyline, yychar, yytext()); }
+"nullSet" { return new Symbol(WCPSSymbol.NULLSET, yyline, yychar, yytext()); }
+"interpolationDefault" { return new Symbol(WCPSSymbol.INTERPOLATIONDEFAULT, yyline, yychar, yytext()); }
+"interpolationSet" { return new Symbol(WCPSSymbol.INTERPOLATIONSET, yyline, yychar, yytext()); }
+"setNullDefault" { return new Symbol(WCPSSymbol.SETNULLDEFAULT, yyline, yychar, yytext()); }
+"setNullSet" { return new Symbol(WCPSSymbol.SETNULLSET, yyline, yychar, yytext()); }
+"setInterpolationDefault" { return new Symbol(WCPSSymbol.SETINTERPOLATIONDEFAULT, yyline, yychar, yytext()); }
+"setInterpolationSet" { return new Symbol(WCPSSymbol.SETINTERPOLATIONSET, yyline, yychar, yytext()); }
+"complex" { return new Symbol(WCPSSymbol.COMPLEX, yyline, yychar, yytext()); }
+"complex2" { return new Symbol(WCPSSymbol.COMPLEX2, yyline, yychar, yytext()); }
+"slice" { return new Symbol(WCPSSymbol.SLICE, yyline, yychar, yytext()); }
+"extend" { return new Symbol(WCPSSymbol.EXTEND, yyline, yychar, yytext()); }
+"linear" { return new Symbol(WCPSSymbol.LINEAR, yyline, yychar, yytext()) ; }
+"quadratic" { return new Symbol(WCPSSymbol.QUADRATIC, yyline, yychar, yytext()); }
+"cubic" { return new Symbol(WCPSSymbol.CUBIC, yyline, yychar, yytext()); }
+"full" { return new Symbol(WCPSSymbol.FULL, yyline, yychar, yytext()); }
+"none" { return new Symbol(WCPSSymbol.NONE, yyline, yychar, yytext()); }
+"half" { return new Symbol(WCPSSymbol.HALF, yyline, yychar, yytext()); }
+"other" { return new Symbol(WCPSSymbol.OTHER, yyline, yychar, yytext()); }
+"coverage" { return new Symbol(WCPSSymbol.COVERAGE, yyline, yychar, yytext()); }
+"values" { return new Symbol(WCPSSymbol.VALUES, yyline, yychar, yytext()); }
+"x" { return new Symbol(WCPSSymbol.X, yyline, yychar, yytext()); }
+"y" { return new Symbol(WCPSSymbol.Y, yyline, yychar, yytext()); }
+"z" { return new Symbol(WCPSSymbol.Z, yyline, yychar, yytext()); }
+"time" { return new Symbol(WCPSSymbol.TIME, yyline, yychar, yytext()); }
+"abstract" { return new Symbol(WCPSSymbol.ABSTRACT, yyline, yychar, yytext()); }
+
+{IDENTIFIER} { System.out.println("Got an Identifier: '" + yytext() + "'"); return new Symbol(WCPSSymbol.ID, yyline, yychar, yytext()); }
+{NUMBER} { System.out.println("Got an int: '" + yytext() + "'"); return new Symbol(WCPSSymbol.NUMBER, yyline, yychar, new Integer(yytext()));}
+{FLOATNUMBER} { System.out.println("Got a float: '" + yytext() + "'"); return new Symbol(WCPSSymbol.FLOATNUMBER, yyline, yychar, new Float(yytext()));}
+{STRING} { System.out.println("Got a string: '" + yytext() + "'"); return new Symbol(WCPSSymbol.STRING, yyline, yychar, yytext()); }
+
+
+
+
+\n {System.out.println("newline" + yytext()); return null; }
+. {System.out.println("illegal input: '" + yytext() +"'"); }
diff --git a/src/syntaxParser/wcps.lex_ORIG b/src/syntaxParser/wcps.lex_ORIG
new file mode 100644
index 0000000..c477710
--- /dev/null
+++ b/src/syntaxParser/wcps.lex_ORIG
@@ -0,0 +1,141 @@
+/*
+ WCPS JLex specification - author: Mattia Parigiani
+
+ This is the JLex specification file for the WCPS abstract grammar. The JLex executable produces a Scanner.java source file which encapsulated
+ all symbol and token definition and which is needed by the Java CUP parser
+
+ This file specifies all possible tokens / symbols that may appear in a WCPS request
+
+ New symbols may be added following the same syntax standard
+
+*/
+
+
+
+
+
+/*
+ Required declarations for source generator.
+ Make sure you know what you are doing if you wish to modify these declarations
+*/
+
+
+import java_cup.runtime.*;
+import java.io.*;
+%%
+
+%notunix
+%implements java_cup.runtime.Scanner
+%type Symbol
+%function next_token
+%class WCPSScanner
+%eofval{ return null;
+%eofval}
+
+/*
+ WCPS data types specification
+*/
+
+IDENTIFIER = [a-zA-Z][a-zA-Z0-9]*
+NUMBER = [0-9]+
+FLOATNUMBER = [-+]?[0-9]*\.?[0-9]+
+
+
+/*
+ WCPS Tokens specification
+
+*/
+
+
+%%
+"+" { return new Symbol(WCPSSymbol.PLUS, yytext()); }
+"*" { return new Symbol(WCPSSymbol.MULTI, yytext()); }
+"/" { return new Symbol(WCPSSymbol.DIVIDE, yytext()); }
+"-" { return new Symbol(WCPSSymbol.MINUS, yytext()); }
+"(" { return new Symbol(WCPSSymbol.LPAREN, yytext()); }
+")" { return new Symbol(WCPSSymbol.RPAREN, yytext()); }
+"{" { return new Symbol(WCPSSymbol.LBRACE, yytext()); }
+"}" { return new Symbol(WCPSSymbol.RBRACE, yytext()); }
+"struct" { return new Symbol(WCPSSymbol.STRUCT, yytext()); }
+"sin" { return new Symbol(WCPSSymbol.SIN, yytext()); }
+"cos" { return new Symbol(WCPSSymbol.COS, yytext()); }
+"tan" { return new Symbol(WCPSSymbol.TAN, yytext()); }
+"sinh" { return new Symbol(WCPSSymbol.SINH, yytext()); }
+"cosh" { return new Symbol(WCPSSymbol.COSH, yytext()); }
+"tanh" { return new Symbol(WCPSSymbol.TANH, yytext()); }
+"arcsin" { return new Symbol(WCPSSymbol.ARCSIN, yytext()); }
+"arccos" { return new Symbol(WCPSSymbol.ARCCOS, yytext()); }
+"arctan" { return new Symbol(WCPSSymbol.ARCTAN, yytext()); }
+"exp" { return new Symbol(WCPSSymbol.EXP, yytext()); }
+"log" { return new Symbol(WCPSSymbol.LOG, yytext()); }
+"ln" { return new Symbol(WCPSSymbol.LN, yytext()); }
+"abs" { return new Symbol(WCPSSymbol.ABS, yytext()); }
+"sqrt" { return new Symbol(WCPSSymbol.SQRT, yytext()); }
+":" { return new Symbol(WCPSSymbol.COLON, yytext()); }
+"." { return new Symbol(WCPSSymbol.DOT, yytext()); }
+"return" { return new Symbol(WCPSSymbol.RETURN, yytext()) ;}
+"for" { return new Symbol(WCPSSymbol.FOR, yytext()) ;}
+"in" { return new Symbol(WCPSSymbol.IN, yytext()) ; }
+"," { return new Symbol(WCPSSymbol.COMMA, yytext()); }
+"encode" { return new Symbol(WCPSSymbol.ENCODE, yytext()) ; }
+"condense" { return new Symbol(WCPSSymbol.CONDENSE, yytext()) ; }
+"over" { return new Symbol(WCPSSymbol.OVER, yytext()) ; }
+"using" { return new Symbol(WCPSSymbol.USING, yytext()) ; }
+"max" { return new Symbol(WCPSSymbol.MAX, yytext()) ; }
+"min" { return new Symbol(WCPSSymbol.MIN, yytext()) ; }
+"and" { return new Symbol(WCPSSymbol.AND, yytext()) ; }
+"or" { return new Symbol(WCPSSymbol.OR, yytext()) ; }
+"setNull" { return new Symbol(WCPSSymbol.SETNULL, yytext()) ; }
+"setInterpolation" { return new Symbol(WCPSSymbol.SETINTERPOLATION, yytext()) ; }
+"setCrs" { return new Symbol(WCPSSymbol.SETCRS, yytext()) ; }
+"setAxis" { return new Symbol(WCPSSymbol.SETAXIS, yytext()) ; }
+"nearest neighbor" { return new Symbol(WCPSSymbol.NEAREST, yytext()) ; }
+"bilinear" { return new Symbol(WCPSSymbol.BILINEAR, yytext()) ; }
+"barycentric" { return new Symbol(WCPSSymbol.BARYCENTRIC, yytext()) ; }
+"bicubic" { return new Symbol(WCPSSymbol.BICUBIC, yytext()) ; }
+"lost-area" { return new Symbol(WCPSSymbol.LOSTAREA, yytext()) ; }
+"yDomain" { return new Symbol(WCPSSymbol.YDOMAIN, yytext()) ; }
+"xDomain" { return new Symbol(WCPSSymbol.XDOMAIN, yytext()) ; }
+"sDomain" { return new Symbol(WCPSSymbol.SDOMAIN, yytext()) ; }
+"tDomain" { return new Symbol(WCPSSymbol.TDOMAIN, yytext()) ; }
+"cTransform" { return new Symbol(WCPSSymbol.CTRANSFORM, yytext()) ; }
+"scale" { return new Symbol(WCPSSymbol.SCALE, yytext()) ; }
+"res" { return new Symbol(WCPSSymbol.RES, yytext()) ; }
+"dim" { return new Symbol(WCPSSymbol.DIM, yytext()) ; }
+"cellType" { return new Symbol(WCPSSymbol.CELLTYPE, yytext()) ; }
+"crs" { return new Symbol(WCPSSymbol.CRS, yytext()) ; }
+"count" { return new Symbol(WCPSSymbol.COUNT, yytext()) ; }
+"all" { return new Symbol(WCPSSymbol.ALL, yytext()) ; }
+"add" { return new Symbol(WCPSSymbol.ADD, yytext()) ; }
+"some" { return new Symbol(WCPSSymbol.SOME, yytext()) ; }
+"avg" { return new Symbol(WCPSSymbol.AVG, yytext()) ; }
+"bool" { return new Symbol(WCPSSymbol.BOOL, yytext()) ; }
+"char" { return new Symbol(WCPSSymbol.CHAR, yytext()) ; }
+"unsigned char" { return new Symbol(WCPSSymbol.UNSIGNEDCHAR, yytext()) ; }
+"unsigned short" { return new Symbol(WCPSSymbol.UNSIGNEDSHORT, yytext()) ; }
+"short" { return new Symbol(WCPSSymbol.SHORT, yytext()) ; }
+"long" { return new Symbol(WCPSSymbol.LONG, yytext()) ; }
+"unsigned long" { return new Symbol(WCPSSymbol.UNSIGNEDLONG, yytext()) ; }
+"float" { return new Symbol(WCPSSymbol.FLOAT, yytext()) ; }
+"double" { return new Symbol(WCPSSymbol.DOUBLE, yytext()) ; }
+"not" { return new Symbol(WCPSSymbol.NOT, yytext()) ; }
+"bit" { return new Symbol(WCPSSymbol.BIT, yytext()) ; }
+"xor" { return new Symbol(WCPSSymbol.XOR, yytext()) ; }
+"=" { return new Symbol(WCPSSymbol.EQUALS, yytext()) ; }
+"!=" { return new Symbol(WCPSSymbol.NOTEQUALS, yytext()) ; }
+"overlay" { return new Symbol(WCPSSymbol.OVERLAY, yytext()) ; }
+">" { return new Symbol(WCPSSymbol.GT, yytext()) ; }
+"<" { return new Symbol(WCPSSymbol.LT, yytext()) ; }
+"<=" { return new Symbol(WCPSSymbol.LTE, yytext()) ; }
+">=" { return new Symbol(WCPSSymbol.GTE, yytext()) ; }
+"[" { return new Symbol(WCPSSymbol.LBRACKET, yytext()) ; }
+"]" { return new Symbol(WCPSSymbol.RBRACKET, yytext()) ; }
+"trim" { return new Symbol(WCPSSymbol.TRIM, yytext()) ; }
+"sect" { return new Symbol(WCPSSymbol.SECT, yytext()) ; }
+"true" { return new Symbol(WCPSSymbol.TRUE, yytext()) ; }
+"false" { return new Symbol(WCPSSymbol.FALSE, yytext()) ; }
+{IDENTIFIER} {return new Symbol(WCPSSymbol.ID, yytext()); }
+{NUMBER} { return new Symbol(WCPSSymbol.NUMBER, new Integer(yytext()));}
+{FLOATNUMBER} { return new Symbol(WCPSSymbol.FLOATNUMBER, new Float(yytext()));}
+\n {System.out.println("newline" + yytext()); }
+. {System.out.println("illegal input" + yytext()); }
diff --git a/src/syntaxParser/wcpsRequest.xml b/src/syntaxParser/wcpsRequest.xml
new file mode 100644
index 0000000..a88e313
--- /dev/null
+++ b/src/syntaxParser/wcpsRequest.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<processCoverage xmlns="http://www.opengis.net/wcps/1.0.0" service="WCPS" version="1.0.0">
+<coverageIterator>
+ <iteratorVar>m</iteratorVar>
+ <coverageName>climate_temperature</coverageName>
+ </coverageIterator>
+ <encode>
+ <format>png</format>
+ <coverage>m</coverage>
+ </encode>
+</processCoverage>