Home | History | Annotate | Download | only in tree
      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 */
      5 org.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(){
     11 var TP = org.antlr.runtime.tree.TreeParser;
     12 
     13 org.antlr.lang.augmentObject(TP, {
     14     DOWN: org.antlr.runtime.Token.DOWN,
     15     UP: org.antlr.runtime.Token.UP
     16 });
     17 
     18 org.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