raabro 1.0.3 → 1.0.4
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/CHANGELOG.txt +5 -0
 - data/README.md +89 -1
 - data/lib/raabro.rb +17 -9
 - data/spec/sample_xel_spec.rb +9 -14
 - metadata +1 -1
 
    
        data/CHANGELOG.txt
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | 
         @@ -6,7 +6,95 @@ 
     | 
|
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
            A very dumb PEG parser library.
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
            Son to [aabro](https://github.com/flon-io/aabro), grandson to [neg](https://github.com/jmettraux/neg).
         
     | 
| 
      
 9 
     | 
    
         
            +
            Son to [aabro](https://github.com/flon-io/aabro), grandson to [neg](https://github.com/jmettraux/neg), grand-grandson to [parslet](https://github.com/kschiess/parslet).
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            ## a sample parser/rewriter
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            You use raabro by providing the parsing rules, then some rewrite rules.
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            The parsing rules make use of the raabro basic parsers `seq`, `alt`, `str`, `rex`, `eseq`, ...
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            The rewrite rules match names passed as first argument to the basic parsers to rewrite the resulting parse trees.
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 21 
     | 
    
         
            +
            require 'raabro'
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            module Fun include Raabro
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              # parse
         
     | 
| 
      
 27 
     | 
    
         
            +
              #
         
     | 
| 
      
 28 
     | 
    
         
            +
              # Last function is the root, "i" stands for "input".
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
              def pa(i); rex(nil, i, /\(\s*/); end
         
     | 
| 
      
 31 
     | 
    
         
            +
              def pz(i); rex(nil, i, /\)\s*/); end
         
     | 
| 
      
 32 
     | 
    
         
            +
              def com(i); rex(nil, i, /,\s*/); end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
              def num(i); rex(:num, i, /-?[0-9]+\s*/); end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
              def args(i); eseq(:args, i, :pa, :exp, :com, :pz); end
         
     | 
| 
      
 37 
     | 
    
         
            +
              def funame(i); rex(:funame, i, /[a-z][a-z0-9]*/); end
         
     | 
| 
      
 38 
     | 
    
         
            +
              def fun(i); seq(:fun, i, :funame, :args); end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
              def exp(i); alt(:exp, i, :fun, :num); end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
              # rewrite
         
     | 
| 
      
 43 
     | 
    
         
            +
              #
         
     | 
| 
      
 44 
     | 
    
         
            +
              # Names above (:num, :fun, ...) get a rewrite_xxx function.
         
     | 
| 
      
 45 
     | 
    
         
            +
              # "t" stands for "tree".
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
              def rewrite_exp(t); rewrite(t.children[0]); end
         
     | 
| 
      
 48 
     | 
    
         
            +
              def rewrite_num(t); t.string.to_i; end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
              def rewrite_fun(t)
         
     | 
| 
      
 51 
     | 
    
         
            +
                [ t.children[0].string ] +
         
     | 
| 
      
 52 
     | 
    
         
            +
                t.children[1].children.inject([]) { |a, e| a << rewrite(e) if e.name; a }
         
     | 
| 
      
 53 
     | 
    
         
            +
              end
         
     | 
| 
      
 54 
     | 
    
         
            +
            end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
            p Fun.parse('mul(1, 2)')
         
     | 
| 
      
 58 
     | 
    
         
            +
              # => ["mul", 1, 2]
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
            p Fun.parse('mul(1, add(-2, 3))')
         
     | 
| 
      
 61 
     | 
    
         
            +
              # => ["mul", 1, ["add", -2, 3]]
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
            p Fun.parse('mul (1, 2)')
         
     | 
| 
      
 64 
     | 
    
         
            +
              # => nil (doesn't accept a space after the function name)
         
     | 
| 
      
 65 
     | 
    
         
            +
            ```
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
            This sample is available at: [doc/readme0.rb](doc/readme0.rb).
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
            ## basic parsers
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
            The first parameter is the name used by rewrite rules.
         
     | 
| 
      
 73 
     | 
    
         
            +
            The second parameter is a `Raabro::Input` instance, mostly a wrapped string.
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 76 
     | 
    
         
            +
            def seq(name, input, *parsers)
         
     | 
| 
      
 77 
     | 
    
         
            +
              # a sequence of parsers
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
            def alt(name, input, *parsers)
         
     | 
| 
      
 80 
     | 
    
         
            +
              # tries the parsers returns as soon as one succeeds
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
            def altg(name, input, *parsers)
         
     | 
| 
      
 83 
     | 
    
         
            +
              # tries all the parsers, returns with the longest match
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
            def rep(name, input, parser, min, max=0)
         
     | 
| 
      
 86 
     | 
    
         
            +
              # repeats the the wrapped parser
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
            def ren(name, input, parser)
         
     | 
| 
      
 89 
     | 
    
         
            +
              # renames the output of the wrapped parser
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
            def jseq(name, input, eltpa, seppa)
         
     | 
| 
      
 92 
     | 
    
         
            +
              # seq(name, input, eltpa, seppa, eltpa, seppa, eltpaa, seppa, ...)
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
            def eseq(name, input, startpa, eltpa, seppa, endpa)
         
     | 
| 
      
 95 
     | 
    
         
            +
              # seq(name, input, startpa, eltpa, seppa, eltpa, seppa, ..., endpa)
         
     | 
| 
      
 96 
     | 
    
         
            +
            ```
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
       10 
98 
     | 
    
         | 
| 
       11 
99 
     | 
    
         
             
            ## LICENSE
         
     | 
| 
       12 
100 
     | 
    
         | 
    
        data/lib/raabro.rb
    CHANGED
    
    | 
         @@ -26,7 +26,7 @@ 
     | 
|
| 
       26 
26 
     | 
    
         | 
| 
       27 
27 
     | 
    
         
             
            module Raabro
         
     | 
| 
       28 
28 
     | 
    
         | 
| 
       29 
     | 
    
         
            -
              VERSION = '1.0. 
     | 
| 
      
 29 
     | 
    
         
            +
              VERSION = '1.0.4'
         
     | 
| 
       30 
30 
     | 
    
         | 
| 
       31 
31 
     | 
    
         
             
              class Input
         
     | 
| 
       32 
32 
     | 
    
         | 
| 
         @@ -388,6 +388,17 @@ module Raabro 
     | 
|
| 
       388 
388 
     | 
    
         
             
                end
         
     | 
| 
       389 
389 
     | 
    
         
             
                alias jseq eseq
         
     | 
| 
       390 
390 
     | 
    
         | 
| 
      
 391 
     | 
    
         
            +
                attr_accessor :last
         
     | 
| 
      
 392 
     | 
    
         
            +
             
     | 
| 
      
 393 
     | 
    
         
            +
                def method_added(name)
         
     | 
| 
      
 394 
     | 
    
         
            +
             
     | 
| 
      
 395 
     | 
    
         
            +
                  m = method(name)
         
     | 
| 
      
 396 
     | 
    
         
            +
                  return unless m.arity == 1
         
     | 
| 
      
 397 
     | 
    
         
            +
                  return unless m.parameters[0][1] == :i || m.parameters[0][1] == :input
         
     | 
| 
      
 398 
     | 
    
         
            +
             
     | 
| 
      
 399 
     | 
    
         
            +
                  @last = name.to_sym
         
     | 
| 
      
 400 
     | 
    
         
            +
                end
         
     | 
| 
      
 401 
     | 
    
         
            +
             
     | 
| 
       391 
402 
     | 
    
         
             
                def parse(input, opts={})
         
     | 
| 
       392 
403 
     | 
    
         | 
| 
       393 
404 
     | 
    
         
             
                  opts[:prune] = true unless opts.has_key?(:prune)
         
     | 
| 
         @@ -405,20 +416,17 @@ module Raabro 
     | 
|
| 
       405 
416 
     | 
    
         | 
| 
       406 
417 
     | 
    
         
             
                  t = t.children.first if t.parter == :all
         
     | 
| 
       407 
418 
     | 
    
         | 
| 
       408 
     | 
    
         
            -
                  return rewrite(t) if opts[:rewrite] != false &&  
     | 
| 
      
 419 
     | 
    
         
            +
                  return rewrite(t) if opts[:rewrite] != false && rewrite(0) == true
         
     | 
| 
       409 
420 
     | 
    
         | 
| 
       410 
421 
     | 
    
         
             
                  t
         
     | 
| 
       411 
422 
     | 
    
         
             
                end
         
     | 
| 
       412 
423 
     | 
    
         | 
| 
       413 
     | 
    
         
            -
                 
     | 
| 
      
 424 
     | 
    
         
            +
                def rewrite(tree)
         
     | 
| 
       414 
425 
     | 
    
         | 
| 
       415 
     | 
    
         
            -
             
     | 
| 
      
 426 
     | 
    
         
            +
                  return !! methods.find { |m| m.to_s.match(/^rewrite_/) } if tree == 0
         
     | 
| 
      
 427 
     | 
    
         
            +
                    # return true when "rewrite_xxx" methods seem to have been provided
         
     | 
| 
       416 
428 
     | 
    
         | 
| 
       417 
     | 
    
         
            -
                   
     | 
| 
       418 
     | 
    
         
            -
                  return unless m.arity == 1
         
     | 
| 
       419 
     | 
    
         
            -
                  return unless m.parameters[0][1] == :i || m.parameters[0][1] == :input
         
     | 
| 
       420 
     | 
    
         
            -
             
     | 
| 
       421 
     | 
    
         
            -
                  @last = name.to_sym
         
     | 
| 
      
 429 
     | 
    
         
            +
                  send("rewrite_#{tree.name}", tree)
         
     | 
| 
       422 
430 
     | 
    
         
             
                end
         
     | 
| 
       423 
431 
     | 
    
         
             
              end
         
     | 
| 
       424 
432 
     | 
    
         
             
              extend ModuleMethods
         
     | 
    
        data/spec/sample_xel_spec.rb
    CHANGED
    
    | 
         @@ -10,7 +10,7 @@ require 'spec_helper' 
     | 
|
| 
       10 
10 
     | 
    
         | 
| 
       11 
11 
     | 
    
         
             
            module Sample::Xel include Raabro
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
     | 
    
         
            -
              #  
     | 
| 
      
 13 
     | 
    
         
            +
              # parse
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
       15 
15 
     | 
    
         
             
              def pa(i); str(nil, i, '('); end
         
     | 
| 
       16 
16 
     | 
    
         
             
              def pz(i); str(nil, i, ')'); end
         
     | 
| 
         @@ -27,19 +27,14 @@ module Sample::Xel include Raabro 
     | 
|
| 
       27 
27 
     | 
    
         
             
              #alias root exp
         
     | 
| 
       28 
28 
     | 
    
         
             
                # not necessary since Raabro takes the last defined parser as the root
         
     | 
| 
       29 
29 
     | 
    
         | 
| 
       30 
     | 
    
         
            -
               
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
                    [ tree.children[0].string ] +
         
     | 
| 
       39 
     | 
    
         
            -
                    tree.children[1].children.select(&:name).collect { |e| rewrite(e) }
         
     | 
| 
       40 
     | 
    
         
            -
                  else
         
     | 
| 
       41 
     | 
    
         
            -
                    fail ArgumentError.new("cannot rewrite #{tree.to_a.inspect}")
         
     | 
| 
       42 
     | 
    
         
            -
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
              # rewrite
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
              def rewrite_exp(t); rewrite(t.children[0]); end
         
     | 
| 
      
 33 
     | 
    
         
            +
              def rewrite_num(t); t.string.to_i; end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
              def rewrite_fun(t)
         
     | 
| 
      
 36 
     | 
    
         
            +
                [ t.children[0].string ] +
         
     | 
| 
      
 37 
     | 
    
         
            +
                t.children[1].children.inject([]) { |a, e| a << rewrite(e) if e.name; a }
         
     | 
| 
       43 
38 
     | 
    
         
             
              end
         
     | 
| 
       44 
39 
     | 
    
         
             
            end
         
     | 
| 
       45 
40 
     | 
    
         |