Class: Grammar
- Inherits:
-
Object
- Object
- Grammar
- Includes:
- Molecules
- Defined in:
- lib/grammar.rb,
lib/grammar/ruby.rb,
lib/grammar/ruby0.rb,
lib/grammar/rubycall.rb,
lib/grammar/ruby/code.rb,
lib/grammar/ruby2cext.rb,
lib/grammar/ruby2cext_hack.rb
Overview
The Grammar class defines operators and methods that allow Grammars to be built in a tree. The result is similar to BNF seen in other parser generators. No actual parsing is done by this class. That is up to an engine.
Defined Under Namespace
Modules: Molecules Classes: Ruby, Ruby0, Ruby2CExt, RubyCall
Constant Summary
Constants included from Molecules
Molecules::ANY, Molecules::EOF, Molecules::NULL
Instance Method Summary collapse
-
#*(mult) ⇒ Object
Grammar that matches
self
replicatedmultiplier
times. -
#+(other) ⇒ Object
Grammar that matches
self
followed byother
. -
#+@ ⇒ Object
Zero-width Grammar that matches
self
(discards results). -
#-@ ⇒ Object
Zero-width Grammar that matches anything but
self
(discards results). -
#<<(gram) ⇒ Object
Replaces the contained lambda with one from another Grammar.
-
#[](engine) ⇒ Object
Executes the Grammar with an engine.
-
#backref(&block) ⇒ Object
not sure if this is needed or wanted right now.
-
#backtrack(len = nil) ⇒ Object
Grammar that matches
self
, but backtracks when it fails instead of raising an error. -
#discard(&block) ⇒ Object
Grammar that discards parsing results of
self
and afterwards yields the engine to the optional block which should return something to be appended to the output. -
#group(buf0, &block) ⇒ Object
Grammar that redirects parsing results of
self
to abuf0
.clone and yields the resulting buffer and possibly the engine afterwards to an optional block which should return something to be appended to the output. -
#initialize(&block) ⇒ Grammar
constructor
Create a Grammar from a block.
-
#optional ⇒ Object
Grammar that optionally matches
self
. -
#pipe(parser, buf0, len = nil, &block) ⇒ Object
Grammar that uses
self
as a lexer to generate tokens forparser
which sends its results to the output. -
#redirect(buf0, &block) ⇒ Object
Grammar that redirects parsing results of
self
to abuf0
.clone and yields the resulting buffer and possibly the engine afterwards. -
#repeat0(term = nil) ⇒ Object
Grammar that matches a sequence of zero or more
self
followed by an optional terminator (term
). -
#repeat1(term = nil) ⇒ Object
Grammar that matches a sequence of one or more
self
followed by an optional terminator (term
). -
#supply(parser, buf0, &block) ⇒ Object
Grammar that uses a looped
self
as a lexer to generate tokens forparser
which sends its results to the output. -
#to_proc ⇒ Object
Returns the lambda that the Grammar holds.
-
#|(other) ⇒ Object
Grammar that matches
self
orother
if that fails. -
#~ ⇒ Object
Grammar that as long as what follows doesn’t match
self
, it matches to the next element.
Methods included from Molecules
#Always, #Chain, #Check, #Common, #Element, #Fail, #Grammar, #Output, #Recurse, #Variables
Constructor Details
#initialize(&block) ⇒ Grammar
Create a Grammar from a block. The block is passed a Grammar engine which should be used to do any parsing.
17 18 19 |
# File 'lib/grammar.rb', line 17 def initialize(&block) # :yield: engine @block = block end |
Instance Method Details
#*(mult) ⇒ Object
Grammar that matches self
replicated multiplier
times. multiplier
can be a Range to specify a variable multiplier. The multiplier
just needs to responds to #=== to determine the min and max iterations.
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/grammar.rb', line 82 def *(mult) Common { |e| Variables(0) { |i| case mult when Fixnum start = Check { e[mult].equal?(i << i[] + e[1]) } inside = Fail() when Range start = case (range0=mult.begin) when Fixnum; Check { e[range0].equal?(i << i[] + e[1]) } else; Check { e[range0] <= (i << i[] + e[1]) } end range1 = mult.end mult.exclude_end? or range1 = begin;range1.succ;rescue;range1+1;end inside = case range1 when Fixnum; Check { e.not(e[range1].equal?(i << i[] + e[1])) } when 1.0/0; NULL else; Check { e[range1] > (i << i[] + e[1]) } end else start = inside = Check { e[mult] === (i << i[] + e[1]) } end tail = Recurse { |l| l + inside + self | NULL } ((mult===0) ? tail : Recurse { |r| self + (start + tail | r) }) } } end |
#+(other) ⇒ Object
Grammar that matches self
followed by other
.
38 39 40 |
# File 'lib/grammar.rb', line 38 def +(other) Grammar { |e| e.sequence(self.to_proc, &other) } end |
#+@ ⇒ Object
Zero-width Grammar that matches self
(discards results).
42 43 44 |
# File 'lib/grammar.rb', line 42 def +@ Grammar { |e| e.positive(&self) } end |
#-@ ⇒ Object
Zero-width Grammar that matches anything but self
(discards results).
46 47 48 |
# File 'lib/grammar.rb', line 46 def -@ Grammar { |e| e.negative(&self) } end |
#<<(gram) ⇒ Object
Replaces the contained lambda with one from another Grammar.
30 31 32 |
# File 'lib/grammar.rb', line 30 def <<(gram) @block = gram && gram.to_proc end |
#[](engine) ⇒ Object
Executes the Grammar with an engine. The engine simply gets passed to the block (actually a lambda now) contained in the Grammar.
22 23 24 |
# File 'lib/grammar.rb', line 22 def [](engine) @block[engine] end |
#backref(&block) ⇒ Object
not sure if this is needed or wanted right now
134 135 136 |
# File 'lib/grammar.rb', line 134 def backref(&block) # :nodoc: :yield: n[, engine] Grammar { |e| e.backref(self.to_proc, &block) } end |
#backtrack(len = nil) ⇒ Object
Grammar that matches self
, but backtracks when it fails instead of raising an error.
139 140 141 |
# File 'lib/grammar.rb', line 139 def backtrack(len=nil) Grammar { |e| e.backtrack(self.to_proc, len) } end |
#discard(&block) ⇒ Object
Grammar that discards parsing results of self
and afterwards yields the engine to the optional block which should return something to be appended to the output.
119 120 121 |
# File 'lib/grammar.rb', line 119 def discard(&block) # :yield: engine Grammar { |e| e.discard(self.to_proc, &block) } end |
#group(buf0, &block) ⇒ Object
Grammar that redirects parsing results of self
to a buf0
.clone and yields the resulting buffer and possibly the engine afterwards to an optional block which should return something to be appended to the output.
126 127 128 129 130 131 132 |
# File 'lib/grammar.rb', line 126 def group(buf0, &block) # :yield: buf[, engine] block_given? ? redirect(buf0) { |buf, e| e << (block.arity==1 ? yield(buf) : yield(buf, e)) } : redirect(buf0) { |buf, e| e << buf } end |
#optional ⇒ Object
Grammar that optionally matches self
.
55 56 57 |
# File 'lib/grammar.rb', line 55 def optional self | NULL end |
#pipe(parser, buf0, len = nil, &block) ⇒ Object
Grammar that uses self
as a lexer to generate tokens for parser
which sends its results to the output. buf0
.clone is used hold tokens between the lexer and the parser.
153 154 155 156 157 |
# File 'lib/grammar.rb', line 153 def pipe(parser, buf0, len=nil, &block) # :yield: buf[, engine] Grammar { |e| e.pipe(self.to_proc, parser.to_proc, buf0, len, &block) } end |
#redirect(buf0, &block) ⇒ Object
Grammar that redirects parsing results of self
to a buf0
.clone and yields the resulting buffer and possibly the engine afterwards.
113 114 115 |
# File 'lib/grammar.rb', line 113 def redirect(buf0, &block) # :yield: buf[, engine] Grammar { |e| e.redirect(self.to_proc, buf0, &block) } end |
#repeat0(term = nil) ⇒ Object
Grammar that matches a sequence of zero or more self
followed by an optional terminator (term
). If term
is given it takes precedence over matching self
items.
61 62 63 64 65 66 67 |
# File 'lib/grammar.rb', line 61 def repeat0(term=nil) if term Recurse { |g| term | self + g } else Recurse { |g| g + self | NULL } end end |
#repeat1(term = nil) ⇒ Object
Grammar that matches a sequence of one or more self
followed by an optional terminator (term
). If term
is given it takes precedence over matching self
items.
71 72 73 74 75 76 77 |
# File 'lib/grammar.rb', line 71 def repeat1(term=nil) if term Recurse { |g| self + (term | g) } else Recurse { |g| (g | NULL) + self } end end |
#supply(parser, buf0, &block) ⇒ Object
Grammar that uses a looped self
as a lexer to generate tokens for parser
which sends its results to the output. buf0
.clone is used hold tokens between the lexer and the parser.
145 146 147 148 149 |
# File 'lib/grammar.rb', line 145 def supply(parser, buf0, &block) # :yield: buf[, engine] Grammar { |e| e.supply(self.to_proc, parser.to_proc, buf0, &block) } end |
#to_proc ⇒ Object
Returns the lambda that the Grammar holds.
26 27 28 |
# File 'lib/grammar.rb', line 26 def to_proc @block end |
#|(other) ⇒ Object
Grammar that matches self
or other
if that fails.
34 35 36 |
# File 'lib/grammar.rb', line 34 def |(other) Grammar { |e| e.alternation(self.to_proc, &other) } end |
#~ ⇒ Object
Grammar that as long as what follows doesn’t match self
, it matches to the next element. Most useful for a single element Grammar.
51 52 53 |
# File 'lib/grammar.rb', line 51 def ~ -self + ANY end |