Mercurial > hg > Members > nobuyasu > SampleSource
comparison WindowsOnly/WinScript2/script-parser.yy @ 0:db40c85cad7a default tip
upload sample source
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 09 May 2011 03:11:59 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:db40c85cad7a |
---|---|
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 %parse-param { compiler& driver } | |
15 %lex-param { compiler& driver } | |
16 %locations | |
17 %expect 1 /* if文で衝突が発生するので、1つの衝突は無視 */ | |
18 %initial-action | |
19 { | |
20 // ロケーション初期化 | |
21 @$.begin.filename = @$.end.filename = &driver.get_filename(); | |
22 } ; | |
23 // %debug | |
24 %error-verbose | |
25 // Symbols. | |
26 %union | |
27 { | |
28 int ival; | |
29 std::string *sval; | |
30 | |
31 int type; | |
32 CValueList *value_list; | |
33 CArgList *arglist; | |
34 CDeclList *decls; | |
35 CStateList *states; | |
36 CStatement *statement; | |
37 CArgDef *argdef; | |
38 CArgs *args; | |
39 CValueNode *value; | |
40 CNode *expr; | |
41 CAssign *assign; | |
42 CStateBlock *block; | |
43 } | |
44 %{ | |
45 #include "compiler.h" | |
46 %} | |
47 | |
48 %token END_OF_FILE 0 "end of file" | |
49 %token <ival> TK_IVAL "ival" | |
50 %token <sval> TK_IDENTIFIER "identifier" | |
51 %token <sval> TK_SVAL "sval" | |
52 %token TK_LOGOR "||" | |
53 %token TK_LOGAND "&&" | |
54 %token TK_EQ "==" | |
55 %token TK_NE "!=" | |
56 %token TK_GE ">=" | |
57 %token TK_LE "<=" | |
58 %token TK_LSHIFT "<<" | |
59 %token TK_RSHIFT ">>" | |
60 %token TK_ADD_ASSIGN "+=" | |
61 %token TK_SUB_ASSIGN "-=" | |
62 %token TK_MUL_ASSIGN "*=" | |
63 %token TK_DIV_ASSIGN "/=" | |
64 %token TK_MOD_ASSIGN "%=" | |
65 | |
66 %token TK_IF "if" | |
67 %token TK_ELSE "else" | |
68 %token TK_WHILE "while" | |
69 %token TK_FOR "for" | |
70 %token TK_SWITCH "switch" | |
71 %token TK_CASE "case" | |
72 %token TK_DEFAULT "default" | |
73 %token TK_BREAK "break" | |
74 %token TK_RETURN "return" | |
75 %token TK_INTEGER "int" | |
76 %token TK_STRING "string" | |
77 %token TK_VOID "void" | |
78 | |
79 %type <expr> expr | |
80 %type <value> value | |
81 %type <assign> assign | |
82 %type <value_list> value_list | |
83 %type <arglist> arglist | |
84 %type <argdef> arg | |
85 %type <decls> decls decl_list | |
86 %type <states> states state_list | |
87 %type <block> block | |
88 %type <args> args | |
89 %type <statement> statement | |
90 %type <type> type | |
91 | |
92 %destructor { delete $$; } "identifier" | |
93 %destructor { delete $$; } "sval" | |
94 | |
95 %destructor { delete $$; } value_list | |
96 %destructor { delete $$; } arglist | |
97 %destructor { delete $$; } arg | |
98 %destructor { delete $$; } decls decl_list | |
99 %destructor { delete $$; } states state_list | |
100 %destructor { delete $$; } args | |
101 %destructor { delete $$; } block | |
102 %destructor { delete $$; } assign | |
103 %destructor { delete $$; } statement | |
104 %destructor { delete $$; } value | |
105 %destructor { delete $$; } expr | |
106 | |
107 %left "||"; | |
108 %left "&&"; | |
109 %nonassoc "==" "!=" '>' '<' ">=" "<="; | |
110 %left '&' '|'; | |
111 %left "<<" ">>"; | |
112 %left '+' '-'; | |
113 %left '*' '/' '%'; | |
114 %left NEG; | |
115 %% | |
116 %start unit; | |
117 | |
118 unit : define_or_state | |
119 | unit define_or_state | |
120 ; | |
121 | |
122 define_or_state : error ';' | |
123 | function | |
124 | declaration | |
125 ; | |
126 | |
127 declaration : type value_list ';' { driver.DefineValue(@2, $1, $2); } | |
128 | type "identifier" '(' ')' ';' { driver.DefineFunction(@2, $1, $2, NULL); } | |
129 | type "identifier" '(' arglist ')' ';' { driver.DefineFunction(@2, $1, $2, $4); } | |
130 | "void" "identifier" '(' ')' ';' { driver.DefineFunction(@2, TYPE_VOID, $2, NULL); } | |
131 | "void" "identifier" '(' arglist ')' ';' { driver.DefineFunction(@2, TYPE_VOID, $2, $4); } | |
132 ; | |
133 | |
134 value_list : value { $$ = new CValueList($1); } | |
135 | value_list ',' value { $$ = $1->Add($3); } | |
136 ; | |
137 | |
138 arglist : arg { $$ = new CArgList($1); } | |
139 | arglist ',' arg { $$ = $1->Add($3); } | |
140 ; | |
141 | |
142 arg : type { $$ = new CArgDef(@1, $1, NULL); } | |
143 | type '&' { $$ = new CArgDef(@1, TypeToRef($1), NULL); } | |
144 | type "identifier" { $$ = new CArgDef(@1, $1, $2); } | |
145 | type '&' "identifier" { $$ = new CArgDef(@1, TypeToRef($1), $3); } | |
146 | type "identifier" '[' ']' { $$ = new CArgDef(@1, TypeToRef($1), $2); } | |
147 | type '&' "identifier" '[' ']' { $$ = new CArgDef(@1, TypeToRef($1), $3); } | |
148 ; | |
149 | |
150 function : type "identifier" '(' ')' block { driver.AddFunction(@1, $1, $2, NULL, $5); } | |
151 | type "identifier" '(' arglist ')' block { driver.AddFunction(@1, $1, $2, $4, $6); } | |
152 | "void" "identifier" '(' ')' block { driver.AddFunction(@1, TYPE_VOID, $2, NULL, $5); } | |
153 | "void" "identifier" '(' arglist ')' block { driver.AddFunction(@1, TYPE_VOID, $2, $4, $6); } | |
154 ; | |
155 | |
156 type : "int" { $$ = TYPE_INTEGER; } | |
157 | "string" { $$ = TYPE_STRING; } | |
158 ; | |
159 | |
160 block : '{' decl_list state_list '}' { $$ = new CStateBlock($2, $3); } | |
161 ; | |
162 | |
163 decl_list : { $$ = NULL } | |
164 | decls { $$ = $1 } | |
165 ; | |
166 | |
167 state_list : { $$ = NULL } | |
168 | states { $$ = $1 } | |
169 ; | |
170 | |
171 decls : type value_list ';' { $$ = new CDeclList(new CDecl($1, $2)); } | |
172 | decls type value_list ';' { $$ = $1->Add(new CDecl($2, $3)); } | |
173 ; | |
174 | |
175 states : statement { $$ = new CStateList($1); } | |
176 | states statement { $$ = $1->Add($2); } | |
177 ; | |
178 | |
179 statement : ';' { $$ = new CNopStatement(@1); } | |
180 | assign ';' { $$ = new CAssignStatement(@1, $1); } | |
181 | "identifier" '(' args ')' ';' { $$ = new CFunctionStatement(@1, $1, $3); } | |
182 | "identifier" '(' ')' ';' { $$ = new CFunctionStatement(@1, $1, NULL); } | |
183 | "case" expr ':' { $$ = new CCaseStatement(@1, $2); } | |
184 | "default" ':' { $$ = new CDefaultStatement(@1); } | |
185 | "break" ';' { $$ = new CBreakStatement(@1); } | |
186 | "return" ';' { $$ = new CReturnStatement(@1, NULL); } | |
187 | "return" expr ';' { $$ = new CReturnStatement(@1, $2); } | |
188 | "if" '(' expr ')' statement { $$ = new CIfStatement(@1, $3, $5); } | |
189 | "if" '(' expr ')' statement "else" statement { $$ = new CIfStatement(@1, $3, $5, $7); } | |
190 | "for" '(' assign ';' expr ';' assign ')' statement | |
191 { $$ = new CForStatement(@1, $3, $5, $7, $9); } | |
192 | "while" '(' expr ')' statement { $$ = new CWhileStatement(@1, $3, $5); } | |
193 | "switch" '(' expr ')' '{' state_list '}' { $$ = new CSwitchStatement(@1, $3, $6); } | |
194 | block { $$ = new CBlockStatement(@1, $1); } | |
195 ; | |
196 | |
197 assign : value '=' expr { $$ = new CAssign(@1, '=', $1, $3); } | |
198 | value "+=" expr { $$ = new CAssign(@1, '+', $1, $3); } | |
199 | value "-=" expr { $$ = new CAssign(@1, '-', $1, $3); } | |
200 | value "*=" expr { $$ = new CAssign(@1, '*', $1, $3); } | |
201 | value "/=" expr { $$ = new CAssign(@1, '/', $1, $3); } | |
202 | value "%=" expr { $$ = new CAssign(@1, '%', $1, $3); } | |
203 ; | |
204 | |
205 expr : expr "&&" expr { $$ = CNode::MakeNode(driver, @2, OP_LOGAND, $1, $3); } | |
206 | expr "||" expr { $$ = CNode::MakeNode(driver, @2, OP_LOGOR, $1, $3); } | |
207 | expr "==" expr { $$ = CNode::MakeNode(driver, @2, OP_EQ, $1, $3); } | |
208 | expr "!=" expr { $$ = CNode::MakeNode(driver, @2, OP_NE, $1, $3); } | |
209 | expr '>' expr { $$ = CNode::MakeNode(driver, @2, OP_GT, $1, $3); } | |
210 | expr ">=" expr { $$ = CNode::MakeNode(driver, @2, OP_GE, $1, $3); } | |
211 | expr '<' expr { $$ = CNode::MakeNode(driver, @2, OP_LT, $1, $3); } | |
212 | expr "<=" expr { $$ = CNode::MakeNode(driver, @2, OP_LE, $1, $3); } | |
213 | expr '&' expr { $$ = CNode::MakeNode(driver, @2, OP_AND, $1, $3); } | |
214 | expr '|' expr { $$ = CNode::MakeNode(driver, @2, OP_OR, $1, $3); } | |
215 | expr "<<" expr { $$ = CNode::MakeNode(driver, @2, OP_LSHIFT, $1, $3); } | |
216 | expr ">>" expr { $$ = CNode::MakeNode(driver, @2, OP_RSHIFT, $1, $3); } | |
217 | expr '-' expr { $$ = CNode::MakeNode(driver, @2, OP_MINUS, $1, $3); } | |
218 | expr '+' expr { $$ = CNode::MakeNode(driver, @2, OP_PLUS, $1, $3); } | |
219 | expr '*' expr { $$ = CNode::MakeNode(driver, @2, OP_TIMES, $1, $3); } | |
220 | expr '/' expr { $$ = CNode::MakeNode(driver, @2, OP_DIVIDE, $1, $3); } | |
221 | expr '%' expr { $$ = CNode::MakeNode(driver, @2, OP_MOD, $1, $3); } | |
222 | '-' expr %prec NEG { $$ = CNode::MakeNode(driver, @2, OP_NEG, $2); } | |
223 | '(' expr ')' { $$ = $2; } | |
224 | value { $$ = $1; } | |
225 | "ival" { $$ = new CNode(@1, OP_CONST, $1); } | |
226 | "sval" { $$ = new CNode(@1, OP_STRING, $1); } | |
227 | "identifier" '(' args ')' { $$ = new CFunctionNode(@1, $1, $3); } | |
228 | "identifier" '(' ')' { $$ = new CFunctionNode(@1, $1, NULL); } | |
229 ; | |
230 | |
231 value : "identifier" { $$ = new CValueNode(@1, $1); } | |
232 | "identifier" '[' expr ']' { $$ = new CValueNode(@1, $1, $3); } | |
233 ; | |
234 | |
235 args : expr { $$ = new CArgs($1); } | |
236 | args ',' expr { $$ = $1->Add($3); } | |
237 ; | |
238 | |
239 %% | |
240 void yy::script_parser::error(const yy::script_parser::location_type& l, const std::string& m) | |
241 { | |
242 driver.error(l, m); | |
243 } |