Package sam94;

Helpers
  digit = ['0'..'9'] ;
  lcase = ['a'..'z'] ;
  ucase = ['A'..'Z'] ;
  letter = lcase | ucase ;

Tokens
  iconst = ('+'|'-'|) digit+ ;
  blank = (' '|13|10)+ ;
  if = 'if' ;
  read = 'read' ;
  print = 'print' ;
  semi = ';' ;
  assign = '=' ;
  plus = '+' ;
  minus = '-' ;
  aster = '*' ;
  slash = '/' ;
  lt = '<' ;
  gt = '>' ;
  lbra = '{' ;
  rbra = '}' ;
  lpar = '(' ;
  rpar = ')' ;
  ident = letter (letter|digit)* ;

Ignored Tokens
  blank;

Productions
  prog = {stlist} stlist
       ;
  stlist = {stat} stlist stat
         | {empty}
         ;
  stat = {assign} ident assign expr semi
       ;
  expr = {gt} [left]:nexp gt [right]:nexp
       | {lt} [left]:nexp lt [right]:nexp
       | {one} nexp
       ;
  nexp = {add} nexp plus term
       | {sub} nexp minus term
       | {one} term
       ;
  term = {mul} term aster fact
       | {div} term slash fact
       | {one} fact
       ;
  fact = {ident}  ident
       | {iconst} iconst
       ;
package sam94;
import sam94.analysis.*;
import sam94.node.*;
import java.io.*;
import java.util.*;

class Executor extends DepthFirstAdapter {
  Scanner sc = new Scanner(System.in);
  PrintStream pr = System.out;
  HashMap<String,Integer> vars = new HashMap<String,Integer>();
  @Override
  public void outAAssignStat(AAssignStat node) {
    int v = (Integer)getOut(node.getExpr());
    String s = node.getIdent().getText();
    pr.printf("%s = %d\n", s, v);
    vars.put(s, v);
  }
  @Override
  public void outAGtExpr(AGtExpr node) {
    int x = (Integer)getOut(node.getLeft());
    int y = (Integer)getOut(node.getRight());
    setOut(node, new Integer((x > y) ? 1 : 0));
  }
  @Override
  public void outALtExpr(ALtExpr node) {
    int x = (Integer)getOut(node.getLeft());
    int y = (Integer)getOut(node.getRight());
    setOut(node, new Integer((x < y) ? 1 : 0));
  }
  @Override
  public void outAOneExpr(AOneExpr node) {
    setOut(node, getOut(node.getNexp()));
  }
  @Override
  public void outAAddNexp(AAddNexp node) {
    int x = (Integer)getOut(node.getNexp());
    int y = (Integer)getOut(node.getTerm());
    setOut(node, new Integer(x+y));
  }
  @Override
  public void outASubNexp(ASubNexp node) {
    int x = (Integer)getOut(node.getNexp());
    int y = (Integer)getOut(node.getTerm());
    setOut(node, new Integer(x-y));
  }
  @Override
  public void outAOneNexp(AOneNexp node) {
    setOut(node, getOut(node.getTerm()));
  }
  @Override
  public void outAMulTerm(AMulTerm node) {
    int x = (Integer)getOut(node.getTerm());
    int y = (Integer)getOut(node.getFact());
    setOut(node, new Integer(x*y));
  }
  @Override
  public void outADivTerm(ADivTerm node) {
    int x = (Integer)getOut(node.getTerm());
    int y = (Integer)getOut(node.getFact());
    setOut(node, new Integer(x/y));
  }
  @Override
  public void outAOneTerm(AOneTerm node) {
    setOut(node, getOut(node.getFact()));
  }
  @Override
  public void outAIdentFact(AIdentFact node) {
    Object o = vars.get(node.getIdent().getText());
    if(o == null) { o = new Integer(0); }
    setOut(node, o);
  }
  @Override
  public void outAIconstFact(AIconstFact node) {
    setOut(node, new Integer(node.getIconst().getText()));
  }
}
package sam94;
import sam94.parser.*;
import sam94.lexer.*;
import sam94.node.*;
import java.io.*;
import java.util.*;

public class Sam94 {
  public static void main(String[] args) throws Exception {
    Parser p = new Parser(new Lexer(new PushbackReader(
      new InputStreamReader(new FileInputStream(args[0])), 1024)));
    Start tree = p.parse();
    tree.apply(new Executor());
  }
}
% sablecc sam94.grammer
...
% javac sam94/Sam94.java
...
% cat test.min
x = 10;
y = x * 3;
% java sam94.Sam94 test.min
x = 10
y = 30
 pr.printf("> "); int x = sc.nextInt(); sc.nextLine();
 (変数の値としてvarsに書き込む)
 (式の値を取得する)
 pr.printf("%d\n", 値);