1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 /* 使用指令%skeleton "lalr1.cc"选择C++解析器的骨架 */
17 %skeleton "lalr1.cc"
18
19 /* 指定bison的版本 */
20 %require "3.0.4"
21
22 %define api.namespace {Uscript} //声明命名空间与下面声明的类名结合使用 Uscript::Parser:: 在scanner.l中有体现
23 %define parser_class_name { Parser }
24 %define api.token.constructor
25 %define api.value.type variant //使得类型与token定义可以使用各种复杂的结构与类型
26 %defines //生成各种头文件 location.hh position.hh parser.hpp
27
28 %code requires
29 {
30 /*requires中的内容会放在YYLTYPE与YYSTPYPE定义前*/
31 #include <iostream>
32 #include <string>
33 #include <vector>
34 #include <stdint.h>
35 #include <cmath>
36 #include "location.hh"
37 #include "script_statement.h"
38 #include "script_param.h"
39 #include "script_function.h"
40 #include "script_expression.h"
41
42 using std::string;
43
44 namespace Uscript { /*避免包含头文件时冲突 */
45 class Scanner;
46 class ScriptInterpreter;
47 }
48
49 }
50
51 %code top
52 {
53 /* 尽可能放在parser.cpp靠近头部的地方,与requires相似 */
54 #include <iostream>
55 #include "scanner.h"
56 #include "parser.hpp"
57 #include "script_interpreter.h"
58 #include "log.h"
59
60 /* 注意:这里的参数由%parse-param决定 */
yylex(Uscript::Scanner * scanner,Uscript::ScriptInterpreter * interpreter)61 static Uscript::Parser::symbol_type yylex(Uscript::Scanner* scanner, Uscript::ScriptInterpreter* interpreter){
62 return scanner->nextToken();
63 }
64
65 using namespace std;
66 using namespace Uscript;
67 using namespace Updater;
68 }
69
70 %{
error(const location_type & loc,const std::string & msg)71 void Parser::error (const location_type& loc, const std::string& msg)
72 {
73 LOG(Updater::ERROR) << "error " << msg << " loc " << loc << std::endl;
74 }
75 %}
76
77 /*定义parser传给scanner的参数*/
78 %lex-param { Uscript::Scanner* scanner }
79 %lex-param { Uscript::ScriptInterpreter* interpreter }
80
81 /*定义interpreter传给parser的参数*/
82 %parse-param { Uscript::Scanner* scanner }
83 %parse-param { Uscript::ScriptInterpreter* interpreter }
84
85 %locations
86
87 /*详细显示错误信息*/
88 %define parse.error verbose
89
90 /*通过Marker::Parser::make_XXX(loc)给token添加前缀*/
91 %define api.token.prefix {TOKEN_}
92
93 %token <int> NUMBER
94 %token <float> FLOAT
95
96 %token EOL
97 %token END 0
98
99 %token <string>VAR FUNCTION GLOBAL FOR WHILE IF ELSE ADD SUB MUL DIV ASSIGN AND OR
100 EQ NE GT GE LT LE LP RP LC RC SEMICOLON IDENTIFIER
101 BREAK CONTINUE RETURN COMMA STRING
102
103 %type <ScriptParams*>arglist
104
105 %type <ScriptFunction*>function_definition
106
107 %type <UScriptExpression*> definition_or_statement
108 expression value_expression compare_expression add_sub_expression mul_div_expression
109 primary_expression expression_option arg
110
111 %type <UScriptStatementList*> block statement_list
112
113 %type <UScriptStatement*> expression_statement return_statement continue_statement break_statement
114 for_statement while_statement statement if_statement
115
116 %%
117 translation_unit: definition_or_statement
118 | translation_unit definition_or_statement
119 ;
120 definition_or_statement:function_definition
121 {
122 interpreter->AddFunction($1);
123 }
124 |statement
125 {
126 interpreter->AddStatement($1);
127 }
128 ;
129 function_definition: FUNCTION IDENTIFIER LP arglist RP block
130 {
131 $$ = ScriptFunction::CreateInstance($2, $4, $6);
132 }
133 |
134 FUNCTION IDENTIFIER LP RP block
135 {
136 $$ = ScriptFunction::CreateInstance($2, nullptr, $5);
137 }
138 ;
139 statement:expression_statement
140 {
141 $$ = $1;
142 }
143 |for_statement
144 {
145 $$ = $1;
146 }
147 |while_statement
148 {
149 $$ = $1;
150 }
151 |if_statement
152 {
153 $$ = $1;
154 }
155 |break_statement
156 {
157 $$ = $1;
158 }
159 |continue_statement
160 {
161 $$ = $1;
162 }
163 |return_statement
164 {
165 $$ = $1;
166 }
167 ;
168 expression_statement:expression SEMICOLON
169 {
170 $$ = UScriptStatement::CreateExpressionStatement($1);
171 }
172 ;
173 expression: value_expression
174 {
175 $$ = $1;
176 }
177 |IDENTIFIER ASSIGN expression
178 {
179 $$ = AssignExpression::CreateExpression($1, $3);
180 }
181 |IDENTIFIER COMMA IDENTIFIER ASSIGN expression
182 {
183 $$ = AssignExpression::CreateExpression($1, $5);
184 AssignExpression::AddIdentifier($$, $3);
185 }
186 |IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER ASSIGN expression
187 {
188 $$ = AssignExpression::CreateExpression($1, $7);
189 AssignExpression::AddIdentifier($$, $3);
190 AssignExpression::AddIdentifier($$, $5);
191 }
192 |IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER ASSIGN expression
193 {
194 $$ = AssignExpression::CreateExpression($1, $9);
195 AssignExpression::AddIdentifier($$, $3);
196 AssignExpression::AddIdentifier($$, $5);
197 AssignExpression::AddIdentifier($$, $7);
198 }
199 ;
200 value_expression: compare_expression
201 {
202 $$ = $1;
203 }
204 |value_expression EQ compare_expression
205 {
206 $$ = BinaryExpression::CreateExpression(UScriptExpression::EQ_OPERATOR, $1, $3);
207 }
208 |value_expression NE compare_expression
209 {
210 $$ = BinaryExpression::CreateExpression(UScriptExpression::NE_OPERATOR, $1, $3);
211 }
212 |value_expression AND compare_expression
213 {
214 $$ = BinaryExpression::CreateExpression(UScriptExpression::AND_OPERATOR, $1, $3);
215 }
216 |value_expression OR compare_expression
217 {
218 $$ = BinaryExpression::CreateExpression(UScriptExpression::OR_OPERATOR, $1, $3);
219 }
220 ;
221 compare_expression:add_sub_expression
222 {
223 $$ = $1;
224 }
225 |compare_expression GT add_sub_expression
226 {
227 $$ = BinaryExpression::CreateExpression(UScriptExpression::GT_OPERATOR, $1, $3);
228 }
229 |compare_expression GE add_sub_expression
230 {
231 $$ = BinaryExpression::CreateExpression(UScriptExpression::GE_OPERATOR, $1, $3);
232 }
233 |compare_expression LT add_sub_expression
234 {
235 $$ = BinaryExpression::CreateExpression(UScriptExpression::LT_OPERATOR, $1, $3);
236 }
237 |compare_expression LE add_sub_expression
238 {
239 $$ = BinaryExpression::CreateExpression(UScriptExpression::LE_OPERATOR, $1, $3);
240 }
241 ;
242 add_sub_expression:mul_div_expression
243 {
244 $$ = $1;
245 }
246 |add_sub_expression ADD mul_div_expression
247 {
248 $$ = BinaryExpression::CreateExpression(UScriptExpression::ADD_OPERATOR, $1, $3);
249 }
250 |add_sub_expression SUB mul_div_expression
251 {
252 $$ = BinaryExpression::CreateExpression(UScriptExpression::SUB_OPERATOR, $1, $3);
253 }
254 ;
255 mul_div_expression:primary_expression
256 {
257 $$ = $1;
258 }
259 |mul_div_expression DIV primary_expression
260 {
261 $$ = BinaryExpression::CreateExpression(UScriptExpression::DIV_OPERATOR, $1, $3);
262 }
263 |mul_div_expression MUL primary_expression
264 {
265 $$ = BinaryExpression::CreateExpression(UScriptExpression::MUL_OPERATOR, $1, $3);
266 }
267 ;
268 primary_expression:SUB primary_expression
269 {
270 $$=$2;
271 }
272 |LP expression RP
273 {
274 $$=$2;
275 }
276 |IDENTIFIER
277 {
278 $$ = IdentifierExpression::CreateExpression($1);
279 }
280 |STRING
281 {
282 $$ = StringExpression::CreateExpression($1);
283 }
284 |NUMBER
285 {
286 $$ = IntegerExpression::CreateExpression($1);
287 }
288 |FLOAT
289 {
290 $$ = FloatExpression::CreateExpression($1);
291 }
292 |IDENTIFIER LP RP
293 {
294 $$ = FunctionCallExpression::CreateExpression($1, nullptr);
295 }
296 |IDENTIFIER LP arglist RP
297 {
298 $$ = FunctionCallExpression::CreateExpression($1, $3);
299 }
300 ;
301 statement_list:statement_list statement
302 {
303 $1->AddScriptStatement($2);
304 $$ = $1;
305 }
306 |statement
307 {
308 $$ = UScriptStatementList::CreateInstance($1);
309 }
310 ;
311 block:LC RC
312 {
313 $$=nullptr;
314 }
315 |LC statement_list RC
316 {
317 $$=$2;
318 }
319 ;
320 arglist:arglist COMMA arg
321 {
322 $$ = ScriptParams::AddParams($1, $3);
323 }
324 |arg
325 {
326 $$ = ScriptParams::CreateParams($1);
327 }
328 ;
329 arg: value_expression
330 {
331 $$ = $1;
332 }
333 ;
334 expression_option:
335 {
336 $$=nullptr;
337 }
338 |expression
339 {
340 $$ = $1;
341 }
342 ;
343 for_statement: FOR LP expression_option SEMICOLON expression_option SEMICOLON expression_option RP block
344 {
345 $$ = UScriptStatement::CreateForStatement($3,$5,$7,$9);
346 }
347 ;
348 while_statement: WHILE LP expression_option RP block
349 {
350 $$ = UScriptStatement::CreateWhileStatement($3, (UScriptStatementList*)$5);
351 }
352 ;
353 if_statement: IF LP expression RP block
354 {
355 $$ = UScriptStatement::CreateIfStatement($3,$5);
356 }
357 | IF LP expression RP block ELSE if_statement
358 {
359 $$ = UScriptStatement::CreateIfStatement($3,$5, nullptr, $7);
360 }
361 | IF LP expression RP block ELSE block
362 {
363 $$ = UScriptStatement::CreateIfStatement($3,$5, $7);
364 }
365 ;
366 break_statement:BREAK SEMICOLON
367 {
368 $$ = UScriptStatement::CreateStatement(UScriptStatement::STATEMENT_TYPE_BREAK);
369 }
370 ;
371 continue_statement:CONTINUE SEMICOLON
372 {
373 //$$=create_Statement(STATEMENT_TYPE_CONTINUE);
374 $$ = UScriptStatement::CreateStatement(UScriptStatement::STATEMENT_TYPE_CONTINUE);
375 }
376 ;
377 return_statement:RETURN arglist SEMICOLON
378 {
379 $$ = UScriptReturnStatement::CreateStatement($2);
380 }
381 | RETURN SEMICOLON
382 {
383 $$ = UScriptReturnStatement::CreateStatement(nullptr);
384 }
385 ;