Commit f5c5695
Changed files (11)
lib/mpeg/alternative.rb
@@ -0,0 +1,12 @@
+module Mpeg
+ class Alternative < Base
+ def initialize(left, right)
+ @left = left
+ @right = right
+ end
+
+ def call(input)
+ @left.call(input) || @right.call(input)
+ end
+ end
+end
lib/mpeg/base.rb
@@ -0,0 +1,23 @@
+module Mpeg
+ class Base
+ def parse(string)
+ call(Input.new(string))
+ end
+
+ def repeat(min = 0, max = nil)
+ Repitition.new(self, min, max)
+ end
+
+ def |(parser)
+ Alternative.new(self, parser)
+ end
+
+ def >>(parser)
+ Sequence.new(self, parser)
+ end
+
+ def absent?
+ Lookahead.new(self, false)
+ end
+ end
+end
lib/mpeg/input.rb
@@ -0,0 +1,18 @@
+module Mpeg
+ class Input
+ def initialize(string)
+ @scanner = StringScanner.new(string)
+ end
+
+ def matches?(pattern)
+ @scanner.match?(pattern)
+ end
+
+ def consume(characters)
+ position = @scanner.pos
+ slice = @scanner.scan(/(.|$){#{characters}}/m)
+
+ Slice.new(position, slice)
+ end
+ end
+end
lib/mpeg/lookahead.rb
@@ -0,0 +1,8 @@
+module Mpeg
+ class Lookahead < Base
+ def initialize(parser, positive)
+ @parser = parser
+ @positive = positive
+ end
+ end
+end
lib/mpeg/parser.rb
@@ -1,124 +1,4 @@
module Mpeg
- class Base
- def parse(string)
- call(Input.new(string))
- end
-
- def repeat(min = 0, max = nil)
- Repitition.new(self, min, max)
- end
-
- def |(parser)
- Alternative.new(self, parser)
- end
-
- def >>(parser)
- Sequence.new(self, parser)
- end
-
- def absent?
- Lookahead.new(self, false)
- end
- end
-
- class Slice
- def initialize(position, string)
- end
- end
-
- class Input
- def initialize(string)
- @scanner = StringScanner.new(string)
- end
-
- def matches?(pattern)
- @scanner.match?(pattern)
- end
-
- def consume(characters)
- position = @scanner.pos
- slice = @scanner.scan(/(.|$){#{characters}}/m)
-
- Slice.new(position, slice)
- end
- end
-
- class Lookahead < Base
- def initialize(parser, positive)
- @parser = parser
- @positive = positive
- end
- end
-
- class Sequence < Base
- def initialize(left, right)
- @left = left
- @right = right
- end
-
- def call(input)
- @left.call(input) && @right.call(input)
- end
- end
-
- class Alternative < Base
- def initialize(left, right)
- @left = left
- @right = right
- end
-
- def call(input)
- @left.call(input) || @right.call(input)
- end
- end
-
- class Repitition < Base
- def initialize(parser, min, max)
- @parser = parser
- @min = min
- @max = max
- end
-
- def call(input)
- occurrences = 0
- loop do
- break unless @parser.call(input)
- occurrences += 1
- return false if @max && occurrences > @max
- end
- occurrences >= @min
- end
- end
-
- class Re < Base
- def initialize(regex)
- @regex = Regexp.new("[#{regex}]", Regexp::MULTILINE)
- end
-
- def call(input)
- if input.matches?(@regex)
- input.consume(1)
- return true
- end
- false
- end
- end
-
- class Str < Base
- def initialize(string)
- @length = string.size
- @regex = Regexp.new(Regexp.escape(string))
- end
-
- def call(input)
- if input.matches?(@regex)
- input.consume(1)
- return true
- end
- false
- end
- end
-
class Parser
def parse(string)
root.parse(string)
lib/mpeg/re.rb
@@ -0,0 +1,15 @@
+module Mpeg
+ class Re < Base
+ def initialize(regex)
+ @regex = Regexp.new("[#{regex}]", Regexp::MULTILINE)
+ end
+
+ def call(input)
+ if input.matches?(@regex)
+ input.consume(1)
+ return true
+ end
+ false
+ end
+ end
+end
lib/mpeg/repitition.rb
@@ -0,0 +1,19 @@
+module Mpeg
+ class Repitition < Base
+ def initialize(parser, min, max)
+ @parser = parser
+ @min = min
+ @max = max
+ end
+
+ def call(input)
+ occurrences = 0
+ loop do
+ break unless @parser.call(input)
+ occurrences += 1
+ return false if @max && occurrences > @max
+ end
+ occurrences >= @min
+ end
+ end
+end
lib/mpeg/sequence.rb
@@ -0,0 +1,12 @@
+module Mpeg
+ class Sequence < Base
+ def initialize(left, right)
+ @left = left
+ @right = right
+ end
+
+ def call(input)
+ @left.call(input) && @right.call(input)
+ end
+ end
+end
lib/mpeg/slice.rb
@@ -0,0 +1,6 @@
+module Mpeg
+ class Slice
+ def initialize(position, string)
+ end
+ end
+end
lib/mpeg/str.rb
@@ -0,0 +1,16 @@
+module Mpeg
+ class Str < Base
+ def initialize(string)
+ @length = string.size
+ @regex = Regexp.new(Regexp.escape(string))
+ end
+
+ def call(input)
+ if input.matches?(@regex)
+ input.consume(1)
+ return true
+ end
+ false
+ end
+ end
+end
lib/mpeg.rb
@@ -1,5 +1,16 @@
-require "mpeg/parser"
require "mpeg/version"
+require "mpeg/base"
+
+require "mpeg/alternative"
+require "mpeg/input"
+require "mpeg/lookahead"
+require "mpeg/parser"
+require "mpeg/parser"
+require "mpeg/re"
+require "mpeg/repitition"
+require "mpeg/sequence"
+require "mpeg/slice"
+require "mpeg/str"
module Mpeg
class Error < StandardError; end