Class: Depager::Grammar
- Inherits:
-
Object
- Object
- Depager::Grammar
- Defined in:
- lib/depager/grammar.rb
Direct Known Subclasses
Defined Under Namespace
Classes: SymbolSet
Instance Attribute Summary collapse
-
#f0e ⇒ Object
Returns the value of attribute f0e.
-
#first1 ⇒ Object
Returns the value of attribute first1.
-
#lhs_to_rule ⇒ Object
Returns the value of attribute lhs_to_rule.
-
#mask_sym ⇒ Object
readonly
Returns the value of attribute mask_sym.
-
#nonterms ⇒ Object
Returns the value of attribute nonterms.
-
#precs ⇒ Object
Returns the value of attribute precs.
-
#rulelist ⇒ Object
Returns the value of attribute rulelist.
-
#syms ⇒ Object
Returns the value of attribute syms.
-
#terms ⇒ Object
Returns the value of attribute terms.
Instance Method Summary collapse
- #[](n) ⇒ Object
- #first(p) ⇒ Object
-
#initialize(rulelist, terms, nonterms, precs = nil) ⇒ Grammar
constructor
A new instance of Grammar.
- #initialize_depend ⇒ Object
- #make_sym_first ⇒ Object
- #make_sym_mask ⇒ Object
- #mask_size ⇒ Object
- #nonterm?(i) ⇒ Boolean
- #sym_mask(sym) ⇒ Object
- #symname(sym) ⇒ Object
- #symset(syms = nil) ⇒ Object
- #term?(i) ⇒ Boolean
Constructor Details
#initialize(rulelist, terms, nonterms, precs = nil) ⇒ Grammar
Returns a new instance of Grammar.
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/depager/grammar.rb', line 7 def initialize(rulelist, terms, nonterms, precs = nil) @precs = precs @nonterms = nonterms.invert @terms = terms.invert @syms = nonterms.invert.merge(terms.invert) @rulelist = rulelist @lhs_to_rule = [] @nonterms.size.times { |i| @lhs_to_rule[i] = [] } @empty_rules = {} @rulelist.each_with_index do |rule, rx| rule.grammar = self rule.n = rx @lhs_to_rule[rule.lhs] << rule @empty_rules[rule.lhs] = rule.n if rule.rhs.empty? end make_sym_mask make_sym_first initialize_depend end |
Instance Attribute Details
#f0e ⇒ Object
Returns the value of attribute f0e.
5 6 7 |
# File 'lib/depager/grammar.rb', line 5 def f0e @f0e end |
#first1 ⇒ Object
Returns the value of attribute first1.
5 6 7 |
# File 'lib/depager/grammar.rb', line 5 def first1 @first1 end |
#lhs_to_rule ⇒ Object
Returns the value of attribute lhs_to_rule.
5 6 7 |
# File 'lib/depager/grammar.rb', line 5 def lhs_to_rule @lhs_to_rule end |
#mask_sym ⇒ Object (readonly)
Returns the value of attribute mask_sym.
55 56 57 |
# File 'lib/depager/grammar.rb', line 55 def mask_sym @mask_sym end |
#nonterms ⇒ Object
Returns the value of attribute nonterms.
5 6 7 |
# File 'lib/depager/grammar.rb', line 5 def nonterms @nonterms end |
#precs ⇒ Object
Returns the value of attribute precs.
5 6 7 |
# File 'lib/depager/grammar.rb', line 5 def precs @precs end |
#rulelist ⇒ Object
Returns the value of attribute rulelist.
5 6 7 |
# File 'lib/depager/grammar.rb', line 5 def rulelist @rulelist end |
#syms ⇒ Object
Returns the value of attribute syms.
5 6 7 |
# File 'lib/depager/grammar.rb', line 5 def syms @syms end |
#terms ⇒ Object
Returns the value of attribute terms.
5 6 7 |
# File 'lib/depager/grammar.rb', line 5 def terms @terms end |
Instance Method Details
#[](n) ⇒ Object
118 119 120 |
# File 'lib/depager/grammar.rb', line 118 def [](n) @rulelist[n] end |
#first(p) ⇒ Object
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/depager/grammar.rb', line 92 def first(p) return symset([EPS]) if p.empty? r = symset x = 0 p.each do |i| unless i == EPS r.merge! @first1[i] break unless @first1[i].include? EPS end x += 1 end r.delete EPS r << EPS if x == p.size r end |
#initialize_depend ⇒ Object
28 |
# File 'lib/depager/grammar.rb', line 28 def initialize_depend; end |
#make_sym_first ⇒ Object
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/depager/grammar.rb', line 57 def make_sym_first @first1 = {} @syms.each_key do |s| @first1[s] = symset @first1[s] << s if term? s @first1[s] << EPS if @empty_rules[s] end begin changed = false @nonterms.size.times do |lhs| @lhs_to_rule[lhs].each do |rule| rule.rhs.each do |s| unless @first1[s].subset_of?(@first1[lhs]) # warn "%b\n%b" % [@first1[s].set, @first1[lhs].set] # warn "update{" # warn " R:#{symname(s)}:#{@first1[s].inspect}" # warn " L:#{symname(lhs)}:#{@first1[lhs].inspect}" @first1[lhs].merge! @first1[s] # warn " L:#{symname(lhs)}:#{@first1[lhs].inspect}" # warn "}" changed = true end break unless @first1[s].include? EPS end if !@first1[lhs].include?(EPS) && rule.rhs.all? { |i| @first1[i].include? EPS } @first1[lhs] << EPS changed = true end end end end while changed end |
#make_sym_mask ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/depager/grammar.rb', line 30 def make_sym_mask @sym_mask = {} @mask_sym = [] @terms.sort_by { |a, _b| a }.each_with_index do |i, x| @sym_mask[i[0]] = 1 << x @mask_sym[x] = i[0] end @sym_mask[EPS] = (1 << @sym_mask.size) @mask_sym << EPS end |
#mask_size ⇒ Object
51 52 53 |
# File 'lib/depager/grammar.rb', line 51 def mask_size @mask_sym.size end |
#nonterm?(i) ⇒ Boolean
114 115 116 |
# File 'lib/depager/grammar.rb', line 114 def nonterm?(i) i && i < @nonterms.size end |
#sym_mask(sym) ⇒ Object
47 48 49 |
# File 'lib/depager/grammar.rb', line 47 def sym_mask(sym) @sym_mask[sym] end |
#symname(sym) ⇒ Object
122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/depager/grammar.rb', line 122 def symname(sym) name = @syms[sym] return nil unless sym.is_a? Integer return "$start" if sym == 0 return "$empty" if sym == EPS return "$end" if name.nil? return "$error" if name == false return name.to_s if name.is_a? Symbol "'#{name}'" end |
#symset(syms = nil) ⇒ Object
42 43 44 45 |
# File 'lib/depager/grammar.rb', line 42 def symset(syms = nil) ss = SymbolSet.new(self) syms ? ss.concat_array(syms) : ss end |
#term?(i) ⇒ Boolean
110 111 112 |
# File 'lib/depager/grammar.rb', line 110 def term?(i) i && i >= @nonterms.size end |