/** * オプションの指定 */ options { LOOKAHEAD = 1; // 先読みトークン数 STATIC = false; // true にするとスタティックメソッドを生成 UNICODE_INPUT = true; // true にすると Unicode 入力を扱う DEBUG_PARSER = false; // true にするとデバグ情報出力 } /** * 作成する構文解析クラスの定義 * PARSER_BEGIN (クラス名) * と * PARSER_END (クラス名) * の間に作成するクラスの main メソッドを記述する。 */ PARSER_BEGIN (ParserCode) package kc; import java.util.*; import java.io.*; /** * Macro statements are as follows : *
::= "main" "(" ")" "{" { | } "}" EOF * ::= "int" { "," } ";" * ::= NAME * ::= | | | | "{" { } "}" * ::= "if" "(" ")" * ::= "while" "(" ")" * ::= "outputint" "(" ")" ";" * ::= Name "=" ";" * ::= { ( "+" | "-" ) } * ::= { ( "*" | "/" ) } * ::= NAME | INTEGER | "inputint" * * Execute as follows : * $ javac kc/ParserCode.java * $ java kc.ParserCode inputfile */ public class ParserCode { static VarTable varTable; // 変数表 static PseudoIseg iseg; // 疑似ISEG public static void main (String[] args) { varTable = new VarTable(); iseg = new PseudoIseg(); try { ParserCode parser = new ParserCode (new FileReader (args[0])); parser.enable_tracing(); // デバグ情報収集 parser.Main(); } catch (Exception err_mes) { // 構文エラーがあった場合 System.out.println (err_mes); // エラーメッセージを出力 } iseg.dump2file(); // アセンブラコード出力 System.out.println ("finished"); } } PARSER_END (ParserCode) /** * 字句解析時変数の宣言 * 字句解析時に必要な変数があればここで宣言する。 */ TOKEN_MGR_DECLS : {} /** * 空白文字の定義 * 空白文字は * SKIP : * { * <パターン> * } * の形で定義され、パターンには正規表現を用いることができる。 */ SKIP : { <" " | "\t" | "\n" | "\r"> | <"//" (~["\n", "\r"])* ["\n","\r"]> | <"/*"> : IN_COMMENT } SKIP : { <~[]> | <"*/"> : DEFAULT } /** * トークンの定義 * トークンは * TOKEN : * { * <トークン名: パターン> * } * の形で定義され、パターンには正規表現を用いることができる。 */ TOKEN : { | | | | | | | | | | | | | | | | | } /** *
::= "main" "(" "{" { } { } "}" */ void Main() : {} { "main" "(" ")" "{" ( Decl() )* ( State() )* "}" { iseg.appendCode (Operator.HALT); } } /** * ::= "int" { "," } */ void Decl() : {} { "int" Name() ( "," Name() )*";" } /** * ::= NAME */ void Name() : { String name; } { token = { name = token.image; varTable.registerNewVariable (Type.INT, name, 1); } } /** * ::= { | | | | "{" { } "} } */ void State() : {} { If() | While() | Output() | Assgn() | "{" ( State() )* "}" } /** * ::= "if" "(" ")" */ void If() : { int beqAddr, nextAddr; } { "if" "(" Exp() { beqAddr = iseg.appendCode (Operator.BEQ); } ")" State() { nextAddr = iseg.getLastCodeAddress() + 1; iseg.replaceCode (beqAddr, nextAddr); } } /** * ::= "while" "(" ")" */ void While() : { int expAddr, beqAddr, nextAddr; } { "while" "(" { expAddr = iseg.getLastCodeAddress() + 1; } Exp() { beqAddr = iseg.appendCode (Operator.BEQ); } ")" State() { nextAddr = iseg.appendCode (Operator.JUMP, expAddr) + 1; iseg.replaceCode (beqAddr, nextAddr); } } /** * ::= "outputint" "(" ")" ; */ void Output() : {} { "outputint" "(" Exp() { iseg.appendCode (Operator.OUTPUT); } ")" ";" } /** * ::= NAME "=" ";" */ void Assgn() : { String name; int addr; } { token = { name = token.image; addr = varTable.getAddress(name); iseg.appendCode (Operator.PUSHI, addr); } "=" Exp() { iseg.appendCode (Operator.ASSGN); } ";" { iseg.appendCode (Operator.REMOVE); } } /** * ::= { ( "+" | "-" ) } */ void Exp() : { Operator opcode; } { Term() ( ( "+" { opcode = Operator.ADD; } | "-" { opcode = Operator.SUB; } ) Term() { iseg.appendCode (opcode); } )* } /** * ::= { ( "*" | "/" ) } */ void Term() : { Operator opcode; } { Factor() ( ( "*" { opcode = Operator.MUL; } | "/" { opcode = Operator.DIV; } ) Factor() { iseg.appendCode (opcode); } )* } /** * ::= NAME | INTEGER | "inputint" */ void Factor() : { int val, addr; String name; } { token = { name = token.image; addr = varTable.getAddress (name); iseg.appendCode (Operator.PUSH, addr); } | token = { val = Integer.parseInt (token.image); iseg.appendCode (Operator.PUSHI, val); } | "inputint" { iseg.appendCode (Operator.INPUT); } }