rattler 0.2.2 → 0.3.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.rdoc +83 -64
- data/features/grammar/comments.feature +24 -0
- data/features/grammar/list_matching.feature +41 -0
- data/features/grammar/symantic_action.feature +30 -12
- data/lib/rattler/back_end/parser_generator/assert_generator.rb +27 -27
- data/lib/rattler/back_end/parser_generator/choice_generator.rb +29 -29
- data/lib/rattler/back_end/parser_generator/direct_action_generator.rb +17 -17
- data/lib/rattler/back_end/parser_generator/disallow_generator.rb +27 -27
- data/lib/rattler/back_end/parser_generator/dispatch_action_generator.rb +17 -17
- data/lib/rattler/back_end/parser_generator/expr_generator.rb +129 -40
- data/lib/rattler/back_end/parser_generator/label_generator.rb +15 -15
- data/lib/rattler/back_end/parser_generator/list1_generator.rb +61 -0
- data/lib/rattler/back_end/parser_generator/list_generating.rb +71 -0
- data/lib/rattler/back_end/parser_generator/list_generator.rb +57 -0
- data/lib/rattler/back_end/parser_generator/one_or_more_generator.rb +14 -15
- data/lib/rattler/back_end/parser_generator/optional_generator.rb +24 -24
- data/lib/rattler/back_end/parser_generator/predicate_propogating.rb +9 -9
- data/lib/rattler/back_end/parser_generator/repeat_generating.rb +16 -16
- data/lib/rattler/back_end/parser_generator/sequence_generator.rb +40 -40
- data/lib/rattler/back_end/parser_generator/skip_generator.rb +18 -18
- data/lib/rattler/back_end/parser_generator/skip_propogating.rb +5 -5
- data/lib/rattler/back_end/parser_generator/sub_generating.rb +128 -0
- data/lib/rattler/back_end/parser_generator/token_generator.rb +15 -15
- data/lib/rattler/back_end/parser_generator/token_propogating.rb +1 -1
- data/lib/rattler/back_end/parser_generator/zero_or_more_generator.rb +12 -13
- data/lib/rattler/back_end/parser_generator.rb +10 -7
- data/lib/rattler/grammar/grammar_parser.rb +16 -21
- data/lib/rattler/grammar/metagrammar.rb +1039 -1035
- data/lib/rattler/grammar/rattler.rtlr +28 -28
- data/lib/rattler/parsers/action_code.rb +20 -9
- data/lib/rattler/parsers/fail.rb +7 -1
- data/lib/rattler/parsers/list.rb +57 -0
- data/lib/rattler/parsers/list1.rb +58 -0
- data/lib/rattler/parsers/parser_dsl.rb +60 -38
- data/lib/rattler/parsers.rb +5 -3
- data/lib/rattler/runtime/extended_packrat_parser.rb +88 -20
- data/lib/rattler/runtime/packrat_parser.rb +21 -14
- data/lib/rattler/runtime/parser.rb +74 -18
- data/lib/rattler/runtime/recursive_descent_parser.rb +15 -46
- data/spec/rattler/back_end/compiler_spec.rb +173 -107
- data/spec/rattler/back_end/parser_generator/list1_generator_spec.rb +304 -0
- data/spec/rattler/back_end/parser_generator/list_generator_spec.rb +288 -0
- data/spec/rattler/grammar/grammar_parser_spec.rb +65 -76
- data/spec/rattler/parsers/action_code_spec.rb +84 -34
- data/spec/rattler/parsers/direct_action_spec.rb +56 -34
- data/spec/rattler/parsers/fail_spec.rb +20 -0
- data/spec/rattler/parsers/list1_spec.rb +82 -0
- data/spec/rattler/parsers/list_spec.rb +82 -0
- data/spec/rattler/parsers/parser_dsl_spec.rb +48 -19
- data/spec/rattler/runtime/extended_packrat_parser_spec.rb +0 -1
- metadata +92 -173
- data/bin/rtlr.bat +0 -3
- data/lib/rattler/back_end/parser_generator/generator_helper.rb +0 -130
- data/lib/rattler/back_end/parser_generator/generators.rb +0 -86
- data/lib/rattler/back_end/parser_generator/nested_generators.rb +0 -15
- data/lib/rattler/back_end/parser_generator/top_level_generators.rb +0 -15
@@ -8,32 +8,32 @@ include Rattler::Parsers
|
|
8
8
|
|
9
9
|
grammar <- heading rules EOF <Grammar>
|
10
10
|
|
11
|
-
heading <- requires module_decl? includes {
|
11
|
+
heading <- requires module_decl? includes { heading *_ }
|
12
12
|
|
13
|
-
requires <- (~`require` literal ~eol)* {
|
13
|
+
requires <- (~`require` literal ~eol)* { { :requires => _ } }
|
14
14
|
|
15
|
-
module_decl <- ~`parser` constant (~'<' constant)? ~eol {
|
16
|
-
| ~`grammar` constant ~eol {
|
15
|
+
module_decl <- ~`parser` constant (~'<' constant)? ~eol { parser_decl *_ }
|
16
|
+
| ~`grammar` constant ~eol { { :grammar_name => _ } }
|
17
17
|
|
18
|
-
includes <- (~`include` constant ~eol)* {
|
18
|
+
includes <- (~`include` constant ~eol)* { { :includes => _ } }
|
19
19
|
|
20
20
|
rules <- (directive | rule | block_close)+ <Rules>
|
21
21
|
|
22
22
|
directive <- ws_directive | wc_directive
|
23
23
|
|
24
|
-
ws_directive <- ws_decl ~'{' {
|
25
|
-
| ws_decl {
|
24
|
+
ws_directive <- ws_decl ~'{' { start_ws _ }
|
25
|
+
| ws_decl { set_ws _ }
|
26
26
|
|
27
27
|
ws_decl <- ~`%whitespace` unattributed
|
28
28
|
|
29
|
-
wc_directive <- wc_decl ~'{' {
|
30
|
-
| wc_decl {
|
29
|
+
wc_directive <- wc_decl ~'{' { start_wc _ }
|
30
|
+
| wc_decl { set_wc _ }
|
31
31
|
|
32
32
|
wc_decl <- ~`%word_character` unattributed
|
33
33
|
|
34
34
|
block_close <- ~'}' { end_block }
|
35
35
|
|
36
|
-
rule <- identifier ~'<-' expression {
|
36
|
+
rule <- identifier ~'<-' expression { rule *_ }
|
37
37
|
|
38
38
|
unattributed <- unattributed ~'|' terms <Choice>
|
39
39
|
| terms
|
@@ -41,32 +41,32 @@ include Rattler::Parsers
|
|
41
41
|
expression <- expression ~'|' attributed <Choice>
|
42
42
|
| attributed
|
43
43
|
|
44
|
-
attributed <- attributed
|
45
|
-
| attributed action
|
44
|
+
attributed <- attributed ~'<' dispatch? ~'>' <DispatchAction>
|
45
|
+
| attributed ~'{' action ~'}' <DirectAction>
|
46
46
|
| terms
|
47
47
|
|
48
|
-
|
48
|
+
dispatch <- @(name (~'.' var_name)?)
|
49
49
|
|
50
|
-
|
51
|
-
|
52
|
-
method <- ~'.' var_name
|
53
|
-
|
54
|
-
action <- ~'{' @(('{' [^}]* '}' | [^{}])*) ~'}'
|
55
|
-
| ~'<' method ~'>' {|m| "|_| _.#{m}" }
|
50
|
+
action <- @(('{' [^}]* '}' | [^{}])*)
|
56
51
|
|
57
52
|
terms <- terms term <Sequence>
|
58
53
|
| term
|
59
54
|
|
60
|
-
term <- fail_expr | labeled |
|
55
|
+
term <- fail_expr | labeled | labelable
|
61
56
|
|
62
57
|
fail_expr <- (`fail` | `fail_rule` | `fail_parse`) fail_arg <Fail>
|
63
58
|
|
64
59
|
fail_arg <- ~'(' literal ~')'
|
65
60
|
| literal
|
66
61
|
|
67
|
-
labeled <-
|
62
|
+
labeled <- var_name ~':' labelable <Label>
|
63
|
+
|
64
|
+
labelable <- list | list_term
|
65
|
+
|
66
|
+
list <- list_term ~'*^' list_term <List>
|
67
|
+
| list_term ~'+^' list_term <List1>
|
68
68
|
|
69
|
-
|
69
|
+
list_term <- prefixed | prefixable
|
70
70
|
|
71
71
|
prefixed <- ~'&' prefixable <Assert>
|
72
72
|
| ~'!' prefixable <Disallow>
|
@@ -76,18 +76,18 @@ include Rattler::Parsers
|
|
76
76
|
prefixable <- suffixed | primary
|
77
77
|
|
78
78
|
suffixed <- primary ~'?' <Optional>
|
79
|
-
| primary ~'*'
|
80
|
-
| primary ~'+'
|
79
|
+
| primary ~'*' !'^' <ZeroOrMore>
|
80
|
+
| primary ~'+' !'^' <OneOrMore>
|
81
81
|
|
82
82
|
primary <- ~'(' expression ~')'
|
83
83
|
| atom
|
84
84
|
|
85
85
|
atom <- `EOF` <Eof>
|
86
|
-
| posix_class {
|
86
|
+
| posix_class { posix_class _ }
|
87
87
|
| identifier !'<-' <Apply>
|
88
|
-
| literal {
|
89
|
-
| word_literal {
|
90
|
-
| class {
|
88
|
+
| literal { literal _ }
|
89
|
+
| word_literal { word_literal _ }
|
90
|
+
| class { char_class _ }
|
91
91
|
| regexp <Match>
|
92
92
|
| ~'.' { Match[/./] }
|
93
93
|
|
@@ -10,26 +10,37 @@ require 'rattler/parsers'
|
|
10
10
|
module Rattler::Parsers
|
11
11
|
# @private
|
12
12
|
class ActionCode #:nodoc:
|
13
|
-
|
13
|
+
|
14
14
|
def initialize(code)
|
15
15
|
if md = /\A\s*\|([^|]*)\|(.*)\Z/.match(code)
|
16
16
|
@param_names = md[1].split(',').map {|_| _.strip }
|
17
17
|
@body = md[2].strip
|
18
18
|
else
|
19
19
|
@param_names = []
|
20
|
-
@body = code
|
20
|
+
@body = code.strip
|
21
21
|
end
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
attr_reader :param_names, :body
|
25
|
-
|
25
|
+
|
26
26
|
def bind(*args)
|
27
27
|
bindings = {}
|
28
|
-
|
28
|
+
if args.first.respond_to?(:to_ary)
|
29
|
+
a = args.shift
|
30
|
+
bindings.merge!(blank_binding(a)).merge!(arg_bindings(a))
|
31
|
+
end
|
29
32
|
bindings.merge!(args.shift) unless args.empty?
|
30
33
|
bind_in body, bindings
|
31
34
|
end
|
32
|
-
|
35
|
+
|
36
|
+
def blank_binding(args)
|
37
|
+
case args.size
|
38
|
+
when 0 then {}
|
39
|
+
when 1 then { '_' => args.first }
|
40
|
+
else { '_' => '[' + args.join(', ') + ']' }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
33
44
|
def arg_bindings(args)
|
34
45
|
if param_names.count > args.count
|
35
46
|
raise ArgumentError, 'more parameter names than arguments'
|
@@ -38,9 +49,9 @@ module Rattler::Parsers
|
|
38
49
|
param_names.zip(args).each {|name, arg| bindings[name] = arg if name }
|
39
50
|
bindings
|
40
51
|
end
|
41
|
-
|
52
|
+
|
42
53
|
private
|
43
|
-
|
54
|
+
|
44
55
|
def bind_in(code, bindings)
|
45
56
|
new_code = code
|
46
57
|
bindings.each do |k, v|
|
@@ -49,6 +60,6 @@ module Rattler::Parsers
|
|
49
60
|
end
|
50
61
|
new_code
|
51
62
|
end
|
52
|
-
|
63
|
+
|
53
64
|
end
|
54
65
|
end
|
data/lib/rattler/parsers/fail.rb
CHANGED
@@ -14,7 +14,7 @@ module Rattler::Parsers
|
|
14
14
|
#
|
15
15
|
# @author Jason Arhart
|
16
16
|
#
|
17
|
-
class Fail <
|
17
|
+
class Fail < Parser
|
18
18
|
|
19
19
|
# @private
|
20
20
|
def self.parsed(results, *_) #:nodoc:
|
@@ -51,5 +51,11 @@ module Rattler::Parsers
|
|
51
51
|
false
|
52
52
|
end
|
53
53
|
|
54
|
+
# Always +false+
|
55
|
+
# @return false
|
56
|
+
def capturing?
|
57
|
+
false
|
58
|
+
end
|
59
|
+
|
54
60
|
end
|
55
61
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
#
|
2
|
+
# = rattler/parsers/list.rb
|
3
|
+
#
|
4
|
+
# Author:: Jason Arhart
|
5
|
+
# Documentation:: Author
|
6
|
+
#
|
7
|
+
|
8
|
+
require 'rattler/parsers'
|
9
|
+
|
10
|
+
module Rattler::Parsers
|
11
|
+
#
|
12
|
+
# +List+ matches terms matched by a term parser in a list with separators
|
13
|
+
# matched by a separator parser. +List+ always matches even if there are no
|
14
|
+
# matched terms.
|
15
|
+
#
|
16
|
+
# @author Jason Arhart
|
17
|
+
#
|
18
|
+
class List < Parser
|
19
|
+
include Combining
|
20
|
+
|
21
|
+
# @private
|
22
|
+
def self.parsed(results, *_) #:nodoc:
|
23
|
+
self[*results]
|
24
|
+
end
|
25
|
+
|
26
|
+
# Create a new list parser that matches terms with +term_parser+ and
|
27
|
+
# separators with +sep_parser+
|
28
|
+
def self.[](term_parser, sep_parser)
|
29
|
+
self.new(term_parser, :sep_parser => sep_parser)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Parse terms matched by the term parser in a list with separators matched
|
33
|
+
# by the separator parser. Return the terms in an array, or +true+ if the
|
34
|
+
# term parser is not <tt>capturing?</tt>.
|
35
|
+
#
|
36
|
+
# @param (see Parser#parse_labeled)
|
37
|
+
#
|
38
|
+
# @return [Array, true] an array containing the term parser's parse results,
|
39
|
+
# or +true+ if the term parser is not <tt>capturing?</tt>
|
40
|
+
def parse(scanner, rules, labeled = {})
|
41
|
+
a = []
|
42
|
+
p = scanner.pos
|
43
|
+
while result = child.parse(scanner, rules)
|
44
|
+
p = scanner.pos
|
45
|
+
a << result
|
46
|
+
break unless sep_parser.parse(scanner, rules)
|
47
|
+
end
|
48
|
+
scanner.pos = p
|
49
|
+
capturing? ? a : true
|
50
|
+
end
|
51
|
+
|
52
|
+
def variable_capture_count?
|
53
|
+
true
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
#
|
2
|
+
# = rattler/parsers/list1.rb
|
3
|
+
#
|
4
|
+
# Author:: Jason Arhart
|
5
|
+
# Documentation:: Author
|
6
|
+
#
|
7
|
+
|
8
|
+
require 'rattler/parsers'
|
9
|
+
|
10
|
+
module Rattler::Parsers
|
11
|
+
#
|
12
|
+
# +List1+ matches terms matched by a term parser in a list with separators
|
13
|
+
# matched by a separator parser. +List1+ fails unless at least one term is
|
14
|
+
# matched.
|
15
|
+
#
|
16
|
+
# @author Jason Arhart
|
17
|
+
#
|
18
|
+
class List1 < Parser
|
19
|
+
include Combining
|
20
|
+
|
21
|
+
# @private
|
22
|
+
def self.parsed(results, *_) #:nodoc:
|
23
|
+
self[*results]
|
24
|
+
end
|
25
|
+
|
26
|
+
# Create a new list1 parser that matches terms with +term_parser+ and
|
27
|
+
# separators with +sep_parser+
|
28
|
+
def self.[](term_parser, sep_parser)
|
29
|
+
self.new(term_parser, :sep_parser => sep_parser)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Parse terms matched by the term parser in a list with separators matched
|
33
|
+
# by the separator parser. Return the terms in an array, or +true+ if the
|
34
|
+
# term parser is not <tt>capturing?</tt>, or +false+ if no terms matched..
|
35
|
+
#
|
36
|
+
# @param (see Parser#parse_labeled)
|
37
|
+
#
|
38
|
+
# @return [Array, true] an array containing the term parser's parse results,
|
39
|
+
# or +true+ if the term parser is not <tt>capturing?</tt>, or +false+ if
|
40
|
+
# no terms matched.
|
41
|
+
def parse(scanner, rules, labeled = {})
|
42
|
+
a = []
|
43
|
+
p = scanner.pos
|
44
|
+
while result = child.parse(scanner, rules)
|
45
|
+
p = scanner.pos
|
46
|
+
a << result
|
47
|
+
break unless sep_parser.parse(scanner, rules)
|
48
|
+
end
|
49
|
+
scanner.pos = p
|
50
|
+
(capturing? ? a : true) unless a.empty?
|
51
|
+
end
|
52
|
+
|
53
|
+
def variable_capture_count?
|
54
|
+
true
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
@@ -15,7 +15,7 @@ module Rattler
|
|
15
15
|
# @author Jason Arhart
|
16
16
|
#
|
17
17
|
class ParserDSL
|
18
|
-
|
18
|
+
|
19
19
|
# Define parse rules with the given block
|
20
20
|
#
|
21
21
|
# @option options [Parser] ws (nil) a parser to be used to skip whitespace
|
@@ -25,27 +25,27 @@ module Rattler
|
|
25
25
|
def self.rules(options = {}, &block)
|
26
26
|
self.new(options).rules(&block)
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
# @private
|
30
30
|
def initialize(options = {}) #:nodoc:
|
31
31
|
@rules = options[:rules] || []
|
32
32
|
@options = options
|
33
33
|
@ws = options[:ws]
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
# @private
|
37
37
|
def with_options(options, &block) #:nodoc:
|
38
38
|
dsl = self.class.new(@options.merge(:rules => @rules).merge(options))
|
39
39
|
dsl.instance_exec(dsl, &block)
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
# Evaluate the given block using +ws+ to skip whitespace
|
43
43
|
#
|
44
44
|
# @param [Parser] ws the parser to be used to skip whitespace
|
45
45
|
def with_ws(ws, &block)
|
46
46
|
with_options(:ws => to_parser(ws), &block)
|
47
47
|
end
|
48
|
-
|
48
|
+
|
49
49
|
# Evaluate the given block to define parse rules
|
50
50
|
#
|
51
51
|
# @return [Rules] the rules defined in the block
|
@@ -53,7 +53,7 @@ module Rattler
|
|
53
53
|
instance_exec(self, &block)
|
54
54
|
Rules[@rules]
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
# Evaluate the given block to define a parse rule
|
58
58
|
#
|
59
59
|
# @param [Symbol] name the name for the rule
|
@@ -64,7 +64,7 @@ module Rattler
|
|
64
64
|
@rules << Rule[name, (@ws ? parser.with_ws(@ws) : parser)]
|
65
65
|
@rules.last
|
66
66
|
end
|
67
|
-
|
67
|
+
|
68
68
|
# Create a new parser to match a pattern, literal, referenced parse rule,
|
69
69
|
# posix character class, or EOF.
|
70
70
|
#
|
@@ -108,7 +108,7 @@ module Rattler
|
|
108
108
|
else match Regexp.new(Regexp.escape(arg.to_s))
|
109
109
|
end
|
110
110
|
end
|
111
|
-
|
111
|
+
|
112
112
|
# Create a new optional parser.
|
113
113
|
#
|
114
114
|
# @overload optional(parser)
|
@@ -120,7 +120,7 @@ module Rattler
|
|
120
120
|
def optional(arg)
|
121
121
|
Optional[to_parser(arg)]
|
122
122
|
end
|
123
|
-
|
123
|
+
|
124
124
|
# Create a new zero-or-more parser.
|
125
125
|
#
|
126
126
|
# @overload zero_or_more(parser)
|
@@ -132,7 +132,7 @@ module Rattler
|
|
132
132
|
def zero_or_more(arg)
|
133
133
|
ZeroOrMore[to_parser(arg)]
|
134
134
|
end
|
135
|
-
|
135
|
+
|
136
136
|
# Create a new one-or-more parser.
|
137
137
|
#
|
138
138
|
# @overload one_or_more(parser)
|
@@ -144,7 +144,29 @@ module Rattler
|
|
144
144
|
def one_or_more(arg)
|
145
145
|
OneOrMore[to_parser(arg)]
|
146
146
|
end
|
147
|
-
|
147
|
+
|
148
|
+
# Create a new list parser.
|
149
|
+
#
|
150
|
+
# @overload list(term_parser, sep_parser)
|
151
|
+
# @return [List] a new list parser
|
152
|
+
# @overload list(term_arg, sep_arg)
|
153
|
+
# @return [List] a new list parser using args to define a match parsers
|
154
|
+
# @see #match
|
155
|
+
def list(term_arg, sep_arg)
|
156
|
+
List[to_parser(term_arg), to_parser(sep_arg)]
|
157
|
+
end
|
158
|
+
|
159
|
+
# Create a new list1 parser.
|
160
|
+
#
|
161
|
+
# @overload list(term_parser, sep_parser)
|
162
|
+
# @return [List1] a new list1 parser
|
163
|
+
# @overload list(term_arg, sep_arg)
|
164
|
+
# @return [List1] a new list1 parser using args to define match parsers
|
165
|
+
# @see #match
|
166
|
+
def list1(term_arg, sep_arg)
|
167
|
+
List1[to_parser(term_arg), to_parser(sep_arg)]
|
168
|
+
end
|
169
|
+
|
148
170
|
# Create a new assert parser.
|
149
171
|
#
|
150
172
|
# @overload assert(parser)
|
@@ -156,7 +178,7 @@ module Rattler
|
|
156
178
|
def assert(arg)
|
157
179
|
Assert[to_parser(arg)]
|
158
180
|
end
|
159
|
-
|
181
|
+
|
160
182
|
# Create a new disallow parser.
|
161
183
|
#
|
162
184
|
# @overload disallow(parser)
|
@@ -168,12 +190,12 @@ module Rattler
|
|
168
190
|
def disallow(arg)
|
169
191
|
Disallow[to_parser(arg)]
|
170
192
|
end
|
171
|
-
|
193
|
+
|
172
194
|
# @return the eof parser
|
173
195
|
def eof
|
174
196
|
Eof[]
|
175
197
|
end
|
176
|
-
|
198
|
+
|
177
199
|
# Create a new symantic action that dispatches to a method.
|
178
200
|
#
|
179
201
|
# @overload dispatch_action(parser)
|
@@ -185,9 +207,9 @@ module Rattler
|
|
185
207
|
def dispatch_action(arg, attrs={})
|
186
208
|
DispatchAction[to_parser(arg), attrs]
|
187
209
|
end
|
188
|
-
|
210
|
+
|
189
211
|
# alias action dispatch_action
|
190
|
-
|
212
|
+
|
191
213
|
# Create a new symantic action that evaluates ruby code.
|
192
214
|
#
|
193
215
|
# @overload direct_action(parser, code)
|
@@ -199,7 +221,7 @@ module Rattler
|
|
199
221
|
def direct_action(arg, code)
|
200
222
|
DirectAction[to_parser(arg), code]
|
201
223
|
end
|
202
|
-
|
224
|
+
|
203
225
|
# Create a new token parser or token rule.
|
204
226
|
#
|
205
227
|
# @overload token(rule_name, &block)
|
@@ -216,7 +238,7 @@ module Rattler
|
|
216
238
|
Token[to_parser(arg)]
|
217
239
|
end
|
218
240
|
end
|
219
|
-
|
241
|
+
|
220
242
|
# Create a new skip parser.
|
221
243
|
#
|
222
244
|
# @overload skip(parser)
|
@@ -228,7 +250,7 @@ module Rattler
|
|
228
250
|
def skip(arg)
|
229
251
|
Skip[to_parser(arg)]
|
230
252
|
end
|
231
|
-
|
253
|
+
|
232
254
|
# Create a new labeled parser.
|
233
255
|
#
|
234
256
|
# @overload label(parser)
|
@@ -240,89 +262,89 @@ module Rattler
|
|
240
262
|
def label(name, arg)
|
241
263
|
Label[name, to_parser(arg)]
|
242
264
|
end
|
243
|
-
|
265
|
+
|
244
266
|
# @return [Fail] a parser that always fails
|
245
267
|
def fail(message)
|
246
268
|
Fail[:expr, message]
|
247
269
|
end
|
248
|
-
|
270
|
+
|
249
271
|
# @return [Fail] a parser that fails the entire rule
|
250
272
|
def fail_rule(message)
|
251
273
|
Fail[:rule, message]
|
252
274
|
end
|
253
|
-
|
275
|
+
|
254
276
|
# @return [Fail] a parser that fails the entire parse
|
255
277
|
def fail_parse(message)
|
256
278
|
Fail[:parse, message]
|
257
279
|
end
|
258
|
-
|
280
|
+
|
259
281
|
# @return [Match] a parser matching any character
|
260
282
|
def any
|
261
283
|
match /./
|
262
284
|
end
|
263
|
-
|
285
|
+
|
264
286
|
# @return [Match] a parser matching the POSIX +alnum+ character class
|
265
287
|
def alnum
|
266
288
|
match :ALNUM
|
267
289
|
end
|
268
|
-
|
290
|
+
|
269
291
|
# @return [Match] a parser matching the POSIX +alpha+ character class
|
270
292
|
def alpha
|
271
293
|
match :ALPHA
|
272
294
|
end
|
273
|
-
|
295
|
+
|
274
296
|
# @return [Match] a parser matching the POSIX +blank+ character class
|
275
297
|
def blank
|
276
298
|
match :BLANK
|
277
299
|
end
|
278
|
-
|
300
|
+
|
279
301
|
# @return [Match] a parser matching the POSIX +cntrl+ character class
|
280
302
|
def cntrl
|
281
303
|
match :CNTRL
|
282
304
|
end
|
283
|
-
|
305
|
+
|
284
306
|
# @return [Match] a parser matching the POSIX +digit+ character class
|
285
307
|
def digit
|
286
308
|
match :DIGIT
|
287
309
|
end
|
288
|
-
|
310
|
+
|
289
311
|
# @return [Match] a parser matching the POSIX +graph+ character class
|
290
312
|
def graph
|
291
313
|
match :GRAPH
|
292
314
|
end
|
293
|
-
|
315
|
+
|
294
316
|
# @return [Match] a parser matching the POSIX +lower+ character class
|
295
317
|
def lower
|
296
318
|
match :LOWER
|
297
319
|
end
|
298
|
-
|
320
|
+
|
299
321
|
# @return [Match] a parser matching the POSIX +print+ character class
|
300
322
|
def print
|
301
323
|
match :PRINT
|
302
324
|
end
|
303
|
-
|
325
|
+
|
304
326
|
# @return [Match] a parser matching the POSIX +punct+ character class
|
305
327
|
def punct
|
306
328
|
match :PUNCT
|
307
329
|
end
|
308
|
-
|
330
|
+
|
309
331
|
# @return [Match] a parser matching the POSIX +space+ character class
|
310
332
|
def space
|
311
333
|
match :SPACE
|
312
334
|
end
|
313
|
-
|
335
|
+
|
314
336
|
# @return [Match] a parser matching the POSIX +upper+ character class
|
315
337
|
def upper
|
316
338
|
match :UPPER
|
317
339
|
end
|
318
|
-
|
340
|
+
|
319
341
|
# @return [Match] a parser matching the POSIX +xdigit+ character class
|
320
342
|
def xdigit
|
321
343
|
match :XDIGIT
|
322
344
|
end
|
323
|
-
|
345
|
+
|
324
346
|
private
|
325
|
-
|
347
|
+
|
326
348
|
def to_parser(o)
|
327
349
|
case o
|
328
350
|
when Parser then o
|
@@ -331,7 +353,7 @@ module Rattler
|
|
331
353
|
else match(o)
|
332
354
|
end
|
333
355
|
end
|
334
|
-
|
356
|
+
|
335
357
|
end
|
336
358
|
end
|
337
359
|
end
|
data/lib/rattler/parsers.rb
CHANGED
@@ -14,7 +14,7 @@ module Rattler
|
|
14
14
|
# @author Jason Arhart
|
15
15
|
#
|
16
16
|
module Parsers
|
17
|
-
|
17
|
+
|
18
18
|
autoload :Parser, 'rattler/parsers/parser'
|
19
19
|
autoload :Rules, 'rattler/parsers/rules'
|
20
20
|
autoload :Rule, 'rattler/parsers/rule'
|
@@ -24,6 +24,8 @@ module Rattler
|
|
24
24
|
autoload :Optional, 'rattler/parsers/optional'
|
25
25
|
autoload :ZeroOrMore, 'rattler/parsers/zero_or_more'
|
26
26
|
autoload :OneOrMore, 'rattler/parsers/one_or_more'
|
27
|
+
autoload :List, 'rattler/parsers/list'
|
28
|
+
autoload :List1, 'rattler/parsers/list1'
|
27
29
|
autoload :Apply, 'rattler/parsers/apply'
|
28
30
|
autoload :Assert, 'rattler/parsers/assert'
|
29
31
|
autoload :Disallow, 'rattler/parsers/disallow'
|
@@ -39,7 +41,7 @@ module Rattler
|
|
39
41
|
autoload :Combining, 'rattler/parsers/combining'
|
40
42
|
autoload :MatchJoining, 'rattler/parsers/match_joining'
|
41
43
|
autoload :ActionCode, 'rattler/parsers/action_code'
|
42
|
-
|
44
|
+
|
43
45
|
class <<self
|
44
46
|
# Define parse rules with the given block
|
45
47
|
#
|
@@ -49,6 +51,6 @@ module Rattler
|
|
49
51
|
ParserDSL.rules(&block)
|
50
52
|
end
|
51
53
|
end
|
52
|
-
|
54
|
+
|
53
55
|
end
|
54
56
|
end
|