Implement h_action.
This commit is contained in:
parent
8c653b519e
commit
a302953dfd
4 changed files with 42 additions and 1 deletions
|
|
@ -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]}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue