class PosxmlCompiler::XsdParser
Constants
- DELIMITER_END_INSTRUCTION
- DELIMITER_END_PARAMETER
Attributes
instructions[RW]
text[RW]
Public Class Methods
new(text)
click to toggle source
# File lib/posxml_compiler/xsd_parser.rb, line 8 def initialize(text) @text = text index_start = text.index("<xs:group name=\"comandos\">") index_end = text.index("<\/xs:group>") groups = text[index_start..index_end] # select only group text complex = text[index_end..-1] # select only complex text commands = parse_bytecodes(groups) @instructions = parse_parameters(commands, complex) # => {"if" => {:bytecode => "I", :order => ["variable", "operator", "value"], :parameters => {"variable" => :string_or_integer, "operator" => :string, "value" => :string_or_integer}} end
Public Instance Methods
find(name)
click to toggle source
# File lib/posxml_compiler/xsd_parser.rb, line 47 def find(name) self.instructions[name] # => {:bytecode => "I", :order => ["variable", "operator", "value"], :parameters => {"variable" => :string_or_integer, "operator" => :string, "value" => :string_or_integer} end
parameter_type(instruction, parameter)
click to toggle source
# File lib/posxml_compiler/xsd_parser.rb, line 25 def parameter_type(instruction, parameter) self.instructions[instruction][:parameters][parameter.to_s] end
parameters_validate(instruction_name, instruction, parameters)
click to toggle source
# File lib/posxml_compiler/xsd_parser.rb, line 51 def parameters_validate(instruction_name, instruction, parameters) return unless instruction[:parameters] parameters_valid = instruction[:parameters].keys parameters.each do |name, data| unless parameters_valid.include? name raise ParameterNotFoundError.new("invalid parameter '#{name}' for instruction '#{instruction_name}'") end end end
to_bytecode(name, parameters)
click to toggle source
Receive:
("if", {"variable" => {:original => "$(sKeyTouchScreen)", :value => "$(1)", :type => :string}, "operator" => {:original => "equalto", :value => "equalto", :type => :string}, "value" => {:original => "KEY_CLEAR", :value => "KEY_CLEAR", :type => :string})
Return:
"I$(1)\nequalto\nKEY_CLEAR"
# File lib/posxml_compiler/xsd_parser.rb, line 33 def to_bytecode(name, parameters) instruction = self.find(name) # => {:bytecode => "I", :order => ["variable", "operator", "value"], :parameters => {"variable" => :string_or_integer, "operator" => :string, "value" => :string_or_integer} raise InstructionNotFoundError.new("Instruction #{name.inspect} not found") unless instruction parameters_validate(name, instruction, parameters) line = instruction[:order].collect { |param| parameters[param][:value] } if line.empty? instruction[:bytecode].chr + DELIMITER_END_INSTRUCTION else instruction[:bytecode].chr + line.join(DELIMITER_END_PARAMETER) + DELIMITER_END_PARAMETER + DELIMITER_END_INSTRUCTION end end
valid?()
click to toggle source
# File lib/posxml_compiler/xsd_parser.rb, line 21 def valid? !! @instructions end
Private Instance Methods
check_type(str)
click to toggle source
# File lib/posxml_compiler/xsd_parser.rb, line 147 def check_type(str) if str.include? "<xs:documentation>" if type_string_or_integer?(str) :string_or_integer elsif type_integer?(str) :integer else :string end end end
parse_bytecodes(str)
click to toggle source
Will return a hash with instruction name and bytecode in array
{ "if" => {:bytecode => "I", :order => ["variable", "operator", "value"]}, "/if" => {:bytecode => "E"} }
# File lib/posxml_compiler/xsd_parser.rb, line 83 def parse_bytecodes(str) last, end_element = nil str.split("\n").inject({}) do |hash, str| key = str.match(/<xs:element name="(.*)" type="/) if key last = key[1] hash[last] ||= {:order => []} end_element = false end value = str.match(/<xs:appinfo>(.*)<\/xs:appinfo>/) value = value[1] if value if value if end_element hash["/" + last] = {:order => [], :bytecode => string2byte(value)} elsif ! value.include?(";") hash[last][:order] = value.split(",") else end_element = true hash[last][:bytecode] = string2byte(value) end end hash end end
parse_parameters(bytecodes, str)
click to toggle source
With commands generate by parse_bytecodes
:
{"if" => ["I"], "/if" => ["E"]} { "if" => {:bytecode => "I", :order => ["variable", "operator", "value"]}, "/if" => {:bytecode => "E"} }
this method parse parameters and types:
{ "if" => { :bytecode => "I", :order => ["variable", "operator", "value"], :parameters => {"variable" => :string_or_integer, "operator" => :string, "value" => :string_or_integer} }, "/if" => {:bytecode => "E"} }
# File lib/posxml_compiler/xsd_parser.rb, line 127 def parse_parameters(bytecodes, str) commands = bytecodes.dup last_byte = nil last_param = nil str.split("\n").each do |str| key = str.match(/<xs:complexType name="(.*)">/) last_byte = key[1] if key value = str.match(/<xs:attribute name="(.*)" type/) last_param = value[1] if value value = check_type(str) if value && last_byte commands[last_byte][:parameters] ||= {} commands[last_byte][:parameters][last_param] = value end end commands end
string2byte(str)
click to toggle source
# File lib/posxml_compiler/xsd_parser.rb, line 62 def string2byte(str) value = str.gsub(";", "").gsub("true", "").gsub("false", "") if value == "\\x0B" "\x0B" elsif value.include?("\\x") value.sub("\\x", "").to_i(16).chr elsif value == ">" ">" elsif value == "<" "<" else value end end
type_integer?(str)
click to toggle source
def type_string?(str) data = str.match(/(string)/) end
# File lib/posxml_compiler/xsd_parser.rb, line 167 def type_integer?(str) data = str.to_s.downcase.match(/(integer|inteiro)/) end
type_string_or_integer?(str)
click to toggle source
# File lib/posxml_compiler/xsd_parser.rb, line 159 def type_string_or_integer?(str) str.match(/(string ou inteiro|string or integer|float)/) end