simo vor 1 Monat
Ursprung
Commit
e9bb61a011
60 geänderte Dateien mit 1181 neuen und 33 gelöschten Zeilen
  1. BIN
      344/arro/Java/AssignStmt.class
  2. 38 0
      344/arro/Java/AssignStmt.java
  3. BIN
      344/arro/Java/Exp.class
  4. 39 0
      344/arro/Java/Exp.java
  5. BIN
      344/arro/Java/Exprest$1.class
  6. BIN
      344/arro/Java/Exprest.class
  7. 42 0
      344/arro/Java/Exprest.java
  8. BIN
      344/arro/Java/ILazy.class
  9. 13 0
      344/arro/Java/ILazy.java
  10. BIN
      344/arro/Java/IMatch.class
  11. 9 0
      344/arro/Java/IMatch.java
  12. BIN
      344/arro/Java/IScan.class
  13. 6 0
      344/arro/Java/IScan.java
  14. BIN
      344/arro/Java/ITrace.class
  15. 11 0
      344/arro/Java/ITrace.java
  16. BIN
      344/arro/Java/InputStmt.class
  17. 38 0
      344/arro/Java/InputStmt.java
  18. BIN
      344/arro/Java/Mult.class
  19. 39 0
      344/arro/Java/Mult.java
  20. BIN
      344/arro/Java/Multrest$1.class
  21. BIN
      344/arro/Java/Multrest.class
  22. 42 0
      344/arro/Java/Multrest.java
  23. BIN
      344/arro/Java/NUMValue.class
  24. 29 0
      344/arro/Java/NUMValue.java
  25. BIN
      344/arro/Java/OutputStmt.class
  26. 35 0
      344/arro/Java/OutputStmt.java
  27. BIN
      344/arro/Java/PLCCException.class
  28. 18 0
      344/arro/Java/PLCCException.java
  29. BIN
      344/arro/Java/Parse.class
  30. 17 0
      344/arro/Java/Parse.java
  31. BIN
      344/arro/Java/ProcessFiles.class
  32. 84 0
      344/arro/Java/ProcessFiles.java
  33. BIN
      344/arro/Java/Program.class
  34. 33 0
      344/arro/Java/Program.java
  35. BIN
      344/arro/Java/Rep.class
  36. 17 0
      344/arro/Java/Rep.java
  37. BIN
      344/arro/Java/Scan$1.class
  38. BIN
      344/arro/Java/Scan.class
  39. 228 0
      344/arro/Java/Scan.java
  40. BIN
      344/arro/Java/Stmt$1.class
  41. BIN
      344/arro/Java/Stmt.class
  42. 29 0
      344/arro/Java/Stmt.java
  43. BIN
      344/arro/Java/Stmtlist$1.class
  44. BIN
      344/arro/Java/Stmtlist.class
  45. 44 0
      344/arro/Java/Stmtlist.java
  46. BIN
      344/arro/Java/Token$Match.class
  47. BIN
      344/arro/Java/Token$TokType.class
  48. BIN
      344/arro/Java/Token.class
  49. 153 0
      344/arro/Java/Token.java
  50. BIN
      344/arro/Java/Trace.class
  51. 39 0
      344/arro/Java/Trace.java
  52. BIN
      344/arro/Java/VARValue.class
  53. 33 0
      344/arro/Java/VARValue.java
  54. BIN
      344/arro/Java/Value$1.class
  55. BIN
      344/arro/Java/Value.class
  56. 27 0
      344/arro/Java/Value.java
  57. BIN
      344/arro/Java/_Start.class
  58. 16 0
      344/arro/Java/_Start.java
  59. 98 33
      344/arro/arro.plcc
  60. 4 0
      344/arro/sample.plcc

BIN
344/arro/Java/AssignStmt.class


+ 38 - 0
344/arro/Java/AssignStmt.java

@@ -0,0 +1,38 @@
+//AssignStmt:top//
+//AssignStmt:import//
+import java.util.*;
+
+// <stmt>AssignStmt ::= <VAR> <ASSIGN> <exp> <SEMI>
+public class AssignStmt extends Stmt /*AssignStmt:class*/ {
+
+    public static final String $className = "AssignStmt";
+    public static final String $ruleString =
+        "<stmt>AssignStmt ::= <VAR> <ASSIGN> <exp> <SEMI>";
+
+    public Token var;
+    public Token assign;
+    public Exp exp;
+    public Token semi;
+
+    public AssignStmt(Token var, Token assign, Exp exp, Token semi) {
+//AssignStmt:init//
+        this.var = var;
+        this.assign = assign;
+        this.exp = exp;
+        this.semi = semi;
+    }
+
+    public static AssignStmt parse(Scan scn$, Trace trace$) {
+        if (trace$ != null)
+            trace$ = trace$.nonterm("<stmt>AssignStmt", scn$.lno);
+        Token var = scn$.match(Token.Match.VAR, trace$);
+        Token assign = scn$.match(Token.Match.ASSIGN, trace$);
+        Exp exp = Exp.parse(scn$, trace$);
+        Token semi = scn$.match(Token.Match.SEMI, trace$);
+        return new AssignStmt(var, assign, exp, semi);
+    }
+
+    public void execute() { Program.hshmap.put(var.toString(), exp.eval()); }
+
+//AssignStmt//
+}

BIN
344/arro/Java/Exp.class


+ 39 - 0
344/arro/Java/Exp.java

@@ -0,0 +1,39 @@
+//Exp:top//
+//Exp:import//
+import java.util.*;
+
+// <exp> ::= <mult> <exprest>
+public class Exp /*Exp:class*/ {
+
+    public static final String $className = "Exp";
+    public static final String $ruleString =
+        "<exp> ::= <mult> <exprest>";
+
+    public Mult mult;
+    public Exprest exprest;
+
+    public Exp(Mult mult, Exprest exprest) {
+//Exp:init//
+        this.mult = mult;
+        this.exprest = exprest;
+    }
+
+    public static Exp parse(Scan scn$, Trace trace$) {
+        if (trace$ != null)
+            trace$ = trace$.nonterm("<exp>", scn$.lno);
+        Mult mult = Mult.parse(scn$, trace$);
+        Exprest exprest = Exprest.parse(scn$, trace$);
+        return new Exp(mult, exprest);
+    }
+
+    public int eval() {
+      int v = mult.eval();
+      for (int i = 0; i < exprest.opList.size(); i++)
+        v += exprest.opList.get(i).toString().equals("+")
+             ? exprest.multList.get(i).eval()
+             : -exprest.multList.get(i).eval();
+      return v;
+    }
+
+//Exp//
+}

BIN
344/arro/Java/Exprest$1.class


BIN
344/arro/Java/Exprest.class


+ 42 - 0
344/arro/Java/Exprest.java

@@ -0,0 +1,42 @@
+//Exprest:top//
+//Exprest:import//
+import java.util.*;
+
+// <exprest> **= <OP> <mult>
+public class Exprest /*Exprest:class*/ {
+
+    public static final String $className = "Exprest";
+    public static final String $ruleString =
+        "<exprest> **= <OP> <mult>";
+
+    public List<Token> opList;
+    public List<Mult> multList;
+
+    public Exprest(List<Token> opList, List<Mult> multList) {
+//Exprest:init//
+        this.opList = opList;
+        this.multList = multList;
+    }
+
+    public static Exprest parse(Scan scn$, Trace trace$) {
+        if (trace$ != null)
+            trace$ = trace$.nonterm("<exprest>", scn$.lno);
+        List<Token> opList = new ArrayList<Token>();
+        List<Mult> multList = new ArrayList<Mult>();
+        while (true) {
+            Token t$ = scn$.cur();
+            Token.Match match$ = t$.match;
+            switch(match$) {
+            case OP:
+                opList.add(scn$.match(Token.Match.OP, trace$));
+                multList.add(Mult.parse(scn$, trace$));
+                continue;
+            default:
+                return new Exprest(opList, multList);
+            }
+        }
+
+    }
+
+//Exprest//
+}

BIN
344/arro/Java/ILazy.class


+ 13 - 0
344/arro/Java/ILazy.java

@@ -0,0 +1,13 @@
+/**
+ * Lazy interface definition
+ */
+
+public interface ILazy {
+
+    public Token cur();
+
+    public void adv();
+
+    public void put(Token e);
+
+}

BIN
344/arro/Java/IMatch.class


+ 9 - 0
344/arro/Java/IMatch.java

@@ -0,0 +1,9 @@
+/**
+ * Match interface definition
+ */
+
+public interface IMatch {
+
+    public Token match(Token.Match mat, Trace t);
+
+}

BIN
344/arro/Java/IScan.class


+ 6 - 0
344/arro/Java/IScan.java

@@ -0,0 +1,6 @@
+public interface IScan extends ILazy, IMatch {
+
+    // this interface is used simply to collect
+    // the ILazy and IMatch interfaces
+
+}

BIN
344/arro/Java/ITrace.class


+ 11 - 0
344/arro/Java/ITrace.java

@@ -0,0 +1,11 @@
+public interface ITrace {
+
+    public void print(Token t);
+
+    public void print(String s, int lno);
+
+    public Trace nonterm(String s, int lno);
+
+    public void reset();
+
+}

BIN
344/arro/Java/InputStmt.class


+ 38 - 0
344/arro/Java/InputStmt.java

@@ -0,0 +1,38 @@
+//InputStmt:top//
+//InputStmt:import//
+import java.util.*;
+
+// <stmt>InputStmt ::= <IN> <VAR> <SEMI>
+public class InputStmt extends Stmt /*InputStmt:class*/ {
+
+    public static final String $className = "InputStmt";
+    public static final String $ruleString =
+        "<stmt>InputStmt ::= <IN> <VAR> <SEMI>";
+
+    public Token in;
+    public Token var;
+    public Token semi;
+
+    public InputStmt(Token in, Token var, Token semi) {
+//InputStmt:init//
+        this.in = in;
+        this.var = var;
+        this.semi = semi;
+    }
+
+    public static InputStmt parse(Scan scn$, Trace trace$) {
+        if (trace$ != null)
+            trace$ = trace$.nonterm("<stmt>InputStmt", scn$.lno);
+        Token in = scn$.match(Token.Match.IN, trace$);
+        Token var = scn$.match(Token.Match.VAR, trace$);
+        Token semi = scn$.match(Token.Match.SEMI, trace$);
+        return new InputStmt(in, var, semi);
+    }
+
+    public void execute() {
+      System.out.print("? ");
+      Program.hshmap.put(var.toString(), Program.scanner.nextInt());
+    }
+
+//InputStmt//
+}

BIN
344/arro/Java/Mult.class


+ 39 - 0
344/arro/Java/Mult.java

@@ -0,0 +1,39 @@
+//Mult:top//
+//Mult:import//
+import java.util.*;
+
+// <mult> ::= <value> <multrest>
+public class Mult /*Mult:class*/ {
+
+    public static final String $className = "Mult";
+    public static final String $ruleString =
+        "<mult> ::= <value> <multrest>";
+
+    public Value value;
+    public Multrest multrest;
+
+    public Mult(Value value, Multrest multrest) {
+//Mult:init//
+        this.value = value;
+        this.multrest = multrest;
+    }
+
+    public static Mult parse(Scan scn$, Trace trace$) {
+        if (trace$ != null)
+            trace$ = trace$.nonterm("<mult>", scn$.lno);
+        Value value = Value.parse(scn$, trace$);
+        Multrest multrest = Multrest.parse(scn$, trace$);
+        return new Mult(value, multrest);
+    }
+
+    public int eval() {
+      int v = value.eval();
+      for (int i = 0; i < multrest.mopList.size(); i++)
+        v = multrest.mopList.get(i).toString().equals("*")
+            ? v * multrest.valueList.get(i).eval()
+            : v / multrest.valueList.get(i).eval();
+      return v;
+    }
+
+//Mult//
+}

BIN
344/arro/Java/Multrest$1.class


BIN
344/arro/Java/Multrest.class


+ 42 - 0
344/arro/Java/Multrest.java

@@ -0,0 +1,42 @@
+//Multrest:top//
+//Multrest:import//
+import java.util.*;
+
+// <multrest> **= <MOP> <value>
+public class Multrest /*Multrest:class*/ {
+
+    public static final String $className = "Multrest";
+    public static final String $ruleString =
+        "<multrest> **= <MOP> <value>";
+
+    public List<Token> mopList;
+    public List<Value> valueList;
+
+    public Multrest(List<Token> mopList, List<Value> valueList) {
+//Multrest:init//
+        this.mopList = mopList;
+        this.valueList = valueList;
+    }
+
+    public static Multrest parse(Scan scn$, Trace trace$) {
+        if (trace$ != null)
+            trace$ = trace$.nonterm("<multrest>", scn$.lno);
+        List<Token> mopList = new ArrayList<Token>();
+        List<Value> valueList = new ArrayList<Value>();
+        while (true) {
+            Token t$ = scn$.cur();
+            Token.Match match$ = t$.match;
+            switch(match$) {
+            case MOP:
+                mopList.add(scn$.match(Token.Match.MOP, trace$));
+                valueList.add(Value.parse(scn$, trace$));
+                continue;
+            default:
+                return new Multrest(mopList, valueList);
+            }
+        }
+
+    }
+
+//Multrest//
+}

BIN
344/arro/Java/NUMValue.class


+ 29 - 0
344/arro/Java/NUMValue.java

@@ -0,0 +1,29 @@
+//NUMValue:top//
+//NUMValue:import//
+import java.util.*;
+
+// <value>NUMValue ::= <NUM>
+public class NUMValue extends Value /*NUMValue:class*/ {
+
+    public static final String $className = "NUMValue";
+    public static final String $ruleString =
+        "<value>NUMValue ::= <NUM>";
+
+    public Token num;
+
+    public NUMValue(Token num) {
+//NUMValue:init//
+        this.num = num;
+    }
+
+    public static NUMValue parse(Scan scn$, Trace trace$) {
+        if (trace$ != null)
+            trace$ = trace$.nonterm("<value>NUMValue", scn$.lno);
+        Token num = scn$.match(Token.Match.NUM, trace$);
+        return new NUMValue(num);
+    }
+
+    public int eval() { return Integer.parseInt(num.toString()); }
+
+//NUMValue//
+}

BIN
344/arro/Java/OutputStmt.class


+ 35 - 0
344/arro/Java/OutputStmt.java

@@ -0,0 +1,35 @@
+//OutputStmt:top//
+//OutputStmt:import//
+import java.util.*;
+
+// <stmt>OutputStmt ::= <OUT> <exp> <SEMI>
+public class OutputStmt extends Stmt /*OutputStmt:class*/ {
+
+    public static final String $className = "OutputStmt";
+    public static final String $ruleString =
+        "<stmt>OutputStmt ::= <OUT> <exp> <SEMI>";
+
+    public Token out;
+    public Exp exp;
+    public Token semi;
+
+    public OutputStmt(Token out, Exp exp, Token semi) {
+//OutputStmt:init//
+        this.out = out;
+        this.exp = exp;
+        this.semi = semi;
+    }
+
+    public static OutputStmt parse(Scan scn$, Trace trace$) {
+        if (trace$ != null)
+            trace$ = trace$.nonterm("<stmt>OutputStmt", scn$.lno);
+        Token out = scn$.match(Token.Match.OUT, trace$);
+        Exp exp = Exp.parse(scn$, trace$);
+        Token semi = scn$.match(Token.Match.SEMI, trace$);
+        return new OutputStmt(out, exp, semi);
+    }
+
+    public void execute() { System.out.println(exp.eval()); }
+
+//OutputStmt//
+}

BIN
344/arro/Java/PLCCException.class


+ 18 - 0
344/arro/Java/PLCCException.java

@@ -0,0 +1,18 @@
+public class PLCCException extends RuntimeException {
+
+    String msg;
+
+    public PLCCException(String pfx, String msg) {
+        super(msg = "%%% " + pfx + ": " + msg);
+        this.msg = msg;
+    }
+
+    public PLCCException(String msg) {
+        this("Runtime error", msg);
+    }
+
+    public String toString() {
+        return msg;
+    }
+
+}

BIN
344/arro/Java/Parse.class


+ 17 - 0
344/arro/Java/Parse.java

@@ -0,0 +1,17 @@
+import java.util.*;
+import java.io.*;
+
+
+public class Parse extends ProcessFiles {
+
+    // Parse the program and call $ok() on the resulting parse tree
+    public void action(Scan scn, Trace trace) {
+        _Start.parse(scn, trace).$ok();
+    }
+
+    // Read programs from command-line files
+    // and then read programs from standard input.
+    public static void main(String [] args) {
+        new Parse().processFiles(args);
+    }
+}

BIN
344/arro/Java/ProcessFiles.class


+ 84 - 0
344/arro/Java/ProcessFiles.java

@@ -0,0 +1,84 @@
+import java.io.*;
+import java.util.*;
+
+// Process command-line arguments (flags, filenames) from the given args
+// Read programs from named files and then from standard input.
+// If the '-n' flag is given, don't prompt for standard input,
+//     otherwise prompt with "--> "
+// If the '-t' command line argument is given, toggle the trace feature
+//     (defaults to no trace)
+// For each input program, use 'action' to parse the input
+//     and act on the resulting parse tree
+
+public abstract class ProcessFiles {
+
+    // build a parse tree and act on it
+    abstract void action(Scan scn, Trace trace);
+
+    public void processFile(Scan scn, Trace trace, String prompt, String prog) {
+        try {
+            // read and process programs from this 
+            while(true) {
+                System.out.print(prompt);
+                if (scn.isEOF())
+                    break;
+                if (trace != null)
+                    trace.reset();
+                if (prog != null) {
+                    System.out.print(prog);
+                    if (trace != null)
+                        System.out.println(); // format the trace better
+                }
+                action(scn, trace);
+            }
+        } catch (Exception e) {
+            System.err.println(e.getMessage());
+        } catch (Error e) {
+            System.err.println(e);
+            System.exit(1);
+        }
+    }
+
+    public void processFiles(String [] args) {
+        Trace trace = null;
+        // first read and process any input files from the command line
+        Scan scn = null;
+        String prog = null;
+        String prompt = "--> ";
+        for (int i=0 ; i<args.length ; i++) {
+            String s = args[i];
+            if (s.equals("-n")) {
+                // turns off prompts when reading from stdin
+                prompt = "";
+                continue;
+            }
+            if (s.equals("-t")) {
+                // toggle traces
+                trace = (trace == null ? new Trace() : null);
+                continue;
+            }
+            if (s.equals("-v")) {
+                // toggle verbose cmd line name output
+                prog = (prog == null ? "" : null);
+                continue;
+            }
+            try {
+                scn = new Scan(new BufferedReader(new FileReader(s)));
+            } catch (FileNotFoundException e) {
+                System.err.println(s + ": no such file ... exiting");
+                System.exit(1);
+            }
+            if (prog != null)
+                prog = "[" + s + "]";
+            processFile(scn, trace, "", prog);
+        }
+        // finally read and process programs from standard input
+        BufferedReader rdr =
+            new BufferedReader(new InputStreamReader(System.in));
+        scn = new Scan(rdr);
+        if (prog != null)
+            prog = "[stdin]";
+        processFile(scn, trace, prompt, prog);
+    }
+
+}

BIN
344/arro/Java/Program.class


+ 33 - 0
344/arro/Java/Program.java

@@ -0,0 +1,33 @@
+//Program:top//
+        import java.util.*;
+//Program:import//
+import java.util.*;
+
+// <program> ::= <stmtlist>
+public class Program extends _Start /*Program:class*/ {
+
+    public static final String $className = "Program";
+    public static final String $ruleString =
+        "<program> ::= <stmtlist>";
+
+    public Stmtlist stmtlist;
+
+    public Program(Stmtlist stmtlist) {
+//Program:init//
+        this.stmtlist = stmtlist;
+    }
+
+    public static Program parse(Scan scn$, Trace trace$) {
+        if (trace$ != null)
+            trace$ = trace$.nonterm("<program>", scn$.lno);
+        Stmtlist stmtlist = Stmtlist.parse(scn$, trace$);
+        return new Program(stmtlist);
+    }
+
+    public static Map<String, Integer> hshmap = new HashMap<>();
+    public static Scanner scanner = new Scanner(System.in);
+    
+    public void $run() { stmtlist.execute(); }
+
+//Program//
+}

BIN
344/arro/Java/Rep.class


+ 17 - 0
344/arro/Java/Rep.java

@@ -0,0 +1,17 @@
+import java.io.*;
+import java.util.*;
+
+public class Rep extends ProcessFiles {
+
+    // Parse the program and call $run() on the resulting parse tree
+    public void action(Scan scn, Trace trace) {
+        _Start.parse(scn, trace).$run();
+    }
+
+    // Run programs from command-line files
+    // and then perform a read-eval-print loop on programs
+    // read from standard input.
+    public static void main(String [] args) {
+        new Rep().processFiles(args);
+    }
+}

BIN
344/arro/Java/Scan$1.class


BIN
344/arro/Java/Scan.class


+ 228 - 0
344/arro/Java/Scan.java

@@ -0,0 +1,228 @@
+import java.util.regex.*;
+import java.util.*;
+import java.io.*;
+
+public class Scan implements IScan {
+
+    private BufferedReader rdr;  // get input from here, line by line
+    private String s;            // current string being scanned
+    private int start;           // starting position in the string to scan
+    private int end;             // ending position
+
+    public int lno;              // current line number
+    public Token tok;            // this is persistent across all calls to cur()
+    public Token lineMode;       // token to toggle line mode
+
+    // create a scanner object on a buffered reader
+    public Scan(BufferedReader rdr) {
+        this.rdr = rdr;
+        this.lno = 0;
+        this.lineMode = null;
+        this.s = null;
+        this.tok = null;
+        // force the enum Match class to compile its patterns
+        String msg = Token.Match.init();
+        if (msg != null) {
+            // one or more pattern compilation errors have occurred
+            System.err.println(msg);
+            System.exit(1);
+        }
+    }
+
+    // create a scanner object on a string
+    public Scan(String s) {
+        this(new BufferedReader(new StringReader(s)));
+    }
+
+    public void reset() {
+        // force the scanner to process the next line
+        s = null;
+        tok = null;
+        lineMode = null;
+    }
+
+    // fill the string buffer from the reader if it's exhausted or null)
+    public void fillString() {
+        if (s == null || start >= end) {
+            // get the next line from the reader
+            try {
+                s = rdr.readLine();
+                if (s == null)
+                    return; // end of file
+                lno++;
+                s += "\n";  // make sure the string has a newline
+                start = 0;
+                end = s.length();
+            } catch (IOException e) {
+                s = null;
+            }
+            // System.err.print("s=" + s);
+        }
+    }
+
+    public Token cur() {
+        // lazy
+        if (tok != null)
+            return tok; // don't get a new token if we already have one
+
+        String matchString = "";
+        Token.Match matchFound = null;
+
+        LOOP:
+        while (true) {
+            fillString(); // get another line if necessary
+            if (s == null) {
+                tok = new Token(Token.$eof, "!EOF", lno, null); // EOF
+                return tok;
+            }
+            // s cannot be null here
+            // are we in line mode?
+            if (lineMode != null) {
+                Pattern cpat = lineMode.match.cPattern;
+                Matcher m = cpat.matcher(s);
+                m.region(0,end);
+                start = end; // consume the line before next match
+                if (m.lookingAt()) {
+                    // found the lineMode token, exit line mode
+                    // and return the matched lineMode token
+                    // System.out.println("leaving line mode...");
+                    tok = new Token(lineMode.match, m.group(), lno, s);
+                    lineMode = null;
+                    return tok;
+                } else {
+                    // return the entire line as a token
+                    tok = new Token(Token.Match.$LINE, s, lno, s);
+                    return tok;
+                }
+            }
+            int matchEnd = start; // current end of match
+            for (Token.Match match : Token.Match.values()) {
+                Pattern cpat = match.cPattern;
+                if (cpat == null)
+                    break; // nothing matches, so can't find a token
+                if (match.tokType == Token.TokType.SKIP && matchFound != null)
+                    continue; // ignore skips if we have a pending token
+                if (start != 0 && match.pattern.charAt(0) == '^')
+                    continue; // '^' must match at start of line
+                Matcher m = cpat.matcher(s);
+                m.region(start, end);
+                if (m.lookingAt()) {
+                    int e = m.end();
+                    if (e == start)
+                        continue; // empty match, so try next pattern
+                    if (match.tokType == Token.TokType.SKIP) {
+                        // there's a non-empty skip match,
+                        // so we skip over the matched part
+                        // and get more stuff to read
+                        start = e;
+                        continue LOOP;
+                    }
+                    if (matchEnd < e) {
+                        // found a longer match -- keep it!
+                        matchEnd = e;
+                        matchString = m.group();
+                        matchFound = match;
+                    }
+                }
+            }
+            if (matchFound == null) { // got to $ERROR, so nothing matches!!
+                char ch = s.charAt(start++); // grab the char and advance
+                String sch;
+                if (ch >= ' ' && ch <= '~')
+                    sch = String.format("\"%c\"", ch);
+                else
+                    sch = String.format("\\u%04x", (int)ch);
+                tok = new Token(Token.Match.$ERROR, "!ERROR("+sch+")", lno, s);
+                return tok;
+            }
+            start = matchEnd; // start of next token match
+            // matchString is the matching string
+            tok = new Token(matchFound, matchString, lno, s); // persistent
+            // System.out.println(String.format("match=%s\n", toggle));
+            if (matchFound.tokType == Token.TokType.LINE_TOGGLE) {
+                // System.out.println("going to line mode...");
+                start = end; // swallow the rest of the line
+                lineMode = tok;
+            }
+            return tok;
+        }
+    }
+
+    public void adv() {
+        // if we have already advanced past the current token,
+        // we'll have to do it again
+        if (tok == null)
+            cur();
+        tok = null;
+    }
+
+    public void put(Token t) {
+            throw new PLCCException("PLCC Scan error",
+                                    "put not implemented");
+    }
+
+    // See if the expected token match is the same as the match
+    // of the current token
+    public Token match(Token.Match match, Trace trace) {
+        Token t = cur();
+        Token.Match mcur = t.match; // the token we got
+        if (match == mcur) { // compare the match expected with the token we got
+            if (trace != null)
+                trace.print(t);
+            adv();
+        } else {
+            String msg = "expected token " + match + ", got " + t.errString();
+            throw new PLCCException ("Parse error", msg);
+        }
+        return t;
+    }
+
+    public boolean isEOF() {
+        return cur().isEOF();
+    }
+
+    public void printTokens() {
+        while (hasNext()) {
+            Token t = next();
+            String s;
+            switch(t.match) {
+            case $ERROR:
+                s = t.toString();
+                break;
+            default:
+                s = String.format("%s '%s'", t.match.toString(), t.toString());
+            }
+            System.out.println(String.format("%4d: %s", lno, s));
+        }
+    }
+
+    public boolean hasNext() {
+        return !cur().isEOF();
+    }
+
+    public Token next() {
+        Token t = cur();
+        adv();
+        return t;
+    }
+
+    public static void main(String [] args) {
+        BufferedReader rdr = null;
+        if (args.length == 0) {
+            rdr = new BufferedReader(new InputStreamReader(System.in));
+        } else if (args.length == 1) {
+            try {
+                rdr = new BufferedReader(new FileReader(args[0]));
+            } catch (Exception e) {
+                System.out.println(e.getMessage());
+                System.exit(1);
+            }
+        }
+        else {
+            System.err.println("usage: Scan [filename]");
+            System.exit(1);
+        }
+        Scan scn = new Scan(rdr);
+        scn.printTokens();
+    }
+}

BIN
344/arro/Java/Stmt$1.class


BIN
344/arro/Java/Stmt.class


+ 29 - 0
344/arro/Java/Stmt.java

@@ -0,0 +1,29 @@
+//Stmt:top//
+//Stmt:import//
+import java.util.*;
+
+public abstract class Stmt /*Stmt:class*/ {
+
+    public static final String $className = "Stmt";
+    public static Stmt parse(Scan scn$, Trace trace$) {
+        Token t$ = scn$.cur();
+        Token.Match match$ = t$.match;
+        switch(match$) {
+        case IN:
+            return InputStmt.parse(scn$,trace$);
+        case VAR:
+            return AssignStmt.parse(scn$,trace$);
+        case OUT:
+            return OutputStmt.parse(scn$,trace$);
+        default:
+            throw new PLCCException(
+                "Parse error",
+                "Stmt cannot begin with " + t$.errString()
+            );
+        }
+    }
+
+    abstract public void execute();
+
+//Stmt//
+}

BIN
344/arro/Java/Stmtlist$1.class


BIN
344/arro/Java/Stmtlist.class


+ 44 - 0
344/arro/Java/Stmtlist.java

@@ -0,0 +1,44 @@
+//Stmtlist:top//
+//Stmtlist:import//
+import java.util.*;
+
+// <stmtlist> **= <stmt>
+public class Stmtlist /*Stmtlist:class*/ {
+
+    public static final String $className = "Stmtlist";
+    public static final String $ruleString =
+        "<stmtlist> **= <stmt>";
+
+    public List<Stmt> stmtList;
+
+    public Stmtlist(List<Stmt> stmtList) {
+//Stmtlist:init//
+        this.stmtList = stmtList;
+    }
+
+    public static Stmtlist parse(Scan scn$, Trace trace$) {
+        if (trace$ != null)
+            trace$ = trace$.nonterm("<stmtlist>", scn$.lno);
+        List<Stmt> stmtList = new ArrayList<Stmt>();
+        while (true) {
+            Token t$ = scn$.cur();
+            Token.Match match$ = t$.match;
+            switch(match$) {
+            case OUT:
+            case IN:
+            case VAR:
+                stmtList.add(Stmt.parse(scn$, trace$));
+                continue;
+            default:
+                return new Stmtlist(stmtList);
+            }
+        }
+
+    }
+
+    public void execute() {
+      for (Stmt s : stmtList) s.execute();
+    }
+
+//Stmtlist//
+}

BIN
344/arro/Java/Token$Match.class


BIN
344/arro/Java/Token$TokType.class


BIN
344/arro/Java/Token.class


+ 153 - 0
344/arro/Java/Token.java

@@ -0,0 +1,153 @@
+import java.util.*;
+import java.util.regex.*;
+
+// Token class with match patterns (used with the built-in Scan class)
+public class Token {
+
+    // patternFail is set to an error message string
+    // if there are pattern compile errors
+    public static String patternFail = null; //
+    public static final Match $eof = Match.$EOF;
+
+    public enum TokType {
+        TOKEN,
+        SKIP,
+        LINE_TOGGLE,
+        SPECIAL;
+    }
+
+    public enum Match {
+        WHITESPACE ("\\s+", TokType.SKIP),
+        NUM ("[0-9]+"),
+        VAR ("[A-Za-z_][A-Za-z0-9_]*"),
+        OP ("\\+|-"),
+        MOP ("\\*|/"),
+        IN ("==>"),
+        OUT ("<=="),
+        ASSIGN ("->"),
+        SEMI (";"),
+        $ERROR (null),
+        $EOF (null),
+        $LINE (null);
+
+        public String pattern;
+        public TokType tokType;
+        public Pattern cPattern = null; // compiled pattern
+
+        // a SPECIAL token type or a TOKEN/LINE_TOGGLE
+        Match(String pattern) {
+            this(pattern, null);
+        } 
+
+        // legacy ??
+        Match(String pattern, boolean skip) {
+            this(pattern, TokType.SKIP);
+        }
+
+        Match(String pattern, TokType tokType) {
+            if (pattern != null) {
+                if (tokType == TokType.SKIP) {
+                    this.tokType = TokType.SKIP;
+                } else if (pattern.length() >= 2 &&
+                           pattern.substring(0,2).equals("^^")) {
+                    pattern = pattern.substring(1);
+                    this.tokType = TokType.LINE_TOGGLE;
+                } else {
+                    this.tokType = TokType.TOKEN;
+                }
+                this.pattern = pattern;
+                try {
+                    this.cPattern = Pattern.compile(pattern, Pattern.DOTALL);
+                } catch (PatternSyntaxException e) {
+                    if (patternFail == null) {
+                        patternFail = "Lexical specification errors() for";
+                    }
+                    patternFail += (" " +this);
+                    this.cPattern = null;
+                }
+            } else {
+                this.tokType = TokType.SPECIAL; // SPECIAL
+            }
+        }
+
+        // Use this to force loading Match class to compile patterns.
+        public static String init() {
+            return patternFail; // returns null if no errors
+        }
+    }
+
+    public Match match;      // token match
+    public String str;       // this token's lexeme
+    public int lno;          // the line number where this token was found
+    public String line;      // the text line where this token appears
+
+    public Token() {
+        match = null;
+        str = null;
+        lno = 0;
+        line = null;
+    }
+
+    public Token(Match match, String str, int lno, String line) {
+        this.match = match;
+        this.str = str;
+        this.lno = lno;
+        this.line = line;
+    }
+
+    public Token(Match match, String str) {
+        this(match, str, 0, null);
+    }
+
+    public String toString() {
+        return str;
+    }
+
+    public String errString() {
+        switch(match) {
+        case $EOF:
+        case $ERROR:
+            return str;
+        default:
+            return match.toString(); // just the match name
+        }
+    }
+
+    public boolean isEOF() {
+        return this.match == $eof;
+    }
+
+    public static void main(String [] args) {
+        String msg = Match.init();
+        if (msg != null) {
+            System.out.println(msg);
+            System.exit(1);
+        }
+        for (Match match: Match.values()) {
+            if (match.tokType == TokType.SPECIAL) {
+                System.out.println(
+                    String.format("special "+match.toString())
+                );
+                continue; // not a real token
+            }
+            String what = "??";
+            switch(match.tokType) {
+                case SKIP:
+                    what = "skip";
+                    break;
+                case TOKEN:
+                    what = "token";
+                    break;
+                case LINE_TOGGLE:
+                    what = "token (line toggle)";
+                    break;
+            }
+            System.out.println(
+                String.format("%s %s '%s'",what,match.toString(),match.pattern)
+            );
+        }
+    }
+
+//Token//
+
+}

BIN
344/arro/Java/Trace.class


+ 39 - 0
344/arro/Java/Trace.java

@@ -0,0 +1,39 @@
+import java.io.*;
+
+public class Trace implements ITrace {
+
+    public String indent;
+    public PrintStream out;
+
+    public Trace(PrintStream out, String indent) {
+        this.out = out;
+        this.indent = indent;
+    }
+
+    public Trace(PrintStream out) {
+        this(out, "");
+    }
+
+    public Trace() {
+        this(System.err); // output defaults to System.err
+    }
+
+    public void print(String s, int lno) {
+        if (out != null)
+            out.printf("%4d: %s\n", lno, indent + s);
+    }
+
+    public void print(Token t) {
+        print(t.match.toString()+" \""+t.toString()+"\"", t.lno);
+    }
+
+    public Trace nonterm(String s, int lno) {
+        print(s, lno);
+        return new Trace(out, indent + "| ");
+    }
+
+    public void reset() {
+        indent = "";
+    }
+
+}

BIN
344/arro/Java/VARValue.class


+ 33 - 0
344/arro/Java/VARValue.java

@@ -0,0 +1,33 @@
+//VARValue:top//
+//VARValue:import//
+import java.util.*;
+
+// <value>VARValue ::= <VAR>
+public class VARValue extends Value /*VARValue:class*/ {
+
+    public static final String $className = "VARValue";
+    public static final String $ruleString =
+        "<value>VARValue ::= <VAR>";
+
+    public Token var;
+
+    public VARValue(Token var) {
+//VARValue:init//
+        this.var = var;
+    }
+
+    public static VARValue parse(Scan scn$, Trace trace$) {
+        if (trace$ != null)
+            trace$ = trace$.nonterm("<value>VARValue", scn$.lno);
+        Token var = scn$.match(Token.Match.VAR, trace$);
+        return new VARValue(var);
+    }
+
+    public int eval() {
+      if (!Program.hshmap.containsKey(var.toString()))
+        throw new RuntimeException("Undefined variable: " + var);
+      return Program.hshmap.get(var.toString());
+    }
+
+//VARValue//
+}

BIN
344/arro/Java/Value$1.class


BIN
344/arro/Java/Value.class


+ 27 - 0
344/arro/Java/Value.java

@@ -0,0 +1,27 @@
+//Value:top//
+//Value:import//
+import java.util.*;
+
+public abstract class Value /*Value:class*/ {
+
+    public static final String $className = "Value";
+    public static Value parse(Scan scn$, Trace trace$) {
+        Token t$ = scn$.cur();
+        Token.Match match$ = t$.match;
+        switch(match$) {
+        case VAR:
+            return VARValue.parse(scn$,trace$);
+        case NUM:
+            return NUMValue.parse(scn$,trace$);
+        default:
+            throw new PLCCException(
+                "Parse error",
+                "Value cannot begin with " + t$.errString()
+            );
+        }
+    }
+
+    abstract public int eval();
+
+//Value//
+}

BIN
344/arro/Java/_Start.class


+ 16 - 0
344/arro/Java/_Start.java

@@ -0,0 +1,16 @@
+public abstract class _Start {
+
+    public static _Start parse(Scan scn, Trace trace) {
+        return Program.parse(scn, trace);
+    }
+
+    public void $run() {
+        System.out.println(this.toString());
+    }
+
+    public void $ok() {
+        System.out.println("OK");
+    }
+
+}
+

+ 98 - 33
344/arro/arro.plcc

@@ -1,49 +1,114 @@
 skip WHITESPACE '\s+'
 
-token NUM           '[0-9]+'
-token VAR           '[A-Za-z_][A-Za-z0-9_]*'
+token NUM    '[0-9]+'
+token VAR    '[A-Za-z_][A-Za-z0-9_]*'
+token OP     '\+|-'
+token MOP    '\*|/'
+token IN     '==>'
+token OUT    '<=='
+token ASSIGN '->'
+token SEMI   ';'
 
-token OP            '\+|-'
-token MOP           '\*|/'
-
-token IN            '==>'
-token OUT           '<=='
-token ASSIGN         '->'
+%
 
-token LOOP          '\?\?'
-token IF             '\?'
-token ELSE           '\|'
+<program>  ::= <stmtlist>
+<stmtlist> **= <stmt>
 
-token LPAREN        '\('
-token RPAREN        '\)'
-token LBRACE        '\{'
-token RBRACE        '\}'
-token SEMI          ';'
+<stmt>InputStmt  ::= <IN> <VAR> <SEMI>
+<stmt>OutputStmt ::= <OUT> <exp> <SEMI>
+<stmt>AssignStmt ::= <VAR> <ASSIGN> <exp> <SEMI>
 
-token OP '\+|-'
-token MOP '\*|/'
+<exp>      ::= <mult> <exprest>
+<exprest>  **= <OP> <mult>
+<mult>     ::= <value> <multrest>
+<multrest> **= <MOP> <value>
+<value>NUMValue ::= <NUM>
+<value>VARValue ::= <VAR>
 
 %
 
-<program> ::= <stmtlist>
+Program:import
+%%%
+import java.util.*;
+%%%
 
-<stmtlist> **= <stmt>
+Program
+%%%
+  public static Map<String, Integer> hshmap = new HashMap<>();
+  public static Scanner scanner = new Scanner(System.in);
 
-<stmt>InputStmt ::= <IN> <VAR> <SEMI>
-<stmt>OutputStmt ::= <OUT> <exp> <SEMI>
-<stmt>AssignStmt ::= <VAR> <ASSIGN> <exp> <SEMI>
+  public void $run() { stmtlist.execute(); }
+%%%
 
-<stmt>ControlStmt ::= <LPAREN> <exp> <RPAREN> <ctrltail>
+Stmtlist
+%%%
+  public void execute() {
+    for (Stmt s : stmtList) s.execute();
+  }
+%%%
 
-<ctrltail>IfStmt ::= <IF> <block> <ELSE> <block>
-<ctrltail>LoopStmt ::= <LOOP> <block>
+Stmt
+%%%
+  abstract public void execute();
+%%%
 
-<block> ::= <LBRACE> <stmtlist> <RBRACE>
+InputStmt
+%%%
+  public void execute() {
+    System.out.print("? ");
+    Program.hshmap.put(var.toString(), Program.scanner.nextInt());
+  }
+%%%
 
-<exp> ::= <mult> <exprest>
-<exprest> **= <OP> <mult>
-<mult> ::= <value> <multrest>
-<multrest> **= <MOP> <value>
-<value> ::= <NUM> | <VAR>
+OutputStmt
+%%%
+  public void execute() { System.out.println(exp.compute()); }
+%%%
 
-%
+AssignStmt
+%%%
+  public void execute() { Program.hshmap.put(var.toString(), exp.compute()); }
+%%%
+
+Exp
+%%%
+  public int compute() {
+    int v = mult.compute();
+    for (int i = 0; i < exprest.opList.size(); i++)
+      v += exprest.opList.get(i).toString().equals("+")
+           ? exprest.multList.get(i).compute()
+           : -exprest.multList.get(i).compute();
+    return v;
+  }
+%%%
+
+Mult
+%%%
+  public int compute() {
+    int v = value.compute();
+    for (int i = 0; i < multrest.mopList.size(); i++)
+      v = multrest.mopList.get(i).toString().equals("*")
+          ? v * multrest.valueList.get(i).compute()
+          : v / multrest.valueList.get(i).compute();
+    return v;
+  }
+%%%
+
+Value
+%%%
+  abstract public int compute();
+%%%
+
+NUMValue
+%%%
+  public int compute() { return Integer.parseInt(num.toString()); }
+%%%
+
+VARValue
+%%%
+  public int compute() {
+    if (!Program.hshmap.containsKey(var.toString()))
+      throw new RuntimeException("Undefined variable: " + var);
+    return Program.hshmap.get(var.toString());
+  }
+%%%

+ 4 - 0
344/arro/sample.plcc

@@ -0,0 +1,4 @@
+==> x ;
+==> y ;
+z -> x * 2 + y ;
+<== z ;