1/** A parser for a stream of tree nodes. "tree grammars" result in a subclass 2 * of this. All the error reporting and recovery is shared with Parser via 3 * the BaseRecognizer superclass. 4*/ 5org.antlr.runtime.tree.TreeParser = function(input) { 6 org.antlr.runtime.tree.TreeParser.superclass.constructor.call(this, arguments[1]); 7 this.setTreeNodeStream(input); 8}; 9 10(function(){ 11var TP = org.antlr.runtime.tree.TreeParser; 12 13org.antlr.lang.augmentObject(TP, { 14 DOWN: org.antlr.runtime.Token.DOWN, 15 UP: org.antlr.runtime.Token.UP 16}); 17 18org.antlr.lang.extend(TP, org.antlr.runtime.BaseRecognizer, { 19 reset: function() { 20 TP.superclass.reset.call(this); // reset all recognizer state variables 21 if ( this.input ) { 22 this.input.seek(0); // rewind the input 23 } 24 }, 25 26 /** Set the input stream */ 27 setTreeNodeStream: function(input) { 28 this.input = input; 29 }, 30 31 getTreeNodeStream: function() { 32 return this.input; 33 }, 34 35 getSourceName: function() { 36 return this.input.getSourceName(); 37 }, 38 39 getCurrentInputSymbol: function(input) { 40 return input.LT(1); 41 }, 42 43 getMissingSymbol: function(input, e, expectedTokenType, follow) { 44 var tokenText = 45 "<missing "+this.getTokenNames()[expectedTokenType]+">"; 46 return new org.antlr.runtime.tree.CommonTree(new org.antlr.runtime.CommonToken(expectedTokenType, tokenText)); 47 }, 48 49 /** Match '.' in tree parser has special meaning. Skip node or 50 * entire tree if node has children. If children, scan until 51 * corresponding UP node. 52 */ 53 matchAny: function(ignore) { // ignore stream, copy of this.input 54 this.state.errorRecovery = false; 55 this.state.failed = false; 56 var look = this.input.LT(1); 57 if ( this.input.getTreeAdaptor().getChildCount(look)===0 ) { 58 this.input.consume(); // not subtree, consume 1 node and return 59 return; 60 } 61 // current node is a subtree, skip to corresponding UP. 62 // must count nesting level to get right UP 63 var level=0, 64 tokenType = this.input.getTreeAdaptor().getType(look); 65 while ( tokenType!==org.antlr.runtime.Token.EOF && 66 !(tokenType===TP.UP && level===0) ) 67 { 68 this.input.consume(); 69 look = this.input.LT(1); 70 tokenType = this.input.getTreeAdaptor().getType(look); 71 if ( tokenType === TP.DOWN ) { 72 level++; 73 } 74 else if ( tokenType === TP.UP ) { 75 level--; 76 } 77 } 78 this.input.consume(); // consume UP 79 }, 80 81 /** We have DOWN/UP nodes in the stream that have no line info; override. 82 * plus we want to alter the exception type. Don't try to recover 83 * * from tree parser errors inline... 84 */ 85 mismatch: function(input, ttype, follow) { 86 throw new org.antlr.runtime.MismatchedTreeNodeException(ttype, input); 87 }, 88 89 /** Prefix error message with the grammar name because message is 90 * always intended for the programmer because the parser built 91 * the input tree not the user. 92 */ 93 getErrorHeader: function(e) { 94 return this.getGrammarFileName()+": node from "+ 95 (e.approximateLineInfo?"after ":"")+"line "+e.line+":"+e.charPositionInLine; 96 }, 97 98 /** Tree parsers parse nodes they usually have a token object as 99 * payload. Set the exception token and do the default behavior. 100 */ 101 getErrorMessage: function(e, tokenNames) { 102 var adaptor; 103 if ( this instanceof TP ) { 104 adaptor = e.input.getTreeAdaptor(); 105 e.token = adaptor.getToken(e.node); 106 if ( !org.antlr.lang.isValue(e.token) ) { // could be an UP/DOWN node 107 e.token = new org.antlr.runtime.CommonToken( 108 adaptor.getType(e.node), 109 adaptor.getText(e.node)); 110 } 111 } 112 return TP.superclass.getErrorMessage.call(this, e, tokenNames); 113 }, 114 115 traceIn: function(ruleName, ruleIndex) { 116 TP.superclass.traceIn.call(this, ruleName, ruleIndex, this.input.LT(1)); 117 }, 118 119 traceOut: function(ruleName, ruleIndex) { 120 TP.superclass.traceOut.call(this, ruleName, ruleIndex, this.input.LT(1)); 121 } 122}); 123 124})(); 125