/** ** Interpreter (JJTree & Visitor) **/ options { STATIC=false; UNICODE_INPUT=true; DEBUG_PARSER=true; MULTI=true; VISITOR=true; } PARSER_BEGIN(IntVParser) import java.util.Hashtable; public class IntVParser { Hashtable symTable = new Hashtable(); public int nParseErrors = 0; } PARSER_END(IntVParser) TOKEN_MGR_DECLS : { public int nLexicalErrors = 0; } SKIP : { " " | "\t" // | "\n" | "\r" | "\f" | "|" | "|" | " " } TOKEN : { < ADDOP: "+" | "+" > | < SUBOP: "−" | "-" > | < MULOP: "×" | "*" > | < DIVOP: "÷" | "/" > | < SUROP: "%" | "%" > | < ASGNOP: "←" | ":=" > | < INOP: "->"> | < EQOP: "=" | "=" > | < GTOP: ">" | ">" > | < GEOP: "≧" | ">=" > | < LSOP: "<" | "<" > | < LEOP: "≦" | "<=" > | < NTOP: "≠" | "!=" > | < ANDOP: "かつ" > | < OROP: "または" > | < NOTOP: "でない" > | < LC: "{" > | < RC: "}" > | < LD: "[" > | < RD: "]" > | < LP: "(" > | < RP: ")" > | < SM: "\n" > | < CM: "," | "," | "、" > | < CM2: "と" > | < PN: "." > | < EOF_STR: "EOF" > | < NULL_STR: "NULL" > } TOKEN [IGNORE_CASE] : { < VARINT: "整数" > | < VARFLOAT : "実数" > | < VARSTRING : "文字列" > | < PROCEDURAL : "手続き" > | < ENDPROCEDURAL : "手続き終了" > | < FUNCTION : "関数" > | < ENDFUNCTION : "関数終了" > | < RETURN : "を返す" > | < IF : "もし" > | < ENDIF : "を" ( "実行する" | "実行" ) > | < THEN : ( "ならば" | "なら" ) > | < ELSE : "を実行し" "そうで" ( "なければ" | "ないなら" | "ないならば" ) > | < ELSEIF : "を実行し" ( "そうでなく" | "そうでなくて" ) > | < WHILE : "の間" > | < DOWHILE : ( "繰り返し" | "繰返し" ) > | < DOWHILE2 : "を" > | < DOWHILE3 : "になるまで" ( "実行する" | "実行" ) > | < FOR : "を" > | < FOR2 : "から" > | < FOR3 : "まで" > | < FOR4 : "ずつ" > | < FORADD : "増やし" ( "ながら" | "つつ" ) > | < FORSUB : "減らし" ( "ながら" | "つつ" ) > | < ENDLOOP : "を" ( "繰り返す" | "繰返す" ) > | < PUTLN : "を" ("印刷" | "出力" ) "する" > | < PUT : "を改行" ("なし" | "無し") "で" ("印刷" | "出力" ) "する"> | < GET : "input" > | < RANDOM : "random" > | < SIN : "sin" > | < COS : "cos" > | < TAN : "tan" > | < SQRT : "sqrt" > | < FLOOR : "floor" > | < CEIL : "ceil" > | < ROUND : "round" > | < ABS : "abs" > | < INT : "int" > | < LOG : "log" > | < LENGTH : "length" > | < SUBSTRING : "substring" > | < INSERT : "insert" > | < REPLACE : "replace" > | < EXTRACT : "extract" > | < gWindowOpen : "gWindowOpen" > | < gWindowClose : "gWindowClose" > | < gColor : "gColor" > | < gDrawOval : "gDrawOval" > | < gDrawPoint : "gDrawPoint" > | < gFillOval : "gFillOval" > | < gFillPoint : "gFillPoint" > | < gDrawLine : "gDrawLine" > | < gDrawBox : "gDrawBox" > | < gFillBox : "gFillBox" > | < gDrawArc : "gDrawArc" > | < gFillArc : "gFillArc" > | < OPENR : "openr" > | < OPENW : "openw" > | < OPENA : "opena" > | < CLOSE : "close" > | < GETSTR : "getstr" > | < GETLINE : "getline" > | < PUTSTR : "putstr" > | < PUTLINE : "putline" > | < FLUSH : "flush" > | < ISFILE : "isfile" > | < RENAME : "rename" > | < REMOVE : "remove" > } TOKEN : { < #DIGIT: [ "0"-"9"] > | < #LETTER: [ "a"-"z", "A"-"Z", "_" ] > } TOKEN : { < LITERAL: ()+ > | < FLOAT_LITERAL: ( ) > | < IDENT: (|)* > { int idx; int len = image.length(); if (!Character.isJavaIdentifierStart(image.charAt(0))) { ++nLexicalErrors; new ConsoleAppend( "### " + matchedToken.beginLine + "行目で" + "エラーです : \"" + matchedToken.image.charAt(0) + "\"(" + Integer.toHexString(matchedToken.image.charAt(0)) + ")\n" ); } for (idx = 1; idx < len; ++idx) { if (!Character.isJavaIdentifierPart(image.charAt(idx))) { ++nLexicalErrors; new ConsoleAppend( "### " + matchedToken.beginLine + "行目で" + "エラーです : \"" + matchedToken.image.charAt(idx) + "\"(" + Integer.toHexString(matchedToken.image.charAt(idx)) + ")\n" ); } } } } MORE: { < "\""| "「"> :STR } TOKEN: { < STRLIT: "\"" | "」" |"\r\n" > { if ( (image.charAt(0) == '\"' && image.charAt(image.length()-1) == '\"') || (image.charAt(0) == '「' && image.charAt(image.length()-1) == '」') ){ matchedToken.image = image.substring(1, image.length()-1); }else{ ++nLexicalErrors; matchedToken.image = image.substring(1, image.length()-2); new ConsoleAppend( "### " + matchedToken.beginLine + "行目の" + "出力文で[\"] か[ 」]を忘れていませんか?\n" ); } } :DEFAULT } MORE: { < "\\\"" | "\\」" | "\\「" > { image.deleteCharAt(image.length() - 2); } } MORE: { < "\\n" > { image.delete(image.length() - 2, image.length()); image.append('\n'); } } MORE: { < ~[] > } MORE: { "/*" :COMM } SPECIAL_TOKEN: { < COMMENT: "*/" > :DEFAULT } MORE: { < ~[] > } SKIP : { < ~[] > { ++nLexicalErrors; new ConsoleAppend( "### " + input_stream.getBeginLine() + "行目で" + "エラーです : '" + image + "'\n" ); } } void IntVUnit() : { Token t; } { ( try { VarDecl() | Function() | Stat() | { return; } | ErrorOccur() } catch (ParseException e) { ++nParseErrors; new ConsoleAppend("### " + e.getMessage() + "\n"); throw new ParseException(); do { t = getNextToken(); } while (t.kind != SM && t.kind != RC && t.kind != EOF); } )* } JAVACODE void ErrorOccur() { ParseException e = generateParseException(); throw e; } void Function() : { Token t; } { ( ( { jjtn000.decl = 1; } | { jjtn000.decl = 2; } | { jjtn000.decl = 3; } ) t= [ FunctionVar() ] { jjtn000.line_num1 = jj_consume_token(SM).beginLine; } ( VarDecl() | Stat() )* #Block | { jjtn000.decl = 0; } t= [ FunctionVar() ] { jjtn000.line_num1 = jj_consume_token(SM).beginLine; } ( VarDecl() | Stat() )* #Block ) { jjtn000.line_num2 = jj_consume_token(SM).beginLine; } { if (!symTable.containsKey(t.image)) { symTable.put(t.image, new Object()); jjtThis.varName = t.image; } else { new ConsoleAppend( "### " + t.beginLine + "行目の \"" + t.image + "\" は既に変数として宣言されています\"\n" ); throw new ParseException(); } } } void FunctionVar() : {} { ( { jjtn000.decl = 1; } | { jjtn000.decl = 2; } | { jjtn000.decl = 3; } ) Decl() [ FunctionVar() ] } void VarDecl() : {} { ( { jjtn000.decl = 1; } | { jjtn000.decl = 2; } | { jjtn000.decl = 3; } ) Decl() ( Decl() )* { jjtn000.line_num1 = jj_consume_token(SM).beginLine; } } void Decl() : { Token t; } { t= [ Array() ] { symTable.put(t.image, new Object()); jjtThis.varName = t.image; /* if (!symTable.containsKey(t.image)) { symTable.put(t.image, new Object()); jjtThis.varName = t.image; } else { new ConsoleAppend( "### " + t.beginLine + "行目の \"" + t.image + "\" は既に変数として宣言されています\"\n" ); throw new ParseException(); } */ } } void Array() : {} { AddExpr() [ Array() ] } void Stat() #void : {} { LOOKAHEAD(10) AssignStats() | IfStat() | LOOKAHEAD(10) WhileStat() | RepeatUntil() | LOOKAHEAD(10) ForStat() // | GetStat() | LOOKAHEAD(10) PutStat() | LOOKAHEAD(10) Return() // | Block() | gWindowOpen() | gWindowClose() | gColor() | gDrawOval() | gDrawPoint() | gFillOval() | gFillPoint() | gDrawLine() | gDrawBox() | gFillBox() | gDrawArc() | gFillArc() | File_close() | File_putstr() | File_putline() | File_flush() | File_rename() | File_remove() | FunctionCall() | } void AssignStats() : {} { AssignStat() ( AssignStat() )* {jjtn000.line_num1 = jj_consume_token(SM).beginLine;} } void AssignStat() : {} { Ident() AddExpr() } void IfStat() : {} { Cond() { jjtn000.line_num1 = jj_consume_token(THEN).beginLine; } ( LOOKAHEAD(10) AssignStats() | LOOKAHEAD(10) PutStat() | ( Stat() )* #Block [ ( LOOKAHEAD(2) { jjtn000.line_num2 = jj_consume_token(SM).beginLine; } ( Stat() )* #Block | ElseIfStat() ) ] { jjtn000.line_num3 = jj_consume_token(SM).beginLine; } ) } void ElseIfStat() #IfStat : {} { Cond() { jjtn000.line_num1 = jj_consume_token(THEN).beginLine; } ( Stat() )* #Block [ ( LOOKAHEAD(2) { jjtn000.line_num2 = jj_consume_token(SM).beginLine; } ( Stat() )* #Block | ElseIfStat() ) ] } void WhileStat() : {} { Cond() { jjtn000.line_num1 = jj_consume_token(SM).beginLine; } ( Stat() )* #Block { jjtn000.line_num2 = jj_consume_token(SM).beginLine; } } void RepeatUntil() : {} { { jjtn000.line_num1 = jj_consume_token(SM).beginLine; } ( Stat() )* #Block Cond() { jjtn000.line_num2 = jj_consume_token(SM).beginLine; } } void ForStat() : {} { Ident() AddExpr() AddExpr() ForStatAdd() { jjtn000.line_num1 = jj_consume_token(SM).beginLine; } (Stat())* #Block { jjtn000.line_num2 = jj_consume_token(SM).beginLine; } } void ForStatAdd() : {} { [ AddExpr() ] ( {jjtThis.op = 1;} | {jjtThis.op = -1;} ) } void GetStat() : {} { Ident() { jjtn000.line_num1 = jj_consume_token(SM).beginLine; } } void PutStat() : {} { PutParam() ( PutParam() )* ( | {jjtThis.n = "\n";} ) { jjtn000.line_num1 = jj_consume_token(SM).beginLine; } } void PutParam() #void : {} { AddExpr() // | Strlit() } void Block() : {} { ( Stat() )* } void Cond() #void : {} { ORExpr() } void ORExpr() #void : {} { AndExpr() [ Cond() #ORNode(2) ] } void AndExpr() #void : {} { NotExpr() [ AndExpr() #ANDNode(2) ] } void NotExpr() #void : {} { EqualityExpr() [ #NOTNode(1) ] } void EqualityExpr() #void : {} { RelationalExpr() [ EqualityExpr() #EQNode(2) | EqualityExpr() #NTNode(2) ] } void RelationalExpr() #void : {} { AddExpr() [ RelationalExpr() #LSNode(2) | RelationalExpr() #GTNode(2) | RelationalExpr() #LENode(2) | RelationalExpr() #GENode(2) ] } void AddExpr() #void : {} { MulExpr() ( MulExpr() #AddNode(2) | MulExpr() #SubNode(2) )* } void MulExpr() #void : {} { UnExpr() ( UnExpr() #MulNode(2) | UnExpr() #DivNode(2) | UnExpr() #SurNode(2) )* } void UnExpr() #void : {} { PrimExpr() | UnExpr() #MinNode(1) } void PrimExpr() #void : {} { Literal() | FloatLiteral() | Strlit() | EOF_STR() | FunctionExpr() | Ident() // | FunctionCall() | Cond() } void FunctionExpr() #void : {} { Get() | Random() | Sine() | Cosine() | Tangent() | Sqrt() | Floor() | Ceil() | Round() | Abs() | Log() | Int() | Length() | Substring() | Insert() | Replace() | Extract() | File_openr() | File_openw() | File_opena() | File_getstr() | File_getline() | File_isfile() } void Get() : {} { } void Random() : {} { AddExpr() } void Sine() : {} { AddExpr() } void Cosine() : {} { AddExpr() } void Tangent() : {} { AddExpr() } void Sqrt() : {} { AddExpr() } void Floor() : {} { AddExpr() } void Ceil() : {} { AddExpr() } void Round() : {} { AddExpr() } void Abs() : {} { AddExpr() } void Log() : {} { AddExpr() } void Int() : {} { AddExpr() } void Length() : {} { AddExpr() } void Substring() : {} { AddExpr() AddExpr() [ AddExpr() ] } void Insert() : {} { AddExpr() AddExpr() AddExpr() } void Replace() : {} { AddExpr() AddExpr() AddExpr() AddExpr() } void Extract() : {} { AddExpr() AddExpr() AddExpr() } void gWindowOpen() : {} { AddExpr() AddExpr() {jjtn000.line_num1 = jj_consume_token(SM).beginLine;} } void gWindowClose() : {} { {jjtn000.line_num1 = jj_consume_token(SM).beginLine;} } void gColor() : {} { AddExpr() AddExpr() AddExpr() {jjtn000.line_num1 = jj_consume_token(SM).beginLine;} } void gDrawOval() : {} { AddExpr() AddExpr() AddExpr() AddExpr() {jjtn000.line_num1 = jj_consume_token(SM).beginLine;} } void gDrawPoint() : {} { AddExpr() AddExpr() {jjtn000.line_num1 = jj_consume_token(SM).beginLine;} } void gFillOval() : {} { AddExpr() AddExpr() AddExpr() AddExpr() {jjtn000.line_num1 = jj_consume_token(SM).beginLine;} } void gFillPoint() : {} { AddExpr() AddExpr() {jjtn000.line_num1 = jj_consume_token(SM).beginLine;} } void gDrawLine() : {} { AddExpr() AddExpr() AddExpr() AddExpr() {jjtn000.line_num1 = jj_consume_token(SM).beginLine;} } void gDrawBox() : {} { AddExpr() AddExpr() AddExpr() AddExpr() {jjtn000.line_num1 = jj_consume_token(SM).beginLine;} } void gFillBox() : {} { AddExpr() AddExpr() AddExpr() AddExpr() {jjtn000.line_num1 = jj_consume_token(SM).beginLine;} } void gDrawArc() : {} { AddExpr() AddExpr() AddExpr() AddExpr() AddExpr() AddExpr() AddExpr() {jjtn000.line_num1 = jj_consume_token(SM).beginLine;} } void gFillArc() : {} { AddExpr() AddExpr() AddExpr() AddExpr() AddExpr() AddExpr() AddExpr() {jjtn000.line_num1 = jj_consume_token(SM).beginLine;} } void File_openr() : {} { AddExpr() } void File_openw() : {} { AddExpr() } void File_opena() : {} { AddExpr() } void File_close() : {} { AddExpr() {jjtn000.line_num1 = jj_consume_token(SM).beginLine;} } void File_getstr() : {} { AddExpr() AddExpr() } void File_getline() : {} { AddExpr() } void File_putstr() : {} { AddExpr() AddExpr() {jjtn000.line_num1 = jj_consume_token(SM).beginLine;} } void File_putline() : {} { AddExpr() AddExpr() {jjtn000.line_num1 = jj_consume_token(SM).beginLine;} } void File_flush() : {} { AddExpr() {jjtn000.line_num1 = jj_consume_token(SM).beginLine;} } void File_isfile() : {} { AddExpr() } void File_rename() : {} { AddExpr() AddExpr() {jjtn000.line_num1 = jj_consume_token(SM).beginLine;} } void File_remove() : {} { AddExpr() {jjtn000.line_num1 = jj_consume_token(SM).beginLine;} } void Ident() : { Token t; } { t= [ ArrayNum() | [ AddExpr() ( AddExpr() )* ] { jjtThis.flag = false; } ] { // if (symTable.containsKey(t.image)){ jjtThis.varName = t.image; jjtThis.varName2= t.image; // } else { /* new ConsoleAppend( "### 宣言されていない変数名が" + t.beginLine + "行目で使用されました\n" ); throw new ParseException(); */ // } } } void ArrayNum() : {} { AddExpr() [ ArrayNum() ] } void FunctionCall() : { Token t; } { t= [ AddExpr() ( AddExpr() )* ] {jjtn000.line_num1 = jj_consume_token(SM).beginLine;} { jjtThis.varName = t.image; } } void Return() : {} { AddExpr() {jjtn000.line_num1 = jj_consume_token(SM).beginLine;} } void Literal() : { Token t; } { t= { try { jjtThis.litValue = Integer.parseInt(t.image); } catch (Exception e) { jjtThis.litValue = 0; new ConsoleAppend( "### " + t.beginLine + "行目は無効な値です : " + t.image + "\n" ); throw new ParseException(); } } } void FloatLiteral() : { Token t; } { t= { try { jjtThis.litValue = Double.parseDouble(t.image); } catch (Exception e) { jjtThis.litValue = 0; new ConsoleAppend( "### " + t.beginLine + "行目は無効な値です : " + t.image + "\n" ); throw new ParseException(); } } } void Strlit() : { Token t; } { t= { jjtThis.litString = t.image; } } void EOF_STR() : {} { { jjtn000.char_code = -1; } | { jjtn000.char_code = -2; } }