public class Token {
public static final int EOF = -1, NL = 0, IDENT = 1, ICONST = 2,
STR = 3, LPAR = 4, RPAR = 5, LBRA = 6, RBRA = 7, SEMI = 7,
ASSIGN = 8, PLUS = 9, MINUS = 10, ASTER = 11, SLASH = 12,
WHILE = 13, IF = 14, READ = 15, PRINT = 16;
}
%%
%class Lexer
%int
L = [A-Za-z_]
D = [0-9]
Ident = {L}({L}|{D})*
Iconst = [-+]?{D}+
String = \"(\\\"|.)*\"
Newline = \n
Blank = [ \t]+
%%
\= { return Token.ASSIGN; }
\+ { return Token.PLUS; }
\- { return Token.MINUS; }
\* { return Token.ASTER; }
\/ { return Token.SLASH; }
\; { return Token.SEMI; }
\( { return Token.LPAR; }
\) { return Token.RPAR; }
\{ { return Token.LBRA; }
\} { return Token.RBRA; }
while { return Token.WHILE; }
if { return Token.IF; }
read { return Token.READ; }
print { return Token.PRINT; }
{Ident} { return Token.IDENT; }
{Iconst} { return Token.ICONST; }
{String} { return Token.STR; }
{Newline} { return Token.NL; }
{Blank} { /* ignore */ }
import java.util.*;
public class Tree {
public static Map<String,Integer> vars = new TreeMap<String,Integer>();
public abstract static class Node {
List<Node> child = new ArrayList<Node>();
public void add(Node n) { child.add(n); }
public abstract int eval();
}
public static class Lit extends Node {
int val;
public Lit(int v) { val = v; }
public int eval() { return val; }
public String toString() { return ""+val; }
}
public static class Var extends Node {
String name;
public Var(String n) { name = n; }
public int eval() { return vars.get(name); }
public String toString() { return name; }
}
public abstract static class BinOp extends Node {
String op;
public BinOp(String o, Node n1, Node n2) { op = o; add(n1); add(n2); }
public String toString() { return "("+child.get(0)+op+child.get(1)+")"; }
}
public static class Add extends BinOp {
public Add(Node n1, Node n2) { super("+", n1, n2); }
public int eval() { return child.get(0).eval() + child.get(1).eval(); }
}
public static class Sub extends BinOp {
public Sub(Node n1, Node n2) { super("-", n1, n2); }
public int eval() { return child.get(0).eval() - child.get(1).eval(); }
}
public static class Mul extends BinOp {
public Mul(Node n1, Node n2) { super("+", n1, n2); }
public int eval() { return child.get(0).eval() * child.get(1).eval(); }
}
public static class Div extends BinOp {
public Div(Node n1, Node n2) { super("/", n1, n2); }
public int eval() { return child.get(0).eval() / child.get(1).eval(); }
}
public static class Mod extends BinOp {
public Mod(Node n1, Node n2) { super("%", n1, n2); }
public int eval() { return child.get(0).eval() % child.get(1).eval(); }
}
public static class Eq extends BinOp {
public Eq(Node n1, Node n2) { super("==", n1, n2); }
public int eval() { return child.get(0).eval()==child.get(1).eval()?1:0; }
}
public static class Ne extends BinOp {
public Ne(Node n1, Node n2) { super("!=", n1, n2); }
public int eval() { return child.get(0).eval()!=child.get(1).eval()?1:0; }
}
public static class Gt extends BinOp {
public Gt(Node n1, Node n2) { super(">", n1, n2); }
public int eval() { return child.get(0).eval()>child.get(1).eval()?1:0; }
}
public static class Ge extends BinOp {
public Ge(Node n1, Node n2) { super(">=", n1, n2); }
public int eval() { return child.get(0).eval()>=child.get(1).eval()?1:0; }
}
public static class Lt extends BinOp {
public Lt(Node n1, Node n2) { super("<", n1, n2); }
public int eval() { return child.get(0).eval()<child.get(1).eval()?1:0; }
}
public static class Le extends BinOp {
public Le(Node n1, Node n2) { super("<=", n1, n2); }
public int eval() { return child.get(0).eval()<=child.get(1).eval()?1:0; }
}
public static class And extends BinOp {
public And(Node n1, Node n2) { super("&&", n1, n2); }
public int eval() {
int v = child.get(0).eval();
if(v == 0) { return 0; } else { return child.get(1).eval(); }
}
}
public static class Or extends BinOp {
public Or(Node n1, Node n2) { super("||", n1, n2); }
public int eval() {
int v = child.get(0).eval();
if(v != 0) { return v; } else { return child.get(1).eval(); }
}
}
public abstract static class UniOp extends Node {
String op;
public UniOp(String o, Node n1) { op = o; add(n1); }
public String toString() { return "("+op+child.get(0)+")"; }
}
public static class Not extends UniOp {
public Not(Node n1) { super("!", n1); }
public int eval() { return child.get(0).eval()==0?1:0; }
}
public static class Assign extends Node {
Var v1; Node n1;
public Assign(Var v, Node n) { v1 = v; n1 = n; }
public int eval() {
int v = n1.eval(); vars.put(v1.toString(), v); return v;
}
public String toString() { return v1+"="+n1; }
}
public static class Seq extends Node {
public Seq(Node... a) { for(Node n:a) { child.add(n); } }
public int eval() {
int v = 0;
for(Node n:child) { v = n.eval(); }
return v;
}
public String toString() {
String s = "{\n";
for(Node n:child) { s += n.toString() + ";\n"; }
return s + "}";
}
}
public static class Read extends Node {
Var v1;
public Read(Var v) { v1 = v; }
public int eval() {
System.out.print(v1+"? ");
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
int i = Integer.parseInt(str);
vars.put(v1.toString(), i); return i;
}
public String toString() { return "read "+v1; }
}
public static class Print extends Node {
public Print(Node n1) { child.add(n1); }
public int eval() {
int v = child.get(0).eval(); System.out.println(v); return v;
}
public String toString() { return "print "+child.get(0); }
}
public static class While extends Node {
public While(Node n1, Node n2) { child.add(n1); child.add(n2); }
public int eval() {
int v = 0;
while(child.get(0).eval() != 0) { v = child.get(1).eval(); }
return v;
}
public String toString() {
return "while("+child.get(0)+")"+child.get(1);
}
}
public static class If1 extends Node {
public If1(Node n1, Node n2) { child.add(n1); child.add(n2); }
public int eval() {
int v = 0;
if(child.get(0).eval() != 0) { v = child.get(1).eval(); }
return v;
}
public String toString() { return "if("+child.get(0)+")"+child.get(1); }
}
}
import java.util.*;
import java.io.*;
public class Sam71 {
static Tokenizer tok;
public static void main(String[] args) throws Exception {
tok = new Tokenizer(args[0]);
Tree.Node n = prog();
if(n != null) { System.out.println(n.toString()); n.eval(); }
}
static Tree.Node prog() {
Tree.Seq n1 = new Tree.Seq();
while(!tok.chk(Token.RBRA) && !tok.chk(Token.EOF)) {
Tree.Node n2 = stat();
if(n2 != null) { n1.add(n2); continue; }
System.err.printf("%d: error stat at: %s\n", tok.curLine(), tok.curStr());
return null;
}
return n1;
}
static Tree.Node stat() {
if(tok.chk(Token.IDENT)) {
Tree.Var n1 = new Tree.Var(tok.curStr()); tok.fwd();
boolean b1 = tok.chkfwd(Token.ASSIGN);
Tree.Node n2 = expr();
boolean b2 = tok.chkfwd(Token.SEMI);
if(b1 && n2 != null) { return new Tree.Assign(n1, n2); }
} else if(tok.chkfwd(Token.READ)) {
Tree.Var n1 = null;
if(tok.chk(Token.IDENT)) { n1 = new Tree.Var(tok.curStr()); tok.fwd(); }
if(n1 != null && tok.chkfwd(Token.SEMI)) { return new Tree.Read(n1); }
} else if(tok.chkfwd(Token.PRINT)) {
Tree.Node n1 = expr();
if(n1 != null && tok.chkfwd(Token.SEMI)) { return new Tree.Print(n1); }
} else if(tok.chkfwd(Token.IF)) {
boolean b1 = tok.chkfwd(Token.LPAR);
Tree.Node n1 = expr();
boolean b2 = tok.chkfwd(Token.RPAR);
Tree.Node n2 = stat();
if(b1 && n1 != null && b2 && n2 != null) { return new Tree.If1(n1,n2); }
} else if(tok.chkfwd(Token.WHILE)) {
boolean b1 = tok.chkfwd(Token.LPAR);
Tree.Node n1 = expr();
boolean b2 = tok.chkfwd(Token.RPAR);
Tree.Node n2 = stat();
if(b1 && n1!=null && b2 && n2!=null) { return new Tree.While(n1, n2); }
} else if(tok.chkfwd(Token.LBRA)) {
Tree.Node n1 = prog();
if(tok.chkfwd(Token.RBRA)) { return n1; }
}
System.err.printf("%d: error stat at: %s\n", tok.curLine(), tok.curStr());
return null;
}
static Tree.Node expr() {
Tree.Node n = term();
while(n != null && !tok.chk(Token.RPAR) && !tok.chk(Token.SEMI)) {
if(tok.chkfwd(Token.PLUS)) {
Tree.Node n1 = term(); n = (n1 == null) ? null : new Tree.Add(n, n1);
} else if(tok.chkfwd(Token.MINUS)) {
Tree.Node n1 = term(); n = (n1 == null) ? null : new Tree.Sub(n, n1);
} else {
n = null;
}
}
if(n != null) { return n; }
System.err.printf("%d: error expr at: %s\n",tok.curLine(),tok.curStr());
return null;
}
static Tree.Node term() {
Tree.Node n = fact();
while(n != null && !tok.chk(Token.RPAR) && !tok.chk(Token.SEMI) &&
!tok.chk(Token.PLUS) && !tok.chk(Token.MINUS)) {
if(tok.chkfwd(Token.ASTER)) {
Tree.Node n1 = term(); n = (n1 == null) ? null : new Tree.Mul(n, n1);
} else if(tok.chkfwd(Token.SLASH)) {
Tree.Node n1 = term(); n = (n1 == null) ? null : new Tree.Div(n, n1);
} else {
n = null;
}
}
if(n != null) { return n; }
System.err.printf("%d: error term at: %s\n",tok.curLine(),tok.curStr());
return null;
}
static Tree.Node fact() {
if(tok.chk(Token.IDENT)) {
Tree.Node n = new Tree.Var(tok.curStr()); tok.fwd(); return n;
} else if(tok.chk(Token.ICONST)) {
Tree.Node n = new Tree.Lit(Integer.parseInt(tok.curStr()));
tok.fwd(); return n;
} else if(tok.chkfwd(Token.LPAR)) {
Tree.Node n = expr();
if(tok.chkfwd(Token.RPAR)) { return n; }
System.err.printf("%d: no closing ')'\n", tok.curLine());
return null;
}
System.err.printf("%d: error term at: %s\n", tok.curLine(), tok.curStr());
return null;
}
}
class Tokenizer {
Lexer lex;
int tok, line = 1;
boolean eof = false;
public Tokenizer(String s) throws Exception {
lex = new Lexer(new FileReader(s));
tok = lex.yylex();
}
public boolean isEof() { return tok == Lexer.YYEOF; }
public int curTok() { return tok; }
public String curStr() { return lex.yytext(); }
public int curLine() { return line; }
public boolean chk(int t) { return tok == t; }
public void fwd() {
if(isEof()) { return; }
try {
tok = lex.yylex();
while(tok == Token.NL) { ++line; tok = lex.yylex(); }
} catch(IOException ex) { tok = Lexer.YYEOF; }
}
public boolean chkfwd(int t) {
if(chk(t)) { fwd(); return true; } else { return false; }
}
}
read x;
while(x) {
if(x - 5) { print x; }
x = x - 1;
}