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 ;