Object
Dynamic Generation Interface
# File racc/grammar.rb, line 201 def Grammar.define(&block) env = DefinitionEnv.new env.instance_eval(&block) env.grammar end
# File racc/grammar.rb, line 24 def initialize(debug_flags = DebugFlags.new) @symboltable = SymbolTable.new @debug_symbol = debug_flags.token @rules = [] # :: [Rule] @start = nil @n_expected_srconflicts = nil @prec_table = [] @prec_table_closed = false @closed = false @states = nil end
Grammar
Definition Interface
# File racc/grammar.rb, line 166 def add(rule) raise ArgumentError, "rule added after the Grammar closed" if @closed @rules.push rule end
# File racc/grammar.rb, line 171 def added?(sym) @rules.detect {|r| r.target == sym } end
# File racc/grammar.rb, line 180 def declare_precedence(assoc, syms) raise CompileError, "precedence table defined twice" if @prec_table_closed @prec_table.push [assoc, syms] end
# File racc/grammar.rb, line 120 def dfa (@states ||= States.new(self)).dfa end
# File racc/grammar.rb, line 50 def each_index(&block) @rules.each_index(&block) end
# File racc/grammar.rb, line 44 def each_rule(&block) @rules.each(&block) end
# File racc/grammar.rb, line 92 def each_useless_nonterminal return to_enum __method__ unless block_given? @symboltable.each_nonterminal do |sym| yield sym if sym.useless? end end
# File racc/grammar.rb, line 108 def each_useless_rule return to_enum __method__ unless block_given? each do |r| yield r if r.useless? end end
# File racc/grammar.rb, line 54 def each_with_index(&block) @rules.each_with_index(&block) end
# File racc/grammar.rb, line 185 def end_precedence_declaration(reverse) @prec_table_closed = true return if @prec_table.empty? table = reverse ? @prec_table.reverse : @prec_table table.each_with_index do |(assoc, syms), idx| syms.each do |sym| sym.assoc = assoc sym.precedence = idx end end end
Computation
# File racc/grammar.rb, line 409 def init return if @closed @closed = true @start ||= @rules.map {|r| r.target }.detect {|sym| not sym.dummy? } raise CompileError, 'no rule in input' if @rules.empty? add_start_rule @rules.freeze fix_ident compute_hash compute_heads determine_terminals compute_nullable_0 @symboltable.fix compute_locate @symboltable.each_nonterminal {|t| compute_expand t } compute_nullable compute_useless end
# File racc/grammar.rb, line 72 def intern(value, dummy = false) @symboltable.intern(value, dummy) end
# File racc/grammar.rb, line 88 def n_useless_nonterminals @n_useless_nonterminals ||= each_useless_nonterminal.count end
# File racc/grammar.rb, line 104 def n_useless_rules @n_useless_rules ||= each_useless_rule.count end
# File racc/grammar.rb, line 116 def nfa (@states ||= States.new(self)).nfa end
# File racc/grammar.rb, line 80 def nonterminal_base @symboltable.nt_base end
# File racc/grammar.rb, line 130 def parser_class states = states() # cache if $DEBUG srcfilename = caller(1).first.slice(/\A(.*?):/, 1) begin write_log srcfilename + ".output" rescue SystemCallError end report = lambda {|s| $stderr.puts "racc: #{srcfilename}: #{s}" } if states.should_report_srconflict? report["#{states.n_srconflicts} shift/reduce conflicts"] end if states.rrconflict_exist? report["#{states.n_rrconflicts} reduce/reduce conflicts"] end g = states.grammar if g.useless_nonterminal_exist? report["#{g.n_useless_nonterminals} useless nonterminals"] end if g.useless_rule_exist? report["#{g.n_useless_rules} useless rules"] end end states.state_transition_table.parser_class end
# File racc/grammar.rb, line 175 def start_symbol=(s) raise CompileError, "start symbol set twice'" if @start @start = s end
# File racc/grammar.rb, line 126 def state_transition_table states().state_transition_table end
# File racc/grammar.rb, line 76 def symbols @symboltable.symbols end
# File racc/grammar.rb, line 84 def useless_nonterminal_exist? n_useless_nonterminals() != 0 end