Class: CTioga2::Commands::Parsers::FileParser
- Inherits:
-
Object
- Object
- CTioga2::Commands::Parsers::FileParser
- Includes:
- Log
- Defined in:
- lib/ctioga2/commands/parsers/file.rb
Overview
This class parses a “new style” command file, delegating to the old parser if this looks like an old style command file.
Class Method Summary collapse
-
.run_command_file(file, interpreter) ⇒ Object
Runs a command file targeting the given interpreter.
-
.run_commands(strings, interpreter) ⇒ Object
Runs the given command strings.
Instance Method Summary collapse
-
#parse_io_object(io, interpreter) ⇒ Object
Parses a given io object, sending commands/variable definitions to the given interpreter.
-
#run_command_file(file, interpreter) ⇒ Object
Runs a command file targeting the given interpreter.
-
#run_commands(strings, interpreter) ⇒ Object
Runs the given command strings.
Methods included from Log
context, counts, debug, error, fatal, #format_exception, #identify, info, init_logger, log_to, logger, set_level, #spawn, warn
Class Method Details
.run_command_file(file, interpreter) ⇒ Object
Runs a command file targeting the given interpreter.
36 37 38 |
# File 'lib/ctioga2/commands/parsers/file.rb', line 36 def self.run_command_file(file, interpreter) FileParser.new.run_command_file(file, interpreter) end |
.run_commands(strings, interpreter) ⇒ Object
Runs the given command strings
41 42 43 |
# File 'lib/ctioga2/commands/parsers/file.rb', line 41 def self.run_commands(strings, interpreter) FileParser.new.run_commands(strings, interpreter) end |
Instance Method Details
#parse_io_object(io, interpreter) ⇒ Object
Parses a given io object, sending commands/variable definitions to the given interpreter.
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/ctioga2/commands/parsers/file.rb', line 59 def parse_io_object(io, interpreter) # We first split everything into lines lines = io.readlines # First, we look for old-style commands to see if we # delegate to the other parser. In any case, we build up a # list of "unsplit" lines (ie gather lines that end with \) parsed_lines = [] cur = nil lines_indices = [] idx = 0 has_ruby = false ## @todo line counting ? for l in lines idx += 1 # If we find something that looks like an old command at the # beginning of a line, we say this is an old style file. ## @todo Find a way to disable this compatibility stuff -- ## or make it more accurate ? The problem is that in a ## large command file, there may be things that look like ## old style commands ? if l =~ /^\s*ruby\s*$/ has_ruby = true elsif l =~ /^([a-z0-9-]+)\(/ && (!has_ruby) path = io.respond_to?(:path) ? io.path : io.to_s warn { "Found old style (deprecated) commands in '#{path}', using old style parser"} return OldFileParser.new. run_commands(lines.join(""), interpreter) end if cur cur << l else cur = l end if cur =~ /\\$/ cur.gsub!(/\\$/,'') cur.chomp! else # Strip all white space at the end of unfinished lines. parsed_lines << cur.gsub(/\s+$/,"\n") lines_indices << idx cur = nil end end # Flush any pending unfinished line parsed_lines << cur if cur lines_indices << idx if cur # Now, we rearrange the lines... idx = -1 ruby = false # False, or a [var, values, code] triplet loop = false for l in parsed_lines idx += 1 interpreter.context.parsing_file(nil, io, lines_indices[idx]) if l =~ /^\s*ruby\s*$/ ruby = "" elsif ruby if l =~ /^\s*ruby\s+end\s*$/ begin Ruby.run_code(ruby) ruby = false rescue Exception => e fatal { "Error #{e.inspect} running inline Ruby code at #{interpreter.context}" } end else ruby << l end elsif l =~ /^\s*for\s+(\w+)\s+in\s+(.*)/ v = $2 var = $1 v << "\n" s = InterpreterString.parse_until_unquoted(StringIO.new(v),"\n") vals = s.(/\s+/, interpreter) loop = [var, vals, ""] elsif loop if l =~ /^\s*for\s+end\s*$/ for v in loop[1] interpreter.variables.define_variable(loop[0], v) run_commands(loop[2], interpreter) end loop = false else loop[2] << l end elsif l =~ /^\s*([a-zA-Z0-9_-]+)\s*(\??)(=|:=)\s*(.*)/ symbol = $1 value = InterpreterString.parse_until_unquoted(StringIO.new($4),"\n", false) override = !($2 == '?') rec = (($3 == "=") ? nil : interpreter) interpreter.variables.define_variable(symbol, value, rec, override) elsif l =~ /^\s*#/ # comment... else l += "\n" str = InterpreterString.parse_until_unquoted(StringIO.new(l),"\n") words = str.(/\s+/, interpreter) # Take care of strings starting with spaces... if words.size == 0 next end symbol = words[0] all_args = words[1..-1] cmd = interpreter.get_command(symbol) args, opts = parse_args_and_opts(cmd, all_args) interpreter.context.parsing_file(symbol, io, lines_indices[idx]) # Missing line number interpreter.run_command(cmd, args, opts) end end end |
#run_command_file(file, interpreter) ⇒ Object
Runs a command file targeting the given interpreter.
46 47 48 49 |
# File 'lib/ctioga2/commands/parsers/file.rb', line 46 def run_command_file(file, interpreter) f = Utils::open(file) parse_io_object(f, interpreter) end |
#run_commands(strings, interpreter) ⇒ Object
Runs the given command strings
52 53 54 55 |
# File 'lib/ctioga2/commands/parsers/file.rb', line 52 def run_commands(strings, interpreter) io = StringIO.new(strings) parse_io_object(io, interpreter) end |