1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#!/usr/bin/ruby 2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# encoding: utf-8 3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin LICENSE 5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver[The "BSD licence"] 7324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverCopyright (c) 2009-2010 Kyle Yetter 8324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverAll rights reserved. 9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 10324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverRedistribution and use in source and binary forms, with or without 11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodification, are permitted provided that the following conditions 12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverare met: 13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1. Redistributions of source code must retain the above copyright 15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver notice, this list of conditions and the following disclaimer. 16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2. Redistributions in binary form must reproduce the above copyright 17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver notice, this list of conditions and the following disclaimer in the 18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver documentation and/or other materials provided with the distribution. 19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 3. The name of the author may not be used to endorse or promote products 20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver derived from this software without specific prior written permission. 21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 22324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTHIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverIMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverIN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverNOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTHIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end 34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrequire 'antlr3' 36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule ANTLR3 38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::AST 40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 41324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverName space containing all of the entities pertaining to tree construction and 42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvertree parsing. 43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end 45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule AST 47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverautoload :Wizard, 'antlr3/tree/wizard' 49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverautoload :Visitor, 'antlr3/tree/visitor' 50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#################################################################################################### 52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver############################################ Tree Parser ########################################### 53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#################################################################################################### 54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::AST::TreeParser 56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver= TreeParser 58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 59324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTreeParser is the default base class of ANTLR-generated tree parsers. The class 60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvertailors the functionality provided by Recognizer to the task of tree-pattern 61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrecognition. 62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver== About Tree Parsers 64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 65324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverANTLR generates three basic types of recognizers: 66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver* lexers 67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver* parsers 68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver* tree parsers 69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 70324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverFurthermore, it is capable of generating several different flavors of parser, 71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverincluding parsers that take token input and use it to build Abstract Syntax 72324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTrees (ASTs), tree structures that reflect the high-level syntactic and semantic 73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstructures defined by the language. 74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 75324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverYou can take the information encapsulated by the AST and process it directly in 76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvera program. However, ANTLR also provides a means to create a recognizer which is 77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvercapable of walking through the AST, verifying its structure and performing 78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvercustom actions along the way -- tree parsers. 79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 80324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTree parsers are created from tree grammars. ANTLR-generated tree parsers 81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclosely mirror the general structure of regular parsers and lexers. 82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 83324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverFor more in-depth coverage of the topic, check out the ANTLR documentation 84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver(http://www.antlr.org). 85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver== The Tree Parser API 87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 88324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverLike Parser, the class does not stray too far from the Recognizer API. 89324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverMainly, it customizes a few methods specifically to deal with tree nodes 90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver(instead of basic tokens), and adds some helper methods for working with trees. 91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 92324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverLike all ANTLR recognizers, tree parsers contained a shared state structure and 93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruveran input stream, which should be a TreeNodeStream. ANTLR intends to keep its 94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvertree features flexible and customizable, and thus it does not make any 95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverassumptions about the class of the actual nodes it processes. One consequence of 96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverthis flexibility is that tree parsers also require an extra tree adaptor object, 97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverthe purpose of which is to provide a homogeneous interface for handling tree 98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverconstruction and analysis of your tree nodes. 99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 100324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverSee Tree and TreeAdaptor for more information. 101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end 103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass TreeParser < Recognizer 105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def self.main( argv = ARGV, options = {} ) 106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ::Hash === argv then argv, options = ARGV, argv end 107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver main = ANTLR3::Main::WalkerMain.new( self, options ) 108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver block_given? ? yield( main ) : main.execute( argv ) 109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def initialize( input, options = {} ) 112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver super( options ) 113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @input = input 114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver alias tree_node_stream input 117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver alias tree_node_stream= input= 118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def source_name 120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @input.source_name 121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def missing_symbol( error, expected_token_type, follow ) 124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver name = token_name( expected_token_type ).to_s 125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver text = "<missing " << name << '>' 126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tk = create_token do |t| 127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver t.text = text 128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver t.type = expected_token_type 129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( CommonTree.new( tk ) ) 131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def match_any( ignore = nil ) 134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @state.error_recovery = false 135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver look, adaptor = @input.look, @input.tree_adaptor 137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if adaptor.child_count( look ) == 0 138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @input.consume 139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return 140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver level = 0 143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver while type = @input.peek and type != EOF 144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver #token_type == EOF or ( token_type == UP && level == 0 ) 145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @input.consume 146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver case type 147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when DOWN then level += 1 148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when UP 149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver level -= 1 150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver level.zero? and break 151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def mismatch( input, type, follow = nil ) 156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver raise MismatchedTreeNode.new( type, input ) 157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def error_header( e ) 160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver <<-END.strip! 161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver #{ grammar_file_name }: node from #{ 162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver e.approximate_line_info? ? 'after ' : '' 163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } line #{ e.line }:#{ e.column } 164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def error_message( e ) 168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver adaptor = e.input.adaptor 169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver e.token = adaptor.token( e.node ) 170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver e.token ||= create_token do | tok | 171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tok.type = adaptor.type_of( e.node ) 172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tok.text = adaptor.text_of( e.node ) 173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return super( e ) 175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def trace_in( rule_name, rule_index ) 178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver super( rule_name, rule_index, @input.look ) 179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def trace_out( rule_name, rule_index ) 182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver super( rule_name, rule_index, @input.look ) 183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#################################################################################################### 187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver############################################ Tree Nodes ############################################ 188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#################################################################################################### 189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::AST::Tree 191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver= ANTLR Abstract Syntax Trees 193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 194324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverAs ANTLR is concerned, an Abstract Syntax Tree (AST) node is an object that 195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverwraps a token, a list of child trees, and some information about the collective 196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruversource text embodied within the tree and its children. 197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 198324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverThe Tree module, like the Token and Stream modules, emulates an abstract base 199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass for AST classes; it specifies the attributes that are expected of basic 200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvertree nodes as well as the methods trees need to implement. 201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver== Terminology 203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 204324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverWhile much of this terminology is probably familiar to most developers, the 205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverfollowing brief glossary is intended to clarify terminology used in code 206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverthroughout the AST library: 207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver[payload] either a token value contained within a node or +nil+ 209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver[flat list (nil tree)] a tree node without a token payload, but with more 210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver than one children -- functions like an array of 211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree nodes 212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver[root] a top-level tree node, i.e. a node that does not have a parent 213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver[leaf] a node that does not have any children 214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver[siblings] all other nodes sharing the same parent as some node 215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver[ancestors] the list of successive parents from a tree node to the root node 216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver[error node] a special node used to represent an erroneous series of tokens 217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver from an input stream 218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end 220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule Tree 222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver #attr_accessor :parent 224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_accessor :start_index 225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_accessor :stop_index 226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_accessor :child_index 227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_reader :type 228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_reader :text 229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_reader :line 230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_reader :column 231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver #attr_reader :children 232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_reader :token 233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def root? 236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver parent.nil? 237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver alias detached? root? 239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def root 241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver cursor = self 242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver until cursor.root? 243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver yield( parent_node = cursor.parent ) 244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver cursor = parent_node 245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( cursor ) 247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # 250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def leaf? 251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver children.nil? or children.empty? 252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def has_child?( node ) 255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver children and children.include?( node ) 256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def depth 259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver root? ? 0 : parent.depth + 1 260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def siblings 263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver root? and return [] 264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver parent.children.reject { | c | c.equal?( self ) } 265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def each_ancestor 268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver block_given? or return( enum_for( :each_ancestor ) ) 269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver cursor = self 270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver until cursor.root? 271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver yield( parent_node = cursor.parent ) 272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver cursor = parent_node 273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( self ) 275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def ancestors 278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver each_ancestor.to_a 279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def walk 282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver block_given? or return( enum_for( :walk ) ) 283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stack = [] 284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver cursor = self 285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver while true 286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver begin 287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver yield( cursor ) 288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stack.push( cursor.children.dup ) unless cursor.empty? 289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver rescue StopIteration 290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # skips adding children to prune the node 291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ensure 292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver break if stack.empty? 293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver cursor = stack.last.shift 294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stack.pop if stack.last.empty? 295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return self 298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::AST::BaseTree 304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 305324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverA base implementation of an Abstract Syntax Tree Node. It mainly defines the 306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermethods and attributes required to implement the parent-node-children 307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrelationship that characterize a tree; it does not provide any logic concerning 308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvera node's token <i>payload</i>. 309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end 311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass BaseTree < ::Array 313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_accessor :parent 314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver extend ClassMacros 315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver include Tree 316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def initialize( node = nil ) 318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver super() 319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @parent = nil 320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @child_index = 0 321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def children() self end 324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver alias child at 326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver alias child_count length 327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def first_with_type( tree_type ) 329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver find { | child | child.type == tree_type } 330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def add_child( child_tree ) 333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver child_tree.nil? and return 334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if child_tree.flat_list? 335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver self.equal?( child_tree.children ) and 336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver raise ArgumentError, "attempt to add child list to itself" 337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver child_tree.each_with_index do | child, index | 338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver child.parent = self 339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver child.child_index = length + index 340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver concat( child_tree ) 342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver child_tree.child_index = length 344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver child_tree.parent = self 345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver self << child_tree 346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( self ) 348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def detach 351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @parent = nil 352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @child_index = -1 353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( self ) 354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver alias add_children concat 357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver alias each_child each 358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def set_child( index, tree ) 360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return if tree.nil? 361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree.flat_list? and raise ArgumentError, "Can't set single child to a list" 362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree.parent = self 363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree.child_index = index 364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver self[ index ] = tree 365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def delete_child( index ) 368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver killed = delete_at( index ) and freshen( index ) 369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return killed 370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def replace_children( start, stop, new_tree ) 373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver start >= length or stop >= length and 374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver raise IndexError, ( <<-END ).gsub!( /^\s+\| /,'' ) 375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | indices span beyond the number of children: 376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | children.length = #{ length } 377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | start = #{ start_index.inspect } 378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | stop = #{ stop_index.inspect } 379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver new_children = new_tree.flat_list? ? new_tree : [ new_tree ] 381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver self[ start .. stop ] = new_children 382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver freshen( start_index ) 383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return self 384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 385324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 386324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def flat_list? 387324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver false 388324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 389324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 390324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def freshen( offset = 0 ) 391324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for i in offset ... length 392324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver node = self[ i ] 393324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver node.child_index = i 394324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver node.parent = self 395324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 396324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 397324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 398324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def sanity_check( parent = nil, i = -1 ) 399324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver parent == @parent or 400324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver raise TreeInconsistency.failed_parent_check!( parent, @parent ) 401324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver i == @child_index or 402324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver raise TreeInconsistency.failed_index_check!( i, @child_index ) 403324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver each_with_index do | child, index | 404324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver child.sanity_check( self, index ) 405324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 406324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 407324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 408324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def inspect 409324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver empty? and return to_s 410324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver buffer = '' 411324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver buffer << '(' << to_s << ' ' unless flat_list? 412324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver buffer << map { | c | c.inspect }.join( ' ' ) 413324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver buffer << ')' unless flat_list? 414324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( buffer ) 415324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 416324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 417324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def walk 418324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver block_given? or return( enum_for( :walk ) ) 419324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stack = [] 420324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver cursor = self 421324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver while true 422324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver begin 423324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver yield( cursor ) 424324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stack.push( Array[ *cursor ] ) unless cursor.empty? 425324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver rescue StopIteration 426324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # skips adding children to prune the node 427324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ensure 428324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver break if stack.empty? 429324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver cursor = stack.last.shift 430324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stack.pop if stack.last.empty? 431324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 432324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 433324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return self 434324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 435324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 436324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def prune 437324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver raise StopIteration 438324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 439324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 440324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver abstract :to_s 441324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver #protected :sanity_check, :freshen 442324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 443324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def root?() @parent.nil? end 444324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver alias leaf? empty? 445324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 446324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 447324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 448324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::AST::CommonTree 449324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 450324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverThe default Tree class implementation used by ANTLR tree-related code. 451324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 452324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverA CommonTree object is a tree node that wraps a token <i>payload</i> (or a +nil+ 453324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvervalue) and contains zero or more child tree nodes. Additionally, it tracks 454324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverinformation about the range of data collectively spanned by the tree node: 455324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 456324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver* the token stream start and stop indexes of tokens contained throughout 457324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver the tree 458324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver* that start and stop positions of the character input stream from which 459324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver the tokens were defined 460324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 461324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTracking this information simplifies tasks like extracting a block of code or 462324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrewriting the input stream. However, depending on the purpose of the 463324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverapplication, building trees with all of this extra information may be 464324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverunnecessary. In such a case, a more bare-bones tree class could be written 465324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver(optionally using the BaseTree class or the Token module). Define a customized 466324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTreeAdaptor class to handle tree construction and manipulation for the 467324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvercustomized node class, and recognizers will be able to build, rewrite, and parse 468324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverthe customized lighter-weight trees. 469324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 470324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end 471324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 472324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass CommonTree < BaseTree 473324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def initialize( payload = nil ) 474324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver super() 475324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @start_index = -1 476324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @stop_index = -1 477324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @child_index = -1 478324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver case payload 479324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when CommonTree then # copy-constructor style init 480324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @token = payload.token 481324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @start_index = payload.start_index 482324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @stop_index = payload.stop_index 483324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when nil, Token then @token = payload 484324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else raise ArgumentError, 485324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "Invalid argument type: %s (%p)" % [ payload.class, payload ] 486324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 487324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 488324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 489324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def initialize_copy( orig ) 490324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver super 491324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver clear 492324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @parent = nil 493324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 494324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 495324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def copy_node 496324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return self.class.new( @token ) 497324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 498324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 499324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def flat_list? 500324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @token.nil? 501324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 502324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 503324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def type 504324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @token ? @token.type : 0 505324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 506324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 507324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def text 508324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @token.text rescue nil 509324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 510324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 511324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def line 512324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if @token.nil? or @token.line == 0 513324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return ( empty? ? 0 : first.line ) 514324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 515324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return @token.line 516324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 517324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 518324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def column 519324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if @token.nil? or @token.column == -1 520324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( empty? ? 0 : first.column ) 521324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 522324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return @token.column 523324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 524324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 525324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def start_index 526324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @start_index == -1 and @token and return @token.index 527324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return @start_index 528324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 529324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 530324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def stop_index 531324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @stop_index == -1 and @token and return @token.index 532324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return @stop_index 533324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 534324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 535324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver alias token_start_index= start_index= 536324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver alias token_stop_index= stop_index= 537324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver alias token_start_index start_index 538324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver alias token_stop_index stop_index 539324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 540324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def name 541324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @token.name rescue 'INVALID' 542324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 543324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 544324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def token_range 545324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver unknown_boundaries? and infer_boundaries 546324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @start_index .. @stop_index 547324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 548324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 549324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def source_range 550324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver unknown_boundaries? and infer_boundaries 551324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tokens = map do | node | 552324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tk = node.token and tk.index >= 0 ? tk : nil 553324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 554324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tokens.compact! 555324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver first, last = tokens.minmax_by { |t| t.index } 556324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver first.start .. last.stop 557324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 558324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 559324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def infer_boundaries 560324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if empty? and @start_index < 0 || @stop_index < 0 561324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @start_index = @stop_index = @token.index rescue -1 562324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return 563324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 564324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for child in self do child.infer_boundaries end 565324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return if @start_index >= 0 and @stop_index >= 0 566324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 567324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @start_index = first.start_index 568324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @stop_index = last.stop_index 569324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return nil 570324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 571324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 572324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def unknown_boundaries? 573324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @start_index < 0 or @stop_index < 0 574324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 575324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 576324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def to_s 577324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver flat_list? ? 'nil' : @token.text.to_s 578324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 579324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 580324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def pretty_print( printer ) 581324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver text = @token ? @token.text : 'nil' 582324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver text =~ /\s+/ and 583324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver text = text.dump 584324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 585324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if empty? 586324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver printer.text( text ) 587324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 588324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver endpoints = @token ? [ "(#{ text }", ')' ] : [ '', '' ] 589324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver printer.group( 1, *endpoints ) do 590324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for child in self 591324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver printer.breakable 592324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver printer.pp( child ) 593324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 594324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 595324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 596324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 597324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 598324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 599324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 600324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::AST::CommonErrorNode 601324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 602324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverRepresents a series of erroneous tokens from a token stream input 603324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 604324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end 605324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 606324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass CommonErrorNode < CommonTree 607324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver include ANTLR3::Error 608324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver include ANTLR3::Constants 609324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 610324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_accessor :input, :start, :stop, :error 611324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 612324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def initialize( input, start, stop, error ) 613324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver super( nil ) 614324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stop = start if stop.nil? or 615324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ( stop.token_index < start.token_index and stop.type != EOF ) 616324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @input = input 617324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @start = start 618324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @stop = stop 619324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @error = error 620324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 621324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 622324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def flat_list? 623324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return false 624324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 625324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 626324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def type 627324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver INVALID_TOKEN_TYPE 628324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 629324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 630324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def text 631324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver case @start 632324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when Token 633324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver i = @start.token_index 634324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver j = ( @stop.type == EOF ) ? @input.size : @stop.token_index 635324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @input.to_s( i, j ) # <- the bad text 636324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when Tree 637324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @input.to_s( @start, @stop ) # <- the bad text 638324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 639324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "<unknown>" 640324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 641324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 642324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 643324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def to_s 644324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver case @error 645324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when MissingToken 646324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "<missing type: #{ @error.missing_type }>" 647324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when UnwantedToken 648324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "<extraneous: #{ @error.token.inspect }, resync = #{ text }>" 649324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when MismatchedToken 650324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "<mismatched token: #{ @error.token.inspect }, resync = #{ text }>" 651324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when NoViableAlternative 652324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "<unexpected: #{ @error.token.inspect }, resync = #{ text }>" 653324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else "<error: #{ text }>" 654324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 655324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 656324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 657324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 658324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 659324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverConstants::INVALID_NODE = CommonTree.new( ANTLR3::INVALID_TOKEN ) 660324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 661324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#################################################################################################### 662324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver########################################### Tree Adaptors ########################################## 663324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#################################################################################################### 664324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 665324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::AST::TreeAdaptor 666324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 667324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverSince a tree can be represented by a multitude of formats, ANTLR's tree-related 668324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvercode mandates the use of Tree Adaptor objects to build and manipulate any actual 669324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvertrees. Using an adaptor object permits a single recognizer to work with any 670324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvernumber of different tree structures without adding rigid interface requirements 671324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruveron customized tree structures. For example, if you want to represent trees using 672324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruversimple arrays of arrays, you just need to design an appropriate tree adaptor and 673324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverprovide it to the parser. 674324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 675324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTree adaptors are tasked with: 676324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 677324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver* copying and creating tree nodes and tokens 678324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver* defining parent-child relationships between nodes 679324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver* cleaning up / normalizing a full tree structure after construction 680324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver* reading and writing the attributes ANTLR expects of tree nodes 681324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver* providing node access and iteration 682324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 683324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end 684324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 685324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule TreeAdaptor 686324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver include TokenFactory 687324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver include Constants 688324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver include Error 689324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 690324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def add_child( tree, child ) 691324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree.add_child( child ) if tree and child 692324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 693324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 694324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def child_count( tree ) 695324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree.child_count 696324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 697324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 698324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def child_index( tree ) 699324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree.child_index rescue 0 700324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 701324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 702324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def child_of( tree, index ) 703324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree.nil? ? nil : tree.child( index ) 704324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 705324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 706324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def copy_node( tree_node ) 707324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree_node and tree_node.dup 708324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 709324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 710324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def copy_tree( tree, parent = nil ) 711324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree or return nil 712324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver new_tree = copy_node( tree ) 713324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver set_child_index( new_tree, child_index( tree ) ) 714324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver set_parent( new_tree, parent ) 715324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver each_child( tree ) do | child | 716324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver new_sub_tree = copy_tree( child, new_tree ) 717324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver add_child( new_tree, new_sub_tree ) 718324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 719324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return new_tree 720324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 721324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 722324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def delete_child( tree, index ) 723324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree.delete_child( index ) 724324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 725324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 726324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 727324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def each_child( tree ) 728324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver block_given? or return enum_for( :each_child, tree ) 729324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for i in 0 ... child_count( tree ) 730324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver yield( child_of( tree, i ) ) 731324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 732324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return tree 733324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 734324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 735324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def each_ancestor( tree, include_tree = true ) 736324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver block_given? or return enum_for( :each_ancestor, tree, include_tree ) 737324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if include_tree 738324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver begin yield( tree ) end while tree = parent_of( tree ) 739324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 740324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver while tree = parent_of( tree ) do yield( tree ) end 741324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 742324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 743324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 744324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def flat_list?( tree ) 745324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree.flat_list? 746324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 747324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 748324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def empty?( tree ) 749324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver child_count( tree ).zero? 750324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 751324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 752324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def parent( tree ) 753324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree.parent 754324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 755324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 756324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def replace_children( parent, start, stop, replacement ) 757324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver parent and parent.replace_children( start, stop, replacement ) 758324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 759324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 760324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def rule_post_processing( root ) 761324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if root and root.flat_list? 762324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver case root.child_count 763324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when 0 then root = nil 764324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when 1 765324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver root = root.child( 0 ).detach 766324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 767324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 768324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return root 769324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 770324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 771324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def set_child_index( tree, index ) 772324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree.child_index = index 773324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 774324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 775324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def set_parent( tree, parent ) 776324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree.parent = parent 777324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 778324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 779324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def set_token_boundaries( tree, start_token = nil, stop_token = nil ) 780324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return unless tree 781324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver start = stop = 0 782324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver start_token and start = start_token.index 783324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stop_token and stop = stop_token.index 784324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree.start_index = start 785324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree.stop_index = stop 786324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return tree 787324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 788324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 789324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def text_of( tree ) 790324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree.text rescue nil 791324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 792324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 793324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def token( tree ) 794324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver CommonTree === tree ? tree.token : nil 795324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 796324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 797324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def token_start_index( tree ) 798324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree ? tree.token_start_index : -1 799324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 800324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 801324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def token_stop_index( tree ) 802324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree ? tree.token_stop_index : -1 803324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 804324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 805324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def type_name( tree ) 806324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree.name rescue 'INVALID' 807324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 808324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 809324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def type_of( tree ) 810324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree.type rescue INVALID_TOKEN_TYPE 811324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 812324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 813324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def unique_id( node ) 814324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver node.hash 815324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 816324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 817324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 818324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 819324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::AST::CommonTreeAdaptor 820324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 821324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverThe default tree adaptor used by ANTLR-generated tree code. It, of course, 822324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverbuilds and manipulates CommonTree nodes. 823324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 824324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end 825324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 826324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass CommonTreeAdaptor 827324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver extend ClassMacros 828324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver include TreeAdaptor 829324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver include ANTLR3::Constants 830324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 831324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def initialize( token_class = ANTLR3::CommonToken ) 832324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @token_class = token_class 833324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 834324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 835324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def create_flat_list 836324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return create_with_payload( nil ) 837324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 838324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver alias create_flat_list! create_flat_list 839324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 840324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def become_root( new_root, old_root ) 841324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver new_root = create( new_root ) if new_root.is_a?( Token ) 842324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver old_root or return( new_root ) 843324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 844324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver new_root = create_with_payload( new_root ) unless CommonTree === new_root 845324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if new_root.flat_list? 846324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver count = new_root.child_count 847324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if count == 1 848324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver new_root = new_root.child( 0 ) 849324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver elsif count > 1 850324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver raise TreeInconsistency.multiple_roots! 851324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 852324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 853324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 854324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver new_root.add_child( old_root ) 855324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return new_root 856324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 857324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 858324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def create_from_token( token_type, from_token, text = nil ) 859324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver from_token = from_token.dup 860324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver from_token.type = token_type 861324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver from_token.text = text.to_s if text 862324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree = create_with_payload( from_token ) 863324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return tree 864324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 865324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 866324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def create_from_type( token_type, text ) 867324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver from_token = create_token( token_type, DEFAULT_CHANNEL, text ) 868324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver create_with_payload( from_token ) 869324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 870324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 871324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def create_error_node( input, start, stop, exc ) 872324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver CommonErrorNode.new( input, start, stop, exc ) 873324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 874324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 875324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def create_with_payload( payload ) 876324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return CommonTree.new( payload ) 877324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 878324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 879324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def create( *args ) 880324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver n = args.length 881324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if n == 1 and args.first.is_a?( Token ) then create_with_payload( args[ 0 ] ) 882324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver elsif n == 2 and Integer === args.first and String === args[ 1 ] 883324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver create_from_type( *args ) 884324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver elsif n >= 2 and Integer === args.first 885324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver create_from_token( *args ) 886324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 887324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver sig = args.map { |f| f.class }.join( ', ' ) 888324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver raise TypeError, "No create method with this signature found: (#{ sig })" 889324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 890324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 891324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 892324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver creation_methods = %w( 893324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver create_from_token create_from_type 894324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver create_error_node create_with_payload 895324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver create 896324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ) 897324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 898324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for method_name in creation_methods 899324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver bang_method = method_name + '!' 900324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver alias_method( bang_method, method_name ) 901324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver deprecate( bang_method, "use method ##{ method_name } instead" ) 902324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 903324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 904324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def rule_post_processing( root ) 905324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if root and root.flat_list? 906324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if root.empty? then root = nil 907324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver elsif root.child_count == 1 then root = root.first.detach 908324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 909324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 910324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return root 911324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 912324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 913324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def empty?( tree ) 914324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree.empty? 915324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 916324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 917324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def each_child( tree ) 918324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver block_given? or return enum_for( :each_child, tree ) 919324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree.each do | child | 920324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver yield( child ) 921324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 922324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 923324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 924324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 925324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 926324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 927324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#################################################################################################### 928324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver########################################### Tree Streams ########################################### 929324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#################################################################################################### 930324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 931324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::AST::TreeNodeStream 932324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 933324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTreeNodeStreams flatten two-dimensional tree structures into one-dimensional 934324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruversequences. They preserve the two-dimensional structure of the tree by inserting 935324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverspecial +UP+ and +DOWN+ nodes. 936324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 937324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverConsider a hypothetical tree: 938324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 939324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver [A] 940324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver +--[B] 941324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | +--[C] 942324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | `--[D] 943324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver `--[E] 944324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver `--[F] 945324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 946324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverA tree node stream would serialize the tree into the following sequence: 947324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 948324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver A DOWN B DOWN C D UP E DOWN F UP UP EOF 949324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 950324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverOther than serializing a tree into a sequence of nodes, a tree node stream 951324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruveroperates similarly to other streams. They are commonly used by tree parsers as 952324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverthe main form of input. #peek, like token streams, returns the type of the token 953324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverof the next node. #look returns the next full tree node. 954324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 955324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end 956324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 957324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule TreeNodeStream 958324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver extend ClassMacros 959324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver include Stream 960324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver include Constants 961324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 962324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver abstract :at 963324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver abstract :look 964324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver abstract :tree_source 965324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver abstract :token_stream 966324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver abstract :tree_adaptor 967324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver abstract :unique_navigation_nodes= 968324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver abstract :to_s 969324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver abstract :replace_children 970324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 971324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 972324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::AST::CommonTreeNodeStream 973324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 974324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverAn implementation of TreeNodeStream tailed for streams based on CommonTree 975324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverobjects. CommonTreeNodeStreams are the default input streams for tree parsers. 976324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 977324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end 978324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 979324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass CommonTreeNodeStream 980324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver include TreeNodeStream 981324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 982324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_accessor :token_stream 983324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_reader :adaptor, :position 984324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 985324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def initialize( *args ) 986324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver options = args.last.is_a?( ::Hash ) ? args.pop : {} 987324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver case n = args.length 988324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when 1 989324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @root = args.first 990324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @token_stream = @adaptor = @nodes = @down = @up = @eof = nil 991324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when 2 992324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @adaptor, @root = args 993324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @token_stream = @nodes = @down = @up = @eof = nil 994324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when 3 995324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver parent, start, stop = *args 996324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @adaptor = parent.adaptor 997324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @root = parent.root 998324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @nodes = parent.nodes[ start ... stop ] 999324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @down = parent.down 1000324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @up = parent.up 1001324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @eof = parent.eof 1002324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @token_stream = parent.token_stream 1003324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when 0 1004324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver raise ArgumentError, "wrong number of arguments (0 for 1)" 1005324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else raise ArgumentError, "wrong number of arguments (#{ n } for 3)" 1006324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1007324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @adaptor ||= options.fetch( :adaptor ) { CommonTreeAdaptor.new } 1008324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @token_stream ||= options[ :token_stream ] 1009324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @down ||= options.fetch( :down ) { @adaptor.create_from_type( DOWN, 'DOWN' ) } 1010324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @up ||= options.fetch( :up ) { @adaptor.create_from_type( UP, 'UP' ) } 1011324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @eof ||= options.fetch( :eof ) { @adaptor.create_from_type( EOF, 'EOF' ) } 1012324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @nodes ||= [] 1013324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1014324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @unique_navigation_nodes = options.fetch( :unique_navigation_nodes, false ) 1015324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @position = -1 1016324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @last_marker = nil 1017324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @calls = [] 1018324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1019324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1020324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def fill_buffer( tree = @root ) 1021324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @nodes << tree unless nil_tree = @adaptor.flat_list?( tree ) 1022324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver unless @adaptor.empty?( tree ) 1023324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver add_navigation_node( DOWN ) unless nil_tree 1024324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @adaptor.each_child( tree ) { | c | fill_buffer( c ) } 1025324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver add_navigation_node( UP ) unless nil_tree 1026324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1027324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @position = 0 if tree == @root 1028324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( self ) 1029324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1030324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1031324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def node_index( node ) 1032324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @position == -1 and fill_buffer 1033324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return @nodes.index( node ) 1034324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1035324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1036324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def add_navigation_node( type ) 1037324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver navigation_node = 1038324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver case type 1039324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when DOWN 1040324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver has_unique_navigation_nodes? ? @adaptor.create_from_type( DOWN, 'DOWN' ) : @down 1041324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 1042324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver has_unique_navigation_nodes? ? @adaptor.create_from_type( UP, 'UP' ) : @up 1043324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1044324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @nodes << navigation_node 1045324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1046324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1047324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def at( index ) 1048324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @position == -1 and fill_buffer 1049324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @nodes.at( index ) 1050324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1051324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1052324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def look( k = 1 ) 1053324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @position == -1 and fill_buffer 1054324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver k == 0 and return nil 1055324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver k < 0 and return self.look_behind( -k ) 1056324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1057324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver absolute = @position + k - 1 1058324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @nodes.fetch( absolute, @eof ) 1059324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1060324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1061324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def current_symbol 1062324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver look 1063324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1064324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1065324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def look_behind( k = 1 ) 1066324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver k == 0 and return nil 1067324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver absolute = @position - k 1068324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( absolute < 0 ? nil : @nodes.fetch( absolute, @eof ) ) 1069324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1070324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1071324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def tree_source 1072324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @root 1073324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1074324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1075324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def source_name 1076324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver self.token_stream.source_name 1077324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1078324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1079324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def tree_adaptor 1080324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @adaptor 1081324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1082324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1083324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def has_unique_navigation_nodes? 1084324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return @unique_navigation_nodes 1085324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1086324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_writer :unique_navigation_nodes 1087324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1088324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def consume 1089324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @position == -1 and fill_buffer 1090324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver node = @nodes.fetch( @position, @eof ) 1091324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @position += 1 1092324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( node ) 1093324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1094324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1095324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def peek( i = 1 ) 1096324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @adaptor.type_of look( i ) 1097324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1098324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1099324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver alias >> peek 1100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def <<( k ) 1101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver self >> -k 1102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def mark 1105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @position == -1 and fill_buffer 1106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @last_marker = @position 1107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return @last_marker 1108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def release( marker = nil ) 1111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # do nothing? 1112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver alias index position 1115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def rewind( marker = @last_marker, release = true ) 1117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver seek( marker ) 1118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def seek( index ) 1121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @position == -1 and fill_buffer 1122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @position = index 1123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def push( index ) 1126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @calls << @position 1127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver seek( index ) 1128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def pop 1131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pos = @calls.pop and seek( pos ) 1132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return pos 1133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def reset 1136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @position = 0 1137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @last_marker = 0 1138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @calls = [] 1139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def replace_children( parent, start, stop, replacement ) 1142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver parent and @adaptor.replace_children( parent, start, stop, replacement ) 1143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def size 1146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @position == -1 and fill_buffer 1147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return @nodes.length 1148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def inspect 1151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @position == -1 and fill_buffer 1152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @nodes.map { |nd| @adaptor.type_name( nd ) }.join( ' ' ) 1153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def extract_text( start = nil, stop = nil ) 1156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver start.nil? || stop.nil? and return nil 1157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @position == -1 and fill_buffer 1158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if @token_stream 1160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver from = @adaptor.token_start_index( start ) 1161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver to = 1162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver case @adaptor.type_of( stop ) 1163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when UP then @adaptor.token_stop_index( start ) 1164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when EOF then to = @nodes.length - 2 1165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else @adaptor.token_stop_index( stop ) 1166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return @token_stream.extract_text( from, to ) 1168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver buffer = '' 1171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for node in @nodes 1172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if node == start ... node == stop # <-- hey look, it's the flip flop operator 1173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver buffer << @adaptor.text_of( node ) #|| ' ' << @adaptor.type_of( node ).to_s ) 1174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( buffer ) 1177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def each 1180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @position == -1 and fill_buffer 1181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver block_given? or return enum_for( :each ) 1182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for node in @nodes do yield( node ) end 1183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver self 1184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver include Enumerable 1187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def to_a 1189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return @nodes.dup 1190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def extract_text( start = nil, stop = nil ) 1193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @position == -1 and fill_buffer 1194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver start ||= @nodes.first 1195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stop ||= @nodes.last 1196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if @token_stream 1198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver case @adaptor.type_of( stop ) 1199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when UP 1200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stop_index = @adaptor.token_stop_index( start ) 1201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when EOF 1202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return extract_text( start, @nodes[ - 2 ] ) 1203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 1204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stop_index = @adaptor.token_stop_index( stop ) 1205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver start_index = @adaptor.token_start_index( start ) 1208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return @token_stream.extract_text( start_index, stop_index ) 1209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 1210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver start_index = @nodes.index( start ) || @nodes.length 1211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stop_index = @nodes.index( stop ) || @nodes.length 1212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( 1213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @nodes[ start_index .. stop_index ].map do | n | 1214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @adaptor.text_of( n ) or " " + @adaptor.type_of( n ).to_s 1215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end.join( '' ) 1216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ) 1217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver alias to_s extract_text 1221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#private 1223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# 1224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# def linear_node_index( node ) 1225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# @position == -1 and fill_buffer 1226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# @nodes.each_with_index do |n, i| 1227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# node == n and return(i) 1228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# end 1229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# return -1 1230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# end 1231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 1232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::AST::RewriteRuleElementStream 1234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1235324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverSpecial type of stream that is used internally by tree-building and tree- 1236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrewriting parsers. 1237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end 1239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass RewriteRuleElementStream # < Array 1241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver extend ClassMacros 1242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver include Error 1243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def initialize( adaptor, element_description, elements = nil ) 1245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @cursor = 0 1246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @single_element = nil 1247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @elements = nil 1248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @dirty = false 1249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @element_description = element_description 1250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @adaptor = adaptor 1251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if elements.instance_of?( Array ) 1252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @elements = elements 1253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 1254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver add( elements ) 1255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def reset 1259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @cursor = 0 1260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @dirty = true 1261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def add( el ) 1264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( nil ) unless el 1265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver case 1266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when ! el then return( nil ) 1267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when @elements then @elements << el 1268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when @single_element.nil? then @single_element = el 1269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 1270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @elements = [ @single_element, el ] 1271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @single_element = nil 1272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( @elements ) 1273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def next_tree 1277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if @dirty or @cursor >= length && length == 1 1278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return dup( __next__ ) 1279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver __next__ 1281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver abstract :dup 1284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def to_tree( el ) 1286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return el 1287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def has_next? 1290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( @single_element && @cursor < 1 or 1291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @elements && @cursor < @elements.length ) 1292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def size 1295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @single_element and return 1 1296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @elements and return @elements.length 1297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return 0 1298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver alias length size 1301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverprivate 1303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def __next__ 1305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver l = length 1306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver case 1307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when l.zero? 1308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver raise Error::RewriteEmptyStream.new( @element_description ) 1309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when @cursor >= l 1310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver l == 1 and return to_tree( @single_element ) 1311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver raise RewriteCardinalityError.new( @element_description ) 1312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when @single_element 1313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @cursor += 1 1314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( to_tree( @single_element ) ) 1315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 1316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver out = to_tree( @elements.at( @cursor ) ) 1317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @cursor += 1 1318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( out ) 1319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 1322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::AST::RewriteRuleTokenStream 1325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1326324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverSpecial type of stream that is used internally by tree-building and tree- 1327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrewriting parsers. 1328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end 1330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass RewriteRuleTokenStream < RewriteRuleElementStream 1331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def next_node 1332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return @adaptor.create_with_payload( __next__ ) 1333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver alias :next :__next__ 1336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public :next 1337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def dup( el ) 1339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver raise TypeError, "dup can't be called for a token stream" 1340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 1342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::AST::RewriteRuleSubtreeStream 1344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1345324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverSpecial type of stream that is used internally by tree-building and tree- 1346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrewriting parsers. 1347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end 1349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass RewriteRuleSubtreeStream < RewriteRuleElementStream 1351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def next_node 1352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if @dirty or @cursor >= length && length == 1 1353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return @adaptor.copy_node( __next__ ) 1354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return __next__ 1356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def dup( el ) 1359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @adaptor.copy_tree( el ) 1360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 1362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::AST::RewriteRuleNodeStream 1364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1365324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverSpecial type of stream that is used internally by tree-building and tree- 1366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrewriting parsers. 1367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end 1369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass RewriteRuleNodeStream < RewriteRuleElementStream 1371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver alias next_node __next__ 1372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public :next_node 1373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def to_tree( el ) 1374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @adaptor.copy_node( el ) 1375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def dup( el ) 1378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver raise TypeError, "dup can't be called for a node stream" 1379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 1380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 1381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 1382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverinclude AST 1384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 1385