class FilterLexer::Parser
The parser is your main entrypoint for the lexer
You never instantiate it, you just use it's static methods
Public Class Methods
output_tree(element, indent = '')
click to toggle source
When using the lexer, it may be useful to have a visual representation of the tree
Just pass the tree (or any node in it, if you're only interested in that part) to this function, and a visual representation of the tree will magically appear in stdout
# File lib/filter_lexer.rb, line 39 def output_tree(element, indent = '') puts "#{indent}#{element.class}: #{element.text_value}" (element.elements || []).each do |e| output_tree(e, "#{indent} ") end end
parse(data)
click to toggle source
The bread and butter of the entire thing: parsing, and it's pretty simple
Just pass in a string, and out comes a parsed tree, or an exception
The parsed tree will always be an FilterLexer::Expression
object The exception will always be an FilterLexer::ParseException
object
# File lib/filter_lexer.rb, line 22 def parse(data) # Pass the data over to the parser instance tree = @parser.parse(data) # If the AST is nil then there was an error during parsing fail ParseException, @parser if tree.nil? # Cleanup the tree clean_tree(tree) return tree end
Private Class Methods
clean_tree(root_node)
click to toggle source
# File lib/filter_lexer.rb, line 56 def clean_tree(root_node) return if root_node.elements.nil? # Clean child elements root_node.elements.each { |node| clean_tree(node) } # Remove empty syntax elements root_node.elements.reject! { |node| node_elem(node).empty? && syn?(node) } # Replace syntax elements with just one child with that child root_node.elements.map! { |node| (node_elem(node).size == 1 && syn?(node)) ? node.elements.first : node } end
node_elem(node)
click to toggle source
# File lib/filter_lexer.rb, line 52 def node_elem(node) return node.elements || [] end
syn?(node)
click to toggle source
# File lib/filter_lexer.rb, line 48 def syn?(node) return node.class.name == 'Treetop::Runtime::SyntaxNode' end