All pastes #921328 Raw Edit

MizardX

public java v1 · immutable
#921328 ·published 2008-02-27 23:17 UTC
rendered paste body
/** * Jacc parser for the regular language: * ( [0-9]a | b )* ( [0-9][0-9] | c )* */%{import java.io.*;import java.util.*;%}%class Parser%interface ParserSymbols%next nextToken()%get getToken()%semantic Object : getSemantic()%token <ASem> 'a'%token <BSem> 'b'%token <CSem> 'c'%token <Digit> DIGIT%type <List1> list1%type <List2> list2%type <Type1> type1%type <Type2> type2%type <P> p%start p%%p : list1 list2    { $$ = new P($1, $2); }  ;list1 : list1 type1        { $$ = $1; $1.addElement($2); }      |        { $$ = new List1(); }      ;list2 : list2 type2        { $$ = $1; $1.addElement($2); }      |        { $$ = new List2(); }      ;type1 : DIGIT 'a'        { $$ = new DA($1, $2); }      | 'b'        { $$ = new B($1); }      ;type2 : DIGIT DIGIT        { $$ = new DD($1, $2); }      | 'c'        { $$ = new C($1); }      ;%%    private int curtok;    // Current token    private Object cursem; // It's semantic object    private Reader input;  // Input    private int pos = 0;   // Counts the position    // Constructor    public Parser(Reader input) {        this.input = input;        this.nextToken();    }    // Error handler    private void yyerror(String msg) {        System.err.println(msg);        throw new RuntimeException(msg);    }    // Reads and returns the next token    private int nextToken() {        try {            int c = input.read();            put("Read: " + (char)c);            this.pos++;            switch (c) {                case 'a':                    this.curtok = c;                    this.cursem = new ASem();                    return this.curtok;                case 'b':                    this.curtok = c;                    this.cursem = new BSem();                    return this.curtok;                case 'c':                    this.curtok = c;                    this.cursem = new CSem();                    return this.curtok;                case '0': case '1': case '2':                case '3': case '4': case '5':                case '6': case '7': case '8':                case '9':                    this.curtok = DIGIT;                    this.cursem = new Digit(c-'0');                    return this.curtok;            }        }        catch (IOException e) {            // Empty        }        this.cursem = null;        this.curtok = 0;        return this.curtok;    }    // Returns the last token read.    private int getToken() {        return this.curtok;    }    // Returns the current semantic object    private Object getSemantic() {        return this.cursem;    }        // Prints a message (just a shortcut)    void put(String msg) {        System.out.println(msg);    }    // Semantic class for 'a'    private class ASem {        public final int index = pos;        public ASem() { put("Made ASem"); }        public String toString() {            return "ASem(" + index + ")";        }    }    // Semantic class for 'b'    private class BSem {        public final int index = pos;        public BSem() { put("Made BSem"); }        public String toString() {            return "BSem(" + index + ")";        }    }    // Semantic class for 'c'    private class CSem {        public final int index = pos;        public CSem() { put("Made CSem"); }        public String toString() {            return "CSem(" + index + ")";        }    }    // Semantic class for a digit    private class Digit {        public final int index = pos;        public int d;        public Digit(int d) {            put("Made Digit: " + d);            this.d = d;        }        public String toString() {            return "Digit(" + d + "," + index + ")";        }    }    // Semantic class for non-terminal type1    private class Type1 {}    // ..for the 'b' in type1    private class B extends Type1 {        public BSem b;        public B(BSem b) {            this.b = b;            put("Made B: " + b);        }        public String toString() {            return "B[" + b + "]";        }    }    // ..for the DIGIT 'a' in type1    private class DA extends Type1 {        public Digit d;        public ASem a;        public DA(Digit d, ASem a) {            this.d = d;            this.a = a;            put("Made DA: " + d + ", " + a);        }        public String toString() {            return "DA[" + d + ", " + a + "]";        }    }    // Semantic class for the non-terminal type2    private class Type2 {}    // ..for the 'c' in type2    private class C extends Type2 {        public CSem c;        public C(CSem c) {            this.c = c;            put("Made C: " + c);        }        public String toString() {            return "C[" + c + "]";        }    }    // ..for the DIGIT DIGIT in type2    private class DD extends Type2 {        public Digit d1,d2;        public DD(Digit d1, Digit d2) {            this.d1 = d1;            this.d2 = d2;            put("Made DD: " + d1 + ", " + d2);        }        public String toString() {            return "DD[" + d1 + ", " + d2 + "]";        }    }    // Semantic class for the non-terminal list1    private class List1 {        public LinkedList<Type1> elements;        public List1() {            this.elements = new LinkedList<Type1>();            put("Made List1");        }        public void addElement(Type1 elm) {            put(this + " + " + elm);            this.elements.addLast(elm);        }        public String toString() {            StringBuilder sb = new StringBuilder("List1[");            boolean first = true;            for (Type1 elm : elements) {                if (first)                    first = false;                else                     sb.append(", ");                sb.append(elm);            }            sb.append("]");            return sb.toString();        }    }    // Semantic class for the non-terminal list2    private class List2 {        public LinkedList<Type2> elements;        public List2() {            this.elements = new LinkedList<Type2>();        }        public void addElement(Type2 elm) {            put(this + " + " + elm);            this.elements.addLast(elm);        }        public String toString() {            StringBuilder sb = new StringBuilder("List2[");            boolean first = true;            for (Type2 elm : elements) {                if (first)                    first = false;                else                    sb.append(", ");                sb.append(elm);            }            sb.append("]");            return sb.toString();        }    }    // Semantic class for the non-terminal p    private class P {        public List1 list1;        public List2 list2;        public P(List1 list1, List2 list2) {            this.list1 = list1;            this.list2 = list2;        }        public String toString() {            return "P[" + list1 + ", " + list2 + "]";        }    }    // Called from the command-line    public static void main(String[] argv) {        System.out.println("Input: " + argv[0]);        StringReader r = new StringReader(argv[0]);        Parser p = new Parser(r);        p.parse();        System.out.println("Result: " + p.yyrv);        //yyrv gets defined and assigned by the parser    }