Class: Kanocc::Nonterminal
- Inherits:
-
Object
- Object
- Kanocc::Nonterminal
show all
- Defined in:
- lib/kanocc/nonterminal.rb
Constant Summary
collapse
- Left =
1
- Right =
2
- @@rules =
Hash.new
- @@last_rule =
Hash.new
- @@bind_right =
Hash.new
- @@method_names =
Hash.new
- @@listClassNumber =
0
Class Method Summary
collapse
Instance Method Summary
collapse
Class Method Details
.add_rule(rule) ⇒ Object
34
35
36
37
38
|
# File 'lib/kanocc/nonterminal.rb', line 34
def Nonterminal.add_rule(rule)
@@rules[self] ||= []
@@rules[self].push(rule)
@@last_rule[self] = rule
end
|
.derives_right ⇒ Object
127
128
129
130
|
# File 'lib/kanocc/nonterminal.rb', line 127
def Nonterminal.derives_right
raise "Call to derives_right must be preceded by a rule" unless @@last_rule[self]
@@last_rule[self].derives_right = true
end
|
.generate_method_name(*args) ⇒ Object
109
110
111
112
113
114
115
116
117
118
119
|
# File 'lib/kanocc/nonterminal.rb', line 109
def Nonterminal.generate_method_name(*args)
class_name = self.name || ""
method_name = class_name + " --> " + args.map {|a| a.inspect}.join(' ')
@@method_names[self] ||= []
i = 1
while @@method_names[self].member?(method_name) do
method_name += ' ';
end
@@method_names[self].push(method_name)
return method_name
end
|
.is_a_grammarsymbol?(x) ⇒ Boolean
40
41
42
|
# File 'lib/kanocc/nonterminal.rb', line 40
def Nonterminal.is_a_grammarsymbol?(x)
x.is_a?(String) or (x.respond_to?("is_a_kanocc_grammarsymbol?") and x.is_a_kanocc_grammarsymbol?)
end
|
.is_a_kanocc_grammarsymbol? ⇒ Boolean
44
45
46
|
# File 'lib/kanocc/nonterminal.rb', line 44
def Nonterminal.is_a_kanocc_grammarsymbol?
return true
end
|
.new_list_class ⇒ Object
98
99
100
101
102
103
104
105
106
107
|
# File 'lib/kanocc/nonterminal.rb', line 98
def Nonterminal.new_list_class
list_class = Class.new(AnonymousNonterminal)
@@listClassNumber += 1
def list_class.inspect
return "anonList_#{@@listClassNumber}"
end
return list_class
end
|
.om(symbols, sep = nil) ⇒ Object
78
79
80
81
82
83
84
85
86
87
88
|
# File 'lib/kanocc/nonterminal.rb', line 78
def Nonterminal.om(symbols, sep = nil)
symbols = [symbols] unless symbols.is_a? Array
non_empty_list_class = new_list_class
non_empty_list_class.rule(*symbols) {@elements = @rhs}
if sep
non_empty_list_class.rule(non_empty_list_class, sep, *symbols) {@elements = @rhs[0].elements + @rhs[2..@rhs.length]}
else
non_empty_list_class.rule(non_empty_list_class, *symbols) {@elements = @rhs[0].elements + @rhs[1..@rhs.length]}
end
return non_empty_list_class
end
|
.precedence(prec) ⇒ Object
121
122
123
124
125
|
# File 'lib/kanocc/nonterminal.rb', line 121
def Nonterminal.precedence(prec)
raise "Given rule precedence was not a Numeric" unless prec.is_a? Numeric
raise "Call to precedence must be preceded by a rule" unless @@last_rule[self]
@@last_rule[self].precedence = prec
end
|
.rule(*rhs, &block) ⇒ Object
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
# File 'lib/kanocc/nonterminal.rb', line 48
def Nonterminal.rule(*rhs, &block)
for pos in 0..rhs.length - 1 do
unless is_a_grammarsymbol?(rhs[pos])
raise "Problem with rule: #{rhs.inspect}, element:#{pos.to_s} - #{rhs[pos].inspect}\nElements of a rule must be Strings, Tokens or Nonterminals"
end
end
if block_given?
method_name = generate_method_name(*rhs)
define_method(method_name.to_sym, &block)
add_rule(GrammarRule.new(self, rhs, method_name.to_sym))
else
add_rule(GrammarRule.new(self, rhs, nil))
end
end
|
.rules ⇒ Object
29
30
31
32
|
# File 'lib/kanocc/nonterminal.rb', line 29
def Nonterminal.rules
rules = @@rules[self]
return rules ? rules : []
end
|
.show_all_rules ⇒ Object
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
# File 'lib/kanocc/nonterminal.rb', line 146
def Nonterminal.show_all_rules
queue = [self]
done = {}
i = 0
while (i < queue.length)
queue[i].show_rules
done[queue[i]] = true
queue[i].rules.each do |rule|
rule.rhs.each do |gs|
if gs.respond_to?(:rules) and not done[gs]
queue.push(gs)
end
end
end
i += 1
end
end
|
.show_method_names ⇒ Object
132
133
134
|
# File 'lib/kanocc/nonterminal.rb', line 132
def Nonterminal.show_method_names
@@method_names[self].each{|mn| puts mn.inspect} if @@method_names[self]
end
|
.show_rules ⇒ Object
140
141
142
143
144
|
# File 'lib/kanocc/nonterminal.rb', line 140
def Nonterminal.show_rules
rules.each do |rule|
puts rule.inspect
end
end
|
.zm(symbols, sep = nil) ⇒ Object
64
65
66
67
68
69
70
71
72
73
74
75
76
|
# File 'lib/kanocc/nonterminal.rb', line 64
def Nonterminal.zm(symbols, sep = nil)
list_class = new_list_class
non_empty_list_class = new_list_class
list_class.rule() {@elements = []}
list_class.rule(non_empty_list_class) {@elements = @rhs[0].elements}
non_empty_list_class.rule(*symbols) {@elements = @rhs}
if sep
non_empty_list_class.rule(non_empty_list_class, sep, *symbols) {@elements = @rhs[0].elements + @rhs[2..@rhs.length]}
else
non_empty_list_class.rule(non_empty_list_class, *symbols) {@elements = @rhs[0].elements + @rhs[1..@rhs.length]}
end
return list_class
end
|
.zo(symbols) ⇒ Object
90
91
92
93
94
|
# File 'lib/kanocc/nonterminal.rb', line 90
def Nonterminal.zo(symbols)
zero_or_one_class = new_list_class
zero_or_one_class.rule(*symbols) {@elements = @rhs}
zero_or_one_class.rule() {@elements = []}
end
|
Instance Method Details
#inspect ⇒ Object
136
137
138
|
# File 'lib/kanocc/nonterminal.rb', line 136
def inspect
self.class.name
end
|