A Very Simple Example Scanner
付録の Scanner の例を bison マニュアルの中間記法電卓で確認
CUP ファイルは、
import java_cup.runtime.*; terminal SEMI, PLUS, MINUS, TIMES, DIVIDE, MOD, EXPON, EOL, LPAREN, RPAREN; terminal UMINUS; terminal Integer NUMBER; non terminal Object input, line; non terminal Integer exp; precedence left MINUS, PLUS; precedence left TIMES, DIVIDE; precedence left UMINUS; precedence right EXPON; input ::= | input line ; line ::= EOL | exp:e EOL {: System.out.println("\t" + e); :} | error EOL ; exp ::= NUMBER:n {: RESULT = n; :} | exp:e1 PLUS exp:e2 {: RESULT = new Integer(e1.intValue() + e2.intValue()); :} | exp:e1 MINUS exp:e2 {: RESULT = new Integer(e1.intValue() - e2.intValue()); :} | exp:e1 TIMES exp:e2 {: RESULT = new Integer(e1.intValue() * e2.intValue()); :} | exp:e1 DIVIDE exp:e2 {: RESULT = new Integer(e1.intValue() / e2.intValue()); :} | MINUS exp:e {: RESULT = new Integer(-e.intValue()); :} %prec UMINUS | exp:e1 EXPON exp:e2 {: RESULT = new Integer((int)Math.pow(e1.doubleValue(), e2.doubleValue())); :} | LPAREN exp:e RPAREN {: RESULT = e; :} ;
Java ファイル(scanner クラス)は、
import java_cup.runtime.*; public class scanner implements Scanner { /* single lookahead character */ protected static int next_char; /* advance input by one character */ protected static void advance() throws java.io.IOException { next_char = System.in.read(); } /* initialize the scanner */ public static void init() throws java.io.IOException { advance(); } /* recognize and return the next complete token */ public Symbol next_token() throws java.io.IOException { for (;;) switch (next_char) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* parse a decimal integer */ int i_val = 0; do { i_val = i_val * 10 + (next_char - '0'); advance(); } while (next_char >= '0' && next_char <= '9'); return new Symbol(sym.NUMBER, new Integer(i_val)); case ';': advance(); return new Symbol(sym.SEMI); case '+': advance(); return new Symbol(sym.PLUS); case '-': advance(); return new Symbol(sym.MINUS); case '*': advance(); return new Symbol(sym.TIMES); case '/': advance(); return new Symbol(sym.DIVIDE); case '%': advance(); return new Symbol(sym.MOD); case '^': advance(); return new Symbol(sym.EXPON); case '(': advance(); return new Symbol(sym.LPAREN); case ')': advance(); return new Symbol(sym.RPAREN); case '\n':advance(); return new Symbol(sym.EOL); case -1: return new Symbol(sym.EOF); default: /* in this simple scanner we just ignore everything else */ advance(); break; } } };
Java ファイルは、
import java.io.*; class Main { static public void main(String argv[]) { parser p; try { p = new parser(new scanner()); Object result = p.parse().value; } catch (Exception e) { e.printStackTrace(); } } }
で、
4 + 5 - (34/(8*3+-3)) -56 + 2 3 ^ 2
を標準入力から入力すると、
8 -54 9