forked from kschiess/parslet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
parens.rb
42 lines (36 loc) · 919 Bytes
/
parens.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# A small example that demonstrates the power of tree pattern matching. Also
# uses '.as(:name)' to construct a tree that can reliably be matched
# afterwards.
$:.unshift '../lib'
require 'pp'
require 'parslet'
module LISP # as in 'lots of insipid and stupid parenthesis'
class Parser < Parslet::Parser
rule(:balanced) {
str('(').as(:l) >> balanced.maybe.as(:m) >> str(')').as(:r)
}
root(:balanced)
end
class Transform < Parslet::Transform
rule(:l => '(', :m => simple(:x), :r => ')') {
# innermost :m will contain nil
x.nil? ? 1 : x+1
}
end
end
parser = LISP::Parser.new
transform = LISP::Transform.new
%w!
()
(())
((((()))))
((())
!.each do |pexp|
begin
result = parser.parse(pexp)
puts "#{"%20s"%pexp}: #{result.inspect} (#{transform.apply(result)} parens)"
rescue Parslet::ParseFailed => m
puts "#{"%20s"%pexp}: #{m}"
end
puts
end