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}