pratt_parser 0.0.1 → 0.0.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f8429fe8f5e629ccb6048fdc5766a278bbd5f5ae
4
- data.tar.gz: 03df74e2cb12a8403dd4025c5a4597d3da067a0f
3
+ metadata.gz: ca11d04a7ae882b9277380b20a737f9da15d71ff
4
+ data.tar.gz: 73b065cfad311d5310d37ace99ddd4a78683c81c
5
5
  SHA512:
6
- metadata.gz: b215b84b04fde6efdbce9c5244ece12be8b9cb9d9e268056cd2699eb63e30f253c93e17e8cfd1287de0fc1702514a26c5b3e4154fa11a21712b248e1019685a9
7
- data.tar.gz: e27d791be91a17b96ca7907f32a53274a6ade2a7ab2d88c6cbbfc3d1c77e05f0fc313c560228a6085af4514cf9072d99303e2a31a5c3e8831e768bdce446d9d8
6
+ metadata.gz: 8a2044d7296b0c958153481589955db1d2e8e40b5b31d937e72ec12175a51d6cbdaff5936e3e0739bfdcae78effe4652c037a474c237d6b9cfe121fb99631c3e
7
+ data.tar.gz: f576cb77ce8d32f23427dbab99faeaefab17ca438496684ef6732617516207b019bbdc2ca35312c86fa5872a19c89ae0773fba95f11adcae202a86bc409dbb8f
data/CHANGELOG CHANGED
@@ -1,3 +1,7 @@
1
+ ## 0.0.2 ##
2
+
3
+ * Add examples/tree.rb.
4
+
1
5
  ## 0.0.1 ##
2
6
 
3
7
  * Include examples.
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  # Evaluate simple arithmetic expressions using a PrattParser.
4
- # Supports +, -, *, /, ^ (with ustomarycorrect precedence and
5
- # associativity, and parentheses. Also supports = to compare numbers
4
+ # Supports +, -, *, /, ^ (with customary precedence and
5
+ # associativity), and parentheses. Also supports = to compare numbers
6
6
  # and booleans. Adding support for < and > would be a simple matter
7
7
  # of adding some more tokens.
8
8
  #
9
9
  # Supporting whitespace needs a lexer that throws away whitespace.
10
10
  #
11
11
  # Numeric integer constants are supported using single-digit tokens
12
- # which are left-associatiuve.
12
+ # which are left-associative.
13
13
 
14
14
  require "pratt_parser"
15
15
 
data/examples/tree.rb ADDED
@@ -0,0 +1,150 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Parses simple arithmetic expressions using a PrattParser. Supports
4
+ # +, -, *, /, ^ (with customary precedence and associativity), and
5
+ # parentheses. The parse returns a tree of BinaryNode and NumberNode
6
+ # objects which is printed prefix-style ala Lisp.
7
+ #
8
+ # Numeric integer constants are supported using single-digit tokens
9
+ # which are left-associative.
10
+
11
+ require "pratt_parser"
12
+
13
+ class BinaryNode
14
+ def initialize(operator, left, right)
15
+ @operator = operator
16
+ @left = left
17
+ @right = right
18
+ end
19
+
20
+ def to_s
21
+ "(#{@operator} #{@left} #{@right})"
22
+ end
23
+
24
+ # Returns a pretty-print version of the expression ala Lisp.
25
+
26
+ def pp(indent = "")
27
+ newindent = indent + " "
28
+ "#{indent}(#{@operator}\n#{@left.pp(newindent)}\n#{@right.pp(newindent)})"
29
+ end
30
+ end
31
+
32
+ class NumberNode
33
+ def initialize(number)
34
+ @number = number
35
+ end
36
+
37
+ def get_number
38
+ @number
39
+ end
40
+
41
+ def to_s
42
+ @number.to_s
43
+ end
44
+
45
+ # Returns a pretty-print version of the expression ala Lisp.
46
+
47
+ def pp(indent = "")
48
+ "#{indent}#{@number}"
49
+ end
50
+ end
51
+
52
+ class TreeBuilder
53
+ def self.eval(expression)
54
+ PrattParser.new(Lexer.new(expression)).eval
55
+ end
56
+
57
+ class Lexer
58
+ # Note that new returns an Enumerator, not a Lexer.
59
+
60
+ def self.new(expression)
61
+ Enumerator.new do |y|
62
+ expression.each_char do |c|
63
+ # Discard spaces.
64
+ if c != " "
65
+ y << @@tokens[c]
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ class Token
72
+ def initialize(lbp)
73
+ @lbp = lbp
74
+ end
75
+
76
+ def lbp
77
+ @lbp
78
+ end
79
+ end
80
+
81
+ class InfixToken < Token
82
+ def initialize(operator, lbp, associates = :left)
83
+ super(lbp)
84
+ @operator = operator
85
+ @rbp = (associates == :left ? lbp : lbp - 1)
86
+ end
87
+
88
+ def led(parser, left)
89
+ right = parser.expression(@rbp)
90
+ BinaryNode.new(@operator, left, right)
91
+ end
92
+ end
93
+
94
+ class DigitToken < Token
95
+ def initialize(lbp, value)
96
+ super(lbp)
97
+ @value = value
98
+ end
99
+
100
+ def nud(parser)
101
+ NumberNode.new(@value)
102
+ end
103
+
104
+ def led(parser, left)
105
+ NumberNode.new(left.number*10 + @value)
106
+ end
107
+ end
108
+
109
+ class LeftParenToken < Token
110
+ def nud(parser)
111
+ parser.expression(lbp).tap do
112
+ parser.expect(RightParenToken)
113
+ end
114
+ end
115
+ end
116
+
117
+ class RightParenToken < Token
118
+ end
119
+
120
+ @@tokens = {}
121
+
122
+ def self.token(char, t)
123
+ @@tokens[char] = t
124
+ end
125
+
126
+ def self.infix(char, lbp, associates = :left)
127
+ token(char, InfixToken.new(char, lbp, associates))
128
+ end
129
+
130
+ token("(", LeftParenToken.new(0))
131
+ token(")", RightParenToken.new(0))
132
+
133
+ infix("=", 10)
134
+ infix("+", 20)
135
+ infix("-", 20)
136
+ infix("*", 30)
137
+ infix("/", 30)
138
+ infix("^", 40, :right)
139
+
140
+ (0..9).each do |d|
141
+ token(d.to_s, DigitToken.new(100, d))
142
+ end
143
+ end
144
+ end
145
+
146
+ if __FILE__ == $0
147
+ tree = TreeBuilder.eval(ARGV[0])
148
+ puts tree.to_s
149
+ puts tree.pp
150
+ end
data/pratt_parser.gemspec CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |gem|
8
8
  gem.test_files = `git ls-files -- spec/*`.split("\n")
9
9
  gem.name = "pratt_parser"
10
10
  gem.require_paths = ["lib"]
11
- gem.version = "0.0.1"
11
+ gem.version = "0.0.2"
12
12
  gem.license = "MIT"
13
13
  # gem.required_ruby_version = '>= 2.1.0'
14
14
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pratt_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom May
@@ -24,6 +24,7 @@ files:
24
24
  - README.md
25
25
  - Rakefile
26
26
  - examples/expression_evaluator.rb
27
+ - examples/tree.rb
27
28
  - lib/pratt_parser.rb
28
29
  - pratt_parser.gemspec
29
30
  homepage: https://github.com/tommay/pratt_parser