Class: Racc::Grammar
Relationships & Source Files | |
Namespace Children | |
Classes:
| |
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
self,
Forwardable
|
|
Inherits: | Object |
Defined in: | lib/racc/grammar.rb |
Class Method Summary
-
.define(&block)
Dynamic Generation Interface.
- .new(debug_flags = DebugFlags.new) ⇒ Grammar constructor
Instance Attribute Summary
- #n_expected_srconflicts rw
- #start readonly
- #start_symbol=(s) writeonly
- #symboltable readonly
- #useless_nonterminal_exist? ⇒ Boolean readonly
- #useless_rule_exist? ⇒ Boolean readonly
Instance Method Summary
- #[](x)
-
#add(rule)
Grammar
Definition Interface. - #added?(sym) ⇒ Boolean
- #declare_precedence(assoc, syms)
- #dfa (also: #states)
-
#each(&block)
Alias for #each_rule.
- #each_index(&block)
- #each_rule(&block) (also: #each)
- #each_with_index(&block)
- #end_precedence_declaration(reverse)
-
#init
Computation.
- #intern(value, dummy = false)
- #n_useless_nonterminals
- #n_useless_rules
- #nfa
- #nonterminal_base
- #parser_class
- #size
- #state_transition_table
-
#states
Alias for #dfa.
- #symbols
- #to_s
- #write_log(path)
- #_compute_expand(t, set, lock) private
- #add_start_rule private
- #check_rules_nullable(rules) private
- #check_rules_useless(rules) private
- #check_symbols_nullable(symbols) private
- #check_symbols_useless(s) private
- #compute_expand(t) private
- #compute_hash private
- #compute_heads private
- #compute_locate private
- #compute_nullable private
- #compute_nullable_0 private
-
#compute_useless
private
Sym#useless?, Rule#useless? FIXME: what means “useless”?
- #determine_terminals private
- #fix_ident private
Constructor Details
.new(debug_flags = DebugFlags.new) ⇒ Grammar
# File 'lib/racc/grammar.rb', line 21
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
Class Method Details
.define(&block)
Dynamic Generation Interface
# File 'lib/racc/grammar.rb', line 196
def Grammar.define(&block) env = DefinitionEnv.new env.instance_eval(&block) env.grammar end
Instance Attribute Details
#n_expected_srconflicts (rw)
[ GitHub ]# File 'lib/racc/grammar.rb', line 35
attr_accessor :n_expected_srconflicts
#start (readonly)
[ GitHub ]# File 'lib/racc/grammar.rb', line 33
attr_reader :start
#start_symbol=(s) (writeonly)
# File 'lib/racc/grammar.rb', line 170
def start_symbol=(s) raise CompileError, "start symbol set twice'" if @start @start = s end
#symboltable (readonly)
[ GitHub ]# File 'lib/racc/grammar.rb', line 34
attr_reader :symboltable
#useless_nonterminal_exist? ⇒ Boolean
(readonly)
[ GitHub ]
# File 'lib/racc/grammar.rb', line 81
def useless_nonterminal_exist? n_useless_nonterminals() != 0 end
#useless_rule_exist? ⇒ Boolean
(readonly)
[ GitHub ]
# File 'lib/racc/grammar.rb', line 96
def useless_rule_exist? n_useless_rules() != 0 end
Instance Method Details
#[](x)
[ GitHub ]# File 'lib/racc/grammar.rb', line 37
def [](x) @rules[x] end
#_compute_expand(t, set, lock) (private)
[ GitHub ]# File 'lib/racc/grammar.rb', line 499
def (t, set, lock) if tmp = t. set.update tmp return set end tok = nil set.update_a t.heads t.heads.each do |ptr| tok = ptr.dereference if tok and tok.nonterminal? unless lock[tok.ident] lock[tok.ident] = true tok, set, lock end end end set end
#add(rule)
Grammar
Definition Interface
# File 'lib/racc/grammar.rb', line 161
def add(rule) raise ArgumentError, "rule added after the Grammar closed" if @closed @rules.push rule end
#add_start_rule (private)
[ GitHub ]# File 'lib/racc/grammar.rb', line 425
def add_start_rule r = Rule.new(@symboltable.dummy, [@start, @symboltable.anchor, @symboltable.anchor], UserAction.empty) r.ident = 0 r.hash = 0 r.precedence = nil @rules.unshift r end
#added?(sym) ⇒ Boolean
# File 'lib/racc/grammar.rb', line 166
def added?(sym) @rules.detect {|r| r.target == sym } end
#check_rules_nullable(rules) (private)
[ GitHub ]#check_rules_useless(rules) (private)
[ GitHub ]#check_symbols_nullable(symbols) (private)
[ GitHub ]#check_symbols_useless(s) (private)
[ GitHub ]# File 'lib/racc/grammar.rb', line 586
def check_symbols_useless(s) s.delete_if do |t| t.heads.each do |ptr| unless ptr.rule.useless? t.useless = false break end end not t.useless? end end
#compute_expand(t) (private)
[ GitHub ]#compute_hash (private)
[ GitHub ]#compute_heads (private)
[ GitHub ]# File 'lib/racc/grammar.rb', line 453
def compute_heads @rules.each do |rule| rule.target.heads.push rule.ptrs[0] end end
#compute_locate (private)
[ GitHub ]#compute_nullable (private)
[ GitHub ]# File 'lib/racc/grammar.rb', line 519
def compute_nullable @rules.each {|r| r.null = false } @symboltable.each {|t| t.null = false } r = @rules.dup s = @symboltable.nonterminals begin rs = r.size ss = s.size check_rules_nullable r check_symbols_nullable s end until rs == r.size and ss == s.size end
#compute_nullable_0 (private)
[ GitHub ]# File 'lib/racc/grammar.rb', line 467
def compute_nullable_0 @symboltable.each do |s| if s.terminal? s.snull = false else s.snull = s.heads.any? {|loc| loc.reduce? } end end end
#compute_useless (private)
Sym#useless?, Rule#useless? FIXME: what means “useless”?
# File 'lib/racc/grammar.rb', line 559
def compute_useless @symboltable.each_terminal {|sym| sym.useless = false } @symboltable.each_nonterminal {|sym| sym.useless = true } @rules.each {|rule| rule.useless = true } r = @rules.dup s = @symboltable.nonterminals begin rs = r.size ss = s.size check_rules_useless r check_symbols_useless s end until r.size == rs and s.size == ss end
#declare_precedence(assoc, syms)
# File 'lib/racc/grammar.rb', line 175
def declare_precedence(assoc, syms) raise CompileError, "precedence table defined twice" if @prec_table_closed @prec_table.push [assoc, syms] end
#determine_terminals (private)
[ GitHub ]# File 'lib/racc/grammar.rb', line 460
def determine_terminals @symboltable.each do |s| s.term = s.heads.empty? end end
#dfa Also known as: #states
[ GitHub ]#each(&block)
Alias for #each_rule.
# File 'lib/racc/grammar.rb', line 45
alias each each_rule
#each_index(&block)
[ GitHub ]# File 'lib/racc/grammar.rb', line 47
def each_index(&block) @rules.each_index(&block) end
#each_rule(&block) Also known as: #each
[ GitHub ]# File 'lib/racc/grammar.rb', line 41
def each_rule(&block) @rules.each(&block) end
#each_with_index(&block)
[ GitHub ]# File 'lib/racc/grammar.rb', line 51
def each_with_index(&block) @rules.each_with_index(&block) end
#end_precedence_declaration(reverse)
[ GitHub ]# File 'lib/racc/grammar.rb', line 180
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
#fix_ident (private)
[ GitHub ]# File 'lib/racc/grammar.rb', line 437
def fix_ident @rules.each_with_index do |rule, idx| rule.ident = idx end end
#init
Computation
# File 'lib/racc/grammar.rb', line 404
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| t } compute_nullable compute_useless end
#intern(value, dummy = false)
[ GitHub ]# File 'lib/racc/grammar.rb', line 69
def intern(value, dummy = false) @symboltable.intern(value, dummy) end
#n_useless_nonterminals
[ GitHub ]# File 'lib/racc/grammar.rb', line 85
def n_useless_nonterminals @n_useless_nonterminals ||= begin n = 0 @symboltable.each_nonterminal do |sym| n += 1 if sym.useless? end n end end
#n_useless_rules
[ GitHub ]# File 'lib/racc/grammar.rb', line 100
def n_useless_rules @n_useless_rules ||= begin n = 0 each do |r| n += 1 if r.useless? end n end end
#nfa
[ GitHub ]#nonterminal_base
[ GitHub ]# File 'lib/racc/grammar.rb', line 77
def nonterminal_base @symboltable.nt_base end
#parser_class
[ GitHub ]# File 'lib/racc/grammar.rb', line 125
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
#size
[ GitHub ]# File 'lib/racc/grammar.rb', line 55
def size @rules.size end
#state_transition_table
[ GitHub ]# File 'lib/racc/grammar.rb', line 121
def state_transition_table states().state_transition_table end
#states
Alias for #dfa.
# File 'lib/racc/grammar.rb', line 119
alias states dfa
#symbols
[ GitHub ]# File 'lib/racc/grammar.rb', line 73
def symbols @symboltable.symbols end
#to_s
[ GitHub ]# File 'lib/racc/grammar.rb', line 59
def to_s "<Racc::Grammar>" end
#write_log(path)
[ GitHub ]# File 'lib/racc/grammar.rb', line 151
def write_log(path) File.open(path, 'w') {|f| LogFileGenerator.new(states()).output f } end