pdoc 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.markdown +34 -0
- data/Rakefile +46 -0
- data/bin/pdoc +58 -0
- data/lib/pdoc.rb +32 -0
- data/lib/pdoc/error.rb +4 -0
- data/lib/pdoc/generators.rb +6 -0
- data/lib/pdoc/generators/abstract_generator.rb +16 -0
- data/lib/pdoc/generators/html.rb +8 -0
- data/lib/pdoc/generators/html/helpers.rb +256 -0
- data/lib/pdoc/generators/html/page.rb +71 -0
- data/lib/pdoc/generators/html/syntax_highlighter.rb +41 -0
- data/lib/pdoc/generators/html/template.rb +37 -0
- data/lib/pdoc/generators/html/website.rb +194 -0
- data/lib/pdoc/generators/json.rb +15 -0
- data/lib/pdoc/generators/pythonesque.rb +105 -0
- data/lib/pdoc/models.rb +47 -0
- data/lib/pdoc/models/argument.rb +37 -0
- data/lib/pdoc/models/base.rb +107 -0
- data/lib/pdoc/models/callable.rb +19 -0
- data/lib/pdoc/models/class.rb +28 -0
- data/lib/pdoc/models/class_method.rb +18 -0
- data/lib/pdoc/models/class_property.rb +9 -0
- data/lib/pdoc/models/constant.rb +9 -0
- data/lib/pdoc/models/constructor.rb +14 -0
- data/lib/pdoc/models/container.rb +114 -0
- data/lib/pdoc/models/entity.rb +54 -0
- data/lib/pdoc/models/instance_method.rb +18 -0
- data/lib/pdoc/models/instance_property.rb +9 -0
- data/lib/pdoc/models/mixin.rb +10 -0
- data/lib/pdoc/models/namespace.rb +10 -0
- data/lib/pdoc/models/root.rb +27 -0
- data/lib/pdoc/models/section.rb +19 -0
- data/lib/pdoc/models/signature.rb +27 -0
- data/lib/pdoc/models/utility.rb +11 -0
- data/lib/pdoc/parser.rb +109 -0
- data/lib/pdoc/parser/argument_description_nodes.rb +21 -0
- data/lib/pdoc/parser/basic_nodes.rb +31 -0
- data/lib/pdoc/parser/description_nodes.rb +42 -0
- data/lib/pdoc/parser/documentation_nodes.rb +483 -0
- data/lib/pdoc/parser/ebnf_arguments_nodes.rb +58 -0
- data/lib/pdoc/parser/ebnf_expression_nodes.rb +227 -0
- data/lib/pdoc/parser/fragment.rb +55 -0
- data/lib/pdoc/parser/section_content_nodes.rb +19 -0
- data/lib/pdoc/parser/tags_nodes.rb +14 -0
- data/lib/pdoc/parser/treetop_files/argument_description.treetop +31 -0
- data/lib/pdoc/parser/treetop_files/basic.treetop +41 -0
- data/lib/pdoc/parser/treetop_files/description.treetop +7 -0
- data/lib/pdoc/parser/treetop_files/documentation.treetop +75 -0
- data/lib/pdoc/parser/treetop_files/ebnf_arguments.treetop +33 -0
- data/lib/pdoc/parser/treetop_files/ebnf_expression.treetop +70 -0
- data/lib/pdoc/parser/treetop_files/ebnf_javascript.treetop +54 -0
- data/lib/pdoc/parser/treetop_files/events.treetop +17 -0
- data/lib/pdoc/parser/treetop_files/section_content.treetop +8 -0
- data/lib/pdoc/parser/treetop_files/tags.treetop +31 -0
- data/lib/pdoc/runner.rb +110 -0
- data/lib/pdoc/treemaker.rb +94 -0
- data/pdoc.gemspec +31 -0
- data/templates/html/assets/images/pdoc/alias.png +0 -0
- data/templates/html/assets/images/pdoc/class.png +0 -0
- data/templates/html/assets/images/pdoc/class_deprecated.png +0 -0
- data/templates/html/assets/images/pdoc/class_method.png +0 -0
- data/templates/html/assets/images/pdoc/class_property.png +0 -0
- data/templates/html/assets/images/pdoc/constant.png +0 -0
- data/templates/html/assets/images/pdoc/constructor.png +0 -0
- data/templates/html/assets/images/pdoc/deprecated.png +0 -0
- data/templates/html/assets/images/pdoc/description.png +0 -0
- data/templates/html/assets/images/pdoc/information.png +0 -0
- data/templates/html/assets/images/pdoc/instance_method.png +0 -0
- data/templates/html/assets/images/pdoc/instance_property.png +0 -0
- data/templates/html/assets/images/pdoc/method.png +0 -0
- data/templates/html/assets/images/pdoc/method_deprecated.png +0 -0
- data/templates/html/assets/images/pdoc/mixin.png +0 -0
- data/templates/html/assets/images/pdoc/namespace.png +0 -0
- data/templates/html/assets/images/pdoc/property.png +0 -0
- data/templates/html/assets/images/pdoc/related_to.png +0 -0
- data/templates/html/assets/images/pdoc/search-background.png +0 -0
- data/templates/html/assets/images/pdoc/section-background.png +0 -0
- data/templates/html/assets/images/pdoc/section.png +0 -0
- data/templates/html/assets/images/pdoc/selected-section-background.png +0 -0
- data/templates/html/assets/images/pdoc/subclass.png +0 -0
- data/templates/html/assets/images/pdoc/superclass.png +0 -0
- data/templates/html/assets/images/pdoc/utility.png +0 -0
- data/templates/html/assets/javascripts/pdoc/application.js +478 -0
- data/templates/html/assets/javascripts/pdoc/prototype.js +4874 -0
- data/templates/html/assets/javascripts/pdoc/tabs.js +506 -0
- data/templates/html/assets/stylesheets/pdoc/api.css +677 -0
- data/templates/html/assets/stylesheets/pdoc/pygments.css +62 -0
- data/templates/html/helpers.rb +35 -0
- data/templates/html/index.erb +18 -0
- data/templates/html/item_index.js.erb +6 -0
- data/templates/html/layout.erb +67 -0
- data/templates/html/leaf.erb +22 -0
- data/templates/html/node.erb +30 -0
- data/templates/html/partials/class_relationships.erb +19 -0
- data/templates/html/partials/classes.erb +7 -0
- data/templates/html/partials/constructor.erb +5 -0
- data/templates/html/partials/description.erb +5 -0
- data/templates/html/partials/link_list.erb +1 -0
- data/templates/html/partials/method_signatures.erb +14 -0
- data/templates/html/partials/methodized_note.erb +9 -0
- data/templates/html/partials/mixins.erb +7 -0
- data/templates/html/partials/namespaces.erb +7 -0
- data/templates/html/partials/related_utilities.erb +5 -0
- data/templates/html/partials/relationships.erb +11 -0
- data/templates/html/partials/short_description_list.erb +7 -0
- data/templates/html/partials/title.erb +22 -0
- data/templates/html/section.erb +18 -0
- data/test/unit/parser/argument_description_test.rb +40 -0
- data/test/unit/parser/basic_test.rb +55 -0
- data/test/unit/parser/description_test.rb +34 -0
- data/test/unit/parser/documentation_test.rb +520 -0
- data/test/unit/parser/ebnf_arguments_test.rb +81 -0
- data/test/unit/parser/ebnf_expression_test.rb +382 -0
- data/test/unit/parser/ebnf_javascript_test.rb +37 -0
- data/test/unit/parser/events_test.rb +27 -0
- data/test/unit/parser/section_content_test.rb +44 -0
- data/test/unit/parser/tags_test.rb +39 -0
- data/test/unit/parser/test_fragment.rb +80 -0
- data/test/unit/parser_test_helper.rb +62 -0
- data/test/unit/runner/basic_test.rb +14 -0
- data/test/unit/templates/html_helpers_test.rb +25 -0
- metadata +222 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
module EbnfArguments
|
|
2
|
+
class Argument < Treetop::Runtime::SyntaxNode
|
|
3
|
+
def name
|
|
4
|
+
text_value.strip
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def optional?
|
|
8
|
+
false
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def default_value
|
|
12
|
+
nil
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def flatten_nested_args
|
|
16
|
+
[self]
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
class OptionalArgument < Treetop::Runtime::SyntaxNode
|
|
21
|
+
def name
|
|
22
|
+
required_argument.name
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def optional?
|
|
26
|
+
true
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def default_value
|
|
30
|
+
unless default.empty?
|
|
31
|
+
value = default.value.text_value.strip
|
|
32
|
+
value.empty? ? nil : value
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def flatten_nested_args
|
|
37
|
+
arguments = [self]
|
|
38
|
+
unless nested.empty?
|
|
39
|
+
nested.elements.each do |optional|
|
|
40
|
+
arguments.concat(optional.flatten_nested_args)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
arguments
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
class Arguments < Treetop::Runtime::SyntaxNode
|
|
48
|
+
def to_a
|
|
49
|
+
first_argument.flatten_nested_args + rest_arguments_flattened
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def rest_arguments_flattened
|
|
53
|
+
rest.elements.inject([]) do |args, e|
|
|
54
|
+
args.concat(e.argument.flatten_nested_args)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
module EbnfExpression
|
|
2
|
+
class Base < Treetop::Runtime::SyntaxNode
|
|
3
|
+
def klass_name
|
|
4
|
+
js_namespace.to_a.last
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def name
|
|
8
|
+
js_variable.value
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def full_name
|
|
12
|
+
js_namespace.text_value
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def namespace
|
|
16
|
+
js_namespace.text_value
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def returns
|
|
20
|
+
return_value.value.text_value.strip
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def to_s
|
|
24
|
+
text_value
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def inspect
|
|
28
|
+
"#<#{self.class} @input=#{@input.inspect}>"
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class Method < Base
|
|
33
|
+
def arguments
|
|
34
|
+
args.arguments.to_a
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def methodized?
|
|
38
|
+
false
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def signature
|
|
42
|
+
"#{name}#{args.text_value}"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
class KlassMethod < Method
|
|
47
|
+
def klass_name
|
|
48
|
+
js_namespace.to_a.slice(-2)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def name
|
|
52
|
+
js_namespace.to_a.last
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def methodized?
|
|
56
|
+
args.methodize.text_value == '@'
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def namespace
|
|
60
|
+
js_namespace.to_a.slice(0..-2).join(".")
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def signature
|
|
64
|
+
"#{namespace}.#{name}#{args.text_value.sub('@', '')}"
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
class Utility < Method
|
|
69
|
+
def klass_name
|
|
70
|
+
nil
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def name
|
|
74
|
+
utility_name.text_value
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def full_name
|
|
78
|
+
name
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def namespace
|
|
82
|
+
""
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
class InstanceMethod < Method
|
|
87
|
+
def accessor
|
|
88
|
+
instance_signature.instance_accessor
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def args
|
|
92
|
+
instance_signature.args
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def js_namespace
|
|
96
|
+
accessor.js_namespace
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def js_variable
|
|
100
|
+
accessor.js_variable
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def full_name
|
|
104
|
+
accessor.text_value
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def signature
|
|
108
|
+
instance_signature.text_value
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
class Constructor < Method
|
|
113
|
+
def name
|
|
114
|
+
"new"
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def full_name
|
|
118
|
+
"new #{super}"
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def returns
|
|
122
|
+
nil
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def signature
|
|
126
|
+
"#{full_name}#{args.text_value}"
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
class KlassProperty < Base
|
|
131
|
+
def klass_name
|
|
132
|
+
js_namespace.to_a.slice(-2)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def name
|
|
136
|
+
js_namespace.to_a.last
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def namespace
|
|
140
|
+
js_namespace.to_a.slice(0..-2).join(".")
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def signature
|
|
144
|
+
"#{namespace}.#{name}"
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
class InstanceProperty < Base
|
|
149
|
+
def accessor
|
|
150
|
+
instance_accessor
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def js_namespace
|
|
154
|
+
accessor.js_namespace
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def js_variable
|
|
158
|
+
accessor.js_variable
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def full_name
|
|
162
|
+
accessor.text_value
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def signature
|
|
166
|
+
"#{namespace}##{name}"
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
class Constant < Base
|
|
171
|
+
def klass_name
|
|
172
|
+
nil
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def name
|
|
176
|
+
js_namespace.to_a.last
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def namespace
|
|
180
|
+
js_namespace.to_a.slice(0..-2).join(".")
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def returns
|
|
184
|
+
value.text_value.strip
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def signature
|
|
188
|
+
"#{namespace}.#{name}"
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
class Namespace < Base
|
|
193
|
+
def klass_name
|
|
194
|
+
nil
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def name
|
|
198
|
+
js_namespace.to_a.last
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def namespace
|
|
202
|
+
js_namespace.to_a.slice(0..-2).join(".")
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def mixins
|
|
206
|
+
second_line = elements.last
|
|
207
|
+
if second_line.empty?
|
|
208
|
+
[]
|
|
209
|
+
else
|
|
210
|
+
[second_line.js_namespace].concat(second_line.more.elements.map{|e| e.elements.last})
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
class Klass < Namespace
|
|
216
|
+
def subklass?
|
|
217
|
+
!extends.elements.nil?
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def superklass
|
|
221
|
+
subklass? ? extends.elements.last : nil
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
class Mixin < Namespace
|
|
226
|
+
end
|
|
227
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
require 'pdoc/error'
|
|
2
|
+
|
|
3
|
+
module PDoc
|
|
4
|
+
class Fragment
|
|
5
|
+
PREFIX_REGEXP = /^\s*\*?\s*/
|
|
6
|
+
|
|
7
|
+
attr_reader :line_number
|
|
8
|
+
def initialize(string, line_number)
|
|
9
|
+
@line_number = line_number
|
|
10
|
+
@string = string
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def normalize
|
|
14
|
+
# Cleans up the text by removing opening and closing comment tags
|
|
15
|
+
# and removing the prefix off of every line.
|
|
16
|
+
# Raises and error if prefix are inconsistent. (Prefix is calculated
|
|
17
|
+
# by looking at line 2 of the comment)
|
|
18
|
+
results = []
|
|
19
|
+
lines.each_with_index do |line, index|
|
|
20
|
+
if index == 0 # first line
|
|
21
|
+
results << line.sub(/\s*\/\*\*\s*/, '') # remove opening /**
|
|
22
|
+
elsif index == lines.size - 1 # last line
|
|
23
|
+
results << line.sub(/\s*\*\*?\/\s*/, '') # remove closing **/
|
|
24
|
+
elsif line =~ prefix_regexp # correctly prefixed lines
|
|
25
|
+
results << line.sub(prefix_regexp, '') # remove optional prefix
|
|
26
|
+
else
|
|
27
|
+
raise InconsistentPrefixError.new(self, line, index)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
results
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def prefix
|
|
34
|
+
PREFIX_REGEXP.match(lines[1])[0] if lines.size > 2
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def prefix_regexp
|
|
38
|
+
@prefix_regexp ||= Regexp.new('^' << Regexp.escape(prefix))
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def lines
|
|
42
|
+
@lines ||= @string.split("\n")
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
class InconsistentPrefixError < PDocError
|
|
46
|
+
def initialize(fragment, line, index)
|
|
47
|
+
@fragment = fragment
|
|
48
|
+
actual = PREFIX_REGEXP.match(line)[0].inspect
|
|
49
|
+
msg = "Inconsistent prefixing at line ##{fragment.line_number + index}."
|
|
50
|
+
msg << "Expected prefix is: #{fragment.prefix.inspect}, actual prefix is: #{actual}"
|
|
51
|
+
super(msg)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module SectionContent
|
|
2
|
+
class Section < Treetop::Runtime::SyntaxNode
|
|
3
|
+
def name
|
|
4
|
+
title.text_value.strip
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def description
|
|
8
|
+
text.to_s
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def full_name
|
|
12
|
+
name
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def id
|
|
16
|
+
name.downcase.gsub(/\s+/, "_")
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
grammar ArgumentDescription
|
|
2
|
+
include EbnfJavascript
|
|
3
|
+
|
|
4
|
+
rule argument_description
|
|
5
|
+
first:argument_description_first_line more:(argument_description_line)* <ArgumentDescription>
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
rule argument_description_first_line
|
|
9
|
+
line space* '-' space+ argument_name arg_types:(space+ arguments_types)? ':' description:char+
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
rule argument_description_line
|
|
13
|
+
line space* first_char:(!'-' .) more_char:char+ {
|
|
14
|
+
def to_s
|
|
15
|
+
first_char.text_value << more_char.text_value
|
|
16
|
+
end
|
|
17
|
+
}
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
rule argument_name
|
|
21
|
+
'@'? name:[a-zA-Z$]+
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
rule arguments_types
|
|
25
|
+
'(' space* argument_type more:(space+ '|' space+ argument_type)* space* ')'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
rule argument_type
|
|
29
|
+
js_namespace / '?'
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
grammar Basic
|
|
2
|
+
rule test_base
|
|
3
|
+
(blank_line / text_line / comment_start / comment_end / line / line_break / space / char)+
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
rule blank_line
|
|
7
|
+
line_break space* line_separator space* &(line_break) <BlankLine>
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
rule text_line
|
|
11
|
+
line text:char+ <TextLine>
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
rule line
|
|
15
|
+
line_break space* line_separator space <Line>
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
rule comment_start
|
|
19
|
+
line_break space* "/**" space* <CommentStart>
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
rule comment_end
|
|
23
|
+
line_break space* "**/" space* line_break <CommentEnd>
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
rule line_break
|
|
27
|
+
[\n] <LineBreak>
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
rule line_separator
|
|
31
|
+
"*"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
rule char
|
|
35
|
+
![\n] . <Char>
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
rule space
|
|
39
|
+
" " <Space>
|
|
40
|
+
end
|
|
41
|
+
end
|