Compare commits
2 commits
da2bd5241c
...
67632c6fb4
Author | SHA1 | Date | |
---|---|---|---|
|
67632c6fb4 | ||
|
9e91f407c2 |
3 changed files with 115 additions and 28 deletions
62
lib/parser.rb
Normal file
62
lib/parser.rb
Normal file
|
@ -0,0 +1,62 @@
|
|||
# coding: utf-8
|
||||
|
||||
class String
|
||||
def numeric?
|
||||
Float(self) != nil rescue false
|
||||
end
|
||||
end
|
||||
|
||||
def parse_input( input )
|
||||
splitted_input = input.split(' ')
|
||||
parsed_tree = []
|
||||
|
||||
regrouping = false
|
||||
splitted_input.each do |elt|
|
||||
next if elt.length == 1 && elt[0] == '»'
|
||||
|
||||
parsed_entry = { 'value' => elt }
|
||||
|
||||
if regrouping
|
||||
parsed_entry = parsed_tree.pop
|
||||
|
||||
parsed_entry['value'] = "#{parsed_entry['value']} #{elt}".strip
|
||||
else
|
||||
parsed_entry['type'] = case elt[0]
|
||||
when '«'
|
||||
'PROGRAM'
|
||||
when '"'
|
||||
'STRING'
|
||||
when '\''
|
||||
'NAME'
|
||||
else
|
||||
if elt.numeric?
|
||||
'NUMBER'
|
||||
else
|
||||
'WORD' # TODO: if word isn't known then it's a NAME
|
||||
end
|
||||
end
|
||||
|
||||
parsed_entry['value'] = elt[1..] if %W[PROGRAM STRING NAME].include?( parsed_entry['type'] )
|
||||
end
|
||||
|
||||
regrouping = ( (parsed_entry['type'] == 'NAME' && elt[-1] != '\'') ||
|
||||
(parsed_entry['type'] == 'STRING' && elt[-1] != '"') ||
|
||||
(parsed_entry['type'] == 'PROGRAM' && elt[-1] != '»') )
|
||||
|
||||
parsed_entry['value'] = if ( (parsed_entry['type'] == 'NAME' && elt[-1] == '\'') ||
|
||||
(parsed_entry['type'] == 'STRING' && elt[-1] == '"') ||
|
||||
(parsed_entry['type'] == 'PROGRAM' && elt[-1] == '»') )
|
||||
(parsed_entry['value'][..-2]).strip
|
||||
elsif parsed_entry['type'] == 'NUMBER'
|
||||
parsed_entry['value'].to_f
|
||||
elsif parsed_entry['type'] == 'WORD'
|
||||
parsed_entry['value']
|
||||
else
|
||||
parsed_entry['value']
|
||||
end
|
||||
|
||||
parsed_tree << parsed_entry
|
||||
end
|
||||
|
||||
parsed_tree
|
||||
end
|
31
repl.rb
31
repl.rb
|
@ -3,6 +3,8 @@
|
|||
|
||||
require 'readline'
|
||||
|
||||
require_relative "./lib/parser"
|
||||
|
||||
def run_REPL( stack )
|
||||
Readline.completion_proc = proc do |s|
|
||||
directory_list = Dir.glob("#{s}*")
|
||||
|
@ -27,33 +29,6 @@ def run_REPL( stack )
|
|||
end
|
||||
end
|
||||
|
||||
def parse_input( input )
|
||||
splitted_input = input.split( " " )
|
||||
parsed_input = []
|
||||
|
||||
regrouping = false
|
||||
splitted_input.each do |elt|
|
||||
if regrouping
|
||||
partial_elt = parsed_input.pop
|
||||
elt = "#{partial_elt} #{elt}"
|
||||
end
|
||||
|
||||
if regrouping
|
||||
regrouping = false if (elt[0] == '\'' and elt[-1] == '\'') or (elt[0] == '"' and elt[-1] == '"') or (elt[0] == '«' and elt[-1] == '»')
|
||||
else
|
||||
regrouping = true if elt[0] == '\'' or elt[0] == '"' or elt[0] == '«'
|
||||
end
|
||||
|
||||
# 'xx' is a name (no space allowed)
|
||||
# "xx x x xx" is a string
|
||||
# « xx xx xx » is a program (must have inner spaces)
|
||||
|
||||
parsed_input << elt
|
||||
end
|
||||
|
||||
parsed_input
|
||||
end
|
||||
|
||||
def process_input( stack, input )
|
||||
parse_input( input ).each do |elt|
|
||||
stack << elt
|
||||
|
@ -64,7 +39,7 @@ end
|
|||
|
||||
def display_stack( stack )
|
||||
stack_size = stack.size
|
||||
stack.each_with_index { |v, i| puts "#{stack_size - i}: #{v}"}
|
||||
stack.each_with_index { |elt, i| puts "#{stack_size - i}: #{elt['value']}"}
|
||||
|
||||
stack
|
||||
end
|
||||
|
|
50
spec/parser_spec.rb
Normal file
50
spec/parser_spec.rb
Normal file
|
@ -0,0 +1,50 @@
|
|||
# coding: utf-8
|
||||
require_relative "../lib/parser"
|
||||
|
||||
require 'test/unit'
|
||||
|
||||
class TestParser < Test::Unit::TestCase
|
||||
def test_parse_input_number
|
||||
result = parse_input( "1" )
|
||||
assert_equal [ { 'value' => 1, 'type' => 'NUMBER' } ], result
|
||||
end
|
||||
|
||||
def test_parse_input_word
|
||||
result = parse_input( "dup" )
|
||||
assert_equal [ { 'value' => "dup", 'type' => 'WORD' } ], result
|
||||
end
|
||||
|
||||
def test_parse_input_string
|
||||
result = parse_input( "\"test\"" )
|
||||
assert_equal [ { 'value' => "test", 'type' => 'STRING' } ], result
|
||||
end
|
||||
|
||||
def test_parse_input_name
|
||||
result = parse_input( "'test'" )
|
||||
assert_equal [ { 'value' => "test", 'type' => 'NAME' } ], result
|
||||
end
|
||||
|
||||
def test_parse_input_program
|
||||
result = parse_input( "« test »" )
|
||||
assert_equal [ { 'value' => "test", 'type' => 'PROGRAM' } ], result
|
||||
|
||||
result = parse_input( "«test »" )
|
||||
assert_equal [ { 'value' => "test", 'type' => 'PROGRAM' } ], result
|
||||
|
||||
result = parse_input( "« test test »" )
|
||||
assert_equal [ { 'value' => "test test", 'type' => 'PROGRAM' } ], result
|
||||
|
||||
result = parse_input( "« test \"test\" test »" )
|
||||
assert_equal [ { 'value' => "test \"test\" test", 'type' => 'PROGRAM' } ], result
|
||||
end
|
||||
|
||||
def test_parse_input_number_number
|
||||
result = parse_input( "2 3" )
|
||||
assert_equal [ { 'value' => 2, 'type' => 'NUMBER' }, { 'value' => 3, 'type' => 'NUMBER' } ], result
|
||||
end
|
||||
|
||||
def test_parse_input_number_string
|
||||
result = parse_input( "4 \"test\"" )
|
||||
assert_equal [ { 'value' => 4, 'type' => 'NUMBER' }, { 'value' => "test", 'type' => 'STRING' } ], result
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue