001: package ro.infoiasi.donald.compiler.parser.runtime;
002:
003: import java.util.Stack;
004:
005: public abstract class SkeletonLRParser {
006: private Lexer lex;
007:
008: protected StackSymbol currentToken;
009: protected Stack parseStack = new Stack();
010: protected boolean doneParsing = false;
011: protected boolean DEBUG = false;
012:
013: protected short[][] productionTable;
014: protected short[][] actionTable;
015: protected short[][] gotoTable;
016:
017: public SkeletonLRParser() {
018: // do nothing
019: }
020:
021: public SkeletonLRParser(Lexer lex) {
022: this ();
023: setLexer(lex);
024: }
025:
026: public void setLexer(Lexer lex) {
027: this .lex = lex;
028: }
029:
030: public Lexer getLexer() {
031: return lex;
032: }
033:
034: public abstract short[][] getProductionTable();
035:
036: public abstract short[][] getActionTable();
037:
038: public abstract short[][] getGotoTable();
039:
040: public abstract int getStartState();
041:
042: public abstract int getStartProduction();
043:
044: public abstract int getEOF();
045:
046: public abstract int getTokenOffset();
047:
048: protected abstract void initActions() throws Exception;
049:
050: public abstract StackSymbol doAction(int actNo,
051: SkeletonLRParser parser, Stack stack) throws Exception;
052:
053: public void initCode() throws Exception {
054: // do nothing
055: }
056:
057: public StackSymbol scan() throws Exception {
058: StackSymbol sym = getLexer().nextStackSymbol();
059: if (sym != null) {
060: return sym;
061: } else {
062: return new StackSymbol(getEOF());
063: }
064: }
065:
066: public void doneParsing() {
067: doneParsing = true;
068: }
069:
070: public StackSymbol parse() throws Exception {
071: int action;
072: StackSymbol lhs = null;
073: short rhsCount, lhsSID;
074:
075: productionTable = getProductionTable();
076: actionTable = getActionTable();
077: gotoTable = getGotoTable();
078:
079: initActions();
080: initCode();
081:
082: currentToken = scan();
083: trace("# Current Symbol is " + currentToken.sym);
084:
085: parseStack.removeAllElements();
086: parseStack.push(new StackSymbol(0, getStartState()));
087:
088: while (!doneParsing) {
089: int state = ((StackSymbol) parseStack.peek()).parseState;
090: action = actionTable[state][currentToken.sym
091: - getTokenOffset()];
092: if (action > 0) { // shift action
093: currentToken.parseState = action - 1;
094: parseStack.push(currentToken);
095: currentToken = scan();
096: } else if (action < 0) { // reduce action
097: int prod = (-action) - 1;
098: lhs = doAction(prod, this , parseStack);
099: lhsSID = productionTable[prod][0];
100: rhsCount = productionTable[prod][1];
101: for (int i = 0; i < rhsCount; i++) {
102: parseStack.pop();
103: }
104:
105: state = ((StackSymbol) parseStack.peek()).parseState;
106: action = gotoTable[state][lhsSID];
107: /* shift to that state */
108: lhs.parseState = action;
109: parseStack.push(lhs);
110: } else { // error
111: syntaxError(currentToken);
112: }
113: }
114: return lhs;
115: }
116:
117: public void syntaxError(StackSymbol sym) throws Exception {
118: // sometime we might try to recover
119: reportFatalError("Syntax Error", sym);
120: }
121:
122: public void reportError(String message, Object info) {
123: System.err.print(message);
124: if (info instanceof StackSymbol) {
125: StackSymbol sym = (StackSymbol) info;
126: if (sym.line != -1) {
127: System.err.print(" at line " + sym.line);
128: if (sym.column != -1) {
129: System.err.print(", column " + sym.column);
130: }
131: System.err.println(" of input");
132: }
133: } else {
134: System.err.println();
135: }
136: }
137:
138: public void reportFatalError(String message, Object info)
139: throws java.lang.Exception {
140: doneParsing();
141: reportError(message, info);
142: throw new Exception("Can't recover from previous error(s)");
143: }
144:
145: private void trace(String message) {
146: if (DEBUG) {
147: System.out.println(message);
148: }
149: }
150:
151: protected static short[][] unpackFromStrings(String[] sa) {
152: // Concatanate initialization strings.
153: StringBuffer sb = new StringBuffer(sa[0]);
154: for (int i = 1; i < sa.length; i++) {
155: sb.append(sa[i]);
156: }
157: int n = 0; // location in initialization string
158: int size1 = (((int) sb.charAt(n)) << 16)
159: | ((int) sb.charAt(n + 1));
160: n += 2;
161: short[][] result = new short[size1][];
162: for (int i = 0; i < size1; i++) {
163: int size2 = (((int) sb.charAt(n)) << 16)
164: | ((int) sb.charAt(n + 1));
165: n += 2;
166: result[i] = new short[size2];
167: for (int j = 0; j < size2; j++)
168: result[i][j] = (short) (sb.charAt(n++) - 2);
169: }
170: return result;
171: }
172: }
|