Implement h_action.

This commit is contained in:
Jakob Rath 2013-12-16 23:30:50 +01:00 committed by Dan Hirsch
parent 8c653b519e
commit a302953dfd
4 changed files with 42 additions and 1 deletions

View file

@ -20,3 +20,25 @@ x.bind(Hammer::Parser.token('abd'))
$r = parser.parse 'abcabd' $r = parser.parse 'abcabd'
p $r[:ast][:data][:seq].elements.map {|e| e[:data][:bytes].token } p $r[:ast][:data][:seq].elements.map {|e| e[:data][:bytes].token }
h = Hammer::Parser
parser =
h.many(
h.action(h.uint8) { |r|
p "TT=#{r[:ast][:token_type]}, value=#{r[:ast][:data][:uint]}"
r[:ast][:data][:uint] *= 2
r[:ast] if r[:ast][:data][:uint] % 3 == 0
})
#parser = Hammer::Parser.build {
# many {
# uint8
# action { |r|
# p r
# r[:ast]
# }
# }
#}
$r = parser.parse 'abcdefgh'
p $r[:ast][:data][:seq].elements.map {|e| e[:data][:uint]}

View file

@ -119,7 +119,8 @@ module Hammer
attach_function :h_indirect, [], :h_parser attach_function :h_indirect, [], :h_parser
attach_function :h_bind_indirect, [:h_parser, :h_parser], :void attach_function :h_bind_indirect, [:h_parser, :h_parser], :void
#attach_function :h_action, [:h_parser, ...], :h_parser callback :HAction, [HParseResult.by_ref], HParsedToken.by_ref
attach_function :h_action, [:h_parser, :HAction], :h_parser
#attach_function :h_attr_bool, [:h_parser, ...], :h_parser #attach_function :h_attr_bool, [:h_parser, ...], :h_parser
# free the parse result # free the parse result

View file

@ -45,6 +45,15 @@ module Hammer
@dont_gc << other_parser @dont_gc << other_parser
end end
# Can pass the action either as a Proc in second parameter, or as block.
def self.action(parser, action=nil, &block)
action = block if action.nil?
raise ArgumentError, 'no action' if action.nil?
h_parser = Hammer::Internal.h_action(parser.h_parser, action)
return Hammer::Parser.new(:action, h_parser, [parser, action])
end
def self.token(string) def self.token(string)
# Need to copy string to a memory buffer (not just string.dup) # Need to copy string to a memory buffer (not just string.dup)
# * Original string might be modified, this must not affect existing tokens # * Original string might be modified, this must not affect existing tokens

View file

@ -52,9 +52,18 @@ module Hammer
return self return self
end end
# modifies previous parser
def action(&block)
parser = @parsers.last
raise RuntimeError, 'need a parser before action' if parser.nil?
@parsers << Hammer::Parser.action(parser, &block)
return self
end
# Defines a parser constructor with the given name. # Defines a parser constructor with the given name.
def self.define_parser(name, options = {}) def self.define_parser(name, options = {})
define_method name do |*args| define_method name do |*args|
# TODO: This is wrong!! Needs to accept a block for nested parsers!
@parsers << Hammer::Parser.send(name, *args) @parsers << Hammer::Parser.send(name, *args)
return self return self
end end