2
|
1 %skeleton "lalr1.cc"
|
|
2 %define "parser_class_name" "script_parser"
|
|
3 %defines
|
|
4 %{
|
|
5 #ifdef _MSC_VER
|
|
6 #pragma warning(disable: 4800)
|
|
7 #pragma warning(disable: 4267)
|
|
8 #endif
|
|
9
|
|
10 #include <string>
|
|
11 #include "node.h"
|
|
12 class compiler;
|
|
13 %}
|
|
14 // The parsing context.
|
|
15 %parse-param { compiler& driver }
|
|
16 %lex-param { compiler& driver }
|
|
17 %locations
|
|
18 //%expect 7
|
|
19 %initial-action
|
|
20 {
|
|
21 // ロケーション初期化
|
|
22 @$.begin.filename = @$.end.filename = &driver.get_filename();
|
|
23 };
|
|
24 // %debug
|
|
25 %error-verbose
|
|
26 // Symbols.
|
|
27 %union
|
|
28 {
|
|
29 int ival;
|
|
30 std::string *sval;
|
|
31
|
|
32 CArgs *args;
|
|
33 CNode *expr;
|
|
34 CAssign *assign;
|
|
35 }
|
|
36 %{
|
|
37 #include "compiler.h"
|
|
38 %}
|
|
39
|
|
40 %token END_OF_FILE 0 "end of file"
|
|
41 %token <ival> TK_IVAL "ival"
|
|
42 %token <sval> TK_IDENTIFIER "identifier"
|
|
43 %token TK_EQ "=="
|
|
44 %token TK_NE "!="
|
|
45 %token TK_GE ">="
|
|
46 %token TK_LE "<="
|
|
47 %token TK_NEWLINE "\n"
|
|
48
|
|
49 %token TK_IF "if"
|
|
50 %token TK_THEN "then"
|
|
51 %token TK_ELSE "else"
|
|
52 %token TK_ENDIF "endif"
|
|
53 %token TK_FOR "for"
|
|
54 %token TK_TO "to"
|
|
55 %token TK_NEXT "next"
|
|
56 %token TK_WHILE "while"
|
|
57 %token TK_WEND "wend"
|
|
58 %token TK_END "end"
|
|
59 %token TK_RAND "rand"
|
|
60 %token TK_PRINT "print"
|
|
61
|
|
62 %type <expr> expr
|
|
63 %type <expr> comp_expr
|
|
64 %type <expr> value
|
|
65 %type <assign> assign
|
|
66 %type <args> args
|
|
67
|
|
68 %destructor { delete $$; } "identifier"
|
|
69
|
|
70 %destructor { delete $$; } args
|
|
71 %destructor { delete $$; } assign
|
|
72 %destructor { delete $$; } value
|
|
73 %destructor { delete $$; } expr
|
|
74 %destructor { delete $$; } comp_expr
|
|
75
|
|
76 %left '+' '-';
|
|
77 %left '*' '/' '%';
|
|
78 %left NEG;
|
|
79 %%
|
|
80 %start unit;
|
|
81
|
|
82 unit : states
|
|
83 | unit states
|
|
84 ;
|
|
85
|
|
86 states : statement "\n"
|
|
87 | "\n"
|
|
88 ;
|
|
89
|
|
90 statement : "end" { driver.EndStatement(@1); }
|
|
91 | assign { driver.AssignStatement(@1, $1); }
|
|
92 | "if" comp_expr "then" { driver.IfStatement(@1, $2); }
|
|
93 | "else" { driver.ElseStatement(@1); }
|
|
94 | "endif" { driver.EndifStatement(@1); }
|
|
95 | "for" assign "to" expr "step" expr { driver.ForStatement(@1, $2, $4, $6); }
|
|
96 | "for" assign "to" expr { driver.ForStatement(@1, $2, $4, NULL); }
|
|
97 | "next" { driver.NextStatement(@1); }
|
|
98 | "while" comp_expr { driver.WhileStatement(@1, $2); }
|
|
99 | "wend" { driver.WendStatement(@1); }
|
|
100 | "print" args { driver.PrintStatement(@1, $2); }
|
|
101 | error /* エラーの場合 */
|
|
102 ;
|
|
103
|
|
104 assign : value '=' expr { $$ = new CAssign(@1, '=', $1, $3); }
|
|
105 ;
|
|
106
|
|
107 comp_expr : expr "==" expr { $$ = CNode::MakeNode(driver, @1, OP_EQ, $1, $3); }
|
|
108 | expr "!=" expr { $$ = CNode::MakeNode(driver, @1, OP_NE, $1, $3); }
|
|
109 | expr '>' expr { $$ = CNode::MakeNode(driver, @1, OP_GT, $1, $3); }
|
|
110 | expr ">=" expr { $$ = CNode::MakeNode(driver, @1, OP_GE, $1, $3); }
|
|
111 | expr '<' expr { $$ = CNode::MakeNode(driver, @1, OP_LT, $1, $3); }
|
|
112 | expr "<=" expr { $$ = CNode::MakeNode(driver, @1, OP_LE, $1, $3); }
|
|
113 ;
|
|
114
|
|
115 expr : expr '-' expr { $$ = CNode::MakeNode(driver, @1, OP_MINUS, $1, $3); }
|
|
116 | expr '+' expr { $$ = CNode::MakeNode(driver, @1, OP_PLUS, $1, $3); }
|
|
117 | expr '*' expr { $$ = CNode::MakeNode(driver, @1, OP_TIMES, $1, $3); }
|
|
118 | expr '/' expr { $$ = CNode::MakeNode(driver, @1, OP_DIVIDE, $1, $3); }
|
|
119 | expr '%' expr { $$ = CNode::MakeNode(driver, @1, OP_MOD, $1, $3); }
|
|
120 | '-' expr %prec NEG { $$ = CNode::MakeNode(driver, @1, OP_NEG, $2); }
|
|
121 | '(' expr ')' { $$ = $2; }
|
|
122 | value { $$ = $1; }
|
|
123 | "ival" { $$ = new CNode(@1, OP_CONST, $1); }
|
|
124 | "rand" '(' expr ')' { $$ = new CNode(@1, OP_RANDFUNC, $3); }
|
|
125 ;
|
|
126
|
|
127 value : "identifier" { $$ = new CValueNode(@1, $1); }
|
|
128 ;
|
|
129
|
|
130 args : expr { $$ = new CArgs(@1, $1); }
|
|
131 | args ',' expr { $$ = $1->Add(@3, $3); }
|
|
132 ;
|
|
133
|
|
134 %%
|
|
135 void yy::script_parser::error(const yy::script_parser::location_type& l, const std::string& m)
|
|
136 {
|
|
137 driver.error(l, m);
|
|
138 }
|