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", 値);