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