From 328197add50994d42924ae97ba1269729231f02f Mon Sep 17 00:00:00 2001 From: Roberto Alsina Date: Fri, 2 Aug 2024 17:23:40 -0300 Subject: [PATCH] Improved config parsing --- src/tartrazine.cr | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/src/tartrazine.cr b/src/tartrazine.cr index efa0ad9..841cf20 100644 --- a/src/tartrazine.cr +++ b/src/tartrazine.cr @@ -3,6 +3,11 @@ require "xml" module Tartrazine VERSION = "0.1.0" + class State + property name : String = "" + property rules = [] of String + end + class Lexer property config = { name: "", @@ -12,6 +17,8 @@ module Tartrazine priority: 0, } + property states = [] of State + def self.from_xml(xml : String) : Lexer l = Lexer.new lexer = XML.parse(xml).first_element_child @@ -19,25 +26,39 @@ module Tartrazine config = lexer.children.find { |n| n.name == "config" } if config l.config = { - name: xml_to_s(config, name), - aliases: xml_to_a(config, _alias), - filenames: xml_to_a(config, filename), - mime_types: xml_to_a(config, mime_type), - priority: xml_to_s(config, priority).to_i, + name: xml_to_s(config, name) || "", + aliases: xml_to_a(config, _alias) || [] of String, + filenames: xml_to_a(config, filename) || [] of String, + mime_types: xml_to_a(config, mime_type) || [] of String, + priority: xml_to_i(config, priority) || 0, } end + + rules = lexer.children.find { |n| n.name == "rules" } + if rules + # Rules contains states 🤷 + rules.children.select { |n| n.name == "state" }.each do |node| + state = State.new + state.name = node["name"] + l.states << state + end + end end l end end end -l = Tartrazine::Lexer.from_xml(File.read("lexers/plaintext.xml")) -p! l.config +l = Tartrazine::Lexer.from_xml(File.read("lexers/bash.xml")) +p! l.config, l.states # Convenience macros to parse XML macro xml_to_s(node, name) -{{node}}.children.find{|n| n.name == "{{name}}".lstrip("_")}.as(XML::Node).content.to_s +{{node}}.children.find{|n| n.name == "{{name}}".lstrip("_")}.try &.content.to_s +end + +macro xml_to_i(node, name) +({{node}}.children.find{|n| n.name == "{{name}}".lstrip("_")}.try &.content.to_s.to_i) end macro xml_to_a(node, name)