001package jmri.jmrit.logixng.util.parser; 002 003import java.util.ArrayList; 004import java.util.List; 005import java.util.Map; 006 007/** 008 * A recursive descent parser 009 * 010 * @author Daniel Bergqvist 2019 011 */ 012public class RecursiveDescentParser { 013 014 private List<Token> _tokens; 015 private final Map<String, Variable> _variables; 016 017 018 public RecursiveDescentParser(Map<String, Variable> variables) { 019 _variables = variables; 020 } 021 022 private State next(State state) { 023 int newTokenIndex = state._tokenIndex+1; 024 return new State(newTokenIndex, _tokens.get(newTokenIndex), state._tokenIndex, state._token); 025 } 026 027 028 private State accept(TokenType tokenType, State state) throws ParserException { 029 if (state._token == null) { 030 return null; 031 } 032 if (state._token._tokenType == tokenType) { 033 int newTokenIndex = state._tokenIndex+1; 034 Token newToken; 035 int lastTokenPos = state._lastTokenPos; 036 if (newTokenIndex < _tokens.size()) { 037 newToken = _tokens.get(newTokenIndex); 038 } else { 039 lastTokenPos = state._token._pos + state._token._string.length(); 040 newToken = null; 041 } 042 return new State(newTokenIndex, newToken, lastTokenPos, state._token); 043 } else { 044 return null; 045 } 046 } 047 048 049 private State expect(TokenType tokenType, State state) throws ParserException { 050 State newState = accept(tokenType, state); 051 if (newState == null) { 052 throw new InvalidSyntaxException(Bundle.getMessage("InvalidSyntax")); 053 } 054 return newState; 055 } 056 057 058 public ExpressionNode parseExpression(String expression) throws ParserException { 059 _tokens = Tokenizer.getTokens(expression); 060 061 if (_tokens.isEmpty()) { 062 return null; 063 } 064 065 ExpressionNodeAndState exprNodeAndState; 066 try { 067 exprNodeAndState = firstRule.parse(new State(0, _tokens.get(0), 0, new Token())); 068 } catch (NullPointerException e) { 069 throw new ParserException(Bundle.getMessage("UnableToParseFormula")); 070 } 071 072 if (exprNodeAndState == null) { 073 while (!_tokens.isEmpty() && _tokens.get(0)._tokenType.equals(TokenType.SPACE)) { 074 _tokens.remove(0); 075 } 076 if (!_tokens.isEmpty()) { 077 throw new InvalidSyntaxException(Bundle.getMessage("InvalidSyntax")); 078 } 079 return null; 080 } 081 082 if ((exprNodeAndState._state != null) 083 && (exprNodeAndState._state._tokenIndex < _tokens.size())) { 084 085 throw new InvalidSyntaxException(Bundle.getMessage("InvalidSyntaxNotFullyParsed", exprNodeAndState._state._tokenIndex)); 086 } 087 return exprNodeAndState._exprNode; 088 } 089 090 091 092 093 private static class State { 094 095 private final int _tokenIndex; 096 private final Token _token; 097 private final int _lastTokenPos; 098 private final Token _lastToken; 099 100 public State(int tokenIndex, Token token, int lastTokenPos, Token lastToken) { 101 _tokenIndex = tokenIndex; 102 _token = token; 103 _lastTokenPos = lastTokenPos; 104 _lastToken = lastToken; 105 } 106 } 107 108 109 private static class ExpressionNodeAndState { 110 private final ExpressionNode _exprNode; 111 private final State _state; 112 113 private ExpressionNodeAndState(ExpressionNode exprNode, State state) { 114 _exprNode = exprNode; 115 _state = state; 116 } 117 } 118 119 private interface Rule { 120 121 public ExpressionNodeAndState parse(State state) throws ParserException; 122 123 } 124 125 126 // The rules below are numbered from the list on this page: 127 // https://introcs.cs.princeton.edu/java/11precedence/ 128 129 private final Rule rule1 = new Rule1(); 130 private final Rule rule2 = new Rule2(); 131 private final Rule rule3a = new Rule3a(); 132 private final Rule rule3b = new Rule3b(); 133 private final Rule rule4 = new Rule4(); 134 private final Rule rule5 = new Rule5(); 135 private final Rule rule6 = new Rule6(); 136 private final Rule rule7 = new Rule7(); 137 private final Rule rule8 = new Rule8(); 138 private final Rule rule9 = new Rule9(); 139 private final Rule rule10 = new Rule10(); 140 private final Rule rule11 = new Rule11(); 141 private final Rule rule12 = new Rule12(); 142 private final Rule rule14 = new Rule14(); 143 private final Rule rule15 = new Rule15(); 144 private final Rule rule16 = new Rule16(); 145 private final Rule rule20 = new Rule20(); 146 private final Rule21_Function rule21_Function = new Rule21_Function(); 147 private final Rule21_Method rule21_Method = new Rule21_Method(); 148 149 private final Rule firstRule = rule1; 150 151 152 // Assignment 153 // <rule1> ::= <rule2> || 154 // <rule2> = <rule1> || 155 // <rule2> += <rule1> || 156 // <rule2> -= <rule1> || 157 // <rule2> *= <rule1> || 158 // <rule2> /= <rule1> || 159 // <rule2> %= <rule1> || 160 // <rule2> &= <rule1> || 161 // <rule2> ^= <rule1> || 162 // <rule2> |= <rule1> || 163 // <rule2> <<= <rule1> || 164 // <rule2> >>= <rule1> || 165 // <rule2> >>>= <rule1> 166 private class Rule1 implements Rule { 167 168 @Override 169 public ExpressionNodeAndState parse(State state) throws ParserException { 170 ExpressionNodeAndState leftSide = rule2.parse(state); 171 if (leftSide == null) { 172 return null; 173 } 174 State newState = leftSide._state; 175 if ((newState._token != null) 176 && ( 177 (newState._token._tokenType == TokenType.ASSIGN) 178 || (newState._token._tokenType == TokenType.ASSIGN_ADD) 179 || (newState._token._tokenType == TokenType.ASSIGN_SUBTRACKT) 180 || (newState._token._tokenType == TokenType.ASSIGN_MULTIPLY) 181 || (newState._token._tokenType == TokenType.ASSIGN_DIVIDE) 182 || (newState._token._tokenType == TokenType.ASSIGN_MODULO) 183 || (newState._token._tokenType == TokenType.ASSIGN_AND) 184 || (newState._token._tokenType == TokenType.ASSIGN_OR) 185 || (newState._token._tokenType == TokenType.ASSIGN_XOR) 186 || (newState._token._tokenType == TokenType.ASSIGN_SHIFT_LEFT) 187 || (newState._token._tokenType == TokenType.ASSIGN_SHIFT_RIGHT) 188 || (newState._token._tokenType == TokenType.ASSIGN_UNSIGNED_SHIFT_RIGHT) 189 )) { 190 191 TokenType operatorTokenType = newState._token._tokenType; 192 newState = next(newState); 193 ExpressionNodeAndState rightSide = rule2.parse(newState); 194 195 ExpressionNode exprNode = new ExpressionNodeAssignmentOperator(operatorTokenType, leftSide._exprNode, rightSide._exprNode); 196 leftSide = new ExpressionNodeAndState(exprNode, rightSide._state); 197 } 198 return leftSide; 199 } 200 201 } 202 203 204 // Rule2 is ternary. <rule3a> | <rule3a> ? <rule2> : <rule2> 205 private class Rule2 implements Rule { 206 207 @Override 208 public ExpressionNodeAndState parse(State state) throws ParserException { 209 ExpressionNodeAndState leftSide = rule3a.parse(state); 210 if (leftSide == null) { 211 return null; 212 } 213 State newState = leftSide._state; 214 if ((newState._token != null) 215 && ((newState._token._tokenType == TokenType.TERNARY_QUESTION_MARK))) { 216 217 newState = next(newState); 218 ExpressionNodeAndState middleSide = rule3a.parse(newState); 219 220 newState = middleSide._state; 221 222 if ((newState._token != null) 223 && ((newState._token._tokenType == TokenType.TERNARY_COLON))) { 224 225 newState = next(newState); 226 ExpressionNodeAndState rightRightSide = rule3a.parse(newState); 227 228 ExpressionNode exprNode = new ExpressionNodeTernaryOperator( 229 leftSide._exprNode, middleSide._exprNode, rightRightSide._exprNode); 230 leftSide = new ExpressionNodeAndState(exprNode, rightRightSide._state); 231 } else { 232 throw new InvalidSyntaxException(Bundle.getMessage("InvalidSyntax")); 233 } 234 } 235 return leftSide; 236 } 237 238 } 239 240 241 // Logical OR 242 // <rule3a> ::= <rule3b> | <rule3b> || <rule3b> 243 private class Rule3a implements Rule { 244 245 @Override 246 public ExpressionNodeAndState parse(State state) throws ParserException { 247 ExpressionNodeAndState leftSide = rule3b.parse(state); 248 if (leftSide == null) { 249 return null; 250 } 251 State newState = leftSide._state; 252 while ((newState._token != null) 253 && ((newState._token._tokenType == TokenType.BOOLEAN_OR))) { 254 255 TokenType operatorTokenType = newState._token._tokenType; 256 newState = next(newState); 257 ExpressionNodeAndState rightSide = rule3b.parse(newState); 258 259 ExpressionNode exprNode = new ExpressionNodeBooleanOperator(operatorTokenType, leftSide._exprNode, rightSide._exprNode); 260 leftSide = new ExpressionNodeAndState(exprNode, rightSide._state); 261 newState = rightSide._state; 262 } 263 return leftSide; 264 } 265 266 } 267 268 269 // Logical OR 270 // <rule3b> ::= <rule4> | <rule4> || <rule4> 271 private class Rule3b implements Rule { 272 273 @Override 274 public ExpressionNodeAndState parse(State state) throws ParserException { 275 ExpressionNodeAndState leftSide = rule4.parse(state); 276 if (leftSide == null) { 277 return null; 278 } 279 State newState = leftSide._state; 280 while ((newState._token != null) 281 && ((newState._token._tokenType == TokenType.BOOLEAN_XOR))) { 282 283 TokenType operatorTokenType = newState._token._tokenType; 284 newState = next(newState); 285 ExpressionNodeAndState rightSide = rule4.parse(newState); 286 287 ExpressionNode exprNode = new ExpressionNodeBooleanOperator(operatorTokenType, leftSide._exprNode, rightSide._exprNode); 288 leftSide = new ExpressionNodeAndState(exprNode, rightSide._state); 289 newState = rightSide._state; 290 } 291 return leftSide; 292 } 293 294 } 295 296 297 // Logical AND 298 // <rule4> ::= <rule5> | <rule5> && <rule5> 299 private class Rule4 implements Rule { 300 301 @Override 302 public ExpressionNodeAndState parse(State state) throws ParserException { 303 ExpressionNodeAndState leftSide = rule5.parse(state); 304 if (leftSide == null) { 305 return null; 306 } 307 State newState = leftSide._state; 308 while ((newState._token != null) 309 && ((newState._token._tokenType == TokenType.BOOLEAN_AND))) { 310 311 TokenType operatorTokenType = newState._token._tokenType; 312 newState = next(newState); 313 ExpressionNodeAndState rightSide = rule5.parse(newState); 314 315 ExpressionNode exprNode = new ExpressionNodeBooleanOperator(operatorTokenType, leftSide._exprNode, rightSide._exprNode); 316 leftSide = new ExpressionNodeAndState(exprNode, rightSide._state); 317 newState = rightSide._state; 318 } 319 return leftSide; 320 } 321 322 } 323 324 325 // Bitwise OR 326 // <rule5> ::= <rule6> | <rule6> | <rule6> 327 private class Rule5 implements Rule { 328 329 @Override 330 public ExpressionNodeAndState parse(State state) throws ParserException { 331 ExpressionNodeAndState leftSide = rule6.parse(state); 332 if (leftSide == null) { 333 return null; 334 } 335 State newState = leftSide._state; 336 while ((newState._token != null) 337 && ((newState._token._tokenType == TokenType.BINARY_OR))) { 338 339 TokenType operatorTokenType = newState._token._tokenType; 340 newState = next(newState); 341 ExpressionNodeAndState rightSide = rule6.parse(newState); 342 343 ExpressionNode exprNode = new ExpressionNodeBinaryOperator(operatorTokenType, leftSide._exprNode, rightSide._exprNode); 344 leftSide = new ExpressionNodeAndState(exprNode, rightSide._state); 345 newState = rightSide._state; 346 } 347 return leftSide; 348 } 349 350 } 351 352 353 // Bitwise XOR 354 // <rule6> ::= <rule7> | <rule7> ^ <rule7> 355 private class Rule6 implements Rule { 356 357 @Override 358 public ExpressionNodeAndState parse(State state) throws ParserException { 359 ExpressionNodeAndState leftSide = rule7.parse(state); 360 if (leftSide == null) { 361 return null; 362 } 363 State newState = leftSide._state; 364 while ((newState._token != null) 365 && ((newState._token._tokenType == TokenType.BINARY_XOR))) { 366 367 TokenType operatorTokenType = newState._token._tokenType; 368 newState = next(newState); 369 ExpressionNodeAndState rightSide = rule7.parse(newState); 370 371 ExpressionNode exprNode = new ExpressionNodeBinaryOperator(operatorTokenType, leftSide._exprNode, rightSide._exprNode); 372 leftSide = new ExpressionNodeAndState(exprNode, rightSide._state); 373 newState = rightSide._state; 374 } 375 return leftSide; 376 } 377 378 } 379 380 381 // Bitwise AND 382 // <rule7> ::= <rule8> | <rule8> & <rule8> 383 private class Rule7 implements Rule { 384 385 @Override 386 public ExpressionNodeAndState parse(State state) throws ParserException { 387 ExpressionNodeAndState leftSide = rule8.parse(state); 388 if (leftSide == null) { 389 return null; 390 } 391 State newState = leftSide._state; 392 while ((newState._token != null) 393 && ((newState._token._tokenType == TokenType.BINARY_AND))) { 394 395 TokenType operatorTokenType = newState._token._tokenType; 396 newState = next(newState); 397 ExpressionNodeAndState rightSide = rule8.parse(newState); 398 399 ExpressionNode exprNode = new ExpressionNodeBinaryOperator(operatorTokenType, leftSide._exprNode, rightSide._exprNode); 400 leftSide = new ExpressionNodeAndState(exprNode, rightSide._state); 401 newState = rightSide._state; 402 } 403 return leftSide; 404 } 405 406 } 407 408 409 // Equality 410 // <rule8> ::= <rule9> | <rule9> == <rule9> | <rule9> != <rule9> 411 private class Rule8 implements Rule { 412 413 @Override 414 public ExpressionNodeAndState parse(State state) throws ParserException { 415 ExpressionNodeAndState leftSide = rule9.parse(state); 416 if (leftSide == null) { 417 return null; 418 } 419 State newState = leftSide._state; 420 while ((newState._token != null) 421 && ((newState._token._tokenType == TokenType.EQUAL) 422 || (newState._token._tokenType == TokenType.NOT_EQUAL))) { 423 424 TokenType operatorTokenType = newState._token._tokenType; 425 newState = next(newState); 426 ExpressionNodeAndState rightSide = rule9.parse(newState); 427 428 ExpressionNode exprNode = new ExpressionNodeComparingOperator(operatorTokenType, leftSide._exprNode, rightSide._exprNode); 429 leftSide = new ExpressionNodeAndState(exprNode, rightSide._state); 430 newState = rightSide._state; 431 } 432 return leftSide; 433 } 434 435 } 436 437 438 // Relational 439 // <rule9> ::= <rule10> | <rule10> < <rule10> | <rule10> <= <rule10> | <rule10> > <rule10> | <rule10> >= <rule10> 440 private class Rule9 implements Rule { 441 442 @Override 443 public ExpressionNodeAndState parse(State state) throws ParserException { 444 ExpressionNodeAndState leftSide = rule10.parse(state); 445 if (leftSide == null) { 446 return null; 447 } 448 State newState = leftSide._state; 449 while ((newState._token != null) 450 && ((newState._token._tokenType == TokenType.LESS_THAN) 451 || (newState._token._tokenType == TokenType.LESS_OR_EQUAL) 452 || (newState._token._tokenType == TokenType.GREATER_THAN) 453 || (newState._token._tokenType == TokenType.GREATER_OR_EQUAL))) { 454 455 TokenType operatorTokenType = newState._token._tokenType; 456 newState = next(newState); 457 ExpressionNodeAndState rightSide = rule10.parse(newState); 458 459 ExpressionNode exprNode = new ExpressionNodeComparingOperator(operatorTokenType, leftSide._exprNode, rightSide._exprNode); 460 leftSide = new ExpressionNodeAndState(exprNode, rightSide._state); 461 newState = rightSide._state; 462 } 463 return leftSide; 464 } 465 466 } 467 468 469 // Shift 470 // <rule10> ::= <rule11> | <rule11> << <rule11> | <rule11> >> <rule11> | <rule11> >>> <rule11> 471 private class Rule10 implements Rule { 472 473 @Override 474 public ExpressionNodeAndState parse(State state) throws ParserException { 475 ExpressionNodeAndState leftSide = rule11.parse(state); 476 if (leftSide == null) { 477 return null; 478 } 479 State newState = leftSide._state; 480 while ((newState._token != null) 481 && ((newState._token._tokenType == TokenType.SHIFT_LEFT) 482 || (newState._token._tokenType == TokenType.SHIFT_RIGHT) 483 || (newState._token._tokenType == TokenType.UNSIGNED_SHIFT_RIGHT))) { 484 485 TokenType operatorTokenType = newState._token._tokenType; 486 newState = next(newState); 487 ExpressionNodeAndState rightSide = rule11.parse(newState); 488 489 ExpressionNode exprNode = new ExpressionNodeArithmeticOperator(operatorTokenType, leftSide._exprNode, rightSide._exprNode); 490 leftSide = new ExpressionNodeAndState(exprNode, rightSide._state); 491 newState = rightSide._state; 492 } 493 return leftSide; 494 } 495 496 } 497 498 499 // Additive 500 // <rule11> ::= <rule12> | <rule12> + <rule12> | <rule12> - <rule12> 501 private class Rule11 implements Rule { 502 503 @Override 504 public ExpressionNodeAndState parse(State state) throws ParserException { 505 ExpressionNodeAndState leftSide = rule12.parse(state); 506 if (leftSide == null) { 507 return null; 508 } 509 State newState = leftSide._state; 510 while ((newState._token != null) 511 && ((newState._token._tokenType == TokenType.ADD) 512 || (newState._token._tokenType == TokenType.SUBTRACKT))) { 513 514 TokenType operatorTokenType = newState._token._tokenType; 515 newState = next(newState); 516 ExpressionNodeAndState rightSide = rule12.parse(newState); 517 518 ExpressionNode exprNode = new ExpressionNodeArithmeticOperator(operatorTokenType, leftSide._exprNode, rightSide._exprNode); 519 leftSide = new ExpressionNodeAndState(exprNode, rightSide._state); 520 newState = rightSide._state; 521 } 522 return leftSide; 523 } 524 525 } 526 527 528 // Multiplicative 529 // <rule12> ::= <rule13> | <rule13> * <rule13> | <rule13> / <rule13> | <rule13> % <rule13> 530 private class Rule12 implements Rule { 531 532 @Override 533 public ExpressionNodeAndState parse(State state) throws ParserException { 534 ExpressionNodeAndState leftSide = rule14.parse(state); 535 if (leftSide == null) { 536 return null; 537 } 538 State newState = leftSide._state; 539 while ((newState._token != null) 540 && ((newState._token._tokenType == TokenType.MULTIPLY) 541 || (newState._token._tokenType == TokenType.DIVIDE) 542 || (newState._token._tokenType == TokenType.MODULO))) { 543 544 TokenType operatorTokenType = newState._token._tokenType; 545 newState = next(newState); 546 ExpressionNodeAndState rightSide = rule14.parse(newState); 547 548 ExpressionNode exprNode = new ExpressionNodeArithmeticOperator(operatorTokenType, leftSide._exprNode, rightSide._exprNode); 549 leftSide = new ExpressionNodeAndState(exprNode, rightSide._state); 550 newState = rightSide._state; 551 } 552 return leftSide; 553 } 554 555 } 556 557 558 // Rule13 in Java is cast object and object creation. Not relevant here. 559 560 561 // Unary pre-increment, unary pre-decrement, unary plus, unary minus, unary logical NOT, unary bitwise NOT 562 // <rule14> ::= <rule16> | ++ <rule16> | -- <rule16> | + <rule16> | - <rule16> | ! <rule16> | ~ <rule16> 563 private class Rule14 implements Rule { 564 565 @Override 566 public ExpressionNodeAndState parse(State state) throws ParserException { 567 State newState = accept(TokenType.BOOLEAN_NOT, state); 568 569 if (newState != null) { 570 ExpressionNodeAndState exprNodeAndState = rule14.parse(newState); 571 if (exprNodeAndState._exprNode == null) { 572 throw new InvalidSyntaxException(Bundle.getMessage("InvalidSyntax")); 573 } 574 575 ExpressionNode exprNode = new ExpressionNodeBooleanOperator(newState._lastToken._tokenType, null, exprNodeAndState._exprNode); 576 return new ExpressionNodeAndState(exprNode, exprNodeAndState._state); 577 578 } else { 579 newState = accept(TokenType.BINARY_NOT, state); 580 581 if (newState != null) { 582 ExpressionNodeAndState exprNodeAndState = rule14.parse(newState); 583 584 ExpressionNode exprNode = new ExpressionNodeArithmeticOperator(newState._lastToken._tokenType, null, exprNodeAndState._exprNode); 585 return new ExpressionNodeAndState(exprNode, exprNodeAndState._state); 586 587 } else { 588 newState = accept(TokenType.ADD, state); 589 590 if (newState != null) { 591 ExpressionNodeAndState exprNodeAndState = rule14.parse(newState); 592 593 ExpressionNode exprNode = new ExpressionNodeArithmeticOperator(newState._lastToken._tokenType, null, exprNodeAndState._exprNode); 594 return new ExpressionNodeAndState(exprNode, exprNodeAndState._state); 595 596 } else { 597 newState = accept(TokenType.SUBTRACKT, state); 598 599 if (newState != null) { 600 ExpressionNodeAndState exprNodeAndState = rule14.parse(newState); 601 602 ExpressionNode exprNode = new ExpressionNodeArithmeticOperator(newState._lastToken._tokenType, null, exprNodeAndState._exprNode); 603 return new ExpressionNodeAndState(exprNode, exprNodeAndState._state); 604 605 } else { 606 newState = accept(TokenType.INCREMENT, state); 607 608 if (newState != null) { 609 ExpressionNodeAndState exprNodeAndState = rule15.parse(newState); 610 if (exprNodeAndState == null) { 611 throw new InvalidSyntaxException(Bundle.getMessage("InvalidSyntax")); 612 } 613 614 ExpressionNode exprNode = new ExpressionNodeIncreaseDecreaseOperator(newState._lastToken._tokenType, exprNodeAndState._exprNode, true); 615 return new ExpressionNodeAndState(exprNode, exprNodeAndState._state); 616 617 } else { 618 newState = accept(TokenType.DECREMENT, state); 619 620 if (newState != null) { 621 ExpressionNodeAndState exprNodeAndState = rule15.parse(newState); 622 if (exprNodeAndState == null) { 623 throw new InvalidSyntaxException(Bundle.getMessage("InvalidSyntax")); 624 } 625 626 ExpressionNode exprNode = new ExpressionNodeIncreaseDecreaseOperator(newState._lastToken._tokenType, exprNodeAndState._exprNode, true); 627 return new ExpressionNodeAndState(exprNode, exprNodeAndState._state); 628 629 } else { 630 return rule15.parse(state); 631 } 632 } 633 } 634 } 635 } 636 } 637 } 638 639 } 640 641 642 // Rule15 in Java is unary post-increment, unary post-decrement, ++ and --. 643 private class Rule15 implements Rule { 644 645 @Override 646 public ExpressionNodeAndState parse(State state) throws ParserException { 647 648 ExpressionNodeAndState exprNodeAndState = rule16.parse(state); 649 if (exprNodeAndState == null) return null; 650 651 State newState = accept(TokenType.INCREMENT, exprNodeAndState._state); 652 653 if (newState != null) { 654 ExpressionNode exprNode = new ExpressionNodeIncreaseDecreaseOperator(newState._lastToken._tokenType, exprNodeAndState._exprNode, false); 655 return new ExpressionNodeAndState(exprNode, newState); 656 } else { 657 newState = accept(TokenType.DECREMENT, exprNodeAndState._state); 658 659 if (newState != null) { 660 ExpressionNode exprNode = new ExpressionNodeIncreaseDecreaseOperator(newState._lastToken._tokenType, exprNodeAndState._exprNode, false); 661 return new ExpressionNodeAndState(exprNode, newState); 662 } else { 663 return exprNodeAndState; 664 } 665 } 666 } 667 668 } 669 670 671 // Parentheses 672 // <rule16> ::= <rule20> | ( <firstRule> ) 673 private class Rule16 implements Rule { 674 675 @Override 676 public ExpressionNodeAndState parse(State state) throws ParserException { 677 678 State newState = accept(TokenType.LEFT_PARENTHESIS, state); 679 680 if (newState != null) { 681 ExpressionNodeAndState exprNodeAndState = firstRule.parse(newState); 682 if (exprNodeAndState._state._token == null) { 683 throw new InvalidSyntaxException(Bundle.getMessage("InvalidSyntax")); 684 } 685 newState = expect(TokenType.RIGHT_PARENTHESIS, exprNodeAndState._state); 686 return new ExpressionNodeAndState(exprNodeAndState._exprNode, newState); 687 } else { 688 return rule20.parse(state); 689 } 690 } 691 692 } 693 694 695 // Identifiers and constants 696 // <rule20> ::= <identifier> 697 // | <identifier> ( <rule21> ) 698 // | <rule20> [ <rule21> ] 699 // | <rule20> { <rule21> } 700 // | <rule20> . <rule20> 701 // | <rule20> . <identifier> ( <rule21> ) 702 703 // <rule20> ::= <identifier> 704 // | <identifier> ( <rule21> ) 705 // | <identifier> [ <rule21> ] 706 // | <identifier> { <rule21> } 707 // | <identifier> . <identifier> 708 // | <identifier> . <identifier> ( <rule21> ) 709 // | <identifier> . <identifier> [ <rule21> ] 710 // | <identifier> . <identifier> { <rule21> } 711 // | <identifier> . <identifier> 712 // | <identifier> . <identifier> . <identifier> ( <rule21> ) 713 // | <identifier> . <identifier> . <identifier> [ <rule21> ] 714 // | <identifier> . <identifier> . <identifier> { <rule21> } 715 // | <identifier> . <identifier> ( <rule21> ) . <identifier> ( <rule21> ) 716 // | <identifier> . <identifier> ( <rule21> ) . <identifier> [ <rule21> ] 717 // | <identifier> . <identifier> ( <rule21> ) . <identifier> { <rule21> } 718 // | <integer number> 719 // | <floating number> 720 // | <string> 721 private class Rule20 implements Rule { 722 723 @Override 724 public ExpressionNodeAndState parse(State state) throws ParserException { 725 ExpressionNode exprNode; 726 State newState; 727 728 // Do we have an integer? 729 if ((newState = accept(TokenType.INTEGER_NUMBER, state)) != null) { 730 exprNode = new ExpressionNodeIntegerNumber(newState._lastToken); 731 return new ExpressionNodeAndState(exprNode, newState); 732 733 // Or do we have a floating point number? 734 } else if ((newState = accept(TokenType.FLOATING_NUMBER, state)) != null) { 735 exprNode = new ExpressionNodeFloatingNumber(newState._lastToken); 736 return new ExpressionNodeAndState(exprNode, newState); 737 } 738 739 740 // Do we have an identifier or a function? 741 ExpressionNodeAndState expressionNodeAndState; 742 if ((newState = accept(TokenType.IDENTIFIER, state)) != null) { 743 State newState2; 744 if ((newState2 = accept(TokenType.LEFT_PARENTHESIS, newState)) != null) { 745 ExpressionNodeAndState exprNodeAndState = 746 rule21_Function.parse(newState2, newState._lastToken._string); 747 if (exprNodeAndState._state._token == null) { 748 throw new InvalidSyntaxException(Bundle.getMessage("InvalidSyntax")); 749 } 750 exprNode = exprNodeAndState._exprNode; 751 newState2 = expect(TokenType.RIGHT_PARENTHESIS, exprNodeAndState._state); 752 expressionNodeAndState = new ExpressionNodeAndState(exprNodeAndState._exprNode, newState2); 753 } else { 754 exprNode = new ExpressionNodeIdentifier(newState._lastToken, _variables); 755 expressionNodeAndState = new ExpressionNodeAndState(exprNode, newState); 756 } 757 } else if ((newState = accept(TokenType.STRING, state)) != null) { 758 exprNode = new ExpressionNodeString(newState._lastToken); 759 expressionNodeAndState = new ExpressionNodeAndState(exprNode, newState); 760 } else { 761 return null; 762 } 763 764 765 // If here, we have an identifier or a function. 766 // Do we have a dot followed by a method call? 767 boolean completed = false; 768 do { 769 State newState2; 770 if ((newState2 = accept(TokenType.DOT, newState)) != null) { 771 State newState3; 772 if ((newState3 = accept(TokenType.IDENTIFIER, newState2)) != null) { 773 State newState4; 774 if ((newState4 = accept(TokenType.LEFT_PARENTHESIS, newState3)) != null) { 775 ExpressionNodeAndState exprNodeAndState2 = 776 rule21_Method.parse(newState4, newState._lastToken._string, newState3._lastToken._string); 777 if (exprNodeAndState2._state._token == null) { 778 throw new InvalidSyntaxException(Bundle.getMessage("InvalidSyntax")); 779 } 780 newState4 = expect(TokenType.RIGHT_PARENTHESIS, exprNodeAndState2._state); 781 exprNode = new ExpressionNodeComplex( 782 exprNode, (ExpressionNodeWithParameter) exprNodeAndState2._exprNode); 783 expressionNodeAndState = new ExpressionNodeAndState(exprNode, newState4); 784 newState = newState4; 785 } else { 786 exprNode = new ExpressionNodeComplex( 787 exprNode, 788 new ExpressionNodeInstanceVariable(newState3._lastToken._string, _variables)); 789 expressionNodeAndState = new ExpressionNodeAndState(exprNode, newState3); 790 newState = newState3; 791 } 792 } else { 793 throw new InvalidSyntaxException(Bundle.getMessage("InvalidSyntax")); 794 } 795 } else if ((newState2 = accept(TokenType.LEFT_SQUARE_BRACKET, newState)) != null) { 796 State newState3; 797 ExpressionNodeAndState exprNodeAndState2 = rule1.parse(newState2); 798 if (exprNodeAndState2._state._token == null) { 799 throw new InvalidSyntaxException(Bundle.getMessage("InvalidSyntax")); 800 } 801 newState3 = expect(TokenType.RIGHT_SQUARE_BRACKET, exprNodeAndState2._state); 802 exprNode = new ExpressionNodeComplex( 803 exprNode, 804 new ExpressionNodeArray(exprNodeAndState2._exprNode)); 805 expressionNodeAndState = new ExpressionNodeAndState(exprNode, newState3); 806 newState = newState3; 807 } else if ((newState2 = accept(TokenType.LEFT_CURLY_BRACKET, newState)) != null) { 808 State newState3; 809 ExpressionNodeAndState exprNodeAndState2 = rule1.parse(newState2); 810 if (exprNodeAndState2._state._token == null) { 811 throw new InvalidSyntaxException(Bundle.getMessage("InvalidSyntax")); 812 } 813 newState3 = expect(TokenType.RIGHT_CURLY_BRACKET, exprNodeAndState2._state); 814 exprNode = new ExpressionNodeComplex( 815 exprNode, 816 new ExpressionNodeMap(exprNodeAndState2._exprNode)); 817 expressionNodeAndState = new ExpressionNodeAndState(exprNode, newState3); 818 newState = newState3; 819 } else { 820 completed = true; 821 } 822 } while (!completed); 823 824 return expressionNodeAndState; 825 } 826 827 } 828 829 830 // <rule21> ::= <empty> | <rule21> | <rule21> , <firstRule> 831 private class Rule21_Function { 832 833 public ExpressionNodeAndState parse(State state, String identifier) throws ParserException { 834 835 List<ExpressionNode> parameterList = new ArrayList<>(); 836 837 State newState = state; 838 State newState2; 839 if ((accept(TokenType.RIGHT_PARENTHESIS, newState)) == null) { 840 ExpressionNodeAndState exprNodeAndState = firstRule.parse(state); 841 parameterList.add(exprNodeAndState._exprNode); 842 843 while ((newState2 = accept(TokenType.COMMA, exprNodeAndState._state)) != null) { 844 exprNodeAndState = firstRule.parse(newState2); 845 parameterList.add(exprNodeAndState._exprNode); 846 } 847 848 newState = exprNodeAndState._state; 849 } 850 ExpressionNode exprNode = new ExpressionNodeFunction(identifier, parameterList); 851 return new ExpressionNodeAndState(exprNode, newState); 852 } 853 854 } 855 856 857 // <rule21> ::= <empty> | <rule21> | <rule21> , <firstRule> 858 private class Rule21_Method { 859 860 public ExpressionNodeAndState parse(State state, String variable, String method) throws ParserException { 861 862 List<ExpressionNode> parameterList = new ArrayList<>(); 863 864 State newState = state; 865 State newState2; 866 if ((accept(TokenType.RIGHT_PARENTHESIS, newState)) == null) { 867 ExpressionNodeAndState exprNodeAndState = firstRule.parse(state); 868 if (exprNodeAndState == null) { 869 throw new InvalidSyntaxException(Bundle.getMessage("InvalidSyntax")); 870 } 871 parameterList.add(exprNodeAndState._exprNode); 872 873 while ((newState2 = accept(TokenType.COMMA, exprNodeAndState._state)) != null) { 874 exprNodeAndState = firstRule.parse(newState2); 875 if (exprNodeAndState == null) { 876 throw new InvalidSyntaxException(Bundle.getMessage("InvalidSyntax")); 877 } 878 parameterList.add(exprNodeAndState._exprNode); 879 } 880 881 newState = exprNodeAndState._state; 882 } 883 ExpressionNode exprNode = new ExpressionNodeMethod(method, _variables, parameterList); 884 return new ExpressionNodeAndState(exprNode, newState); 885 } 886 887 } 888 889 890}