From 937b9d50e05013d5f42c8fad198216cca3c90085 Mon Sep 17 00:00:00 2001 From: Roberto Alsina Date: Sat, 3 Aug 2024 19:25:09 -0300 Subject: [PATCH] Implement 'combined' emitter --- shard.yml | 6 +++++- src/tartrazine.cr | 21 ++++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/shard.yml b/shard.yml index ff1c52f..8e3d63b 100644 --- a/shard.yml +++ b/shard.yml @@ -8,6 +8,10 @@ targets: tartrazine: main: src/tartrazine.cr -crystal: '>= 1.13.0' +dependencies: + base58: + github: crystal-china/base58.cr + +crystal: ">= 1.13.0" license: MIT diff --git a/src/tartrazine.cr b/src/tartrazine.cr index 5ab61b2..03c2f00 100644 --- a/src/tartrazine.cr +++ b/src/tartrazine.cr @@ -1,5 +1,6 @@ -require "xml" +require "base58" require "json" +require "xml" module Tartrazine VERSION = "0.1.0" @@ -13,6 +14,13 @@ module Tartrazine class State property name : String = "" property rules = [] of Rule + + def +(other : State) + new_state = State.new + new_state.name = Random.base58(8) + new_state.rules = rules + other.rules + new_state + end end class Rule @@ -131,6 +139,13 @@ module Tartrazine return [] of Token if match.nil? lexer_name = xml["lexer"].downcase LEXERS[lexer_name].tokenize(match[0]) + when "combined" + # Combine two states into one anonymous state + states = xml.attributes.select { |a| a.name == "state" }.map &.content + new_state = states.map {|name| lexer.states[name]}.reduce { |s1, s2| s1 + s2 } + lexer.states[new_state.name] = new_state + lexer.state_stack << new_state.name + [] of Token else raise Exception.new("Unknown emitter type: #{type}: #{xml}") end @@ -316,7 +331,7 @@ def test_file(testname, lexer) rescue ex : Exception puts ">>>ERROR" p! ex - return + exit 1 end outp = IO::Memory.new i = IO::Memory.new(test) @@ -350,4 +365,4 @@ Dir.glob("tests/*/") do |lexername| test_file(testname, lexer) end end -puts ">>>TOTAL #{total}" \ No newline at end of file +puts ">>>TOTAL #{total}"