parser understands lists

This commit is contained in:
Gwenhael Le Moine 2022-02-17 15:14:20 +01:00
parent 7fce85d694
commit f4fa29da5c
No known key found for this signature in database
GPG key ID: FDFE3669426707A7
2 changed files with 50 additions and 6 deletions

View file

@ -47,6 +47,8 @@ class Interpreter
# 1. regroup strings and programs
opened_programs = 0
closed_programs = 0
opened_lists = 0
closed_lists = 0
string_delimiters = 0
name_delimiters = 0
regrouping = false
@ -56,22 +58,33 @@ class Interpreter
if elt[0] == '«'
opened_programs += 1
elt.gsub!( '«', '« ') if elt.length > 1 && elt[1] != ' '
elsif elt[0] == '{'
opened_lists += 1
elt.gsub!( '{', '{ ') if elt.length > 1 && elt[1] != ' '
elsif elt[0] == '"' && elt.length > 1
string_delimiters += 1
elsif elt[0] == "'" && elt.length > 1
name_delimiters += 1
end
string_delimiters += 1 if elt[0] == '"' && elt.length > 1
name_delimiters += 1 if elt[0] == "'" && elt.length > 1
elt = "#{regrouped_input.pop} #{elt}".strip if regrouping
regrouped_input << elt
if elt[-1] == '»'
case elt[-1]
when '»'
closed_programs += 1
elt.gsub!( '»', ' »') if elt.length > 1 && elt[-2] != ' '
when '}'
closed_lists += 1
elt.gsub!( '}', ' }') if elt.length > 1 && elt[-2] != ' '
when '"'
string_delimiters += 1
when "'"
name_delimiters += 1
end
string_delimiters += 1 if elt[-1] == '"'
name_delimiters += 1 if elt[-1] == "'"
regrouping = string_delimiters.odd? || name_delimiters.odd? || (opened_programs > closed_programs )
regrouping = string_delimiters.odd? || name_delimiters.odd? || (opened_programs > closed_programs ) || (opened_lists > closed_lists )
end
# 2. parse
@ -83,6 +96,8 @@ class Interpreter
parsed_entry[:type] = case elt[0]
when '«'
:program
when '{'
:list
when '"'
:string
when "'"
@ -99,6 +114,8 @@ class Interpreter
parsed_entry[:value] = parsed_entry[:value][1..-2]
elsif parsed_entry[:type] == :program
parsed_entry[:value] = parsed_entry[:value][2..-3]
elsif parsed_entry[:type] == :list
parsed_entry[:value] = parse( parsed_entry[:value][2..-3] )
elsif parsed_entry[:type] == :numeric
parsed_entry[:base] = 10 # TODO: parse others possible bases 0x...

View file

@ -61,6 +61,33 @@ class TestParser < MiniTest::Test
assert_equal [{ value: 'test "test" test', type: :program }], result
end
def test_list
result = Rpl.new.parse( '{ test }' )
assert_equal [{ value: [{ value: 'test', type: :word }], type: :list }], result
result = Rpl.new.parse( '{test }' )
assert_equal [{ value: [{ value: 'test', type: :word }], type: :list }], result
result = Rpl.new.parse( '{ test}' )
assert_equal [{ value: [{ value: 'test', type: :word }], type: :list }], result
result = Rpl.new.parse( '{test}' )
assert_equal [{ value: [{ value: 'test', type: :word }], type: :list }], result
result = Rpl.new.parse( '{ test test }' )
assert_equal [{ value: [{ value: 'test', type: :word },
{ value: 'test', type: :word }], type: :list }], result
result = Rpl.new.parse( '{ test { test } }' )
assert_equal [{ value: [{ value: 'test', type: :word },
{ value: [{ value: 'test', type: :word }], type: :list }], type: :list }], result
result = Rpl.new.parse( '{ test "test" test }' )
assert_equal [{ value: [{ value: 'test', type: :word },
{ value: 'test', type: :string },
{ value: 'test', type: :word }], type: :list }], result
end
def test_number_number
result = Rpl.new.parse( '2 3' )
assert_equal [{ value: 2, type: :numeric, base: 10 }, { value: 3, type: :numeric, base: 10 }], result