View Javadoc
1   // Generated from eu/simuline/relana/parser/Formula.g4 by ANTLR 4.7
2   package eu.simuline.relana.parser;
3   
4       import eu.simuline.relana.model.CClass;
5       import eu.simuline.relana.model.SClass;
6       import eu.simuline.relana.model.CClassLoader;
7       import eu.simuline.relana.model.MapDecl;
8       import eu.simuline.relana.model.Deficiency;
9       import eu.simuline.relana.model.DeficiencyMap;
10      import eu.simuline.relana.model.ClassLocator;
11  
12      import eu.simuline.relana.expressions.FormulaDecl;
13      import eu.simuline.relana.expressions.Operation;
14      import eu.simuline.relana.expressions.Type;
15  
16      import java.io.Reader;
17      import java.io.IOException;
18  
19      import java.util.Set;
20      import java.util.HashSet;
21      import java.util.Stack;
22  
23  import org.antlr.v4.runtime.atn.*;
24  import org.antlr.v4.runtime.dfa.DFA;
25  import org.antlr.v4.runtime.*;
26  import org.antlr.v4.runtime.misc.*;
27  import org.antlr.v4.runtime.tree.*;
28  import java.util.List;
29  import java.util.Iterator;
30  import java.util.ArrayList;
31  
32  @SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
33  public class FormulaParser extends Parser {
34  	static { RuntimeMetaData.checkVersion("4.7", RuntimeMetaData.VERSION); }
35  
36  	protected static final DFA[] _decisionToDFA;
37  	protected static final PredictionContextCache _sharedContextCache =
38  		new PredictionContextCache();
39  	public static final int
40  		T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, T__5=6, WS=7, SingleLineComment=8, 
41  		MultiLineComment=9, INV=10, COV=11, CONT=12, END=13, SEP=14, UNION=15, 
42  		INTERSECT=16, COMPLEMENT=17, NAME=18;
43  	public static final int
44  		RULE_formula = 0, RULE_constFormula = 1, RULE_varFormula = 2, RULE_compFormula = 3, 
45  		RULE_addFormula = 4, RULE_path = 5;
46  	public static final String[] ruleNames = {
47  		"formula", "constFormula", "varFormula", "compFormula", "addFormula", 
48  		"path"
49  	};
50  
51  	private static final String[] _LITERAL_NAMES = {
52  		null, "'<'", "'>'", "'{'", "'}'", "'('", "')'", null, null, null, "'!'", 
53  		"','", "'''", "';'", "'.'", "'|'", "'&'", "'~'"
54  	};
55  	private static final String[] _SYMBOLIC_NAMES = {
56  		null, null, null, null, null, null, null, "WS", "SingleLineComment", "MultiLineComment", 
57  		"INV", "COV", "CONT", "END", "SEP", "UNION", "INTERSECT", "COMPLEMENT", 
58  		"NAME"
59  	};
60  	public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
61  
62  	/**
63  	 * @deprecated Use {@link #VOCABULARY} instead.
64  	 */
65  	@Deprecated
66  	public static final String[] tokenNames;
67  	static {
68  		tokenNames = new String[_SYMBOLIC_NAMES.length];
69  		for (int i = 0; i < tokenNames.length; i++) {
70  			tokenNames[i] = VOCABULARY.getLiteralName(i);
71  			if (tokenNames[i] == null) {
72  				tokenNames[i] = VOCABULARY.getSymbolicName(i);
73  			}
74  
75  			if (tokenNames[i] == null) {
76  				tokenNames[i] = "<INVALID>";
77  			}
78  		}
79  	}
80  
81  	@Override
82  	@Deprecated
83  	public String[] getTokenNames() {
84  		return tokenNames;
85  	}
86  
87  	@Override
88  
89  	public Vocabulary getVocabulary() {
90  		return VOCABULARY;
91  	}
92  
93  	@Override
94  	public String getGrammarFileName() { return "Formula.g4"; }
95  
96  	@Override
97  	public String[] getRuleNames() { return ruleNames; }
98  
99  	@Override
100 	public String getSerializedATN() { return _serializedATN; }
101 
102 	@Override
103 	public ATN getATN() { return _ATN; }
104 
105 
106 
107 	    /* -------------------------------------------------------------------- *
108 	     * fields.                                                              *
109 	     * -------------------------------------------------------------------- */
110 
111 	    private CClassLoader classLoader;
112 	    private CClass cClass;
113 	    private ClassLocator loc;
114 	    private boolean exceptionThrown;
115 
116 	    private int lineNumber;
117 	    private int colnNumber;
118 
119 	    // for data exchange between nodes **** 
120 
121 	    /**
122 	     * The stack of incompletely parsed levels of formulae. 
123 	     * Created by getCompFormula, populated by addFormula
124 	     */
125 	    Stack<Set<FormulaDecl>> argsStack = new Stack<Set<FormulaDecl>>();
126 
127 	    /**
128 	     * Represents a path. 
129 	     * Required by constFormula and varFormula, set by path. 
130 	     */
131 	    List<String> path;
132 
133 	    /**
134 	     * 'Returned by constFormula, varFormula and compFormula. 
135 	     * For recursive parsing of nested formulae: 
136 	     * Added as an argument of an enclosing formula to {@link #argsStack} 
137 	     * by rule addFormula. 
138 	     */
139 	    FormulaDecl fDecl;
140 
141 	    /* -------------------------------------------------------------------- *
142 	     * constructors and creator methods.                                    *
143 	     * -------------------------------------------------------------------- */
144 
145 	//    private static org.antlr.v4.runtime.CommonTokenStream 
146 	//        reader2tokenStream(Reader reader)   
147 	//		throws IOException {
148 	//        org.antlr.v4.runtime.ANTLRInputStream antlrStream = 
149 	//            new org.antlr.v4.runtime.ANTLRInputStream(reader);
150 	//        FormulaLexer lexer = new FormulaLexer(antlrStream);
151 	//        return new CommonTokenStream(lexer);
152 	//    }
153 
154 	//    FormulaParser(Reader reader) {
155 	//        this(reader2tokenStream(reader));
156 	//    }
157 
158 
159 	    /* -------------------------------------------------------------------- *
160 	     * methods.                                                             *
161 	     * -------------------------------------------------------------------- */
162 
163 	    void setLineColNum(int lineNumber, int colnNumber) {
164 	        this.lineNumber = lineNumber;
165 	        this.colnNumber = colnNumber;
166 	    }
167 
168 	    /**
169 	     * To set the <code>CClassLoader</code>. 
170 	     * This is needed whenever the definition of the class currently read 
171 	     * relies on definitions of other classes such as 
172 	     * the superclass if it is given explicitly. 
173 	     * 
174 	     * @param classLoader
175 	     *    the current <code>SClassLoader</code>. 
176 	     */
177 	    public void setClassLoader(CClassLoader classLoader) {
178 	        this.classLoader = classLoader;
179 	    }
180 
181 	    /**
182 	     * Sets the locator for the class currently parsed. 
183 	     * This is needed to analyze formulae in a second parsing step 
184 	     * when all <code>SClass</code> declarations are clarified. 
185 	     * 
186 	     * @param loc
187 	     *    the location of the class currently parsed. 
188 	     */
189 	    void setLocator(ClassLocator loc) {
190 	        this.loc = loc;
191 	    }
192 
193 	    /**
194 	     * Sets the <code>CClass</code> for the class currently parsed 
195 	     * but without formulae. 
196 	     * This is needed to analyze formulae in a second parsing step 
197 	     * when all <code>SClass</code> declarations are clarified. 
198 	     * 
199 	     * @param cClass
200 	     *    
201 	     */
202 	    void setCClass(CClass cClass) {
203 	        this.cClass = cClass;
204 	    }
205 
206 	    /**
207 	     * Returns the all in all formula invoking rule 'formula'. 
208 	     */
209 	    FormulaDecl getFormulaStart() {
210 	        formula();
211 	        return this.fDecl;
212 	    }
213 
214 	    /**
215 	     * Returns a string comprising the current class, 
216 	     * the number of the current line and column, 
217 	     * the last token successfully read and the token tp be read next. 
218 	     *
219 	     * @return
220 	     *    a <code>String</code> of the form 
221 	     *    <code>[{@link #loc}] line ##, column ## 
222 	     *    between tokenRead and tokenToBeRead</code>. 
223 	     */
224 	    String getLocation() {
225 	        StringBuffer result = new StringBuffer();
226 	        Token token = this.getTokenStream().LT(0);
227 	        result.append("[" + this.loc + "] ");
228 	        if (token == null) {
229 	            result.append("no token ");
230 	        } else {
231 	            result.append("line "     + 
232 	                          (token.getLine()-1            +this.lineNumber));
233 	            result.append(", column " + 
234 	                          (token.getCharPositionInLine()+this.colnNumber));
235 	        result.append(", after \"" + token);
236 	        }
237 	        result.append("\": ");
238 	        
239 	        return result.toString();
240 	    }
241 
242 	    /**
243 	     * Reports an error and also the location where it occurred. 
244 	     * **** same as in SClassParser **** 
245 	     * 
246 	     * @param msg 
247 	     *    the message to be displayed. 
248 	     */
249 	//    void report(String msg) throws ParseException {
250 	    void report(String msg) throws RuntimeException {
251 	        System.out.print(getLocation());
252 	        RuntimeException pe = new RuntimeException(msg);
253 	        //System.out.println(pe.getMessage());
254 	        this.exceptionThrown = true;
255 	        throw pe;
256 	    } // report
257 
258 	//    public static void main(String[] args) throws Exception {
259 	//        Reader str = new java.io.StringReader(args[0]);
260 	//System.out.println("str: "+str);
261 	//java.io.StringWriter wr = new java.io.StringWriter();
262 	//while (true) {
263 	//int ch = str.read();
264 	//if (ch == -1) {System.out.println("wr: "+wr);break;}
265 	//wr.write(ch);
266 	//}
267 	//        FormulaParser fParser = new FormulaParser((Reader)null);
268 	//fParser.setCClass(CClass.COMPONENT);
269 	//        fParser.ReInit(str);
270 	//        //fParser.setLineColNum(entry.getValue().lineNumber,
271 	//        //                      entry.getValue().colnNumber);
272 	//       fParser.getFormula();
273 	//    }
274 
275 
276 	public FormulaParser(TokenStream input) {
277 		super(input);
278 		_interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
279 	}
280 	public static class FormulaContext extends ParserRuleContext {
281 		public ConstFormulaContext constFormula() {
282 			return getRuleContext(ConstFormulaContext.class,0);
283 		}
284 		public CompFormulaContext compFormula() {
285 			return getRuleContext(CompFormulaContext.class,0);
286 		}
287 		public VarFormulaContext varFormula() {
288 			return getRuleContext(VarFormulaContext.class,0);
289 		}
290 		public FormulaContext(ParserRuleContext parent, int invokingState) {
291 			super(parent, invokingState);
292 		}
293 		@Override public int getRuleIndex() { return RULE_formula; }
294 		@Override
295 		public void enterRule(ParseTreeListener listener) {
296 			if ( listener instanceof FormulaListener ) ((FormulaListener)listener).enterFormula(this);
297 		}
298 		@Override
299 		public void exitRule(ParseTreeListener listener) {
300 			if ( listener instanceof FormulaListener ) ((FormulaListener)listener).exitFormula(this);
301 		}
302 	}
303 
304 	public final FormulaContext formula() throws RecognitionException {
305 		FormulaContext _localctx = new FormulaContext(_ctx, getState());
306 		enterRule(_localctx, 0, RULE_formula);
307 		try {
308 			enterOuterAlt(_localctx, 1);
309 			{
310 			this.fDecl = null;
311 			setState(16);
312 			_errHandler.sync(this);
313 			switch ( getInterpreter().adaptivePredict(_input,0,_ctx) ) {
314 			case 1:
315 				{
316 				setState(13);
317 				constFormula();
318 				}
319 				break;
320 			case 2:
321 				{
322 				setState(14);
323 				compFormula();
324 				}
325 				break;
326 			case 3:
327 				{
328 				setState(15);
329 				varFormula();
330 				}
331 				break;
332 			}
333 			assert this.fDecl != null;
334 			}
335 		}
336 		catch (RecognitionException re) {
337 			_localctx.exception = re;
338 			_errHandler.reportError(this, re);
339 			_errHandler.recover(this, re);
340 		}
341 		finally {
342 			exitRule();
343 		}
344 		return _localctx;
345 	}
346 
347 	public static class ConstFormulaContext extends ParserRuleContext {
348 		public Token name;
349 		public PathContext path() {
350 			return getRuleContext(PathContext.class,0);
351 		}
352 		public List<TerminalNode> NAME() { return getTokens(FormulaParser.NAME); }
353 		public TerminalNode NAME(int i) {
354 			return getToken(FormulaParser.NAME, i);
355 		}
356 		public ConstFormulaContext(ParserRuleContext parent, int invokingState) {
357 			super(parent, invokingState);
358 		}
359 		@Override public int getRuleIndex() { return RULE_constFormula; }
360 		@Override
361 		public void enterRule(ParseTreeListener listener) {
362 			if ( listener instanceof FormulaListener ) ((FormulaListener)listener).enterConstFormula(this);
363 		}
364 		@Override
365 		public void exitRule(ParseTreeListener listener) {
366 			if ( listener instanceof FormulaListener ) ((FormulaListener)listener).exitConstFormula(this);
367 		}
368 	}
369 
370 	public final ConstFormulaContext constFormula() throws RecognitionException {
371 		ConstFormulaContext _localctx = new ConstFormulaContext(_ctx, getState());
372 		enterRule(_localctx, 2, RULE_constFormula);
373 
374 		    Set<Deficiency> defs = new HashSet<Deficiency>();
375 		    assert this.fDecl == null;
376 		    Type type = null;
377 
378 		int _la;
379 		try {
380 			enterOuterAlt(_localctx, 1);
381 			{
382 			setState(20);
383 			match(T__0);
384 			setState(21);
385 			path();
386 			setState(22);
387 			match(T__1);
388 
389 			            SClass sClass = null;
390 			            try {
391 			                sClass = this.classLoader.loadSClass
392 			                    (ClassLocator.getLocator(this.path),
393 								 this.loc.getPackage());
394 			            } catch (IOException ioe) {
395 			                report("IOException while loading \"" 
396 			                       + ClassLocator.getLocator(this.path) 
397 			                       + "\" in package " + this.loc.getPackage() 
398 			                       + ": " + ioe + ". ");
399 			                sClass = null; // never reached. ****
400 			            } catch (Exception e) {
401 								assert false;// **** to be removed 
402 								// after transition to v4: v4 and v3 exception. 
403 							    }
404 			            assert sClass != null;
405 			            type = sClass.getType();
406 
407 			            defs = new HashSet<Deficiency>();
408 			        
409 			setState(24);
410 			match(T__2);
411 			setState(29);
412 			_errHandler.sync(this);
413 			_la = _input.LA(1);
414 			while (_la==NAME) {
415 				{
416 				{
417 				setState(25);
418 				((ConstFormulaContext)_localctx).name = match(NAME);
419 				defs.add(new Deficiency((((ConstFormulaContext)_localctx).name!=null?((ConstFormulaContext)_localctx).name.getText():null)));
420 				}
421 				}
422 				setState(31);
423 				_errHandler.sync(this);
424 				_la = _input.LA(1);
425 			}
426 			setState(32);
427 			match(T__3);
428 
429 			            if (!type.isValid(defs)) {
430 			                report("Set " + defs + " does not conform with type " +
431 			                       type + ". ");
432 			            }
433 			           this.fDecl = FormulaDecl.getConst(type, defs);
434 			assert this.fDecl != null;
435 			        
436 			}
437 		}
438 		catch (RecognitionException re) {
439 			_localctx.exception = re;
440 			_errHandler.reportError(this, re);
441 			_errHandler.recover(this, re);
442 		}
443 		finally {
444 			exitRule();
445 		}
446 		return _localctx;
447 	}
448 
449 	public static class VarFormulaContext extends ParserRuleContext {
450 		public PathContext path() {
451 			return getRuleContext(PathContext.class,0);
452 		}
453 		public VarFormulaContext(ParserRuleContext parent, int invokingState) {
454 			super(parent, invokingState);
455 		}
456 		@Override public int getRuleIndex() { return RULE_varFormula; }
457 		@Override
458 		public void enterRule(ParseTreeListener listener) {
459 			if ( listener instanceof FormulaListener ) ((FormulaListener)listener).enterVarFormula(this);
460 		}
461 		@Override
462 		public void exitRule(ParseTreeListener listener) {
463 			if ( listener instanceof FormulaListener ) ((FormulaListener)listener).exitVarFormula(this);
464 		}
465 	}
466 
467 	public final VarFormulaContext varFormula() throws RecognitionException {
468 		VarFormulaContext _localctx = new VarFormulaContext(_ctx, getState());
469 		enterRule(_localctx, 4, RULE_varFormula);
470 		try {
471 			enterOuterAlt(_localctx, 1);
472 			{
473 			setState(35);
474 			path();
475 
476 			            assert fDecl == null;
477 			            CClass.SClassDecl declS = this.cClass.getEffectDecl(this.path);
478 			            if (declS == null) {
479 			                report("Found name " + this.path + 
480 			                       " leading to an unknown effect. ");
481 			            }
482 			            this.fDecl = FormulaDecl.getVar(declS, this.path);
483 			assert this.fDecl != null;
484 			        
485 			}
486 		}
487 		catch (RecognitionException re) {
488 			_localctx.exception = re;
489 			_errHandler.reportError(this, re);
490 			_errHandler.recover(this, re);
491 		}
492 		finally {
493 			exitRule();
494 		}
495 		return _localctx;
496 	}
497 
498 	public static class CompFormulaContext extends ParserRuleContext {
499 		public Token opT;
500 		public Token invT;
501 		public Token accT;
502 		public List<AddFormulaContext> addFormula() {
503 			return getRuleContexts(AddFormulaContext.class);
504 		}
505 		public AddFormulaContext addFormula(int i) {
506 			return getRuleContext(AddFormulaContext.class,i);
507 		}
508 		public TerminalNode UNION() { return getToken(FormulaParser.UNION, 0); }
509 		public TerminalNode INTERSECT() { return getToken(FormulaParser.INTERSECT, 0); }
510 		public TerminalNode COMPLEMENT() { return getToken(FormulaParser.COMPLEMENT, 0); }
511 		public TerminalNode NAME() { return getToken(FormulaParser.NAME, 0); }
512 		public TerminalNode CONT() { return getToken(FormulaParser.CONT, 0); }
513 		public TerminalNode COV() { return getToken(FormulaParser.COV, 0); }
514 		public TerminalNode INV() { return getToken(FormulaParser.INV, 0); }
515 		public CompFormulaContext(ParserRuleContext parent, int invokingState) {
516 			super(parent, invokingState);
517 		}
518 		@Override public int getRuleIndex() { return RULE_compFormula; }
519 		@Override
520 		public void enterRule(ParseTreeListener listener) {
521 			if ( listener instanceof FormulaListener ) ((FormulaListener)listener).enterCompFormula(this);
522 		}
523 		@Override
524 		public void exitRule(ParseTreeListener listener) {
525 			if ( listener instanceof FormulaListener ) ((FormulaListener)listener).exitCompFormula(this);
526 		}
527 	}
528 
529 	public final CompFormulaContext compFormula() throws RecognitionException {
530 		CompFormulaContext _localctx = new CompFormulaContext(_ctx, getState());
531 		enterRule(_localctx, 6, RULE_compFormula);
532 
533 		    this.argsStack.push(new HashSet<FormulaDecl>());
534 		    assert this.fDecl == null;
535 		    Operation oper = null;
536 
537 		int _la;
538 		try {
539 			enterOuterAlt(_localctx, 1);
540 			{
541 			setState(49);
542 			_errHandler.sync(this);
543 			switch (_input.LA(1)) {
544 			case UNION:
545 				{
546 				setState(38);
547 				((CompFormulaContext)_localctx).opT = match(UNION);
548 				}
549 				break;
550 			case INTERSECT:
551 				{
552 				setState(39);
553 				((CompFormulaContext)_localctx).opT = match(INTERSECT);
554 				}
555 				break;
556 			case COMPLEMENT:
557 				{
558 				setState(40);
559 				((CompFormulaContext)_localctx).opT = match(COMPLEMENT);
560 				}
561 				break;
562 			case NAME:
563 				{
564 				{
565 				setState(41);
566 				((CompFormulaContext)_localctx).opT = match(NAME);
567 				setState(43);
568 				_errHandler.sync(this);
569 				_la = _input.LA(1);
570 				if (_la==INV) {
571 					{
572 					setState(42);
573 					((CompFormulaContext)_localctx).invT = match(INV);
574 					}
575 				}
576 
577 				setState(47);
578 				_errHandler.sync(this);
579 				switch (_input.LA(1)) {
580 				case CONT:
581 					{
582 					setState(45);
583 					((CompFormulaContext)_localctx).accT = match(CONT);
584 					}
585 					break;
586 				case COV:
587 					{
588 					setState(46);
589 					((CompFormulaContext)_localctx).accT = match(COV);
590 					}
591 					break;
592 				default:
593 					throw new NoViableAltException(this);
594 				}
595 				}
596 				}
597 				break;
598 			default:
599 				throw new NoViableAltException(this);
600 			}
601 
602 			            String key = (((CompFormulaContext)_localctx).opT!=null?((CompFormulaContext)_localctx).opT.getText():null);
603 			            if (((CompFormulaContext)_localctx).accT == null) {
604 			                // opT = <UNION> | <INTERSECT> | <COMPLEMENT> 
605 			                assert ((CompFormulaContext)_localctx).invT == null;
606 			                oper = Operation.BaseOps.getOperation(key);
607 			            } else {
608 			                // opT = f, | opt = f'
609 			                String funName = key;
610 			                MapDecl mapDecl = this.cClass.getMapDecl(funName);
611 			                if (mapDecl == null) {
612 			                    report("Declared no map \"" + funName + "\". " );
613 			                }
614 			                DeficiencyMap map = mapDecl.getMap();
615 			                boolean isInverted = ((CompFormulaContext)_localctx).invT != null;
616 			                if (isInverted) {
617 			                    // replace map by its inverse 
618 			                    map = map.getInverse();
619 			                }
620 			                oper = Operation.getOperation(funName,
621 			                                              isInverted,
622 			                                              map,
623 			                                              Operation.Functor
624 			                                              .covCont((((CompFormulaContext)_localctx).accT!=null?((CompFormulaContext)_localctx).accT.getText():null)));
625 			            }
626 			            assert oper != null;
627 			// Here, the operation is read. 
628 			        
629 			{
630 			setState(52);
631 			match(T__4);
632 			setState(53);
633 			addFormula();
634 			setState(58);
635 			_errHandler.sync(this);
636 			_la = _input.LA(1);
637 			while (_la==COV) {
638 				{
639 				{
640 				setState(54);
641 				match(COV);
642 				setState(55);
643 				addFormula();
644 				}
645 				}
646 				setState(60);
647 				_errHandler.sync(this);
648 				_la = _input.LA(1);
649 			}
650 			setState(61);
651 			match(T__5);
652 			}
653 
654 			            this.fDecl = FormulaDecl.getComp(oper, this.argsStack.pop());
655 			assert this.fDecl != null;
656 			        
657 			}
658 		}
659 		catch (RecognitionException re) {
660 			_localctx.exception = re;
661 			_errHandler.reportError(this, re);
662 			_errHandler.recover(this, re);
663 		}
664 		finally {
665 			exitRule();
666 		}
667 		return _localctx;
668 	}
669 
670 	public static class AddFormulaContext extends ParserRuleContext {
671 		public FormulaContext formula() {
672 			return getRuleContext(FormulaContext.class,0);
673 		}
674 		public AddFormulaContext(ParserRuleContext parent, int invokingState) {
675 			super(parent, invokingState);
676 		}
677 		@Override public int getRuleIndex() { return RULE_addFormula; }
678 		@Override
679 		public void enterRule(ParseTreeListener listener) {
680 			if ( listener instanceof FormulaListener ) ((FormulaListener)listener).enterAddFormula(this);
681 		}
682 		@Override
683 		public void exitRule(ParseTreeListener listener) {
684 			if ( listener instanceof FormulaListener ) ((FormulaListener)listener).exitAddFormula(this);
685 		}
686 	}
687 
688 	public final AddFormulaContext addFormula() throws RecognitionException {
689 		AddFormulaContext _localctx = new AddFormulaContext(_ctx, getState());
690 		enterRule(_localctx, 8, RULE_addFormula);
691 		try {
692 			enterOuterAlt(_localctx, 1);
693 			{
694 			setState(65);
695 			formula();
696 			this.argsStack.peek().add(this.fDecl);
697 			}
698 		}
699 		catch (RecognitionException re) {
700 			_localctx.exception = re;
701 			_errHandler.reportError(this, re);
702 			_errHandler.recover(this, re);
703 		}
704 		finally {
705 			exitRule();
706 		}
707 		return _localctx;
708 	}
709 
710 	public static class PathContext extends ParserRuleContext {
711 		public Token first;
712 		public Token next;
713 		public List<TerminalNode> NAME() { return getTokens(FormulaParser.NAME); }
714 		public TerminalNode NAME(int i) {
715 			return getToken(FormulaParser.NAME, i);
716 		}
717 		public List<TerminalNode> SEP() { return getTokens(FormulaParser.SEP); }
718 		public TerminalNode SEP(int i) {
719 			return getToken(FormulaParser.SEP, i);
720 		}
721 		public PathContext(ParserRuleContext parent, int invokingState) {
722 			super(parent, invokingState);
723 		}
724 		@Override public int getRuleIndex() { return RULE_path; }
725 		@Override
726 		public void enterRule(ParseTreeListener listener) {
727 			if ( listener instanceof FormulaListener ) ((FormulaListener)listener).enterPath(this);
728 		}
729 		@Override
730 		public void exitRule(ParseTreeListener listener) {
731 			if ( listener instanceof FormulaListener ) ((FormulaListener)listener).exitPath(this);
732 		}
733 	}
734 
735 	public final PathContext path() throws RecognitionException {
736 		PathContext _localctx = new PathContext(_ctx, getState());
737 		enterRule(_localctx, 10, RULE_path);
738 		this.path = new ArrayList<String>();
739 		int _la;
740 		try {
741 			enterOuterAlt(_localctx, 1);
742 			{
743 			setState(68);
744 			((PathContext)_localctx).first = match(NAME);
745 			this.path.add((((PathContext)_localctx).first!=null?((PathContext)_localctx).first.getText():null));
746 			setState(75);
747 			_errHandler.sync(this);
748 			_la = _input.LA(1);
749 			while (_la==SEP) {
750 				{
751 				{
752 				setState(70);
753 				match(SEP);
754 				setState(71);
755 				((PathContext)_localctx).next = match(NAME);
756 				this.path.add( (((PathContext)_localctx).next!=null?((PathContext)_localctx).next.getText():null));
757 				}
758 				}
759 				setState(77);
760 				_errHandler.sync(this);
761 				_la = _input.LA(1);
762 			}
763 			}
764 		}
765 		catch (RecognitionException re) {
766 			_localctx.exception = re;
767 			_errHandler.reportError(this, re);
768 			_errHandler.recover(this, re);
769 		}
770 		finally {
771 			exitRule();
772 		}
773 		return _localctx;
774 	}
775 
776 	public static final String _serializedATN =
777 		"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\24Q\4\2\t\2\4\3\t"+
778 		"\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\3\2\3\2\3\2\3\2\5\2\23\n\2\3\2\3\2"+
779 		"\3\3\3\3\3\3\3\3\3\3\3\3\3\3\7\3\36\n\3\f\3\16\3!\13\3\3\3\3\3\3\3\3\4"+
780 		"\3\4\3\4\3\5\3\5\3\5\3\5\3\5\5\5.\n\5\3\5\3\5\5\5\62\n\5\5\5\64\n\5\3"+
781 		"\5\3\5\3\5\3\5\3\5\7\5;\n\5\f\5\16\5>\13\5\3\5\3\5\3\5\3\5\3\6\3\6\3\6"+
782 		"\3\7\3\7\3\7\3\7\3\7\7\7L\n\7\f\7\16\7O\13\7\3\7\2\2\b\2\4\6\b\n\f\2\2"+
783 		"\2T\2\16\3\2\2\2\4\26\3\2\2\2\6%\3\2\2\2\b\63\3\2\2\2\nC\3\2\2\2\fF\3"+
784 		"\2\2\2\16\22\b\2\1\2\17\23\5\4\3\2\20\23\5\b\5\2\21\23\5\6\4\2\22\17\3"+
785 		"\2\2\2\22\20\3\2\2\2\22\21\3\2\2\2\23\24\3\2\2\2\24\25\b\2\1\2\25\3\3"+
786 		"\2\2\2\26\27\7\3\2\2\27\30\5\f\7\2\30\31\7\4\2\2\31\32\b\3\1\2\32\37\7"+
787 		"\5\2\2\33\34\7\24\2\2\34\36\b\3\1\2\35\33\3\2\2\2\36!\3\2\2\2\37\35\3"+
788 		"\2\2\2\37 \3\2\2\2 \"\3\2\2\2!\37\3\2\2\2\"#\7\6\2\2#$\b\3\1\2$\5\3\2"+
789 		"\2\2%&\5\f\7\2&\'\b\4\1\2\'\7\3\2\2\2(\64\7\21\2\2)\64\7\22\2\2*\64\7"+
790 		"\23\2\2+-\7\24\2\2,.\7\f\2\2-,\3\2\2\2-.\3\2\2\2.\61\3\2\2\2/\62\7\16"+
791 		"\2\2\60\62\7\r\2\2\61/\3\2\2\2\61\60\3\2\2\2\62\64\3\2\2\2\63(\3\2\2\2"+
792 		"\63)\3\2\2\2\63*\3\2\2\2\63+\3\2\2\2\64\65\3\2\2\2\65\66\b\5\1\2\66\67"+
793 		"\7\7\2\2\67<\5\n\6\289\7\r\2\29;\5\n\6\2:8\3\2\2\2;>\3\2\2\2<:\3\2\2\2"+
794 		"<=\3\2\2\2=?\3\2\2\2><\3\2\2\2?@\7\b\2\2@A\3\2\2\2AB\b\5\1\2B\t\3\2\2"+
795 		"\2CD\5\2\2\2DE\b\6\1\2E\13\3\2\2\2FG\7\24\2\2GM\b\7\1\2HI\7\20\2\2IJ\7"+
796 		"\24\2\2JL\b\7\1\2KH\3\2\2\2LO\3\2\2\2MK\3\2\2\2MN\3\2\2\2N\r\3\2\2\2O"+
797 		"M\3\2\2\2\t\22\37-\61\63<M";
798 	public static final ATN _ATN =
799 		new ATNDeserializer().deserialize(_serializedATN.toCharArray());
800 	static {
801 		_decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
802 		for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
803 			_decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
804 		}
805 	}
806 }