Define choice and sequence with define_parser method.
This commit is contained in:
parent
5ea0b727d0
commit
d3ff5f5b1e
1 changed files with 13 additions and 26 deletions
|
|
@ -40,48 +40,35 @@ module Hammer
|
||||||
return parser
|
return parser
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.sequence(*parsers)
|
|
||||||
args = parsers.flat_map { |p| [:pointer, p.h_parser] }
|
|
||||||
h_parser = Hammer::Internal.h_sequence(*args, :pointer, nil)
|
|
||||||
sub_parsers = parsers # store them so they don't get garbage-collected (probably not needed, though)
|
|
||||||
# TODO: Use (managed?) FFI struct instead of void pointers
|
|
||||||
|
|
||||||
parser = Hammer::Parser.new
|
|
||||||
parser.instance_variable_set :@h_parser, h_parser
|
|
||||||
parser.instance_variable_set :@sub_parsers, sub_parsers
|
|
||||||
return parser
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.choice(*parsers)
|
|
||||||
args = parsers.flat_map { |p| [:pointer, p.h_parser] }
|
|
||||||
h_parser = Hammer::Internal.h_choice(*args, :pointer, nil)
|
|
||||||
sub_parsers = parsers # store them so they don't get garbage-collected (probably not needed, though)
|
|
||||||
# TODO: Use (managed?) FFI struct instead of void pointers
|
|
||||||
|
|
||||||
parser = Hammer::Parser.new
|
|
||||||
parser.instance_variable_set :@h_parser, h_parser
|
|
||||||
parser.instance_variable_set :@sub_parsers, sub_parsers
|
|
||||||
return parser
|
|
||||||
end
|
|
||||||
|
|
||||||
# Defines a parser constructor with the given name.
|
# Defines a parser constructor with the given name.
|
||||||
# Options:
|
# Options:
|
||||||
# hammer_function: name of the hammer function to call (default: 'h_'+name)
|
# hammer_function: name of the hammer function to call (default: 'h_'+name)
|
||||||
|
# varargs: Whether the function is taking a variable number of arguments (default: false)
|
||||||
def self.define_parser(name, options = {})
|
def self.define_parser(name, options = {})
|
||||||
hammer_function = options[:hammer_function] || ('h_' + name.to_s)
|
hammer_function = options[:hammer_function] || ('h_' + name.to_s)
|
||||||
|
varargs = options[:varargs] || false
|
||||||
|
|
||||||
# Define a new class method
|
# Define a new class method
|
||||||
define_singleton_method name do |*parsers|
|
define_singleton_method name do |*parsers|
|
||||||
#args = parsers.map { |p| p.instance_variable_get :@h_parser }
|
if varargs
|
||||||
h_parser = Hammer::Internal.send hammer_function, *parsers.map(&:h_parser)
|
args = parsers.flat_map { |p| [:pointer, p.h_parser] }
|
||||||
|
args += [:pointer, nil]
|
||||||
|
else
|
||||||
|
args = parsers.map(&:h_parser)
|
||||||
|
end
|
||||||
|
h_parser = Hammer::Internal.send hammer_function, *args
|
||||||
|
|
||||||
parser = Hammer::Parser.new
|
parser = Hammer::Parser.new
|
||||||
parser.instance_variable_set :@h_parser, h_parser
|
parser.instance_variable_set :@h_parser, h_parser
|
||||||
|
parser.instance_variable_set :@sub_parsers, parsers # store sub parsers to prevent them from being garbage-collected
|
||||||
return parser
|
return parser
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
private_class_method :define_parser
|
private_class_method :define_parser
|
||||||
|
|
||||||
|
define_parser :sequence, varargs: true
|
||||||
|
define_parser :choice, varargs: true
|
||||||
|
|
||||||
define_parser :int64
|
define_parser :int64
|
||||||
define_parser :int32
|
define_parser :int32
|
||||||
define_parser :int16
|
define_parser :int16
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue