# begin: ragel
begin¶ ↑
%%{
machine bel; include 'common.rl'; include 'identifier.rl'; include 'string.rl'; action add_ident_param_value { trace('PARAMETER add_ident_param_value') ident = @buffers.delete(:ident) value_node = value(ident, complete: ident.complete, character_range: ident.character_range) @buffers[:param_value] = value_node } action add_string_param_value { trace('PARAMETER add_string_param_value') string_node = @buffers.delete(:string) value_node = value(string_node, complete: string_node.complete, character_range: string_node.character_range) @buffers[:param_value] = value_node } action parameter_end { trace('PARAMETER parameter_end') param_node = parameter() completed = true prefix_node = @buffers.delete(:param_prefix) if prefix_node param_node <<= prefix_node unless prefix_node.complete trace('PN incomplete') completed = false end param_start = prefix_node.range_start else prefix_node = prefix(nil) prefix_node.complete = true trace('PN complete (no prefix)') param_node <<= prefix_node completed = true end value_node = @buffers.delete(:param_value) unless value_node.nil? param_node <<= value_node unless value_node.complete trace('VN incomplete') completed = false end param_start ||= value_node.range_start param_node.character_range = [param_start, value_node.range_end] else completed = false end param_node.complete = completed @buffers[:parameter] = param_node } action add_prefix { trace('PARAMETER add_prefix') ident = @buffers.delete(:ident) prefix_node = prefix(ident, complete: ident.complete, character_range: ident.character_range) @buffers[:param_prefix] = prefix_node } action a_parameter_eof { trace("PARAMETER a_parameter_eof") param_node = parameter() completed = true prefix_node = @buffers.delete(:param_prefix) unless prefix_node.nil? param_node <<= prefix_node unless prefix_node.complete completed = false end end string_value_node = @buffers.delete(:string) unless string_value_node.nil? param_node <<= string_value_node unless string_value_node.complete completed = false end else completed = false end param_node.complete = completed @buffers[:parameter] = param_node } action parameter_node_eof { trace("PARAMETER parameter_node_eof") param_node = parameter() completed = true prefix_node = @buffers.delete(:param_prefix) unless prefix_node.nil? param_node <<= prefix_node unless prefix_node.complete completed = false end end string_value_node = @buffers.delete(:string) unless string_value_node.nil? param_node <<= string_value_node unless string_value_node.complete completed = false end else completed = false end param_node.complete = completed yield param_node } action yield_parameter { trace('PARAMETER yield_parameter') yield @buffers[:parameter] } prefix = an_ident COLON ; ident_value = an_ident %add_ident_param_value ; string_value = a_string %add_string_param_value ; value = ident_value | string_value ; parameter_prefix_value = prefix %add_prefix SP* value ; parameter_prefix_maybe_value = prefix %add_prefix SP* value? ; parameter_value = SP* value ; a_parameter = ( parameter_prefix_value | parameter_value | parameter_prefix_maybe_value ) @eof(a_parameter_eof) %parameter_end ; parameter_node := ( parameter_prefix_value | parameter_value | parameter_prefix_maybe_value ) @eof(parameter_node_eof) %parameter_end %yield_parameter NL? ; #BEL_PARAMETER = (an_ident ':')? @prefix SP* (a_string %string | an_ident %ident); #bel_parameter := BEL_PARAMETER %yield_parameter_ast NL;
}%%
end¶ ↑
# end: ragel
require_relative '../ast/node' require_relative '../mixin/buffer' require_relative '../nonblocking_io_wrapper' require_relative '../tracer'
module BELParser
module Parsers module Expression module Parameter class << self MAX_LENGTH = 1024 * 128 # 128K def parse(content) return nil unless content Parser.new(content).each do |obj| yield obj end end end private class Parser include Enumerable include BELParser::Parsers::Buffer include BELParser::Parsers::AST::Sexp include BELParser::Parsers::Tracer def initialize(content) @content = content # begin: ragel %% write data; # end: ragel end def each @buffers = {} @incomplete = {} data = @content.unpack('C*') p = 0 pe = data.length p_start = 0 p_end = 0 id_start = 0 id_end = 0 eof = data.length # begin: ragel %% write init; %% write exec; # end: ragel end end end end end
end
if __FILE__ == $0
$stdin.each_line do |line| BELParser::Parsers::Expression::Parameter.parse(line) { |obj| puts obj.inspect } end
end
# vim: ft=ruby ts=2 sw=2: # encoding: utf-8