split out parser

This commit is contained in:
Gwenhael Le Moine 2021-10-30 23:36:49 +02:00
parent da2bd5241c
commit 9e91f407c2
No known key found for this signature in database
GPG key ID: FDFE3669426707A7
2 changed files with 65 additions and 28 deletions

62
lib/parser.rb Normal file
View 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
View file

@ -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