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.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -0
- data/CHANGELOG.md +5 -0
- data/examples/data_formats/JSON/json_ast_builder.rb +18 -19
- data/examples/data_formats/JSON/json_ast_nodes.rb +9 -12
- data/examples/data_formats/JSON/json_demo.rb +1 -1
- data/examples/general/calc_iter1/calc_ast_builder.rb +27 -30
- data/examples/general/calc_iter1/calc_ast_nodes.rb +8 -17
- data/examples/general/calc_iter1/calc_lexer.rb +4 -5
- data/examples/general/calc_iter1/spec/calculator_spec.rb +0 -2
- data/lib/rley/constants.rb +1 -1
- data/lib/rley/gfg/grm_flow_graph.rb +1 -1
- data/lib/rley/parser/cst_builder.rb +2 -3
- data/lib/rley/parser/parse_forest_factory.rb +1 -2
- data/lib/rley/parser/parse_tree_builder.rb +16 -19
- data/lib/rley/parser/parse_tree_factory.rb +0 -1
- data/lib/rley/parser/parse_walker_factory.rb +1 -1
- data/lib/rley/syntax/grammar.rb +17 -15
- data/spec/rley/gfg/grm_flow_graph_spec.rb +1 -1
- data/spec/rley/parser/ast_builder_spec.rb +29 -29
- data/spec/rley/parser/cst_builder_spec.rb +3 -3
- data/spec/rley/parser/error_reason_spec.rb +4 -4
- data/spec/rley/support/grammar_arr_int_helper.rb +3 -3
- data/spec/spec_helper.rb +6 -5
- metadata +2 -8
- data/examples/general/calc_iter2/calc_ast_builder.rb +0 -186
- data/examples/general/calc_iter2/calc_ast_nodes.rb +0 -151
- data/examples/general/calc_iter2/calc_demo.rb +0 -40
- data/examples/general/calc_iter2/calc_grammar.rb +0 -28
- data/examples/general/calc_iter2/calc_lexer.rb +0 -81
- data/examples/general/calc_iter2/calc_parser.rb +0 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bf5a9c73feeebf98f1714d89796bc073b406734e
|
4
|
+
data.tar.gz: 33aad5b8b337bb617bda98c55adfd94d9ebfba03
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b1bb0f88617f3ce5c6b7f964c7849e70a016d7889a9568a3d2ba310d4f42f094cc76167f9ca64cb7cae7f71ca00af672f791afb4ba3460199e383dfbeece78c2
|
7
|
+
data.tar.gz: db471ad23ae2a0bdf4f1408ed8371635cfe808808b5daa4454fa3b1189cc107a4ac99514e50f805cdfb58e1ff3ff61cfba8840a5dbeadad9f5766118e7424075
|
data/.rubocop.yml
CHANGED
@@ -54,6 +54,10 @@ EndOfLine:
|
|
54
54
|
IndentationWidth :
|
55
55
|
Enabled: false
|
56
56
|
|
57
|
+
# Disable this because it produces false negatives
|
58
|
+
Naming/HeredocDelimiterNaming:
|
59
|
+
Enabled: false
|
60
|
+
|
57
61
|
# Enabled after end of support of Rubies < 2.3
|
58
62
|
Layout/IndentHeredoc:
|
59
63
|
Enabled: false
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
### 0.5.03 / 2017-10-09
|
2
|
+
* [CHANGE] Refactoring code style to please Rubocop 0.50.0
|
3
|
+
* [CHANGE] File `.rubocop.yml`: Disabling heredoc cop because it produces false negatives
|
4
|
+
* [FIX] File `examples/general/calc_iter1/calc_ast_builder.rb`. Method CalcASTBuilder#new_leaf_node used old signature. Fixed
|
5
|
+
|
1
6
|
### 0.5.02 / 2017-10-08
|
2
7
|
* [NEW] Addedsupport for ASTs (Abstract Syntax Tree)
|
3
8
|
* [CHANGE] File `examples/data_formats/JSON/JSON_demo.rb` Added New command-line switches for details use --help option
|
@@ -9,12 +9,12 @@ require_relative 'json_ast_nodes'
|
|
9
9
|
# nodes) and using a step by step approach.
|
10
10
|
class JSONASTBuilder < Rley::Parser::ParseTreeBuilder
|
11
11
|
Terminal2NodeClass = {
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
'false' => JSONBooleanNode,
|
13
|
+
'true' => JSONBooleanNode,
|
14
|
+
'null' => JSONNullNode,
|
15
|
+
'string' => JSONStringNode,
|
16
|
+
'number' => JSONNumberNode
|
17
|
+
}.freeze
|
18
18
|
|
19
19
|
protected
|
20
20
|
|
@@ -39,12 +39,11 @@ class JSONASTBuilder < Rley::Parser::ParseTreeBuilder
|
|
39
39
|
# @param terminal [Terminal] Terminal symbol associated with the token
|
40
40
|
# @param aTokenPosition [Integer] Position of token in the input stream
|
41
41
|
# @param aToken [Token] The input token
|
42
|
-
def new_leaf_node(terminal, aTokenPosition, aToken)
|
42
|
+
def new_leaf_node(_production, terminal, aTokenPosition, aToken)
|
43
43
|
klass = Terminal2NodeClass.fetch(terminal.name, JSONTerminalNode)
|
44
44
|
return klass.new(aToken, aTokenPosition)
|
45
45
|
end
|
46
46
|
|
47
|
-
|
48
47
|
# Method to override.
|
49
48
|
# Factory method for creating a parent node object.
|
50
49
|
# @param aProduction [Production] Production rule
|
@@ -93,60 +92,60 @@ class JSONASTBuilder < Rley::Parser::ParseTreeBuilder
|
|
93
92
|
end
|
94
93
|
|
95
94
|
# rule 'object' => %w[begin-object member-list end-object]
|
96
|
-
def reduce_object_0(aProduction,
|
95
|
+
def reduce_object_0(aProduction, _range, _tokens, theChildren)
|
97
96
|
second_child = theChildren[1]
|
98
97
|
second_child.symbol = aProduction.lhs
|
99
98
|
return second_child
|
100
99
|
end
|
101
100
|
|
102
101
|
# rule 'object' => %w[begin-object end-object]
|
103
|
-
def reduce_object_1(
|
102
|
+
def reduce_object_1(aProduction, _range, _tokens, _children)
|
104
103
|
return JSONObjectNode.new(aProduction.lhs)
|
105
104
|
end
|
106
105
|
|
107
106
|
# rule 'member-list' => %w[member-list value-separator member]
|
108
|
-
def reduce_member_list_0(
|
107
|
+
def reduce_member_list_0(_range, _tokens, theChildren)
|
109
108
|
node = theChildren[0]
|
110
109
|
node.members << theChildren.last
|
111
110
|
return node
|
112
111
|
end
|
113
112
|
|
114
113
|
# rule 'member-list' => 'member'
|
115
|
-
def reduce_member_list_1(aProduction,
|
114
|
+
def reduce_member_list_1(aProduction, _range, _tokens, theChildren)
|
116
115
|
node = JSONObjectNode.new(aProduction.lhs)
|
117
116
|
node.members << theChildren[0]
|
118
117
|
return node
|
119
118
|
end
|
120
119
|
|
121
120
|
# rule 'member' => %w[string name-separator value]
|
122
|
-
def reduce_member_0(aProduction,
|
121
|
+
def reduce_member_0(aProduction, _range, _tokens, theChildren)
|
123
122
|
return JSONPair.new(theChildren[0], theChildren[2], aProduction.lhs)
|
124
123
|
end
|
125
124
|
|
126
125
|
# rule 'object' => %w[begin-object member-list end-object]
|
127
|
-
def reduce_array_0(aProduction,
|
126
|
+
def reduce_array_0(aProduction, _range, _tokens, theChildren)
|
128
127
|
second_child = theChildren[1]
|
129
128
|
second_child.symbol = aProduction.lhs
|
130
129
|
return second_child
|
131
130
|
end
|
132
131
|
|
133
|
-
|
134
132
|
# rule 'array' => %w[begin-array end-array]
|
135
|
-
def reduce_array_1(
|
133
|
+
def reduce_array_1(_range, _tokens, _children)
|
136
134
|
return JSONArrayNode.new
|
137
135
|
end
|
138
136
|
|
139
137
|
# rule 'array-items' => %w[array-items value-separator value]
|
140
|
-
def reduce_array_items_0(
|
138
|
+
def reduce_array_items_0(_range, _tokens, theChildren)
|
141
139
|
node = theChildren[0]
|
142
140
|
node.children << theChildren[2]
|
143
141
|
return node
|
144
142
|
end
|
145
143
|
|
146
144
|
# rule 'array-items' => %w[value]
|
147
|
-
def reduce_array_items_1(aProduction,
|
145
|
+
def reduce_array_items_1(aProduction, _range, _tokens, theChildren)
|
148
146
|
node = JSONArrayNode.new(aProduction.lhs)
|
149
147
|
node.children << theChildren[0]
|
150
148
|
return node
|
151
149
|
end
|
152
|
-
end # class
|
150
|
+
end # class
|
151
|
+
# End of file
|
@@ -15,18 +15,18 @@ JSONTerminalNode = Struct.new(:token, :value, :position) do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def symbol()
|
18
|
-
|
18
|
+
token.terminal
|
19
19
|
end
|
20
20
|
|
21
21
|
def to_ruby()
|
22
|
-
|
22
|
+
value
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
# Part of the 'visitee' role in Visitor design pattern.
|
26
26
|
# @param aVisitor[ParseTreeVisitor] the visitor
|
27
27
|
def accept(aVisitor)
|
28
28
|
aVisitor.visit_terminal(self)
|
29
|
-
end
|
29
|
+
end
|
30
30
|
end
|
31
31
|
|
32
32
|
|
@@ -45,7 +45,7 @@ end
|
|
45
45
|
class JSONStringNode < JSONTerminalNode
|
46
46
|
end
|
47
47
|
|
48
|
-
class JSONNumberNode
|
48
|
+
class JSONNumberNode < JSONTerminalNode
|
49
49
|
def init_value(aLiteral)
|
50
50
|
case aLiteral
|
51
51
|
when /^[+-]?\d+$/
|
@@ -63,7 +63,7 @@ class JSONCompositeNode
|
|
63
63
|
|
64
64
|
def initialize(aSymbol)
|
65
65
|
@symbol = aSymbol
|
66
|
-
@children = []
|
66
|
+
@children = []
|
67
67
|
end
|
68
68
|
|
69
69
|
# Part of the 'visitee' role in Visitor design pattern.
|
@@ -71,9 +71,8 @@ class JSONCompositeNode
|
|
71
71
|
def accept(aVisitor)
|
72
72
|
aVisitor.visit_nonterminal(self)
|
73
73
|
end
|
74
|
-
|
75
|
-
alias subnodes children
|
76
74
|
|
75
|
+
alias subnodes children
|
77
76
|
end # class
|
78
77
|
|
79
78
|
|
@@ -108,7 +107,7 @@ class JSONPair
|
|
108
107
|
def children()
|
109
108
|
return [name, value]
|
110
109
|
end
|
111
|
-
|
110
|
+
|
112
111
|
alias subnodes children
|
113
112
|
|
114
113
|
# Part of the 'visitee' role in Visitor design pattern.
|
@@ -116,7 +115,6 @@ class JSONPair
|
|
116
115
|
def accept(aVisitor)
|
117
116
|
aVisitor.visit_nonterminal(self)
|
118
117
|
end
|
119
|
-
|
120
118
|
end # class
|
121
119
|
|
122
120
|
class JSONObjectNode < JSONCompositeNode
|
@@ -137,5 +135,4 @@ class JSONObjectNode < JSONCompositeNode
|
|
137
135
|
|
138
136
|
alias members children
|
139
137
|
end # class
|
140
|
-
|
141
|
-
|
138
|
+
# End of file
|
@@ -43,7 +43,7 @@ case cli_options[:format]
|
|
43
43
|
raise StandardError, msg if tree_rep == :cst
|
44
44
|
end
|
45
45
|
|
46
|
-
tree_builder =
|
46
|
+
tree_builder = tree_rep == :ast ? JSONASTBuilder : nil
|
47
47
|
|
48
48
|
# Generate a parse tree from the parse result
|
49
49
|
ptree = result.parse_tree(tree_builder)
|
@@ -10,7 +10,7 @@ require_relative 'calc_ast_nodes'
|
|
10
10
|
class CalcASTBuilder < Rley::Parser::ParseTreeBuilder
|
11
11
|
Terminal2NodeClass = {
|
12
12
|
'NUMBER' => CalcNumberNode
|
13
|
-
}
|
13
|
+
}.freeze
|
14
14
|
|
15
15
|
protected
|
16
16
|
|
@@ -39,18 +39,17 @@ class CalcASTBuilder < Rley::Parser::ParseTreeBuilder
|
|
39
39
|
# @param aTerminal [Terminal] Terminal symbol associated with the token
|
40
40
|
# @param aTokenPosition [Integer] Position of token in the input stream
|
41
41
|
# @param aToken [Token] The input token
|
42
|
-
def new_leaf_node(
|
42
|
+
def new_leaf_node(_production, aTerminal, aTokenPosition, aToken)
|
43
43
|
klass = Terminal2NodeClass.fetch(aTerminal.name, CalcTerminalNode)
|
44
|
-
if klass
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
44
|
+
node = if klass
|
45
|
+
klass.new(aToken, aTokenPosition)
|
46
|
+
else
|
47
|
+
PTree::TerminalNode.new(aToken, aTokenPosition)
|
48
|
+
end
|
49
|
+
|
50
50
|
return node
|
51
51
|
end
|
52
52
|
|
53
|
-
|
54
53
|
# Method to override.
|
55
54
|
# Factory method for creating a parent node object.
|
56
55
|
# @param aProduction [Production] Production rule
|
@@ -83,15 +82,15 @@ class CalcASTBuilder < Rley::Parser::ParseTreeBuilder
|
|
83
82
|
|
84
83
|
when 'add_operator[0]' # rule 'add_operator' => 'PLUS'
|
85
84
|
reduce_add_operator_0(aProduction, aRange, theTokens, theChildren)
|
86
|
-
|
85
|
+
|
87
86
|
when 'add_operator[1]' # rule 'add_operator' => 'MINUS'
|
88
|
-
reduce_add_operator_1(aProduction, aRange, theTokens, theChildren)
|
87
|
+
reduce_add_operator_1(aProduction, aRange, theTokens, theChildren)
|
89
88
|
|
90
89
|
when 'mul_operator[0]' # rule 'mul_operator' => 'STAR'
|
91
90
|
reduce_mul_operator_0(aProduction, aRange, theTokens, theChildren)
|
92
|
-
|
91
|
+
|
93
92
|
when 'mul_operator[1]' # rule 'mul_operator' => 'DIVIDE'
|
94
|
-
reduce_mul_operator_1(aProduction, aRange, theTokens, theChildren)
|
93
|
+
reduce_mul_operator_1(aProduction, aRange, theTokens, theChildren)
|
95
94
|
|
96
95
|
else
|
97
96
|
raise StandardError, "Don't know production #{aProduction.name}"
|
@@ -99,44 +98,42 @@ class CalcASTBuilder < Rley::Parser::ParseTreeBuilder
|
|
99
98
|
|
100
99
|
return node
|
101
100
|
end
|
102
|
-
|
101
|
+
|
103
102
|
def reduce_binary_operator(theChildren)
|
104
103
|
operator_node = theChildren[1]
|
105
104
|
operator_node.children << theChildren[0]
|
106
105
|
operator_node.children << theChildren[2]
|
107
|
-
return operator_node
|
106
|
+
return operator_node
|
108
107
|
end
|
109
108
|
|
110
109
|
# rule 'simple_expression' => %w[simple_expression add_operator term]
|
111
|
-
def reduce_simple_expression_1(
|
110
|
+
def reduce_simple_expression_1(_production, _range, _tokens, theChildren)
|
112
111
|
reduce_binary_operator(theChildren)
|
113
112
|
end
|
114
113
|
|
115
|
-
|
116
114
|
# rule 'term' => %w[term mul_operator factor]
|
117
|
-
def reduce_term_1(
|
115
|
+
def reduce_term_1(_production, _range, _tokens, theChildren)
|
118
116
|
reduce_binary_operator(theChildren)
|
119
117
|
end
|
120
|
-
|
118
|
+
|
121
119
|
# rule 'add_operator' => 'PLUS'
|
122
|
-
def reduce_add_operator_0(
|
120
|
+
def reduce_add_operator_0(_production, _range, _tokens, theChildren)
|
123
121
|
return CalcAddNode.new(theChildren[0].symbol)
|
124
122
|
end
|
125
|
-
|
123
|
+
|
126
124
|
# rule 'add_operator' => 'MINUS'
|
127
|
-
def reduce_add_operator_1(
|
125
|
+
def reduce_add_operator_1(_production, _range, _tokens, theChildren)
|
128
126
|
return CalcSubtractNode.new(theChildren[0].symbol)
|
129
127
|
end
|
130
|
-
|
128
|
+
|
131
129
|
# rule 'mul_operator' => 'STAR'
|
132
|
-
def reduce_mul_operator_0(
|
130
|
+
def reduce_mul_operator_0(_production, _range, _tokens, theChildren)
|
133
131
|
return CalcMultiplyNode.new(theChildren[0].symbol)
|
134
132
|
end
|
135
|
-
|
133
|
+
|
136
134
|
# rule 'mul_operator' => 'DIVIDE'
|
137
|
-
def reduce_mul_operator_1(
|
135
|
+
def reduce_mul_operator_1(_production, _range, _tokens, theChildren)
|
138
136
|
return CalcDivideNode.new(theChildren[0].symbol)
|
139
|
-
end
|
140
|
-
|
141
|
-
|
142
|
-
end # class
|
137
|
+
end
|
138
|
+
end # class
|
139
|
+
# End of file
|
@@ -15,7 +15,7 @@ CalcTerminalNode = Struct.new(:token, :value, :position) do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def symbol()
|
18
|
-
|
18
|
+
token.terminal
|
19
19
|
end
|
20
20
|
|
21
21
|
def interpret()
|
@@ -29,7 +29,7 @@ CalcTerminalNode = Struct.new(:token, :value, :position) do
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
class CalcNumberNode
|
32
|
+
class CalcNumberNode < CalcTerminalNode
|
33
33
|
def init_value(aLiteral)
|
34
34
|
case aLiteral
|
35
35
|
when /^[+-]?\d+$/
|
@@ -57,7 +57,6 @@ class CalcCompositeNode
|
|
57
57
|
end
|
58
58
|
|
59
59
|
alias subnodes children
|
60
|
-
|
61
60
|
end # class
|
62
61
|
|
63
62
|
class CalcUnaryOpNode < CalcCompositeNode
|
@@ -89,7 +88,7 @@ class CalcBinaryOpNode < CalcCompositeNode
|
|
89
88
|
|
90
89
|
protected
|
91
90
|
|
92
|
-
def
|
91
|
+
def retrieve_operands()
|
93
92
|
operands = []
|
94
93
|
children.each do |child|
|
95
94
|
oper = child.respond_to?(:interpret) ? child.interpret : child
|
@@ -98,14 +97,12 @@ class CalcBinaryOpNode < CalcCompositeNode
|
|
98
97
|
|
99
98
|
return operands
|
100
99
|
end
|
101
|
-
|
102
100
|
end # class
|
103
101
|
|
104
102
|
class CalcAddNode < CalcBinaryOpNode
|
105
|
-
|
106
103
|
# TODO
|
107
104
|
def interpret()
|
108
|
-
operands =
|
105
|
+
operands = retrieve_operands
|
109
106
|
|
110
107
|
sum = operands[0] + operands[1]
|
111
108
|
return sum
|
@@ -114,10 +111,9 @@ end # class
|
|
114
111
|
|
115
112
|
|
116
113
|
class CalcSubtractNode < CalcBinaryOpNode
|
117
|
-
|
118
114
|
# TODO
|
119
115
|
def interpret()
|
120
|
-
operands =
|
116
|
+
operands = retrieve_operands
|
121
117
|
|
122
118
|
substraction = operands[0] - operands[1]
|
123
119
|
return substraction
|
@@ -125,27 +121,22 @@ class CalcSubtractNode < CalcBinaryOpNode
|
|
125
121
|
end # class
|
126
122
|
|
127
123
|
class CalcMultiplyNode < CalcBinaryOpNode
|
128
|
-
|
129
124
|
# TODO
|
130
125
|
def interpret()
|
131
|
-
operands =
|
126
|
+
operands = retrieve_operands
|
132
127
|
multiplication = operands[0] * operands[1]
|
133
128
|
return multiplication
|
134
129
|
end
|
135
130
|
end # class
|
136
131
|
|
137
132
|
class CalcDivideNode < CalcBinaryOpNode
|
138
|
-
|
139
133
|
# TODO
|
140
134
|
def interpret()
|
141
|
-
operands =
|
135
|
+
operands = retrieve_operands
|
142
136
|
numerator = operands[0].to_f
|
143
137
|
denominator = operands[1]
|
144
138
|
division = numerator / denominator
|
145
139
|
return division
|
146
140
|
end
|
147
141
|
end # class
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
142
|
+
# End of file
|
@@ -51,13 +51,13 @@ class CalcLexer
|
|
51
51
|
# Single character token
|
52
52
|
token = build_token(@@lexeme2name[curr_ch], scanner.getch)
|
53
53
|
|
54
|
-
elsif lexeme = scanner.scan(/\*\*/)
|
54
|
+
elsif (lexeme = scanner.scan(/\*\*/))
|
55
55
|
token = build_token(@@lexeme2name[lexeme], lexeme)
|
56
|
-
elsif lexeme = scanner.scan(/\*/)
|
56
|
+
elsif (lexeme = scanner.scan(/\*/))
|
57
57
|
token = build_token(@@lexeme2name[lexeme], lexeme)
|
58
|
-
elsif lexeme = scanner.scan(/-?[0-9]+(\.[0-9]+)?([eE][-+]?[0-9])?/)
|
58
|
+
elsif (lexeme = scanner.scan(/-?[0-9]+(\.[0-9]+)?([eE][-+]?[0-9])?/))
|
59
59
|
token = build_token('NUMBER', lexeme)
|
60
|
-
elsif lexeme = scanner.scan(/-/)
|
60
|
+
elsif (lexeme = scanner.scan(/-/))
|
61
61
|
token = build_token(@@lexeme2name[curr_ch], lexeme)
|
62
62
|
else # Unknown token
|
63
63
|
erroneous = curr_ch.nil? ? '' : curr_ch
|
@@ -77,5 +77,4 @@ class CalcLexer
|
|
77
77
|
def skip_whitespaces()
|
78
78
|
scanner.scan(/[ \t\f\n\r]+/)
|
79
79
|
end
|
80
|
-
|
81
80
|
end # class
|