class Racc::GrammarFileParser

Constants

USER_CODE_LABELS

Public Class Methods

new(debug_flags = DebugFlags.new) click to toggle source
# File lib/racc/grammarfileparser.rb, line 173
def initialize(debug_flags = DebugFlags.new)
  @yydebug = debug_flags.parse
end
parse(src, filename = '-', lineno = 1) click to toggle source
# File lib/racc/grammarfileparser.rb, line 169
def GrammarFileParser.parse(src, filename = '-', lineno = 1)
  new().parse(src, filename, lineno)
end
parse_file(filename) click to toggle source
# File lib/racc/grammarfileparser.rb, line 165
def GrammarFileParser.parse_file(filename)
  parse(File.read(filename), filename, 1)
end

Public Instance Methods

parse(src, filename = '-', lineno = 1) click to toggle source
# File lib/racc/grammarfileparser.rb, line 177
def parse(src, filename = '-', lineno = 1)
  @filename = filename
  @lineno = lineno
  @scanner = GrammarFileScanner.new(src, @filename)
  @scanner.debug = @yydebug
  @grammar = Grammar.new
  @result = Result.new(@grammar)
  @embedded_action_seq = 0
  yyparse @scanner, :yylex
  parse_user_code
  @result.grammar.init
  @result
end

Private Instance Methods

add_rule(target, list, sprec) click to toggle source
# File lib/racc/grammarfileparser.rb, line 236
def add_rule(target, list, sprec)
  if list.last.kind_of?(UserAction)
    act = list.pop
  else
    act = UserAction.empty
  end
  list.map! {|s| s.kind_of?(UserAction) ? embedded_action(s) : s }
  rule = Rule.new(target, list, act)
  rule.specified_prec = sprec
  @grammar.add rule
end
add_rule_block(list) click to toggle source
# File lib/racc/grammarfileparser.rb, line 212
def add_rule_block(list)
  sprec = nil
  target = list.shift
  case target
  when OrMark, UserAction, Prec
    raise CompileError, "#{target.lineno}: unexpected symbol #{target.name}"
  end
  curr = []
  list.each do |i|
    case i
    when OrMark
      add_rule target, curr, sprec
      curr = []
      sprec = nil
    when Prec
      raise CompileError, "'=<prec>' used twice in one rule" if sprec
      sprec = i.symbol
    else
      curr.push i
    end
  end
  add_rule target, curr, sprec
end
add_user_code(label, src) click to toggle source
# File lib/racc/grammarfileparser.rb, line 289
def add_user_code(label, src)
  @result.params.public_send(USER_CODE_LABELS[label]).push src
end
canonical_label(src) click to toggle source
# File lib/racc/grammarfileparser.rb, line 281
def canonical_label(src)
  label = src.to_s.strip.downcase.slice(/\w+/)
  unless USER_CODE_LABELS.key?(label)
    raise CompileError, "unknown user code type: #{label.inspect}"
  end
  label
end
embedded_action(act) click to toggle source
# File lib/racc/grammarfileparser.rb, line 248
def embedded_action(act)
  sym = @grammar.intern("@#{@embedded_action_seq += 1}".intern, true)
  @grammar.add Rule.new(sym, [], act)
  sym
end
location() click to toggle source
# File lib/racc/grammarfileparser.rb, line 208
def location
  "#{@filename}:#{@lineno - 1 + @scanner.lineno}"
end
next_token() click to toggle source
# File lib/racc/grammarfileparser.rb, line 193
def next_token
  @scanner.scan
end
on_error(tok, val, _values) click to toggle source
# File lib/racc/grammarfileparser.rb, line 197
def on_error(tok, val, _values)
  if val.respond_to?(:id2name)
    v = val.id2name
  elsif val.kind_of?(String)
    v = val
  else
    v = val.inspect
  end
  raise CompileError, "#{location()}: unexpected token '#{v}'"
end
parse_user_code() click to toggle source

User Code Block

# File lib/racc/grammarfileparser.rb, line 258
def parse_user_code
  line = @scanner.lineno
  _, *blocks = *@scanner.epilogue.split(/^----/)
  blocks.each do |block|
    header, *body = block.lines.to_a
    label0, paths = *header.sub(/\A-+/, '').split('=', 2)
    label = canonical_label(label0)
    (paths ? paths.strip.split(' ') : []).each do |path|
      add_user_code label, SourceText.new(File.read(path), path, 1)
    end
    add_user_code label, SourceText.new(body.join(''), @filename, line + 1)
    line += (1 + body.size)
  end
end