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决定 */
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%{
71void 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%%
117translation_unit: definition_or_statement
118        | translation_unit definition_or_statement
119        ;
120definition_or_statement:function_definition
121        {
122                interpreter->AddFunction($1);
123        }
124        |statement
125        {
126                interpreter->AddStatement($1);
127        }
128        ;
129function_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        ;
139statement: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        ;
168expression_statement:expression SEMICOLON
169        {
170                $$ = UScriptStatement::CreateExpressionStatement($1);
171        }
172        ;
173expression: 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        ;
200value_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        ;
221compare_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        ;
242add_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        ;
255mul_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        ;
268primary_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        ;
301statement_list:statement_list statement
302        {
303                $1->AddScriptStatement($2);
304                $$ = $1;
305        }
306        |statement
307        {
308                $$ = UScriptStatementList::CreateInstance($1);
309        }
310        ;
311block:LC RC
312        {
313                $$=nullptr;
314        }
315        |LC statement_list RC
316        {
317                $$=$2;
318        }
319        ;
320arglist:arglist COMMA arg
321        {
322                $$ = ScriptParams::AddParams($1, $3);
323        }
324        |arg
325        {
326                $$ = ScriptParams::CreateParams($1);
327        }
328        ;
329arg:    value_expression
330        {
331                $$ = $1;
332        }
333        ;
334expression_option:
335        {
336                $$=nullptr;
337        }
338        |expression
339        {
340                $$ = $1;
341        }
342        ;
343for_statement: FOR LP expression_option SEMICOLON expression_option SEMICOLON expression_option  RP block
344        {
345                $$ = UScriptStatement::CreateForStatement($3,$5,$7,$9);
346        }
347        ;
348while_statement:  WHILE LP expression_option RP block
349	{
350		$$ = UScriptStatement::CreateWhileStatement($3, (UScriptStatementList*)$5);
351	}
352	;
353if_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        ;
366break_statement:BREAK SEMICOLON
367        {
368                $$ = UScriptStatement::CreateStatement(UScriptStatement::STATEMENT_TYPE_BREAK);
369        }
370        ;
371continue_statement:CONTINUE SEMICOLON
372        {
373                //$$=create_Statement(STATEMENT_TYPE_CONTINUE);
374                $$ = UScriptStatement::CreateStatement(UScriptStatement::STATEMENT_TYPE_CONTINUE);
375        }
376        ;
377return_statement:RETURN arglist SEMICOLON
378        {
379                $$ = UScriptReturnStatement::CreateStatement($2);
380        }
381        | RETURN SEMICOLON
382        {
383                $$ = UScriptReturnStatement::CreateStatement(nullptr);
384        }
385        ;