Class: Racc::GrammarFileParser
Relationships & Source Files | |
Namespace Children | |
Classes:
| |
Inherits: | Object |
Defined in: | lib/racc/grammarfileparser.rb |
Overview
reopen
Constant Summary
-
USER_CODE_LABELS =
# File 'lib/racc/grammarfileparser.rb', line 378{ 'header' => :header, 'prepare' => :header, # obsolete 'inner' => :inner, 'footer' => :, 'driver' => : # obsolete }
Class Method Summary
Instance Method Summary
- #parse(src, filename = '-', lineno = 1)
- #_add_group_rule(enum) private
- #_add_many1_rule(prev) private
- #_add_many_rule(prev) private
- #_add_option_rule(prev) private
- #_add_rule_block(target, enum) private
- #_gen_target_name(type, sym) private
- #add_rule(target, list, sprec) private
- #add_rule_block(list) private
- #add_user_code(label, src) private
- #canonical_label(src) private
- #embedded_action(act) private
- #location private
- #next_token private
- #on_error(tok, val, _values) private
-
#parse_user_code
private
User Code Block.
Constructor Details
.new(debug_flags = DebugFlags.new) ⇒ GrammarFileParser
# File 'lib/racc/grammarfileparser.rb', line 191
def initialize(debug_flags = DebugFlags.new) @yydebug = debug_flags.parse end
Class Method Details
.parse(src, filename = '-', lineno = 1)
[ GitHub ]# File 'lib/racc/grammarfileparser.rb', line 187
def GrammarFileParser.parse(src, filename = '-', lineno = 1) new().parse(src, filename, lineno) end
.parse_file(filename)
[ GitHub ]# File 'lib/racc/grammarfileparser.rb', line 183
def GrammarFileParser.parse_file(filename) parse(File.read(filename), filename, 1) end
Instance Method Details
#_add_group_rule(enum) (private)
[ GitHub ]# File 'lib/racc/grammarfileparser.rb', line 318
def _add_group_rule(enum) target = @grammar.intern("-temp-group", true) rules, _ = _add_rule_block(target, enum) target_name = rules.map{|syms, sprec| syms.join("-")}.join("|") @group_rule_registry ||= {} unless target = @group_rule_registry[target_name] target = @grammar.intern("-group@#{target_name}", true) @group_rule_registry[target_name] = target src = SourceText.new("result = val", @filename, @scanner.lineno + 1) act = UserAction.source_text(src) rules.each do |syms, sprec| rule = Rule.new(target, syms, act) rule.specified_prec = sprec @grammar.add rule end end target end
#_add_many1_rule(prev) (private)
[ GitHub ]# File 'lib/racc/grammarfileparser.rb', line 305
def _add_many1_rule(prev) @many1_rule_registry ||= {} target = @many1_rule_registry[prev.to_s] return target if target target = _gen_target_name("many1", prev) @many1_rule_registry[prev.to_s] = target src = SourceText.new("result = val[1] ? val[1].unshift(val[0]) : val", @filename, @scanner.lineno + 1) act = UserAction.source_text(src) @grammar.add Rule.new(target, [prev], act) @grammar.add Rule.new(target, [prev, target], act) target end
#_add_many_rule(prev) (private)
[ GitHub ]# File 'lib/racc/grammarfileparser.rb', line 292
def _add_many_rule(prev) @many_rule_registry ||= {} target = @many_rule_registry[prev.to_s] return target if target target = _gen_target_name("many", prev) @many_rule_registry[prev.to_s] = target src = SourceText.new("result = val[1] ? val[1].unshift(val[0]) : val", @filename, @scanner.lineno + 1) act = UserAction.source_text(src) @grammar.add Rule.new(target, [], act) @grammar.add Rule.new(target, [prev, target], act) target end
#_add_option_rule(prev) (private)
[ GitHub ]# File 'lib/racc/grammarfileparser.rb', line 280
def _add_option_rule(prev) @option_rule_registry ||= {} target = @option_rule_registry[prev.to_s] return target if target target = _gen_target_name("option", prev) @option_rule_registry[prev.to_s] = target act = UserAction.empty @grammar.add Rule.new(target, [], act) @grammar.add Rule.new(target, [prev], act) target end
#_add_rule_block(target, enum) (private)
[ GitHub ]# File 'lib/racc/grammarfileparser.rb', line 244
def _add_rule_block(target, enum) rules = [] # [ [seqs, sprec], .. ] curr = [] sprec = nil while (sym, idx = enum.next rescue nil) case sym when OrMark rules << [curr, sprec] curr = [] sprec = nil when OptionMark curr << _add_option_rule(curr.pop) when ManyMark curr << _add_many_rule(curr.pop) when Many1Mark curr << _add_many1_rule(curr.pop) when GroupStartMark curr << _add_group_rule(enum) when GroupEndMark rules << [curr, sprec] return rules, sym, idx when Prec raise CompileError, "'=<prec>' used twice in one rule" if sprec sprec = sym.symbol else curr.push sym end end rules << [curr, sprec] rules.each do |syms, sprec| add_rule target, syms, sprec end nil end
#_gen_target_name(type, sym) (private)
[ GitHub ]# File 'lib/racc/grammarfileparser.rb', line 337
def _gen_target_name(type, sym) @grammar.intern("-#{type}@#{sym.value}", true) end
#add_rule(target, list, sprec) (private)
[ GitHub ]# File 'lib/racc/grammarfileparser.rb', line 341
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) ? (s) : s } rule = Rule.new(target, list, act) rule.specified_prec = sprec @grammar.add rule end
#add_rule_block(list) (private)
[ GitHub ]# File 'lib/racc/grammarfileparser.rb', line 230
def add_rule_block(list) target = list.shift case target when OrMark, OptionMark, ManyMark, Many1Mark, GroupStartMark, GroupEndMark, UserAction, Prec raise CompileError, "#{target.lineno}: unexpected symbol #{target.name}" end enum = list.each.with_index _, sym, idx = _add_rule_block(target, enum) if idx # sym is Racc::GroupEndMark raise "#{sym.lineno}: unexpected symbol ')' at pos=#{idx}" end end
#add_user_code(label, src) (private)
[ GitHub ]# File 'lib/racc/grammarfileparser.rb', line 394
def add_user_code(label, src) @result.params.public_send(USER_CODE_LABELS[label]).push src end
#canonical_label(src) (private)
[ GitHub ]# File 'lib/racc/grammarfileparser.rb', line 386
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) (private)
[ GitHub ]#location (private)
[ GitHub ]# File 'lib/racc/grammarfileparser.rb', line 226
def location "#{@filename}:#{@lineno - 1 + @scanner.lineno}" end
#next_token (private)
[ GitHub ]# File 'lib/racc/grammarfileparser.rb', line 211
def next_token @scanner.scan end
#on_error(tok, val, _values) (private)
# File 'lib/racc/grammarfileparser.rb', line 215
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(src, filename = '-', lineno = 1)
[ GitHub ]# File 'lib/racc/grammarfileparser.rb', line 195
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
#parse_user_code (private)
User Code Block
# File 'lib/racc/grammarfileparser.rb', line 363
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