文法を一日ででっち上げる

やっぱり 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