文法を一日ででっち上げる
やっぱり yacc は書いてて楽しいね。LR だと LL よりも素直にかけてストレスが少ない。
微調整は必要だと思うけど、まあ追々直していこう。
%{ package caitsith.parser; import java.io.*; public class Parser { %} // 構造キーワード %token ACTOR, PROCEDURE, VAR, IS, END // 制御構造キーワード %token IF, THEN, ELSE, FOR, WHILE, DO, TRY, CATCH, FINALLY, SWITCH, CASE, ASSERT // 制御構文キーワード %token INC, DEC, BREAK, CONTINUE, THROW // 演算子 %right ASSIGN, ASSIGN_ADD, ASSIGN_SUB, ASSIGN_MUL, ASSIGN_DIV, ASSIGN_MOD %right QUESTION, COLON %left OR %left XOR %left AND %nonassoc EQ, NEQ %nonassoc LT, LTEQ, GT, GTEQ %left IFNULL %left PLUS, MINUS %left MUL, DIV, MOD %right NEG, NOT, NEW %token DOT, RIGHT_ARROW, RIGHT_DOUBLEARROW // 記号 %token LP, RP, LB, RB, LBT, RBT, LST_LBT, MAP_LBT, SET_LBT %token COMMA, SEMICOLON // 変数 %token NAME, SELF, FIELD, JAVANAME // リテラル %token SYMBOL, NUMBER, STRING, CHAR, NULL, VOID, TRUE, FALSE // その他 %token EOF %% compilationUnit: defActorList EOF ; // アクタの定義 defActorList: | defActor defActorList ; defActor: ACTOR fullname defArgument IS defProcedureListOpt END ; defArgument: | LP RP | LP fieldList RP ; defProcedureListOpt: | defProcedureListOpt defProcedure ; defProcedure: PROCEDURE patternList IS stmtListOpt END ; // 文の定義 stmtListOpt: | stmtList ; stmtList: stmt | stmtList stmt ; stmt: name COLON stmt | SEMICOLON | expr SEMICOLON | exprAssign SEMICOLON | expr exprList SEMICOLON | INC variable SEMICOLON | DEC variable SEMICOLON | INC variable COMMA expr SEMICOLON | DEC variable COMMA expr SEMICOLON | BREAK SEMICOLON | BREAK name SEMICOLON | CONTINUE SEMICOLON | CONTINUE name SEMICOLON | THROW SEMICOLON | THROW expr SEMICOLON | IF expr THEN stmtList END | IF expr THEN stmtList ELSE stmtList END | FOR name ASSIGN expr DO stmtList END | FOR name ASSIGN expr DO stmtList ELSE stmtList END | WHILE expr DO stmtList END | WHILE expr DO stmtList ELSE stmtList END | TRY stmtList CATCH name DO stmtList END | TRY stmtList FINALLY stmtList END | TRY stmtList CATCH name DO stmtList FINALLY stmtList END | SWITCH expr caseList | ASSERT expr SEMICOLON | ASSERT expr ELSE stmtList END ; caseList: caseBody | caseList caseBody ; caseBody: CASE pattern THEN stmtList END ; // 式の定義 exprAssign: variable ASSIGN expr | variable ASSIGN_ADD expr | variable ASSIGN_SUB expr | variable ASSIGN_MUL expr | variable ASSIGN_DIV expr | variable ASSIGN_MOD expr ; exprList: expr | exprList expr ; expr: term | NEG expr | NOT expr | expr MUL expr | expr DIV expr | expr MOD expr | expr PLUS expr | expr MINUS expr | expr IFNULL expr | expr EQ expr | expr NEQ expr | expr LT expr | expr LTEQ expr | expr GT expr | expr GTEQ expr | expr AND expr | expr XOR expr | expr OR expr | expr QUESTION expr COLON expr ; term: variable | SELF | primitive | LP expr RP | LST_LBT listElementOpt RBT | MAP_LBT mapElementOpt RBT | SET_LBT listElementOpt RBT | term RIGHT_ARROW name | term DOT name LP listElementOpt RP | term LBT expr RBT | NEW fullname LP listElementOpt RP | NEW javafullname LP listElementOpt RP ; listElementOpt: | listElement ; mapElementOpt: | mapElement ; listElement: expr | listElement COMMA expr ; mapElement: expr RIGHT_DOUBLEARROW expr | mapElement COMMA expr RIGHT_DOUBLEARROW expr ; // 変数の定義 variable: name | field | javaname ; fullname: name | fullname DOT name ; name: NAME ; fieldList: field | fieldList field ; field: FIELD ; javafullname: javaname | javafullname DOT name ; javaname: JAVANAME ; // パターンの定義 patternList: pattern | patternList pattern ; pattern: primitive | name | wildcard | LST_LBT patternListElementOpt RBT | MAP_LBT patternMapElementOpt RBT | SET_LBT patternListElementOpt RBT ; patternListElementOpt: | patternListElement ; patternMapElementOpt: | patternMapElement ; patternListElement: pattern | patternListElement COMMA pattern ; patternMapElement: pattern RIGHT_DOUBLEARROW pattern | patternMapElement COMMA pattern RIGHT_DOUBLEARROW pattern ; wildcard: QUESTION ; // プリミティブの定義 primitive: SYMBOL | NUMBER | STRING | CHAR | NULL | VOID | TRUE | FALSE ; %% public static void main(String[] args) throws IOException { FileReader source = new FileReader(args[0] ); Scanner scanner = new Scanner(source); Parser yyparser = new Parser(); try { yyparser.yyparse(scanner); } catch (Parser.yyException ye) { System.out.println(ye); } } }
78 terminals, 35 nonterminals
129 grammar rules, 263 states