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