rley 0.5.02 → 0.5.03

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.
@@ -6,10 +6,12 @@ require 'coveralls'
6
6
 
7
7
  Coveralls.wear!
8
8
 
9
- SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
10
- SimpleCov::Formatter::HTMLFormatter,
11
- Coveralls::SimpleCov::Formatter
12
- ])
9
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new(
10
+ [
11
+ SimpleCov::Formatter::HTMLFormatter,
12
+ Coveralls::SimpleCov::Formatter
13
+ ]
14
+ )
13
15
 
14
16
  require 'pp' # Use pretty-print for debugging purposes
15
17
  require 'rspec' # Use the RSpec framework
@@ -25,5 +27,4 @@ RSpec.configure do |config|
25
27
  config.full_backtrace = true
26
28
  end
27
29
 
28
-
29
30
  # End of file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rley
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.02
4
+ version: 0.5.03
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dimitri Geshef
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-08 00:00:00.000000000 Z
11
+ date: 2017-10-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: coveralls
@@ -146,12 +146,6 @@ files:
146
146
  - examples/general/calc_iter1/calc_lexer.rb
147
147
  - examples/general/calc_iter1/calc_parser.rb
148
148
  - examples/general/calc_iter1/spec/calculator_spec.rb
149
- - examples/general/calc_iter2/calc_ast_builder.rb
150
- - examples/general/calc_iter2/calc_ast_nodes.rb
151
- - examples/general/calc_iter2/calc_demo.rb
152
- - examples/general/calc_iter2/calc_grammar.rb
153
- - examples/general/calc_iter2/calc_lexer.rb
154
- - examples/general/calc_iter2/calc_parser.rb
155
149
  - lib/rley.rb
156
150
  - lib/rley/constants.rb
157
151
  - lib/rley/formatter/asciitree.rb
@@ -1,186 +0,0 @@
1
- require_relative 'calc_ast_nodes'
2
-
3
- # The purpose of a CalcASTBuilder is to build piece by piece an AST
4
- # (Abstract Syntax Tree) from a sequence of input tokens and
5
- # visit events produced by walking over a GFGParsing object.
6
- # Uses the Builder GoF pattern.
7
- # The Builder pattern creates a complex object
8
- # (say, a parse tree) from simpler objects (terminal and non-terminal
9
- # nodes) and using a step by step approach.
10
- class CalcASTBuilder < Rley::Parser::ParseTreeBuilder
11
- Terminal2NodeClass = {
12
- # Plus sign character is ambiguous. It can represent an operator
13
- # or a positive value
14
- '+' => { 'add_operator[0]' => CalcAddNode, 'sign[0]' => PTree::TerminalNode },
15
- # Minus sign character is ambiguous. It can represent an operator
16
- # or a negative value
17
- '-' => { 'add_operator[1]' => CalcSubtractNode, 'sign[1]' => CalcNegateNode },
18
- '*' => CalcMultiplyNode,
19
- '/' => CalcDivideNode,
20
- 'number' => CalcNumberNode
21
- }
22
-
23
- protected
24
-
25
- def return_first_child(_range, _tokens, theChildren)
26
- return theChildren[0]
27
- end
28
-
29
- def return_second_child(_range, _tokens, theChildren)
30
- return theChildren[1]
31
- end
32
-
33
- def return_last_child(_range, _tokens, theChildren)
34
- return theChildren[-1]
35
- end
36
-
37
- # Overriding method.
38
- # Create a parse tree object with given
39
- # node as root node.
40
- def create_tree(aRootNode)
41
- return Rley::PTree::ParseTree.new(aRootNode)
42
- end
43
-
44
- # Overriding method.
45
- # Factory method for creating a node object for the given
46
- # input token.
47
- # @param aTerminal [Terminal] Terminal symbol associated with the token
48
- # @param aTokenPosition [Integer] Position of token in the input stream
49
- # @param aToken [Token] The input token
50
- def new_leaf_node(aProduction, aTerminal, aTokenPosition, aToken)
51
- klass = Terminal2NodeClass.fetch(aTerminal.name, CalcTerminalNode)
52
- klass = klass[aProduction.name] if klass.is_a?(Hash) # Lexical ambiguity
53
- return klass.new(aToken, aTokenPosition)
54
- end
55
-
56
-
57
- # Method to override.
58
- # Factory method for creating a parent node object.
59
- # @param aProduction [Production] Production rule
60
- # @param aRange [Range] Range of tokens matched by the rule
61
- # @param theTokens [Array] The input tokens
62
- # @param theChildren [Array] Children nodes (one per rhs symbol)
63
- def new_parent_node(aProduction, aRange, theTokens, theChildren)
64
- node = case aProduction.name
65
- when 'expression[0]' # rule 'expression' => %w[sign simple_expression]
66
- reduce_expression_0(aProduction, aRange, theTokens, theChildren)
67
-
68
- # when /value\[\d\]/
69
- # return_first_child(aRange, theTokens, theChildren)
70
-
71
- # when 'object[0]'
72
- # reduce_object_0(aProduction, aRange, theTokens, theChildren)
73
-
74
- # when 'object[1]'
75
- # reduce_object_1(aRange, theTokens, theChildren)
76
-
77
- # when 'member-list[0]'
78
- # reduce_member_list_0(aRange, theTokens, theChildren)
79
-
80
- # when 'member-list[1]'
81
- # reduce_member_list_1(aProduction, aRange, theTokens, theChildren)
82
-
83
- # when 'member[0]'
84
- # reduce_member_0(aProduction, aRange, theTokens, theChildren)
85
-
86
- # when 'array[0]'
87
- # reduce_array_0(aProduction, aRange, theTokens, theChildren)
88
-
89
- # when 'array[1]'
90
- # reduce_array_1(aRange, theTokens, theChildren)
91
-
92
- # when 'array-items[0]'
93
- # reduce_array_items_0(aRange, theTokens, theChildren)
94
-
95
- when 'sign[0]' # rule 'sign' => 'PLUS'
96
- return_first_child(aRange, theTokens, theChildren)
97
-
98
- when 'sign[1]' # rule 'sign' => 'MINUS'
99
- return_first_child(aRange, theTokens, theChildren)
100
-
101
- when 'sign[2]' #rule 'sign' => []
102
- reduce_sign_2(aProduction, aRange, theTokens, theChildren)
103
- else
104
- raise StandardError, "Don't know production #{aProduction.name}"
105
- end
106
-
107
- return node
108
- end
109
-
110
- # rule 'expression' => %w[sign simple_expression]
111
- def reduce_expression_0(aProduction, aRange, theTokens, theChildren)
112
- sign = theChildren[0]
113
- # Check type of sign
114
- node = if sign && sign.kind_of?(CalcNegateNode)
115
- sign.members << theChildren.last
116
- else
117
- theChildren.last
118
- end
119
-
120
- return node
121
- end
122
-
123
- # rule 'sign' => []
124
- def reduce_sign_2(aProduction, aRange, theTokens, theChildren)
125
- return nil # TODO; check whether this make sense
126
- end
127
- =begin
128
- second_child = theChildren[1]
129
- second_child.symbol = aProduction.lhs
130
- return second_child
131
- end
132
-
133
- # rule 'object' => %w[begin-object end-object]
134
- def reduce_object_1(aRange, theTokens, theChildren)
135
- return CalcObjectNode.new(aProduction.lhs)
136
- end
137
-
138
- # rule 'member-list' => %w[member-list value-separator member]
139
- def reduce_member_list_0(aRange, theTokens, theChildren)
140
- node = theChildren[0]
141
- node.members << theChildren.last
142
- return node
143
- end
144
-
145
- # rule 'member-list' => 'member'
146
- def reduce_member_list_1(aProduction, aRange, theTokens, theChildren)
147
- node = CalcObjectNode.new(aProduction.lhs)
148
- node.members << theChildren[0]
149
- return node
150
- end
151
-
152
- # rule 'member' => %w[string name-separator value]
153
- def reduce_member_0(aProduction, aRange, theTokens, theChildren)
154
- return CalcPair.new(theChildren[0], theChildren[2], aProduction.lhs)
155
- end
156
-
157
- # rule 'object' => %w[begin-object member-list end-object]
158
- def reduce_array_0(aProduction, aRange, theTokens, theChildren)
159
- second_child = theChildren[1]
160
- second_child.symbol = aProduction.lhs
161
- return second_child
162
- end
163
-
164
-
165
- # rule 'array' => %w[begin-array end-array]
166
- def reduce_array_1(aRange, theTokens, theChildren)
167
- return CalcArrayNode.new
168
- end
169
-
170
- # rule 'array-items' => %w[array-items value-separator value]
171
- def reduce_array_items_0(aRange, theTokens, theChildren)
172
- node = theChildren[0]
173
- node.children << theChildren[2]
174
- return node
175
- end
176
-
177
-
178
-
179
- # rule 'array-items' => %w[value]
180
- def reduce_array_items_1(aProduction, aRange, theTokens, theChildren)
181
- node = CalcArrayNode.new(aProduction.lhs)
182
- node.children << theChildren[0]
183
- return node
184
- end
185
- =end
186
- end # class
@@ -1,151 +0,0 @@
1
- # Classes that implement nodes of Abstract Syntax Trees (AST) representing
2
- # calculator parse results.
3
-
4
-
5
- CalcTerminalNode = Struct.new(:token, :value, :position) do
6
- def initialize(aToken, aPosition)
7
- self.token = aToken
8
- self.position = aPosition
9
- init_value(aToken.lexeme)
10
- end
11
-
12
- # This method can be overriden
13
- def init_value(aLiteral)
14
- self.value = aLiteral.dup
15
- end
16
-
17
- def symbol()
18
- self.token.terminal
19
- end
20
-
21
- def to_ruby()
22
- return value
23
- end
24
-
25
- # Part of the 'visitee' role in Visitor design pattern.
26
- # @param aVisitor[ParseTreeVisitor] the visitor
27
- def accept(aVisitor)
28
- aVisitor.visit_terminal(self)
29
- end
30
- end
31
-
32
- class CalcNumberNode < CalcTerminalNode
33
- def init_value(aLiteral)
34
- case aLiteral
35
- when /^[+-]?\d+$/
36
- self.value = aLiteral.to_i
37
-
38
- when /^[+-]?\d+(\.\d+)?([eE][+-]?\d+)?$/
39
- self.value = aLiteral.to_f
40
- end
41
- end
42
- end
43
-
44
- class CalcCompositeNode
45
- attr_accessor(:children)
46
- attr_accessor(:symbol)
47
-
48
- def initialize(aSymbol)
49
- @symbol = aSymbol
50
- @children = []
51
- end
52
-
53
- # Part of the 'visitee' role in Visitor design pattern.
54
- # @param aVisitor[ParseTreeVisitor] the visitor
55
- def accept(aVisitor)
56
- aVisitor.visit_nonterminal(self)
57
- end
58
-
59
- alias subnodes children
60
-
61
- end # class
62
-
63
- class CalcUnaryOpNode < CalcCompositeNode
64
- def initialize(aSymbol)
65
- super(aSymbol)
66
- end
67
-
68
- # Convert this tree node in a simpler Ruby representation.
69
- # Basically a Calc object corresponds to a Ruhy Hash
70
- def to_ruby()
71
- rep = {}
72
- members.each do |pair|
73
- rep[pair.name.to_ruby] = pair.value.to_ruby
74
- end
75
-
76
- return rep
77
- end
78
-
79
- alias members children
80
- end # class
81
-
82
- class CalcNegateNode CalcUnaryOpNode
83
- end # class
84
-
85
- class CalcBinaryOpNode < CalcCompositeNode
86
- def initialize(aSymbol)
87
- super(aSymbol)
88
- end
89
-
90
- end # class
91
-
92
- class CalcAddNode < CalcBinaryOpNode
93
-
94
- # Convert this tree node in a simpler Ruby representation.
95
- # Basically a Calc object corresponds to a Ruhy Hash
96
- def to_ruby()
97
- rep = []
98
- children.each do |child|
99
- rep << child.to_ruby
100
- end
101
-
102
- return rep
103
- end
104
- end # class
105
-
106
-
107
- class CalcSubtractNode < CalcBinaryOpNode
108
-
109
- # Convert this tree node in a simpler Ruby representation.
110
- # Basically a Calc object corresponds to a Ruhy Hash
111
- def to_ruby()
112
- rep = []
113
- children.each do |child|
114
- rep << child.to_ruby
115
- end
116
-
117
- return rep
118
- end
119
- end # class
120
-
121
- class CalcMultiplyNode < CalcBinaryOpNode
122
-
123
- # Convert this tree node in a simpler Ruby representation.
124
- # Basically a Calc object corresponds to a Ruhy Hash
125
- def to_ruby()
126
- rep = []
127
- children.each do |child|
128
- rep << child.to_ruby
129
- end
130
-
131
- return rep
132
- end
133
- end # class
134
-
135
- class CalcDivideNode < CalcBinaryOpNode
136
-
137
- # Convert this tree node in a simpler Ruby representation.
138
- # Basically a Calc object corresponds to a Ruhy Hash
139
- def to_ruby()
140
- rep = []
141
- children.each do |child|
142
- rep << child.to_ruby
143
- end
144
-
145
- return rep
146
- end
147
- end # class
148
-
149
-
150
-
151
-
@@ -1,40 +0,0 @@
1
- require_relative 'calc_parser'
2
-
3
- # Create a calculator parser object
4
- parser = CalcParser.new
5
-
6
- # Parse the input expression in command-line
7
- if ARGV.empty?
8
- my_name = File.basename(__FILE__)
9
- msg = <<-END_MSG
10
- Command-line symtax:
11
- ruby #{my_name} "arithmetic expression"
12
- where:
13
- the arithmetic expression is enclosed between double quotes (")
14
-
15
- Example:
16
- ruby #{my_name} "2 * 3 + (4 - 1)"
17
- END_MSG
18
- puts msg
19
- exit(1)
20
- end
21
- puts ARGV[0]
22
- result = parser.parse_expression(ARGV[0])
23
-
24
- unless result.success?
25
- # Stop if the parse failed...
26
- puts "Parsing of '#{ARGV[0]}' failed"
27
- puts "Reason: #{result.failure_reason.message}"
28
- exit(1)
29
- end
30
-
31
- # Generate a parse tree from the parse result
32
- ptree = result.parse_tree
33
-
34
- # Let's create a parse tree visitor
35
- visitor = Rley::ParseTreeVisitor.new(ptree)
36
-
37
- # Now output formatted parse tree
38
- renderer = Rley::Formatter::Asciitree.new($stdout)
39
- renderer.render(visitor)
40
- # End of file
@@ -1,28 +0,0 @@
1
- # Grammar for simple arithmetical expressions
2
- require 'rley' # Load the gem
3
-
4
- ########################################
5
- # Define a grammar for basic arithmetical expressions
6
- builder = Rley::Syntax::GrammarBuilder.new do
7
- add_terminals('NUMBER')
8
- add_terminals('LPAREN', 'RPAREN') # For '(', ')' delimiters
9
- add_terminals('PLUS', 'MINUS') # For '+', '-' operators or sign
10
- add_terminals('STAR', 'DIVIDE') # For '*', '/' operators
11
- rule 'expression' => %w[sign simple_expression]
12
- rule 'simple_expression' => 'term'
13
- rule 'simple_expression' => %w[simple_expression add_operator term]
14
- rule 'term' => 'factor'
15
- rule 'term' => %w[term mul_operator factor]
16
- rule 'factor' => 'NUMBER'
17
- rule 'factor' => %w[LPAREN expression RPAREN]
18
- rule 'sign' => 'PLUS'
19
- rule 'sign' => 'MINUS'
20
- rule 'sign' => []
21
- rule 'add_operator' => 'PLUS'
22
- rule 'add_operator' => 'MINUS'
23
- rule 'mul_operator' => 'STAR'
24
- rule 'mul_operator' => 'DIVIDE'
25
- end
26
-
27
- # And now build the grammar...
28
- CalcGrammar = builder.grammar