Custom Data for Syntax Nodes

61 views
Skip to first unread message

Phrogz

unread,
Apr 5, 2018, 3:45:20 AM4/5/18
to Treetop Development

I have a grammar that matches some keys. I want to look up the values associated with those keys in a hash I give the parser. How can I make it so that the syntax nodes have access to methods or variables from the parser?


For example, here's a simple grammar that finds a single word and tries to look up its value:

# var.treetop
grammar VarResolver
  include VarLookup

  rule variable
    [a-zA-Z] [a-zA-Z0-9_]*
    {
      def value
        p found:text_value
        find_variable(text_value)
      end
    }
  end
end


Here's a test file using it:

# test.rb
require 'treetop'

module VarLookup
  def set_variables(variable_hash)
    @vars = variable_hash
  end
  def find_variable(str)
    @vars[str.to_sym]
  end
end

Treetop.load('var.treetop')

@p = VarResolverParser.new
@p.set_variables name:'Phrogz'
p @p.parse('name').value


Running this test, I get the output:

{:found=>"name"}
(eval):16:in `value': undefined method `find_variable'
     for #<Treetop::Runtime::SyntaxNode:0x00007f88e091b340> (NoMethodError)


How can I make find_variable accessible inside the value method? (In the real parser, these rules are deeply nested, and need to resolve the value without returning the actual name to the top of the parse tree. I cannot just return the text_value and look it up outside.)

Clifford Heath

unread,
Apr 5, 2018, 6:13:02 AM4/5/18
to treetop-dev@googlegroups.com Development
This is a significant weakness in the design of Treetop.

I (as maintainer) didn't want to slow it down further by
passing yet another argument to every SyntaxNode,
and break any custom SyntaxNode classes folk have
written. These constructors get the "input" object, a Range
that selects part of that input, and optionally an array
of child SyntaxNodes. They should have received the
Parser itself instead of the inputted that should have
the input as a member.

So instead, for my own use (some years back), I made
a custom proxy for the "input" and attached my Context
to it. You might get away with doing something similar:

<https://github.com/cjheath/activefacts-cql/blob/master/lib/activefacts/cql/parser.rb#L203-L249>

Clifford Heath.
> --
> You received this message because you are subscribed to the Google Groups "Treetop Development" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to treetop-dev...@googlegroups.com.
> To post to this group, send email to treet...@googlegroups.com.
> Visit this group at https://groups.google.com/group/treetop-dev.
> For more options, visit https://groups.google.com/d/optout.

Phrogz

unread,
Apr 5, 2018, 8:45:32 AM4/5/18
to Treetop Development
Ahh! A clever hack on an unfortunate limitation. Thanks for the idea and code (and, as always, your maintenance of Treetop).

As I fell asleep after posting last night I had thought to peek into whether each node had an instance variable referencing the parser. I guess not. Too bad.

Reply all
Reply to author
Forward
0 new messages