grammar 0.5 → 0.8
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/benchmark/json.benchmark.rb +355 -0
- data/benchmark/json.grammar.rb +56 -0
- data/benchmark/json.grammar0_5.rb +57 -0
- data/benchmark/json.ll1.rb +155 -0
- data/benchmark/json.peggy.rb +174 -0
- data/benchmark/json.re.rb +81 -0
- data/lib/grammar.rb +212 -639
- data/lib/grammar/ruby.rb +606 -0
- data/lib/grammar/ruby/code.rb +1030 -0
- data/lib/grammar/ruby0.rb +521 -0
- data/lib/grammar/ruby2cext.rb +19 -0
- data/lib/grammar/rubycall.rb +21 -0
- data/test/advanced.rb +105 -0
- data/test/atoms.rb +77 -0
- data/test/basic.rb +32 -0
- data/test/composite.rb +147 -0
- data/test/molecules.rb +125 -0
- data/test/test_demo.rb +200 -0
- data/test/test_ruby.rb +30 -0
- data/test/test_ruby0.rb +30 -0
- data/test/test_ruby2cext.rb +30 -0
- data/test/test_rubycall.rb +30 -0
- metadata +45 -28
- data/samples/fact.tcl +0 -12
- data/samples/infix2postfix.rb +0 -114
- data/samples/tcl.rb +0 -163
- data/samples/test.infix +0 -4
- data/test/test_grammar.rb +0 -274
| @@ -0,0 +1,19 @@ | |
| 1 | 
            +
             | 
| 2 | 
            +
            require 'grammar/ruby'
         | 
| 3 | 
            +
            require 'rubygems'
         | 
| 4 | 
            +
            require 'ruby2cext/eval2c'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            class Grammar
         | 
| 7 | 
            +
            class Ruby2CExt < Ruby
         | 
| 8 | 
            +
                
         | 
| 9 | 
            +
                def self.compile(gram)
         | 
| 10 | 
            +
                    code = new.dump(gram)
         | 
| 11 | 
            +
                    #p(code)
         | 
| 12 | 
            +
                    #code.lined
         | 
| 13 | 
            +
                    Ruby2CExtension::Eval2C.new.compile_to_proc(code.to_s).call.new
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            end
         | 
| 17 | 
            +
            end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
             | 
| @@ -0,0 +1,21 @@ | |
| 1 | 
            +
             | 
| 2 | 
            +
            require 'grammar/ruby'
         | 
| 3 | 
            +
            require 'rubygems'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            class Grammar
         | 
| 6 | 
            +
            class RubyCall < Ruby
         | 
| 7 | 
            +
                
         | 
| 8 | 
            +
                def self.compile(gram)
         | 
| 9 | 
            +
                    code = new.dump(gram)
         | 
| 10 | 
            +
                    #p(code)
         | 
| 11 | 
            +
                    #code.lined
         | 
| 12 | 
            +
                    eval(code.to_s).new
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
                def recurse(inner, expand=false, &outer) # :yield: engine
         | 
| 15 | 
            +
                    expand ? super : call(inner, &outer)
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            end
         | 
| 19 | 
            +
            end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
             | 
    
        data/test/advanced.rb
    ADDED
    
    | @@ -0,0 +1,105 @@ | |
| 1 | 
            +
            #!/bin/env ruby
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'stringio'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            require 'grammar'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            class Grammar
         | 
| 8 | 
            +
            module Test
         | 
| 9 | 
            +
            module Advanced
         | 
| 10 | 
            +
                include Grammar::Molecules
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                def test_positive
         | 
| 13 | 
            +
                    comp = engine.compile(+E(?a) + E(?a..?z))
         | 
| 14 | 
            +
                    assert(comp[out="", StringIO.new("ab").method(:getc)])
         | 
| 15 | 
            +
                    assert_equal("a", out)
         | 
| 16 | 
            +
                    assert_raise(error) { comp[out="", lambda { ?b }] }
         | 
| 17 | 
            +
                    assert_equal("", out)
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
                
         | 
| 20 | 
            +
                def test_negative
         | 
| 21 | 
            +
                    comp = engine.compile(-E(?a) + E(?a..?z))
         | 
| 22 | 
            +
                    assert(comp[out="", StringIO.new("ba").method(:getc)])
         | 
| 23 | 
            +
                    assert_equal("b", out)
         | 
| 24 | 
            +
                    assert_raise(error) { comp[out="", lambda { ?a }] }
         | 
| 25 | 
            +
                    assert_equal("", out)
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
                
         | 
| 28 | 
            +
                def test_redirect
         | 
| 29 | 
            +
                    comp = engine.compile((E(?a)+E(?b)).redirect("") { |buf, eng|
         | 
| 30 | 
            +
                        eng << buf.reverse
         | 
| 31 | 
            +
                    })
         | 
| 32 | 
            +
                    assert(comp[out=[], StringIO.new("ab").method(:getc)])
         | 
| 33 | 
            +
                    assert_equal(["ba"], out)
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
                
         | 
| 36 | 
            +
                def test_discard
         | 
| 37 | 
            +
                    comp = engine.compile(E(?a).discard+E(?b))
         | 
| 38 | 
            +
                    assert(comp[out="", StringIO.new("abb").method(:getc)])
         | 
| 39 | 
            +
                    assert_equal("b", out)
         | 
| 40 | 
            +
                    assert_raise(error) { comp[out="", lambda {?b}] }
         | 
| 41 | 
            +
                    assert_equal("", out)
         | 
| 42 | 
            +
                    comp = engine.compile((E(?a)+E(?b)).discard { |e| e[:ab] } + E(?c))
         | 
| 43 | 
            +
                    assert(comp[out=[], StringIO.new("abca").method(:getc)])
         | 
| 44 | 
            +
                    assert_equal([:ab,?c], out)
         | 
| 45 | 
            +
                    assert_raise(error) {
         | 
| 46 | 
            +
                        comp[out=[], StringIO.new("a").method(:getc)]
         | 
| 47 | 
            +
                    }
         | 
| 48 | 
            +
                    assert_equal([], out)
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
                
         | 
| 51 | 
            +
                #def test_backref
         | 
| 52 | 
            +
                #    comp = engine.compile(E(?a)+(E(?b)+E(?c)).backref { |n, engine|
         | 
| 53 | 
            +
                #        engine.output[-n,n] = engine.output[-n,n].reverse
         | 
| 54 | 
            +
                #    } + E(?d))
         | 
| 55 | 
            +
                #    assert(comp[out="", StringIO.new("abcdab").method(:getc)])
         | 
| 56 | 
            +
                #    assert_equal("acbd", out)
         | 
| 57 | 
            +
                #    assert_raise(error) {
         | 
| 58 | 
            +
                #        comp[out="", StringIO.new("ab").method(:getc)]
         | 
| 59 | 
            +
                #    }
         | 
| 60 | 
            +
                #    assert_equal("a", out)
         | 
| 61 | 
            +
                #end
         | 
| 62 | 
            +
                
         | 
| 63 | 
            +
                def test_backtrack
         | 
| 64 | 
            +
                    comp = engine.compile((E(?a)+E(?b)).backtrack|(E(?a)+E(?c)))
         | 
| 65 | 
            +
                    assert(comp[out="", StringIO.new("abac").method(:getc)])
         | 
| 66 | 
            +
                    assert_equal("ab", out)
         | 
| 67 | 
            +
                    assert(comp[out="", StringIO.new("ac").method(:getc)])
         | 
| 68 | 
            +
                    assert_equal("ac", out)
         | 
| 69 | 
            +
                end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                def test_supply
         | 
| 72 | 
            +
                    token = (E(?a)|E(?b)).redirect("") { |buf, eng|
         | 
| 73 | 
            +
                        eng << buf.capitalize.to_sym
         | 
| 74 | 
            +
                    }
         | 
| 75 | 
            +
                    parser = E(:A) + E(:B)
         | 
| 76 | 
            +
                    leftover = nil
         | 
| 77 | 
            +
                    # TODO: leftover
         | 
| 78 | 
            +
                    comp = engine.compile(token.supply(parser, [])) # { |l, eng| leftover = l}
         | 
| 79 | 
            +
                    assert(comp[out=[], StringIO.new("abba").method(:getc)])
         | 
| 80 | 
            +
                    assert_equal([:A, :B], out)
         | 
| 81 | 
            +
                    #assert_equal([:B], leftover)
         | 
| 82 | 
            +
                    assert_raise(error) { comp[out=[], lambda {?a}] }
         | 
| 83 | 
            +
                    assert_equal([:A], out)
         | 
| 84 | 
            +
                end
         | 
| 85 | 
            +
                
         | 
| 86 | 
            +
                def test_pipe
         | 
| 87 | 
            +
                    lexer = Recurse { |g| g + (E(?a)|E(?b)).redirect("") { |buf, eng|
         | 
| 88 | 
            +
                        eng << buf.capitalize.to_sym
         | 
| 89 | 
            +
                    } | NULL }
         | 
| 90 | 
            +
                    parser = E(:A) + E(:B)
         | 
| 91 | 
            +
                    leftover = nil
         | 
| 92 | 
            +
                    # TODO: leftover
         | 
| 93 | 
            +
                    comp = engine.compile(lexer.pipe(parser, [], 1)) # { |l, eng| leftover = l})
         | 
| 94 | 
            +
                    assert(comp[out=[], StringIO.new("abbba").method(:getc)])
         | 
| 95 | 
            +
                    assert_equal([:A, :B], out)
         | 
| 96 | 
            +
                    #assert_equal([:B, :B], leftover)
         | 
| 97 | 
            +
                    assert_raise(error) { comp[out=[], lambda {?a}] }
         | 
| 98 | 
            +
                    assert_equal([:A], out)
         | 
| 99 | 
            +
                end
         | 
| 100 | 
            +
                
         | 
| 101 | 
            +
            end
         | 
| 102 | 
            +
            end
         | 
| 103 | 
            +
            end
         | 
| 104 | 
            +
             | 
| 105 | 
            +
             | 
    
        data/test/atoms.rb
    ADDED
    
    | @@ -0,0 +1,77 @@ | |
| 1 | 
            +
            #!/bin/env ruby
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'stringio'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            require 'grammar'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            class Grammar
         | 
| 8 | 
            +
            module Test
         | 
| 9 | 
            +
            module Atoms
         | 
| 10 | 
            +
                include Grammar::Molecules
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                def test_Grammar
         | 
| 13 | 
            +
                    gram = Grammar { |eng| eng[true] }
         | 
| 14 | 
            +
                    comp = engine.compile(gram)
         | 
| 15 | 
            +
                    assert(comp[out="", lambda {}])
         | 
| 16 | 
            +
                    assert_equal("", out)
         | 
| 17 | 
            +
                    gram << E(?a)
         | 
| 18 | 
            +
                    comp = engine.compile(gram)
         | 
| 19 | 
            +
                    assert(comp[out="", lambda {?a}])
         | 
| 20 | 
            +
                    assert_equal("a", out)
         | 
| 21 | 
            +
                    assert_raise(error) {
         | 
| 22 | 
            +
                        comp[out="", lambda {}]
         | 
| 23 | 
            +
                    }
         | 
| 24 | 
            +
                    assert_equal("", out)
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
                
         | 
| 27 | 
            +
                def test_Element
         | 
| 28 | 
            +
                    comp = engine.compile(Element(?a))
         | 
| 29 | 
            +
                    assert(comp[out="", StringIO.new("abc").method(:getc)])
         | 
| 30 | 
            +
                    assert_equal("a", out)
         | 
| 31 | 
            +
                    assert_raise(error) {
         | 
| 32 | 
            +
                        comp[out="", StringIO.new("bc").method(:getc)]
         | 
| 33 | 
            +
                    }
         | 
| 34 | 
            +
                    assert_equal("", out)
         | 
| 35 | 
            +
                    comp = engine.compile(E(?a..?z))
         | 
| 36 | 
            +
                    assert(comp[out="", StringIO.new("bc").method(:getc)])
         | 
| 37 | 
            +
                    assert_equal("b", out)
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                def test_Fail
         | 
| 41 | 
            +
                    out = ""
         | 
| 42 | 
            +
                    comp = engine.compile(Fail("TESTING"))
         | 
| 43 | 
            +
                    assert_raise(error) { comp[out, lambda {}] }
         | 
| 44 | 
            +
                    assert_equal("", out)
         | 
| 45 | 
            +
                    assert_raise(error) { comp[out="", lambda { ?a }] }
         | 
| 46 | 
            +
                    assert_equal("", out)
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                def test_NULL
         | 
| 50 | 
            +
                    comp = engine.compile(NULL)
         | 
| 51 | 
            +
                    comp[out="", lambda {}]
         | 
| 52 | 
            +
                    assert_equal("", out)
         | 
| 53 | 
            +
                    comp[out="", lambda { ?a }]
         | 
| 54 | 
            +
                    assert_equal("", out)
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
                
         | 
| 57 | 
            +
                def test_ANY
         | 
| 58 | 
            +
                    comp = engine.compile(ANY)
         | 
| 59 | 
            +
                    comp[out="", lambda { ?a }]
         | 
| 60 | 
            +
                    assert_equal("a", out)
         | 
| 61 | 
            +
                    assert_raise(error) { comp[out="", lambda { }] }
         | 
| 62 | 
            +
                    assert_equal("", out)
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
                
         | 
| 65 | 
            +
                def test_EOF
         | 
| 66 | 
            +
                    comp = engine.compile(EOF)
         | 
| 67 | 
            +
                    comp[out="", lambda {}]
         | 
| 68 | 
            +
                    assert_equal("", out)
         | 
| 69 | 
            +
                    assert_raise(error) { comp[out="", lambda { ?a }] }
         | 
| 70 | 
            +
                    assert_equal("", out)
         | 
| 71 | 
            +
                end
         | 
| 72 | 
            +
                
         | 
| 73 | 
            +
            end
         | 
| 74 | 
            +
            end
         | 
| 75 | 
            +
            end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
             | 
    
        data/test/basic.rb
    ADDED
    
    | @@ -0,0 +1,32 @@ | |
| 1 | 
            +
            #!/bin/env ruby
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'stringio'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            require 'grammar'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            class Grammar
         | 
| 8 | 
            +
            module Test
         | 
| 9 | 
            +
            module Basic
         | 
| 10 | 
            +
                include Grammar::Molecules
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                def test_plus
         | 
| 13 | 
            +
                    comp = engine.compile(E(?a)+E(?a..?z))
         | 
| 14 | 
            +
                    assert(comp[out="", StringIO.new("ab").method(:getc)])
         | 
| 15 | 
            +
                    assert_equal("ab", out)
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
                
         | 
| 18 | 
            +
                def test_or
         | 
| 19 | 
            +
                    comp = engine.compile(E(?a)|E(?b))
         | 
| 20 | 
            +
                    assert(comp[out="", StringIO.new("abc").method(:getc)])
         | 
| 21 | 
            +
                    assert_equal("a", out)
         | 
| 22 | 
            +
                    assert(comp[out="", StringIO.new("bc").method(:getc)])
         | 
| 23 | 
            +
                    assert_equal("b", out)
         | 
| 24 | 
            +
                    assert_raise(error) { comp[out="", StringIO.new("c").method(:getc)] }
         | 
| 25 | 
            +
                    assert_equal("", out)
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
                
         | 
| 28 | 
            +
            end
         | 
| 29 | 
            +
            end
         | 
| 30 | 
            +
            end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
             | 
    
        data/test/composite.rb
    ADDED
    
    | @@ -0,0 +1,147 @@ | |
| 1 | 
            +
            #!/bin/env ruby
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'stringio'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            require 'grammar'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            class Grammar
         | 
| 8 | 
            +
            module Test
         | 
| 9 | 
            +
            module Composite
         | 
| 10 | 
            +
                include Grammar::Molecules
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                def test_Check
         | 
| 13 | 
            +
                    comp = engine.compile(Check {|eng| eng[1]+eng[2]==eng[3]})
         | 
| 14 | 
            +
                    assert(comp[out="", lambda {}])
         | 
| 15 | 
            +
                    comp = engine.compile(Check {|eng| eng[1]+eng[1]==eng[1]})
         | 
| 16 | 
            +
                    assert_raise(error) { comp[out="", lambda {}] }
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
                
         | 
| 19 | 
            +
                def test_not
         | 
| 20 | 
            +
                    comp = engine.compile(~E(?a..?z))
         | 
| 21 | 
            +
                    assert(comp[out="", lambda { ?A }])
         | 
| 22 | 
            +
                    assert_equal("A", out)
         | 
| 23 | 
            +
                    assert_raise(error) { comp[out="", lambda { ?a }] }
         | 
| 24 | 
            +
                    assert_equal("", out)
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
                
         | 
| 27 | 
            +
                def test_optional
         | 
| 28 | 
            +
                    comp = engine.compile(E(?a).optional)
         | 
| 29 | 
            +
                    assert(comp[out="", StringIO.new("ab").method(:getc)])
         | 
| 30 | 
            +
                    assert_equal("a", out)
         | 
| 31 | 
            +
                    assert(comp[out="", StringIO.new("b").method(:getc)])
         | 
| 32 | 
            +
                    assert_equal("", out)
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
                
         | 
| 35 | 
            +
                def test_repeat0
         | 
| 36 | 
            +
                    comp = engine.compile(E(?a).repeat0)
         | 
| 37 | 
            +
                    assert(comp[out="", lambda { }])
         | 
| 38 | 
            +
                    assert_equal("", out)
         | 
| 39 | 
            +
                    assert(comp[out="", StringIO.new("a").method(:getc)])
         | 
| 40 | 
            +
                    assert_equal("a", out)
         | 
| 41 | 
            +
                    assert(comp[out="", StringIO.new("aaa").method(:getc)])
         | 
| 42 | 
            +
                    assert_equal("aaa", out)
         | 
| 43 | 
            +
                    comp = engine.compile(E(?a).repeat0(E(?b)))
         | 
| 44 | 
            +
                    assert(comp[out="", StringIO.new("babaaab").method(:getc)])
         | 
| 45 | 
            +
                    assert_equal("b", out)
         | 
| 46 | 
            +
                    assert(comp[out="", StringIO.new("abaaab").method(:getc)])
         | 
| 47 | 
            +
                    assert_equal("ab", out)
         | 
| 48 | 
            +
                    assert(comp[out="", StringIO.new("aaab").method(:getc)])
         | 
| 49 | 
            +
                    assert_equal("aaab", out)
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
                
         | 
| 52 | 
            +
                def test_repeat1
         | 
| 53 | 
            +
                    comp = engine.compile(E(?a).repeat1)
         | 
| 54 | 
            +
                    out = ""
         | 
| 55 | 
            +
                    assert_raise(error) { comp[out, lambda { }] }
         | 
| 56 | 
            +
                    assert_equal("", out)
         | 
| 57 | 
            +
                    assert(comp[out="", StringIO.new("a").method(:getc)])
         | 
| 58 | 
            +
                    assert_equal("a", out)
         | 
| 59 | 
            +
                    assert(comp[out="", StringIO.new("aaa").method(:getc)])
         | 
| 60 | 
            +
                    assert_equal("aaa", out)
         | 
| 61 | 
            +
                    comp = engine.compile(E(?a).repeat1(E(?b)))
         | 
| 62 | 
            +
                    assert(comp[out="", StringIO.new("abaaabb").method(:getc)])
         | 
| 63 | 
            +
                    assert_equal("ab", out)
         | 
| 64 | 
            +
                    assert(comp[out="", StringIO.new("aaabb").method(:getc)])
         | 
| 65 | 
            +
                    assert_equal("aaab", out)
         | 
| 66 | 
            +
                    assert_raise(error) {
         | 
| 67 | 
            +
                        comp[out="", StringIO.new("b").method(:getc)]
         | 
| 68 | 
            +
                    }
         | 
| 69 | 
            +
                    assert_equal("", out)
         | 
| 70 | 
            +
                end
         | 
| 71 | 
            +
                
         | 
| 72 | 
            +
                def test_times_Fixnum
         | 
| 73 | 
            +
                    comp = engine.compile(E(?a)*2)
         | 
| 74 | 
            +
                    assert(comp[out="", StringIO.new("aab").method(:getc)])
         | 
| 75 | 
            +
                    assert_equal("aa", out)
         | 
| 76 | 
            +
                    assert(comp[out="", StringIO.new("aaa").method(:getc)])
         | 
| 77 | 
            +
                    assert_equal("aa", out)
         | 
| 78 | 
            +
                    assert_raise(error) {
         | 
| 79 | 
            +
                        comp[out="", StringIO.new("b").method(:getc)]
         | 
| 80 | 
            +
                    }
         | 
| 81 | 
            +
                    assert_equal("", out)
         | 
| 82 | 
            +
                    assert_raise(error) {
         | 
| 83 | 
            +
                        comp[out="", StringIO.new("ab").method(:getc)]
         | 
| 84 | 
            +
                    }
         | 
| 85 | 
            +
                    assert_equal("a", out)
         | 
| 86 | 
            +
                end
         | 
| 87 | 
            +
                
         | 
| 88 | 
            +
                def test_times_Range
         | 
| 89 | 
            +
                    comp = engine.compile(E(?a)*(1..2))
         | 
| 90 | 
            +
                    assert(comp[out="", StringIO.new("aaab").method(:getc)])
         | 
| 91 | 
            +
                    assert_equal("aa", out)
         | 
| 92 | 
            +
                    assert(comp[out="", StringIO.new("ab").method(:getc)])
         | 
| 93 | 
            +
                    assert_equal("a", out)
         | 
| 94 | 
            +
                    assert_raise(error) {
         | 
| 95 | 
            +
                        comp[out="", StringIO.new("b").method(:getc)]
         | 
| 96 | 
            +
                    }
         | 
| 97 | 
            +
                    assert_equal("", out)
         | 
| 98 | 
            +
                end
         | 
| 99 | 
            +
                
         | 
| 100 | 
            +
                def test_times_Range1Inf
         | 
| 101 | 
            +
                    comp = engine.compile(E(?a)*(1..1.0/0)+E(?b))
         | 
| 102 | 
            +
                    assert(comp[out="", StringIO.new("abaaaba").method(:getc)])
         | 
| 103 | 
            +
                    assert_equal("ab", out)
         | 
| 104 | 
            +
                    assert(comp[out="", StringIO.new("aaaba").method(:getc)])
         | 
| 105 | 
            +
                    assert_equal("aaab", out)
         | 
| 106 | 
            +
                    assert_raise(error) {
         | 
| 107 | 
            +
                        comp[out="", StringIO.new("a").method(:getc)]
         | 
| 108 | 
            +
                    }
         | 
| 109 | 
            +
                    assert_equal("a", out)
         | 
| 110 | 
            +
                    assert_raise(error) {
         | 
| 111 | 
            +
                        comp[out="", StringIO.new("babaaaba").method(:getc)]
         | 
| 112 | 
            +
                    }
         | 
| 113 | 
            +
                    assert_equal("", out)
         | 
| 114 | 
            +
                end
         | 
| 115 | 
            +
                
         | 
| 116 | 
            +
                def test_times_Range0Inf
         | 
| 117 | 
            +
                    comp = engine.compile(E(?a)*(0..1.0/0)+E(?b))
         | 
| 118 | 
            +
                    assert(comp[out="", StringIO.new("babaaaba").method(:getc)])
         | 
| 119 | 
            +
                    assert_equal("b", out)
         | 
| 120 | 
            +
                    assert(comp[out="", StringIO.new("abaaaba").method(:getc)])
         | 
| 121 | 
            +
                    assert_equal("ab", out)
         | 
| 122 | 
            +
                    assert(comp[out="", StringIO.new("aaaba").method(:getc)])
         | 
| 123 | 
            +
                    assert_equal("aaab", out)
         | 
| 124 | 
            +
                    assert_raise(error) {
         | 
| 125 | 
            +
                        comp[out="", StringIO.new("a").method(:getc)]
         | 
| 126 | 
            +
                    }
         | 
| 127 | 
            +
                    assert_equal("a", out)
         | 
| 128 | 
            +
                end
         | 
| 129 | 
            +
                
         | 
| 130 | 
            +
                def test_group
         | 
| 131 | 
            +
                    comp = engine.compile((E(?a)+E(?b)).group("") + E(?c))
         | 
| 132 | 
            +
                    assert(comp[out=[], StringIO.new("abca").method(:getc)])
         | 
| 133 | 
            +
                    assert_equal(["ab",?c], out)
         | 
| 134 | 
            +
                    assert_raise(error) {
         | 
| 135 | 
            +
                        comp[out=[], StringIO.new("a").method(:getc)]
         | 
| 136 | 
            +
                    }
         | 
| 137 | 
            +
                    assert_equal([], out)
         | 
| 138 | 
            +
                    comp = engine.compile(E(?0..?9).repeat1.group("") { |buf, eng| buf.to_i })
         | 
| 139 | 
            +
                    assert(comp[out=[], StringIO.new("123").method(:getc)])
         | 
| 140 | 
            +
                    assert_equal([123], out)
         | 
| 141 | 
            +
                end
         | 
| 142 | 
            +
                
         | 
| 143 | 
            +
            end
         | 
| 144 | 
            +
            end
         | 
| 145 | 
            +
            end
         | 
| 146 | 
            +
             | 
| 147 | 
            +
             | 
    
        data/test/molecules.rb
    ADDED
    
    | @@ -0,0 +1,125 @@ | |
| 1 | 
            +
            #!/bin/env ruby
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'stringio'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            require 'grammar'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            class Grammar
         | 
| 8 | 
            +
            module Test
         | 
| 9 | 
            +
            module Molecules
         | 
| 10 | 
            +
                include Grammar::Molecules
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                def test_Variables
         | 
| 13 | 
            +
                    comp = engine.compile(Variables(true) { |var| Check { var[] } })
         | 
| 14 | 
            +
                    assert(comp[out="", lambda {}])
         | 
| 15 | 
            +
                    assert_equal("", out)
         | 
| 16 | 
            +
                    comp = engine.compile(Variables(false) { |found|
         | 
| 17 | 
            +
                        (E(?a) + Grammar { |engine| found << engine[true] } | NULL) +
         | 
| 18 | 
            +
                        (Grammar { found[] } + E(?b) | E(?z))
         | 
| 19 | 
            +
                    })
         | 
| 20 | 
            +
                    assert(comp[out="", StringIO.new("abz").method(:getc)])
         | 
| 21 | 
            +
                    assert_equal("ab", out)
         | 
| 22 | 
            +
                    assert(comp[out="", lambda { ?z }])
         | 
| 23 | 
            +
                    assert_equal("z", out)
         | 
| 24 | 
            +
                    assert_raise(error) { comp[out="", lambda { ?b }] }
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
                
         | 
| 27 | 
            +
                def test_Recurse_middle
         | 
| 28 | 
            +
                    comp = engine.compile(Recurse { |gram| E(?() + gram + E(?)) | NULL })
         | 
| 29 | 
            +
                    assert(comp[out="", StringIO.new("()(())(").method(:getc)])
         | 
| 30 | 
            +
                    assert_equal("()", out)
         | 
| 31 | 
            +
                    assert(comp[out="", StringIO.new("(())(").method(:getc)])
         | 
| 32 | 
            +
                    assert_equal("(())", out)
         | 
| 33 | 
            +
                    assert_raise(error) {
         | 
| 34 | 
            +
                        comp[out="", StringIO.new("(").method(:getc)]
         | 
| 35 | 
            +
                    }
         | 
| 36 | 
            +
                    assert_equal("(", out)
         | 
| 37 | 
            +
                    assert(comp[out="", lambda {}])
         | 
| 38 | 
            +
                    assert_equal("", out)
         | 
| 39 | 
            +
                    comp = engine.compile(Recurse { |gram| E(?() + gram + E(?)) | E(?a) })
         | 
| 40 | 
            +
                    assert(comp[out="", StringIO.new("a(a)((a))((ab").method(:getc)])
         | 
| 41 | 
            +
                    assert_equal("a", out)
         | 
| 42 | 
            +
                    assert(comp[out="", StringIO.new("(a)((a))((ab").method(:getc)])
         | 
| 43 | 
            +
                    assert_equal("(a)", out)
         | 
| 44 | 
            +
                    assert(comp[out="", StringIO.new("((a))((ab").method(:getc)])
         | 
| 45 | 
            +
                    assert_equal("((a))", out)
         | 
| 46 | 
            +
                    assert_raise(error) {
         | 
| 47 | 
            +
                        comp[out="", StringIO.new("((ab").method(:getc)]
         | 
| 48 | 
            +
                    }
         | 
| 49 | 
            +
                    assert_equal("((a", out)
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
                
         | 
| 52 | 
            +
                def test_Recurse_right
         | 
| 53 | 
            +
                    comp = engine.compile(Recurse { |gram| E(?a)+gram | NULL })
         | 
| 54 | 
            +
                    assert(comp[out="", lambda {}])
         | 
| 55 | 
            +
                    assert_equal("", out)
         | 
| 56 | 
            +
                    assert(comp[out="", StringIO.new("a").method(:getc)])
         | 
| 57 | 
            +
                    assert_equal("a", out)
         | 
| 58 | 
            +
                    assert(comp[out="", StringIO.new("aaa").method(:getc)])
         | 
| 59 | 
            +
                    assert_equal("aaa", out)
         | 
| 60 | 
            +
                    comp = engine.compile(Recurse { |gram| E(?a) + (E(?b)|gram) })
         | 
| 61 | 
            +
                    assert(comp[out="", StringIO.new("abaaaba").method(:getc)])
         | 
| 62 | 
            +
                    assert_equal("ab", out)
         | 
| 63 | 
            +
                    assert(comp[out="", StringIO.new("aaaba").method(:getc)])
         | 
| 64 | 
            +
                    assert_equal("aaab", out)
         | 
| 65 | 
            +
                    assert_raise(error) {
         | 
| 66 | 
            +
                        comp[out="", StringIO.new("a").method(:getc)]
         | 
| 67 | 
            +
                    }
         | 
| 68 | 
            +
                    assert_equal("a", out)
         | 
| 69 | 
            +
                    assert_raise(error) { comp[out="", lambda { ?b }] }
         | 
| 70 | 
            +
                    assert_equal("", out)
         | 
| 71 | 
            +
                    comp = engine.compile(Recurse { |gram| E(?a) + (E(?b)|gram) } | E(?b))
         | 
| 72 | 
            +
                    assert(comp[out="", StringIO.new("baaaba").method(:getc)])
         | 
| 73 | 
            +
                    assert_equal("b", out)
         | 
| 74 | 
            +
                    assert(comp[out="", StringIO.new("aaaba").method(:getc)])
         | 
| 75 | 
            +
                    assert_equal("aaab", out)
         | 
| 76 | 
            +
                    assert_raise(error) {
         | 
| 77 | 
            +
                        comp[out="", StringIO.new("a").method(:getc)]
         | 
| 78 | 
            +
                    }
         | 
| 79 | 
            +
                    assert_equal("a", out)
         | 
| 80 | 
            +
                end
         | 
| 81 | 
            +
                
         | 
| 82 | 
            +
                def test_Recurse_left
         | 
| 83 | 
            +
                    comp = engine.compile(Recurse { |gram| gram+E(?a) | NULL })
         | 
| 84 | 
            +
                    assert(comp[out="", lambda {}])
         | 
| 85 | 
            +
                    assert_equal("", out)
         | 
| 86 | 
            +
                    assert(comp[out="", StringIO.new("a").method(:getc)])
         | 
| 87 | 
            +
                    assert_equal("a", out)
         | 
| 88 | 
            +
                    assert(comp[out="", StringIO.new("aaa").method(:getc)])
         | 
| 89 | 
            +
                    assert_equal("aaa", out)
         | 
| 90 | 
            +
                    comp = engine.compile(Recurse { |gram| gram+E(?a) | E(?b) })
         | 
| 91 | 
            +
                    assert(comp[out="", lambda { ?b }])
         | 
| 92 | 
            +
                    assert_equal("b", out)
         | 
| 93 | 
            +
                    assert(comp[out="", StringIO.new("ba").method(:getc)])
         | 
| 94 | 
            +
                    assert_equal("ba", out)
         | 
| 95 | 
            +
                    assert(comp[out="", StringIO.new("baaab").method(:getc)])
         | 
| 96 | 
            +
                    assert_equal("baaa", out)
         | 
| 97 | 
            +
                    #comp = engine.compile(Recurse { |gram| gram+NULL })
         | 
| 98 | 
            +
                    #assert_raise(error) {
         | 
| 99 | 
            +
                    #    comp[out="", lambda { E(?a) }]
         | 
| 100 | 
            +
                    #}
         | 
| 101 | 
            +
                    #assert_equal("", out)
         | 
| 102 | 
            +
                    #comp = engine.compile(Recurse { |gram| gram })
         | 
| 103 | 
            +
                    #assert_raise(RuntimeError) {
         | 
| 104 | 
            +
                    #    comp[out="", lambda { E(?a) }]
         | 
| 105 | 
            +
                    #}
         | 
| 106 | 
            +
                    #assert_equal("", out)
         | 
| 107 | 
            +
                    #comp = engine.compile(Recurse { |gram| gram+NULL | NULL })
         | 
| 108 | 
            +
                    #assert_raise(RuntimeError) {
         | 
| 109 | 
            +
                    #    comp[out="", lambda { E(?a) }]
         | 
| 110 | 
            +
                    #}
         | 
| 111 | 
            +
                    #assert_equal("", out)
         | 
| 112 | 
            +
                    comp = engine.compile(Recurse { |gram| gram+E(?a)+E(?c) | E(?b) })
         | 
| 113 | 
            +
                    assert(comp[out="", StringIO.new("bacacbacab").method(:getc)])
         | 
| 114 | 
            +
                    assert_equal("bacac", out)
         | 
| 115 | 
            +
                    assert_raise(error) {
         | 
| 116 | 
            +
                        comp[out="", StringIO.new("bacab").method(:getc)]
         | 
| 117 | 
            +
                    }
         | 
| 118 | 
            +
                    assert_equal("baca", out)
         | 
| 119 | 
            +
                end
         | 
| 120 | 
            +
                
         | 
| 121 | 
            +
            end
         | 
| 122 | 
            +
            end
         | 
| 123 | 
            +
            end
         | 
| 124 | 
            +
             | 
| 125 | 
            +
             |