require "../util.cr" require "./thue.cr" require "./rule.cr" class Thue::Parser def initialize(code_io : IO) @raw_code = code_io.gets_to_end code_io.close # just in case end def parse rules = [] of Rule line_iterator = @raw_code.lines.each line_iterator.each do |line| case line when "", "::=" # stops iteration of lines to be picked up by string builder break # returned match objects are provably not_nil, safe when .matches?(R_INPUT_RULE) m = line.match(R_INPUT_RULE).not_nil! rules << InputRule.new(m[1]) when .matches?(R_OUTPUT_RULE) m = line.match(R_OUTPUT_RULE).not_nil! rules << OutputRule.new(m[1], m[2]) when .matches?(R_NORMAL_RULE) m = line.match(R_NORMAL_RULE).not_nil! rules << NormalRule.new(m[1], m[2]) else raise Util::ParserError.new("No separator between code and initial state near '#{line}'") end end state = String.build do |str| # resumes from where rule parser left off line_iterator.each do |line| str << line str << '\n' end end {rules, state} end end