Class: Elparser::Parser

Inherits:
Racc::Parser
  • Object
show all
Defined in:
lib/elparser.rb,
lib/elparser/parser.tab.rb

Overview

parser class for

Constant Summary collapse

UNESCAPES =
{
  'a' => "\x07", 'b' => "\x08", 't' => "\x09",
  'n' => "\x0a", 'v' => "\x0b", 'f' => "\x0c",
  'r' => "\x0d", 'e' => "\x1b", "\\\\" => "\x5c",
  "\"" => "\x22", "'" => "\x27"
}
UNESCAPES_REGEX =
/\\(?:([#{UNESCAPES.keys.join}])|u([\da-fA-F]{4})|u\{([\da-fA-F]{1,6})\})|\\0?x([\da-fA-F]{2})/
Racc_arg =
[
racc_action_table,
racc_action_check,
racc_action_default,
racc_action_pointer,
racc_goto_table,
racc_goto_check,
racc_goto_default,
racc_goto_pointer,
racc_nt_base,
racc_reduce_table,
racc_token_table,
racc_shift_n,
racc_reduce_n,
racc_use_result_var ]
Racc_token_to_s_table =
[
"$end",
"error",
"\"(\"",
"\")\"",
"INTEGER",
"FLOAT",
"\".\"",
"\"'\"",
"SYMBOL",
"STRING",
"$start",
"target",
"sexp_seq",
"sexp",
"nil",
"val",
"cons",
"symbol",
"string",
"list",
"quoted" ]
Racc_debug_parser =
false

Instance Method Summary collapse

Instance Method Details

#_reduce_none(val, _values, result) ⇒ Object



236
237
238
# File 'lib/elparser/parser.tab.rb', line 236

def _reduce_none(val, _values, result)
  val[0]
end

#_unescape_string(str) ⇒ Object



278
279
280
281
282
283
284
285
286
287
288
289
290
# File 'lib/elparser.rb', line 278

def _unescape_string(str)
  return str.gsub(UNESCAPES_REGEX) do
    if $1
      if $1 == '\\' then '\\' else UNESCAPES[$1] end
    elsif $2 # escape \u0000 unicode
      ["#$2".hex].pack('U*')
    elsif $3 # escape \u{0000} unicode
      ["#$3".hex].pack('U*')
    elsif $4 # escape \0xff or \xff
      [$4].pack('H2')
    end
  end
end

#next_tokenObject



292
293
294
# File 'lib/elparser.rb', line 292

def next_token
  @tokens.shift
end

#normalize(ast) ⇒ Object

replace special symbols



297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
# File 'lib/elparser.rb', line 297

def normalize(ast)
  if ast.class == SExpSymbol
    case ast.name
    when "nil"
      return SExpNil.new
    else
      return ast
    end
  elsif ast.cons? then
    ast.visit do |i|
      normalize(i)
    end
  end
  return ast
end

#parse(str) ⇒ Object

parse s-expression string and return sexp objects.



245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# File 'lib/elparser.rb', line 245

def parse(str)
  if str.nil? || str == ""
    raise ParserError.new("Empty input",0,"")
  end

  s = StringScanner.new str
  @tokens = []

  until s.eos?
    s.skip(/\s+/) ? nil :
      s.scan(/\A[-+]?[0-9]*\.[0-9]+(e[-+]?[0-9]+)?/i) ? (@tokens << [:FLOAT, s.matched]) :
      s.scan(/\A[-+]?(0|[1-9]\d*)/)      ? (@tokens << [:INTEGER, s.matched]) :
      s.scan(/\A\.(?=\s)/)               ? (@tokens << ['.', '.']) :
      s.scan(/\A[a-z\-.\/_:*<>+=$#][a-z\-.\/_:$*<>+=0-9]*/i) ? (@tokens << [:SYMBOL, s.matched]) :
      s.scan(/\A"(([^\\"]|\\.)*)"/)        ? (@tokens << [:STRING, _unescape_string(s.matched.slice(1...-1))])  :
      s.scan(/\A./)                      ? (a = s.matched; @tokens << [a, a]) :
      (raise ParserError.new("Scanner error",s.pos,s.peek(5)))
  end
  @tokens.push [false, 'END']

  return do_parse.map do |i|
    normalize(i)
  end
end

#parse1(str) ⇒ Object

parse s-expression string and return one sexp object.



240
241
242
# File 'lib/elparser.rb', line 240

def parse1(str)
  parse(str)[0]
end