class CTioga2::Commands::Parsers::OldFileParser
This class is in charge of parsing a “old style” command file.
Constants
- SYMBOL_CHAR_REGEX
Public Class Methods
run_command_file(file, interpreter)
click to toggle source
Runs a command file targeting the given interpreter.
# File lib/ctioga2/commands/parsers/old-file.rb, line 44 def self.run_command_file(file, interpreter) OldFileParser.new.run_command_file(file, interpreter) end
run_commands(strings, interpreter)
click to toggle source
Runs the given command strings
# File lib/ctioga2/commands/parsers/old-file.rb, line 49 def self.run_commands(strings, interpreter) OldFileParser.new.run_commands(strings, interpreter) end
Public Instance Methods
parse_io_object(io, interpreter)
click to toggle source
Parses a given io object, sending commands/variable definitions to the given interpreter.
# File lib/ctioga2/commands/parsers/old-file.rb, line 67 def parse_io_object(io, interpreter) # The process is simple: we look for symbols and # corresponding syntax element: parentheses or assignments ## @todo It would be really great if assignments could be ## made conditional (a bit like in makefiles) while(1) symbol = up_to_next_symbol(io) break if not symbol while(1) c = io.getc if ! c # EOF raise ParserSyntaxError, "Expecting something after symbol #{symbol}" end ch = c.chr if ch =~ /\s/ # blank... next elsif ch == '(' # beginning of a function call # Parse string: str = InterpreterString.parse_until_unquoted(io,")") # Now, we need to split str. args = str.expand_and_split(/\s*,\s*/, interpreter) cmd = interpreter.get_command(symbol) real_args = args.slice!(0, cmd.argument_number) # And now the options: options = {} # Problem: the space on the right of the = sign is # *significant*. for o in args if o =~ /^\s*\/?([\w-]+)\s*=(.*)/ if cmd.has_option? $1 options[$1] = $2 else error { "Command #{cmd.name} does not take option #{$1}" } end end end interpreter.context.parsing_file(symbol, io) # Missing line number interpreter.run_command(cmd, real_args, options) io.getc # Slurp up the ) break elsif ch == ':' # Assignment c = io.getc if ! c # EOF raise ParserSyntaxError, "Expecting = after :" end ch = c.chr if ch != '=' raise ParserSyntaxError, "Expecting = after :" end str = InterpreterString.parse_until_unquoted(io,"\n", false) interpreter.variables.define_variable(symbol, str, interpreter) break elsif ch == '=' str = InterpreterString.parse_until_unquoted(io,"\n", false) interpreter.variables.define_variable(symbol, str, nil) break else raise UnexpectedCharacter, "Did not expect #{ch} after #{symbol}" end end end end
run_command_file(file, interpreter)
click to toggle source
Runs a command file targeting the given interpreter.
# File lib/ctioga2/commands/parsers/old-file.rb, line 54 def run_command_file(file, interpreter) f = Utils::open(file) parse_io_object(f, interpreter) end
run_commands(strings, interpreter)
click to toggle source
Runs the given command strings
# File lib/ctioga2/commands/parsers/old-file.rb, line 60 def run_commands(strings, interpreter) io = StringIO.new(strings) parse_io_object(io, interpreter) end
Protected Instance Methods
up_to_next_symbol(io)
click to toggle source
Parses the io stream up to and including the next symbol. Only white space or comments may be found on the way. This function returns the symbol.
Symbols are composed of the alphabet SYMBOL_CHAR_REGEX
.
# File lib/ctioga2/commands/parsers/old-file.rb, line 147 def up_to_next_symbol(io) symbol = nil # As long as no symbol as been started # it will stay nil. while(1) c = io.getc if ! c # EOF if symbol raise UnterminatedSymbol, "EOF reached during symbol parsing" else # File is finished and we didn't meet any symbol. # Nothing to do ! return nil end end ch = c.chr if symbol # We have started if ch =~ SYMBOL_CHAR_REGEX symbol += ch else io.ungetc(c) return symbol end else if ch =~ SYMBOL_CHAR_REGEX symbol = ch elsif ch =~ /\s/ # Nothing elsif ch == '#' io.gets else raise UnexpectedCharacter, "Unexpected character: #{ch}, when looking for a symbol" end end end end