this repo has no description
at fixPythonPipStalling 509 lines 15 kB view raw
1%require "3.0.2" 2%defines 3%define parser_class_name {RezParser} 4%skeleton "lalr1.cc" 5 6%locations; 7 8%define api.token.constructor 9%define api.value.type variant 10%define parse.assert 11 12%token<std::string> IDENTIFIER; 13%token<int> CHARLIT; 14%token<std::string> STRINGLIT; 15%token<int> INTLIT; 16 17%token<std::string> BADTOKEN; 18 19 20%token LEFTBRACE "{"; 21%token RIGHTBRACE "}"; 22%token LEFTBRACKET "["; 23%token RIGHTBRACKET "]"; 24%token LEFTPAREN "("; 25%token RIGHTPAREN ")"; 26%token SEMICOLON ";"; 27%token COMMA ","; 28%token PLUS "+"; 29%token MINUS "-"; 30%token DIVIDE "/"; 31%token STAR "*"; 32%token ASSIGN "="; 33%token COLON ":"; 34%token SHIFTLEFT "<<"; 35%token SHIFTRIGHT ">>"; 36%token EQUAL "=="; 37%token NOTEQUAL "!="; 38%token AND "&"; 39%token OR "|"; 40%token XOR "^"; 41%token COMPL "~"; 42%token DOLLAR "$"; 43 44%token TYPE "type"; 45%token RESOURCE "resource"; 46%token DATA "data"; 47%token READ "read"; 48%token INCLUDE "include"; 49%token CHANGE "change"; 50%token DELETE "delete"; 51 52 53%token ARRAY "array"; 54%token SWITCH "switch"; 55%token CASE "case"; 56%token AS "as"; 57%token FILL "fill"; 58%token ALIGN "align"; 59%token HEX "hex"; 60%token KEY "key"; 61%token WIDE "wide"; 62%token LITERAL "literal"; 63%token UNSIGNED "unsigned"; 64%token BINARY "binary"; 65 66%token BOOLEAN "boolean"; 67%token BIT "bit"; 68%token NIBBLE "nibble"; 69%token BYTE "byte"; 70%token CHAR "char"; 71%token WORD "word"; 72%token INTEGER "integer"; 73%token LONG "long"; 74%token LONGINT "longint"; 75%token PSTRING "pstring"; 76%token WSTRING "wstring"; 77%token STRING "string"; 78%token POINT "point"; 79%token RECT "rect"; 80%token BITSTRING "bitstring"; 81 82%token FUN_COUNTOF "$$countof"; 83%token FUN_ARRAYINDEX "$$arrayindex"; 84%token FUN_READ "$$read"; 85%token FUN_BITFIELD "$$bitfield"; 86%token FUN_WORD "$$word"; 87%token FUN_BYTE "$$byte"; 88%token FUN_LONG "$$long"; 89 90/* 91%left "|"; 92%left "^"; 93%left "&"; 94%left "==" "!="; 95%left ">>" "<<"; 96%left "+" "-"; 97%left "*" "/"; 98*/ 99 100%param { RezLexer& lexer } 101%param { RezWorld& world } 102 103%code requires { 104 #include "ResourceDefinitions.h" 105 #include "Expression.h" 106 #include "ResSpec.h" 107 108 #define YY_NULLPTR nullptr 109 class RezLexer; 110 class RezWorld; 111} 112 113%code provides { 114 using yy::RezParser; 115 //using RezSymbol = yy::RezParser::symbol_type; 116 117 class RezSymbol : public yy::RezParser::symbol_type 118 { 119 public: 120 RezSymbol() = default; 121 RezSymbol(yy::RezParser::symbol_type&& x) : yy::RezParser::symbol_type(std::move(x)) {} 122 }; 123} 124 125%code { 126 #include "RezLexer.h" 127 #include "RezWorld.h" 128 #include "ResourceCompiler.h" 129 #include "Diagnostic.h" 130 131 static yy::RezParser::symbol_type yylex(RezLexer& lexer, RezWorld&) 132 { 133 return lexer.nextToken(); 134 } 135 136 void yy::RezParser::error(const location_type& loc, std::string const& err) 137 { 138 world.problem(Diagnostic(Diagnostic::error, err, loc)); 139 } 140 141 static std::string fromHex(std::string hex) 142 { 143 std::string bin; 144 int nibble; 145 bool haveNibble = false; 146 for(std::string::iterator p = hex.begin(); p != hex.end(); ++p) 147 { 148 if(std::isspace(*p)) 149 continue; 150 assert(isdigit(*p) || (tolower(*p) >= 'a' && tolower(*p) <= 'f')); 151 int digit; 152 if(isdigit(*p)) 153 digit = *p - '0'; 154 else 155 digit = tolower(*p) - 'a' + 0xA; 156 157 if(haveNibble) 158 { 159 bin += (char) ((nibble << 4) | digit); 160 haveNibble = false; 161 } 162 else 163 { 164 nibble = digit; 165 haveNibble = true; 166 } 167 } 168 return bin; 169 } 170 171} 172 173%% 174%start rez; 175 176rez : %empty 177 | rez type_definition ";" 178 | rez resource ";" 179 | rez data ";" 180 ; 181 182type_definition : "type" type_spec 183 { 184 TypeDefinitionPtr td = std::make_shared<TypeDefinition>(); 185 world.addTypeDefinition($type_spec, td); 186 world.fieldLists.push(td); 187 } 188 "{" field_definitions "}" 189 { world.fieldLists.pop(); if(world.verboseFlag) std::cout << "TYPE " << $2 << std::endl; } 190 | "type" type_spec "as" type_spec 191 { 192 if(world.verboseFlag) std::cout << "TYPE " << $2 << std::endl; 193 auto spec = $4; 194 world.addTypeDefinition($2, world.getTypeDefinition(spec.getType(), spec.getID(), @4)); 195 } 196 ; 197 198%type <ResType> res_type; 199res_type : CHARLIT { $$ = ResType($1); } ; 200 201%type <TypeSpec> type_spec; 202type_spec : res_type { $$ = TypeSpec($res_type); } 203 | res_type "(" INTLIT ")" { $$ = TypeSpec($res_type, $INTLIT); } 204 ; 205 206field_definitions : %empty 207 | field_definitions IDENTIFIER ":" { world.fieldLists.top()->addLabel($2, @2); } 208 | field_definitions ";" 209 | field_definitions field_definition ";" { world.fieldLists.top()->addField($2, @2); } 210 ; 211 212%type <FieldPtr> field_definition; 213field_definition: simple_field_definition { $$ = $1; } 214 | array_definition { $$ = $1; } 215 | switch_definition { $$ = $1; } 216 | fill_statement { $$ = $1; } 217 | align_statement { $$ = $1; } 218 ; 219 220%type <SimpleFieldPtr> simple_field_definition; 221simple_field_definition: field_attributes simpletype array_count_opt value_spec_opt 222 { 223 $$ = std::make_shared<SimpleField>(); 224 $$->attrs = $field_attributes; 225 $$->type = $simpletype; 226 $$->arrayCount = $array_count_opt; 227 $$->value = $value_spec_opt; 228 } 229 | simple_field_definition IDENTIFIER 230 { $$ = $1; $$->addNamedValue($IDENTIFIER); } 231 | simple_field_definition IDENTIFIER "=" value 232 { $$ = $1; $$->addNamedValue($IDENTIFIER, $value); } 233 | simple_field_definition "," IDENTIFIER 234 { $$ = $1; $$->addNamedValue($IDENTIFIER); } 235 | simple_field_definition "," IDENTIFIER "=" value 236 { $$ = $1; $$->addNamedValue($IDENTIFIER, $value); } 237 ; 238 239%type <ExprPtr> array_count array_count_opt value_spec_opt value resource_item; 240%type <ExprPtr> expression expression1 expression2 ; 241%type <ExprPtr> expression3 expression4 expression5 ; 242%type <ExprPtr> expression6 expression7 expression8; 243 244value_spec_opt : %empty { $$ = nullptr; } | "=" value { $$ = $2; } ; 245 246%type <SimpleField::Type> simpletype; 247simpletype : "boolean" { $$ = SimpleField::Type::boolean; } 248 | "byte" { $$ = SimpleField::Type::byte; } 249 | "integer" { $$ = SimpleField::Type::integer; } 250 | "longint" { $$ = SimpleField::Type::longint; } 251 | "rect" { $$ = SimpleField::Type::rect; } 252 | "point" { $$ = SimpleField::Type::point; } 253 | "char" { $$ = SimpleField::Type::char_; } 254 | "pstring" { $$ = SimpleField::Type::pstring; } 255 | "wstring" { $$ = SimpleField::Type::wstring; } 256 | "string" { $$ = SimpleField::Type::string; } 257 | "bitstring" { $$ = SimpleField::Type::bitstring; } 258 ; 259 260%type <FieldPtr> fill_statement align_statement; 261fill_statement : "fill" fill_unit array_count_opt 262 { $$ = std::make_shared<FillAlignField>($fill_unit, false, $array_count_opt); } 263 ; 264align_statement : "align" fill_unit 265 { $$ = std::make_shared<FillAlignField>($fill_unit, true); } 266 ; 267 268%type <FillAlignField::Type> fill_unit; 269fill_unit : "bit" { $$ = FillAlignField::Type::bit; } 270 | "nibble" { $$ = FillAlignField::Type::nibble; } 271 | "byte" { $$ = FillAlignField::Type::byte; } 272 | "word" { $$ = FillAlignField::Type::word; } 273 | "long" { $$ = FillAlignField::Type::long_; } 274 ; 275 276%type <FieldPtr> array_definition; 277array_definition: 278 array_attributes "array" array_name_opt array_count_opt 279 { 280 ArrayFieldPtr af = std::make_shared<ArrayField>($array_name_opt, $array_count_opt); 281 world.fieldLists.push(af); 282 } 283 "{" field_definitions "}" 284 { 285 $$ = world.fieldLists.top(); 286 world.fieldLists.pop(); 287 } 288 ; 289 290array_count : "[" expression "]" { $$ = $2; } 291array_count_opt : %empty { $$ = nullptr; } | array_count { $$ = $1; }; 292 293%type <std::string> array_name_opt; 294array_name_opt : %empty { $$ = ""; } | IDENTIFIER { $$ = $1; } ; 295 296array_attributes: %empty | "wide" ; 297 298%type <SimpleField::Attrs> field_attributes field_attribute; 299field_attributes: %empty { $$ = SimpleField::Attrs::none; } 300 | field_attributes field_attribute { $$ = $1 | $2; } 301 ; 302 303field_attribute : "hex" { $$ = SimpleField::Attrs::hex; } 304 | "key" { $$ = SimpleField::Attrs::key; } 305 | "unsigned" { $$ = SimpleField::Attrs::unsigned_; } 306 | "literal" { $$ = SimpleField::Attrs::literal; } 307 | "binary" { $$ = SimpleField::Attrs::binary; } 308 ; 309 310%type <FieldPtr> switch_definition; 311switch_definition: 312 "switch" 313 { world.switches.push(std::make_shared<SwitchField>()); } 314 "{" 315 switch_cases 316 "}" 317 { 318 $$ = world.switches.top(); 319 world.switches.pop(); 320 } 321 ; 322 323switch_cases : %empty | switch_cases switch_case ; 324 325switch_case : "case" IDENTIFIER ":" 326 { 327 world.fieldLists.push(std::make_shared<FieldList>()); 328 } 329 field_definitions 330 { 331 world.switches.top()->addCase($IDENTIFIER, world.fieldLists.top()); 332 world.fieldLists.pop(); 333 } 334 ; 335 336 337value : expression { $$ = $1; } 338 | "{" resource_body "}" { $$ = $2; } 339 | string_expression { $$ = $1; } 340 ; 341 342expression : expression1 { $$ = $1; } 343 | expression "^" expression1 { $$ = std::make_shared<BinaryExpr>(BinaryOp::XOR, $1, $3, @1); } 344 ; 345 346expression1 : expression2 { $$ = $1; } 347 | expression1 "&" expression2 { $$ = std::make_shared<BinaryExpr>(BinaryOp::AND, $1, $3, @1); } 348 ; 349 350expression2 : expression3 { $$ = $1; } 351 | expression2 "|" expression3 { $$ = std::make_shared<BinaryExpr>(BinaryOp::OR, $1, $3, @1); } 352 ; 353 354expression3 : expression4 { $$ = $1; } 355 | expression3 "==" expression4 { $$ = std::make_shared<BinaryExpr>(BinaryOp::EQUAL, $1, $3, @1); } 356 | expression3 "!=" expression4 { $$ = std::make_shared<BinaryExpr>(BinaryOp::NOTEQUAL, $1, $3, @1); } 357 ; 358 359expression4 : expression5 { $$ = $1; } 360 | expression4 ">>" expression5 { $$ = std::make_shared<BinaryExpr>(BinaryOp::SHIFTRIGHT, $1, $3, @1); } 361 | expression4 "<<" expression5 { $$ = std::make_shared<BinaryExpr>(BinaryOp::SHIFTLEFT, $1, $3, @1); } 362 ; 363 364expression5 : expression6 { $$ = $1; } 365 | expression5 "+" expression6 { $$ = std::make_shared<BinaryExpr>(BinaryOp::PLUS, $1, $3, @1); } 366 | expression5 "-" expression6 { $$ = std::make_shared<BinaryExpr>(BinaryOp::MINUS, $1, $3, @1); } 367 ; 368 369expression6 : expression7 { $$ = $1; } 370 | expression6 "*" expression7 { $$ = std::make_shared<BinaryExpr>(BinaryOp::MULTIPLY, $1, $3, @1); } 371 | expression6 "/" expression7 { $$ = std::make_shared<BinaryExpr>(BinaryOp::DIVIDE, $1, $3, @1); } 372 ; 373expression7 : expression8 { $$ = $1; } 374 | "-" expression7 { $$ = std::make_shared<UnaryExpr>(UnaryOp::MINUS, $2, @1); } 375 | "+" expression7 { $$ = $2; } 376 | "~" expression7 { $$ = std::make_shared<UnaryExpr>(UnaryOp::COMPLEMENT, $2, @1); } 377 ; 378 379expression8 : INTLIT { $$ = std::make_shared<IntExpr>($1, @1); } 380 | CHARLIT { $$ = std::make_shared<IntExpr>($1, @1); } 381 382 | identifier_expression { $$ = $1; } 383 | "(" expression ")" { $$ = $2; } 384 385 | "$$countof" "(" identifier_expression ")" 386 { $$ = std::make_shared<CountOfExpr>($identifier_expression, @1); } 387 | "$$arrayindex" "(" identifier_expression ")" 388 { $$ = std::make_shared<ArrayIndexExpr>($identifier_expression, @1); } 389 | "$$bitfield" "(" expression "," expression "," expression ")" 390 { $$ = std::make_shared<PeekExpr>($3, $5, $7, @1); } 391 | "$$word" "(" expression ")" 392 { $$ = std::make_shared<PeekExpr>($3, 16, @1); } 393 | "$$byte" "(" expression ")" 394 { $$ = std::make_shared<PeekExpr>($3, 8, @1); } 395 | "$$long" "(" expression ")" 396 { $$ = std::make_shared<PeekExpr>($3, 32, @1); } 397 ; 398 399%type <IdentifierExprPtr> identifier_expression; 400identifier_expression : IDENTIFIER { $$ = std::make_shared<IdentifierExpr>($1, @1); } 401 | IDENTIFIER 402 { world.functionCalls.push(std::make_shared<IdentifierExpr>($1, @1)); } 403 "[" function_argument_list1 "]" 404 { $$ = world.functionCalls.top(); world.functionCalls.pop(); } 405 ; 406 407function_argument_list : %empty | function_argument_list1 ; 408function_argument_list1 : expression 409 { world.functionCalls.top()->addArgument($expression); } 410 | function_argument_list "," expression 411 { world.functionCalls.top()->addArgument($expression); } 412 ; 413 414%type <ExprPtr> string_expression string_expression1; 415string_expression : string_expression1 { $$ = $1; } 416 | string_expression string_expression1 417 { $$ = std::make_shared<BinaryExpr>(BinaryOp::CONCAT, $1, $2, @1); } 418 ; 419 420%type <std::string> stringlit; 421stringlit : STRINGLIT { $$ = $1; } 422 | DOLLAR STRINGLIT { $$ = fromHex($2); } 423 ; 424 425string_expression1 : stringlit { $$ = std::make_shared<StringExpr>($1, @1); } 426 | "$$read" "(" string_expression ")" 427 { $$ = std::make_shared<ReadExpr>($string_expression, @1); } 428 ; 429 430resource : "resource" res_spec "{" resource_body "}" 431 { 432 world.addResource($res_spec, $resource_body, @1); 433 } 434 ; 435 436%type <ResSpec> res_spec; 437%type <ResSpec> resource_attributes; 438 439res_spec : res_type "(" expression resource_attributes ")" 440 { 441 $$ = $resource_attributes; 442 $$.type() = $res_type; 443 $$.id() = $expression->evaluateInt(nullptr); 444 } 445 ; 446 447resource_attributes : %empty { $$ = ResSpec(); } 448 | resource_attributes "," IDENTIFIER 449 { 450 $$ = $1; 451 if($IDENTIFIER == "changed") 452 $$.attr() |= 2; 453 else if($IDENTIFIER == "preload") 454 $$.attr() |= 4; 455 else if($IDENTIFIER == "protected") 456 $$.attr() |= 8; 457 else if($IDENTIFIER == "locked") 458 $$.attr() |= 16; 459 else if($IDENTIFIER == "purgeable") 460 $$.attr() |= 32; 461 else if($IDENTIFIER == "sysheap") 462 $$.attr() |= 64; 463 else if($IDENTIFIER == "unchanged") 464 $$.attr() &= ~2; 465 else if($IDENTIFIER == "nonpreload") 466 $$.attr() &= ~4; 467 else if($IDENTIFIER == "unprotected") 468 $$.attr() &= ~8; 469 else if($IDENTIFIER == "unlocked") 470 $$.attr() &= ~16; 471 else if($IDENTIFIER == "nonpurgeable") 472 $$.attr() &= ~32; 473 else if($IDENTIFIER == "appheap") 474 $$.attr() &= ~64; 475 else 476 world.problem(Diagnostic(Diagnostic::error, "illegal attribute " + $IDENTIFIER, @1)); 477 } 478 | resource_attributes "," string_expression 479 { 480 $$ = $1; 481 $$.name() = $3->evaluateString(nullptr); 482 } 483 ; 484 485 486 487%type <CompoundExprPtr> resource_body resource_body1; 488resource_body : %empty { $$ = std::make_shared<CompoundExpr>(yy::location()); } 489 | resource_body1 { $$ = $1; $$->location = @1; } 490 ; 491resource_body1 : resource_item { $$ = std::make_shared<CompoundExpr>(@1); $$->addItem($1); } 492 | resource_body1 "," resource_item { $$ = $1; $$->addItem($3); } 493 | resource_body1 ";" resource_item { $$ = $1; $$->addItem($3); } 494 | resource_body1 ";" { $$ = $1; } 495 | resource_body1 "," { $$ = $1; } 496 ; 497 498resource_item : value { $$ = $1; } 499 | IDENTIFIER "{" resource_body "}" { $$ = std::make_shared<CaseExpr>($IDENTIFIER, $resource_body, @1); } 500 ; 501 502 503data : "data" res_spec "{" string_expression "}" 504{ 505 world.addData($res_spec, $string_expression->evaluateString(nullptr), @1); 506} 507; 508 509%%