Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

+ Adapted examples and introduced another simplification

  • Loading branch information...
commit 88a01fc4da7a9585ba3a89e8529bc0f4280e6399 1 parent 3197e7b
Kaspar Schiess authored
27 README
View
@@ -56,7 +56,7 @@ SYNOPSIS
str('"').absnt? >> any
).repeat.as(:string) >>
str('"')
-
+
# Parse the string and capture parts of the interpretation (:string above)
tree = parser.parse(%Q{
"This is a \\"String\\" in which you can escape stuff"
@@ -64,24 +64,19 @@ SYNOPSIS
tree # => {:string=>"This is a \\\"String\\\" in which you can escape stuff"}
- # Here's how you can grab results from that tree:
+ # Here's how you can grab results from that tree, two methods:
+
+ # 1)
Pattern.new(:string => simple(:x)).each_match(tree) do |dictionary|
- puts "String contents: #{dictionary[:x]}"
+ puts "String contents (method 1): #{dictionary[:x]}"
end
-
- # Here's how to transform that tree into something else ----------------------
- # Defines the classes of our new Syntax Tree
- class StringLiteral < Struct.new(:text); end
-
- # Defines a set of transformation rules on tree leaves
- transform = Transform.new
- transform.rule(:string => simple(:x)) { |d| StringLiteral.new(d[:x]) }
-
- # Transforms the tree
- transform.apply(tree)
-
- # => #<struct StringLiteral text="This is a \\\"String\\\" ... escape stuff">
+ # 2)
+ transform = Parslet::Transform.new do
+ rule(:string => simple(:x)) {
+ puts "String contents (method 2): #{x}" }
+ end
+ transform.apply(tree)
COMPATIBILITY
4 example/documentation.rb
View
@@ -6,9 +6,7 @@
require 'pp'
require 'parslet'
-class MyParser
- include Parslet
-
+class MyParser < Parslet::Parser
rule(:a) { str('a').repeat }
def parse(str)
4 example/empty.rb
View
@@ -5,9 +5,7 @@
require 'parslet'
-class Parser
- include Parslet
-
+class Parser < Parslet::Parser
rule(:empty) { }
end
19 example/minilisp.rb
View
@@ -7,9 +7,7 @@
require 'parslet'
module MiniLisp
- class Parser
- include Parslet
-
+ class Parser < Parslet::Parser
root :expression
rule(:expression) {
space? >> str('(') >> space? >> body >> str(')')
@@ -69,20 +67,15 @@ def initialize
@t = Parslet::Transform.new
# To understand these, take a look at what comes out of the parser.
- t.rule(:identifier => simple(:ident)) { |d|
- d[:ident].to_sym }
+ t.rule(:identifier => simple(:ident)) { ident.to_sym }
- t.rule(:string => simple(:str)) { |d|
- d[:str] }
+ t.rule(:string => simple(:str)) { str }
- t.rule(:integer => simple(:int)) { |d|
- Integer(d[:int]) }
+ t.rule(:integer => simple(:int)) { Integer(int) }
- t.rule(:float=>{:integer=> simple(:a), :e=> simple(:b)}) { |d|
- Float(d[:a] + d[:b]) }
+ t.rule(:float=>{:integer=> simple(:a), :e=> simple(:b)}) { Float(a + b) }
- t.rule(:exp => sequence(:exp)) { |d|
- LispExp.new(d[:exp]) }
+ t.rule(:exp => sequence(:exp)) { LispExp.new(exp) }
end
def do(tree)
29 example/readme.rb
View
@@ -7,6 +7,9 @@
require 'parslet'
include Parslet
+require 'parslet'
+include Parslet
+
# Constructs a parser using a Parser Expression Grammar like DSL:
parser = str('"') >>
(
@@ -14,7 +17,7 @@
str('"').absnt? >> any
).repeat.as(:string) >>
str('"')
-
+
# Parse the string and capture parts of the interpretation (:string above)
tree = parser.parse(%Q{
"This is a \\"String\\" in which you can escape stuff"
@@ -22,21 +25,17 @@
tree # => {:string=>"This is a \\\"String\\\" in which you can escape stuff"}
-# Here's how you can grab results from that tree:
+# Here's how you can grab results from that tree, two methods:
+
+# 1)
Pattern.new(:string => simple(:x)).each_match(tree) do |dictionary|
- puts "String contents: #{dictionary[:x]}"
+ puts "String contents (method 1): #{dictionary[:x]}"
end
-
-# Here's how to transform that tree into something else ----------------------
-
-# Defines the classes of our new Syntax Tree
-class StringLiteral < Struct.new(:text); end
-# Defines a set of transformation rules on tree leaves
-transform = Transform.new
-transform.rule(:string => simple(:x)) { |d| StringLiteral.new(d[:x]) }
-
-# Transforms the tree
-transform.apply(tree)
+# 2)
+transform = Parslet::Transform.new do
+ rule(:string => simple(:x)) {
+ puts "String contents (method 2): #{x}" }
+end
+transform.apply(tree)
-# => #<struct StringLiteral text="This is a \\\"String\\\" ... escape stuff">
3  lib/parslet.rb
View
@@ -312,4 +312,5 @@ def simple(symbol)
require 'parslet/atoms'
require 'parslet/pattern'
require 'parslet/pattern/binding'
-require 'parslet/transform'
+require 'parslet/transform'
+require 'parslet/parser'
7 lib/parslet/parser.rb
View
@@ -0,0 +1,7 @@
+
+# A simple wrapper for the functionality to permit clean source code structure.
+# You should use this as the base class for your parsers.
+#
+class Parslet::Parser
+ include Parslet
+end
8 lib/parslet/transform.rb
View
@@ -70,8 +70,14 @@
#
#
class Parslet::Transform
- def initialize
+ include Parslet # FIXME: Maybe only part of it?
+
+ def initialize(&block)
@rules = []
+
+ if block
+ instance_eval(&block)
+ end
end
attr_reader :rules
12 spec/unit/parslet/parser_spec.rb
View
@@ -0,0 +1,12 @@
+require 'spec_helper'
+
+describe Parslet::Parser do
+ class FooParser < Parslet::Parser
+ rule(:foo) { str('foo') }
+ root(:foo)
+ end
+
+ it "should parse 'foo'" do
+ FooParser.new.parse('foo').should == 'foo'
+ end
+end
77 spec/unit/parslet/transform_spec.rb
View
@@ -5,6 +5,7 @@
describe Parslet::Transform do
include Parslet
+ let(:transform) { Parslet::Transform.new }
attr_reader :transform
before(:each) do
@transform = Parslet::Transform.new
@@ -14,43 +15,55 @@ class A < Struct.new(:elt); end
class B < Struct.new(:elt); end
class C < Struct.new(:elt); end
class Bi < Struct.new(:a, :b); end
-
- describe "given simple(:x) => A.new(x)" do
- before(:each) do
- transform.rule(simple(:x)) { |d| A.new(d[:x]) }
- end
-
- it "should transform 'a' into A.new('a')" do
- transform.apply('a').should == A.new('a')
- end
- it "should transform ['a', 'b'] into [A.new('a'), A.new('b')]" do
- transform.apply(['a', 'b']).should ==
- [A.new('a'), A.new('b')]
- end
- end
- describe "given rules on {:a => simple(:x)} and {:b => :_x}" do
- before(:each) do
- transform.rule(:a => simple(:x)) { |d| A.new(d[:x]) }
- transform.rule(:b => simple(:x)) { |d| B.new(d[:x]) }
+
+ describe "delayed construction" do
+ context "given simple(:x) => A.new(x)" do
+ before(:each) do
+ transform.rule(simple(:x)) { |d| A.new(d[:x]) }
+ end
+
+ it "should transform 'a' into A.new('a')" do
+ transform.apply('a').should == A.new('a')
+ end
+ it "should transform ['a', 'b'] into [A.new('a'), A.new('b')]" do
+ transform.apply(['a', 'b']).should ==
+ [A.new('a'), A.new('b')]
+ end
end
-
- it "should transform {:d=>{:b=>'c'}} into d => B('c')" do
- transform.apply({:d=>{:b=>'c'}}).should == {:d => B.new('c')}
+ context "given rules on {:a => simple(:x)} and {:b => :_x}" do
+ before(:each) do
+ transform.rule(:a => simple(:x)) { |d| A.new(d[:x]) }
+ transform.rule(:b => simple(:x)) { |d| B.new(d[:x]) }
+ end
+
+ it "should transform {:d=>{:b=>'c'}} into d => B('c')" do
+ transform.apply({:d=>{:b=>'c'}}).should == {:d => B.new('c')}
+ end
+ it "should transform {:a=>{:b=>'c'}} into A(B('c'))" do
+ transform.apply({:a=>{:b=>'c'}}).should == A.new(B.new('c'))
+ end
end
- it "should transform {:a=>{:b=>'c'}} into A(B('c'))" do
- transform.apply({:a=>{:b=>'c'}}).should == A.new(B.new('c'))
+ describe "pulling out subbranches" do
+ before(:each) do
+ transform.rule(:a => {:b => simple(:x)}, :d => {:e => simple(:y)}) { |d|
+ Bi.new(*d.values_at(:x, :y))
+ }
+ end
+
+ it "should yield Bi.new('c', 'f')" do
+ transform.apply(:a => {:b => 'c'}, :d => {:e => 'f'}).should ==
+ Bi.new('c', 'f')
+ end
end
end
- describe "pulling out subbranches" do
- before(:each) do
- transform.rule(:a => {:b => simple(:x)}, :d => {:e => simple(:y)}) { |d|
- Bi.new(*d.values_at(:x, :y))
- }
- end
+ describe "dsl construction" do
+ let(:transform) { Parslet::Transform.new do
+ rule(simple(:x)) { A.new(x) }
+ end
+ }
- it "should yield Bi.new('c', 'f')" do
- transform.apply(:a => {:b => 'c'}, :d => {:e => 'f'}).should ==
- Bi.new('c', 'f')
+ it "should still evaluate rules correctly" do
+ transform.apply('a').should == A.new('a')
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.