yap-shell-parser 0.3.1 → 0.4.0
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/lib/yap/shell/parser/grammar.y +11 -1
- data/lib/yap/shell/parser/lexer.rb +23 -5
- data/lib/yap/shell/parser/nodes.rb +26 -0
- data/lib/yap/shell/parser/version.rb +1 -1
- data/lib/yap/shell/parser_impl.rb +198 -154
- data/spec/yap/shell/lexer_spec.rb +65 -9
- data/spec/yap/shell/parser_spec.rb +7 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 56c11c5e48960b86e262bf7b4c6dddf59cbbce51
|
4
|
+
data.tar.gz: 0120fd57b88b3ec458a5a88f9d6187e37ca33190
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 00370bf66d7d030a3aee98a670d5697b63f1a6ee2be3717db6f20968cf4ba7453c4f1ab2c6fc5bd864e7dfc9a265fb79462dd787c411dc24b389ccecadac9c71
|
7
|
+
data.tar.gz: 7bd7d734dabbdeafad2d892d23a5d2387218c7505be61b0431d1c639ac8c911fb4c5a97cae05653d69a5ba1e673fa3f62d2ac4347d0818698cbb094d3a979fd4
|
@@ -3,7 +3,7 @@
|
|
3
3
|
# convert Array-like string into Ruby's Array.
|
4
4
|
|
5
5
|
class Yap::Shell::ParserImpl
|
6
|
-
token Command LiteralCommand Argument Heredoc InternalEval Separator Conditional Pipe Redirection LValue RValue BeginCommandSubstitution EndCommandSubstitution Range BlockBegin BlockEnd BlockParams
|
6
|
+
token Command LiteralCommand Argument Heredoc InternalEval Separator Conditional Pipe Redirection LValue RValue BeginCommandSubstitution EndCommandSubstitution Range BlockBegin BlockEnd BlockParams BlankLine Comment
|
7
7
|
#
|
8
8
|
# prechigh
|
9
9
|
# # left '**' '*' '/' '%'
|
@@ -19,6 +19,8 @@ class Yap::Shell::ParserImpl
|
|
19
19
|
rule
|
20
20
|
|
21
21
|
program : stmts
|
22
|
+
| BlankLine
|
23
|
+
{ result = NoOpNode }
|
22
24
|
|
23
25
|
stmts : stmts Separator stmt
|
24
26
|
{ result = StatementsNode.new(val[0], val[2]) }
|
@@ -46,6 +48,12 @@ range_stmt : Range
|
|
46
48
|
pipeline : pipeline Pipe stmts2
|
47
49
|
{ result = PipelineNode.new(val[0], val[2]) }
|
48
50
|
| stmts2
|
51
|
+
| stmts2_w_comment
|
52
|
+
|
53
|
+
stmts2_w_comment : stmts2 Comment
|
54
|
+
{ result = StatementsNode.new(val[0], CommentNode.new(val[1])) }
|
55
|
+
| Comment
|
56
|
+
{ result = CommentNode.new(val[0]) }
|
49
57
|
|
50
58
|
stmts2 : '(' stmts ')'
|
51
59
|
{ result = val[1] }
|
@@ -65,6 +73,8 @@ stmt_w_substitutions2 : BeginCommandSubstitution stmts EndCommandSubstitution
|
|
65
73
|
command_w_heredoc : command_w_redirects Heredoc
|
66
74
|
{ val[0].heredoc = val[1] ; result = val[0] }
|
67
75
|
| command_w_redirects
|
76
|
+
| Redirection
|
77
|
+
{ result = RedirectionNode.new(val[0].value, val[0].attrs[:target]) }
|
68
78
|
|
69
79
|
command_w_redirects : command_w_redirects Redirection
|
70
80
|
{ val[0].redirects << RedirectionNode.new(val[1].value, val[1].attrs[:target]) ; result = val[0] }
|
@@ -37,9 +37,10 @@ module Yap::Shell
|
|
37
37
|
end
|
38
38
|
|
39
39
|
COMMAND_SUBSTITUTION = /\A(`|\$\()/
|
40
|
-
ARG = /[^\s;\|\(\)\{\}\[\]
|
40
|
+
ARG = /[^\s;\|\(\)\{\}\[\]\&\!\\\<\>`][^\s;\|\(\)\{\}\[\]\&\>\<`]*/
|
41
41
|
COMMAND = /\A(#{ARG})/
|
42
42
|
LITERAL_COMMAND = /\A\\(#{ARG})/
|
43
|
+
COMMENT = /\A#[^$]+/
|
43
44
|
WHITESPACE = /\A\s+/
|
44
45
|
LH_ASSIGNMENT = /\A(([A-z_][\w]*)=)/
|
45
46
|
RH_VALUE = /\A(\S+)/
|
@@ -55,12 +56,12 @@ module Yap::Shell
|
|
55
56
|
NUMERIC_RANGE = /\A\(((\d+)\.\.(\d+))\)(\.each)?/
|
56
57
|
NUMERIC_RANGE_W_CALL = /\A\(((\d+)\.\.(\d+))\)(\.each)?\s*:\s*/
|
57
58
|
NUMERIC_RANGE_W_PARAM = /\A(\((\d+)\.\.(\d+))\)\s+as\s+([A-z0-9,\s]+)\s*:\s*/
|
58
|
-
NUMERIC_REPETITION = /\A((\d+)(\.times))
|
59
|
+
NUMERIC_REPETITION = /\A((\d+)(\.times))/
|
59
60
|
NUMERIC_REPETITION_2 = /\A((\d+)(\.times))\s*:\s*/
|
60
61
|
NUMERIC_REPETITION_W_PARAM = /\A((\d+)(\.times))\s+as\s+([A-z0-9,\s]+)\s*:\s*/
|
61
62
|
|
62
|
-
BLOCK_BEGIN = /\A\s
|
63
|
-
BLOCK_END = /\A\s
|
63
|
+
BLOCK_BEGIN = /\A\s+(\{)\s*(?:\|\s*([A-z0-9,\s]+)\s*\|)?/
|
64
|
+
BLOCK_END = /\A\s+(\})\s*/
|
64
65
|
|
65
66
|
SPLIT_BLOCK_PARAMS_RGX = /\s*,\s*|\s*/
|
66
67
|
|
@@ -107,10 +108,12 @@ module Yap::Shell
|
|
107
108
|
max = 100
|
108
109
|
count = 0
|
109
110
|
@current_position = 0
|
111
|
+
last_position = -1
|
110
112
|
process_next_chunk = -> { @chunk = str.slice(@current_position..-1) ; @chunk != "" }
|
111
113
|
|
112
114
|
while process_next_chunk.call
|
113
115
|
result =
|
116
|
+
comment_token ||
|
114
117
|
block_token ||
|
115
118
|
numerical_range_token ||
|
116
119
|
command_substitution_token ||
|
@@ -127,8 +130,10 @@ module Yap::Shell
|
|
127
130
|
internal_eval_token
|
128
131
|
|
129
132
|
count += 1
|
130
|
-
raise "Infinite loop detected on #{@chunk.inspect}" if count == max
|
133
|
+
# raise "Infinite loop detected on #{@chunk.inspect}" if count == max
|
134
|
+
raise "Infinite loop detected in #{str.inspect}\non chunk:\n #{@chunk.inspect}" if @current_position == last_position
|
131
135
|
|
136
|
+
last_position = @current_position
|
132
137
|
@current_position += result.to_i
|
133
138
|
end
|
134
139
|
|
@@ -136,6 +141,8 @@ module Yap::Shell
|
|
136
141
|
token *args
|
137
142
|
end
|
138
143
|
|
144
|
+
token :BlankLine, str if @tokens.empty?
|
145
|
+
|
139
146
|
@tokens
|
140
147
|
end
|
141
148
|
|
@@ -161,6 +168,13 @@ module Yap::Shell
|
|
161
168
|
end
|
162
169
|
end
|
163
170
|
|
171
|
+
def comment_token
|
172
|
+
if md=@chunk.match(COMMENT)
|
173
|
+
token :Comment, md[0]
|
174
|
+
md[0].length
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
164
178
|
def numerical_range_token
|
165
179
|
return if @looking_for_args
|
166
180
|
|
@@ -311,10 +325,14 @@ module Yap::Shell
|
|
311
325
|
prev_char = ''
|
312
326
|
loop do
|
313
327
|
ch = @chunk[characters_read]
|
328
|
+
# binding.pry
|
314
329
|
if %w(' ").include?(ch)
|
315
330
|
result = process_string @chunk[characters_read..-1], ch
|
316
331
|
str << result.str
|
317
332
|
characters_read += result.consumed_length
|
333
|
+
elsif ch == '\\'
|
334
|
+
# no-op
|
335
|
+
characters_read += 1
|
318
336
|
elsif prev_char != '\\' && ch =~ /[\s\|;&\)\}]/
|
319
337
|
break
|
320
338
|
else
|
@@ -6,6 +6,14 @@ module Yap::Shell
|
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
|
+
module NoOpNode
|
10
|
+
extend Visitor
|
11
|
+
|
12
|
+
def self.accept(*args)
|
13
|
+
# no-op
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
9
17
|
class ArgumentNode
|
10
18
|
include Visitor
|
11
19
|
|
@@ -77,6 +85,24 @@ module Yap::Shell
|
|
77
85
|
end
|
78
86
|
end
|
79
87
|
|
88
|
+
class CommentNode
|
89
|
+
include Visitor
|
90
|
+
|
91
|
+
attr_reader :text
|
92
|
+
|
93
|
+
def initialize(text)
|
94
|
+
@text = text
|
95
|
+
end
|
96
|
+
|
97
|
+
def inspect
|
98
|
+
to_s
|
99
|
+
end
|
100
|
+
|
101
|
+
def to_s
|
102
|
+
"CommentNode(#{@text})"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
80
106
|
class EnvNode
|
81
107
|
include Visitor
|
82
108
|
|
@@ -21,7 +21,7 @@ module Yap
|
|
21
21
|
module Shell
|
22
22
|
class ParserImpl < Racc::Parser
|
23
23
|
|
24
|
-
module_eval(<<'...end grammar.y/module_eval...', 'grammar.y',
|
24
|
+
module_eval(<<'...end grammar.y/module_eval...', 'grammar.y', 125)
|
25
25
|
include Yap::Shell::Parser::Nodes
|
26
26
|
|
27
27
|
#=end
|
@@ -45,122 +45,131 @@ module_eval(<<'...end grammar.y/module_eval...', 'grammar.y', 115)
|
|
45
45
|
##### State transition tables begin ###
|
46
46
|
|
47
47
|
racc_action_table = [
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
nil,
|
60
|
-
nil,
|
61
|
-
|
48
|
+
25, 26, 29, 17, 27, 29, 29, 29, 19, 23,
|
49
|
+
34, 17, 60, 8, 32, 64, 62, 3, 11, 12,
|
50
|
+
25, 26, 56, 29, 27, 29, 30, 40, 19, 23,
|
51
|
+
58, 17, 41, 8, 31, 65, 25, 26, 11, 12,
|
52
|
+
27, 57, 25, 26, 19, 23, 27, 17, 38, 8,
|
53
|
+
19, 23, 59, 17, 11, 12, 25, 26, 30, 57,
|
54
|
+
27, 12, 25, 26, 19, 23, 31, 17, 57, 8,
|
55
|
+
47, 43, 54, 33, 11, 12, 25, 26, 33, 38,
|
56
|
+
27, 29, 25, 26, 19, 23, 27, 17, 38, 8,
|
57
|
+
19, 23, 28, 17, 11, 12, 17, 44, 25, 26,
|
58
|
+
11, 12, 27, 32, nil, nil, 19, 23, nil, 17,
|
59
|
+
nil, 8, nil, nil, 25, 26, 11, 12, 27, nil,
|
60
|
+
nil, nil, 19, 23, nil, 17, nil, 8, nil, nil,
|
61
|
+
25, 26, 11, 12, 27, nil, nil, nil, 19, 23,
|
62
|
+
nil, 17, nil, 8, nil, nil, 52, nil, 11, 12 ]
|
62
63
|
|
63
64
|
racc_action_check = [
|
64
|
-
0, 0,
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
28,
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
nil,
|
76
|
-
nil,
|
77
|
-
|
65
|
+
0, 0, 51, 9, 0, 61, 53, 36, 0, 0,
|
66
|
+
9, 0, 51, 0, 49, 61, 53, 0, 0, 0,
|
67
|
+
54, 54, 36, 39, 54, 63, 4, 18, 54, 54,
|
68
|
+
39, 54, 18, 54, 4, 63, 52, 52, 54, 54,
|
69
|
+
52, 37, 33, 33, 52, 52, 33, 52, 16, 52,
|
70
|
+
33, 33, 43, 33, 52, 52, 32, 32, 48, 45,
|
71
|
+
32, 33, 22, 22, 32, 32, 48, 32, 46, 32,
|
72
|
+
28, 22, 32, 6, 32, 32, 17, 17, 50, 26,
|
73
|
+
17, 2, 30, 30, 17, 17, 30, 17, 25, 17,
|
74
|
+
30, 30, 1, 30, 17, 17, 55, 23, 12, 12,
|
75
|
+
30, 30, 12, 5, nil, nil, 12, 12, nil, 12,
|
76
|
+
nil, 12, nil, nil, 29, 29, 12, 12, 29, nil,
|
77
|
+
nil, nil, 29, 29, nil, 29, nil, 29, nil, nil,
|
78
|
+
31, 31, 29, 29, 31, nil, nil, nil, 31, 31,
|
79
|
+
nil, 31, nil, 31, nil, nil, 31, nil, 31, 31 ]
|
78
80
|
|
79
81
|
racc_action_pointer = [
|
80
|
-
-2,
|
81
|
-
nil, nil, nil,
|
82
|
-
nil, 60,
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
nil ]
|
82
|
+
-2, 92, 74, nil, 18, 87, 64, nil, nil, -10,
|
83
|
+
nil, nil, 96, nil, nil, nil, 44, 74, 22, nil,
|
84
|
+
nil, nil, 60, 85, nil, 84, 75, nil, 70, 112,
|
85
|
+
80, 128, 54, 40, nil, nil, 0, 37, nil, 16,
|
86
|
+
nil, nil, nil, 40, nil, 55, 64, nil, 50, -2,
|
87
|
+
69, -5, 34, -1, 18, 83, nil, nil, nil, nil,
|
88
|
+
nil, -2, nil, 18, nil, nil ]
|
87
89
|
|
88
90
|
racc_action_default = [
|
89
|
-
-
|
90
|
-
-
|
91
|
-
-
|
92
|
-
-
|
93
|
-
-
|
94
|
-
|
95
|
-
-9 ]
|
91
|
+
-45, -45, -1, -2, -4, -5, -7, -8, -13, -15,
|
92
|
+
-16, -18, -45, -21, -22, -23, -25, -45, -28, -29,
|
93
|
+
-31, -32, -33, -45, -37, -38, -40, -44, -45, -45,
|
94
|
+
-45, -45, -45, -45, -17, -20, -45, -24, -42, -45,
|
95
|
+
-27, -30, -34, -45, -36, -39, -41, 66, -3, -45,
|
96
|
+
-6, -45, -45, -45, -45, -14, -19, -43, -26, -35,
|
97
|
+
-11, -45, -9, -45, -12, -10 ]
|
96
98
|
|
97
99
|
racc_goto_table = [
|
98
|
-
2,
|
99
|
-
|
100
|
-
nil, nil, nil, nil, nil, nil, nil, 46, 48, nil,
|
100
|
+
2, 35, 50, 49, 37, 55, 48, 1, 42, nil,
|
101
|
+
nil, nil, 36, 45, 46, nil, nil, 39, nil, nil,
|
101
102
|
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
102
|
-
nil, nil, nil,
|
103
|
+
nil, 51, 53, nil, nil, nil, nil, nil, nil, nil,
|
104
|
+
nil, nil, nil, nil, nil, nil, nil, 35, nil, nil,
|
105
|
+
nil, nil, 61, nil, 63 ]
|
103
106
|
|
104
107
|
racc_goto_check = [
|
105
|
-
2,
|
106
|
-
|
107
|
-
nil, nil, nil, nil, nil, nil, nil, 2, 2, nil,
|
108
|
+
2, 9, 5, 4, 13, 7, 3, 1, 16, nil,
|
109
|
+
nil, nil, 2, 13, 13, nil, nil, 2, nil, nil,
|
108
110
|
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
109
|
-
nil, nil, nil,
|
111
|
+
nil, 2, 2, nil, nil, nil, nil, nil, nil, nil,
|
112
|
+
nil, nil, nil, nil, nil, nil, nil, 9, nil, nil,
|
113
|
+
nil, nil, 2, nil, 2 ]
|
110
114
|
|
111
115
|
racc_goto_pointer = [
|
112
|
-
nil, 7, 0, -
|
113
|
-
nil, nil, -
|
116
|
+
nil, 7, 0, -23, -26, -28, nil, -28, nil, -8,
|
117
|
+
nil, nil, nil, -12, nil, nil, -14, nil, nil ]
|
114
118
|
|
115
119
|
racc_goto_default = [
|
116
|
-
nil, nil, nil,
|
117
|
-
|
120
|
+
nil, nil, nil, 4, 5, 6, 7, 9, 10, 13,
|
121
|
+
14, 15, 16, nil, 18, 20, 21, 22, 24 ]
|
118
122
|
|
119
123
|
racc_reduce_table = [
|
120
124
|
0, 0, :racc_error,
|
121
|
-
1, 22, :_reduce_none,
|
122
|
-
3, 23, :_reduce_2,
|
123
|
-
1, 23, :_reduce_3,
|
124
|
-
1, 23, :_reduce_none,
|
125
|
-
3, 24, :_reduce_5,
|
126
125
|
1, 24, :_reduce_none,
|
127
|
-
1, 24, :
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
1, 25, :_reduce_12,
|
133
|
-
3, 26, :_reduce_13,
|
126
|
+
1, 24, :_reduce_2,
|
127
|
+
3, 25, :_reduce_3,
|
128
|
+
1, 25, :_reduce_4,
|
129
|
+
1, 25, :_reduce_none,
|
130
|
+
3, 26, :_reduce_6,
|
134
131
|
1, 26, :_reduce_none,
|
135
|
-
|
136
|
-
|
137
|
-
|
132
|
+
1, 26, :_reduce_none,
|
133
|
+
4, 29, :_reduce_9,
|
134
|
+
5, 29, :_reduce_10,
|
135
|
+
4, 29, :_reduce_11,
|
136
|
+
5, 29, :_reduce_12,
|
137
|
+
1, 27, :_reduce_13,
|
138
|
+
3, 28, :_reduce_14,
|
138
139
|
1, 28, :_reduce_none,
|
139
140
|
1, 28, :_reduce_none,
|
140
|
-
2,
|
141
|
-
1,
|
142
|
-
3,
|
143
|
-
2, 30, :
|
141
|
+
2, 31, :_reduce_17,
|
142
|
+
1, 31, :_reduce_18,
|
143
|
+
3, 30, :_reduce_19,
|
144
|
+
2, 30, :_reduce_20,
|
145
|
+
1, 30, :_reduce_none,
|
146
|
+
1, 30, :_reduce_none,
|
144
147
|
1, 30, :_reduce_none,
|
145
|
-
2,
|
146
|
-
1,
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
2, 37, :
|
152
|
-
1,
|
153
|
-
1,
|
148
|
+
2, 32, :_reduce_24,
|
149
|
+
1, 32, :_reduce_none,
|
150
|
+
3, 35, :_reduce_26,
|
151
|
+
2, 33, :_reduce_27,
|
152
|
+
1, 33, :_reduce_none,
|
153
|
+
1, 33, :_reduce_29,
|
154
|
+
2, 37, :_reduce_30,
|
155
|
+
1, 37, :_reduce_none,
|
156
|
+
1, 37, :_reduce_none,
|
157
|
+
1, 37, :_reduce_none,
|
154
158
|
2, 38, :_reduce_34,
|
155
|
-
|
156
|
-
2,
|
157
|
-
1,
|
158
|
-
|
159
|
-
|
159
|
+
3, 40, :_reduce_35,
|
160
|
+
2, 40, :_reduce_36,
|
161
|
+
1, 39, :_reduce_none,
|
162
|
+
1, 41, :_reduce_38,
|
163
|
+
2, 41, :_reduce_39,
|
164
|
+
1, 41, :_reduce_40,
|
165
|
+
2, 41, :_reduce_41,
|
166
|
+
1, 36, :_reduce_42,
|
167
|
+
2, 36, :_reduce_43,
|
168
|
+
1, 34, :_reduce_44 ]
|
160
169
|
|
161
|
-
racc_reduce_n =
|
170
|
+
racc_reduce_n = 45
|
162
171
|
|
163
|
-
racc_shift_n =
|
172
|
+
racc_shift_n = 66
|
164
173
|
|
165
174
|
racc_token_table = {
|
166
175
|
false => 0,
|
@@ -182,10 +191,12 @@ racc_token_table = {
|
|
182
191
|
:BlockBegin => 16,
|
183
192
|
:BlockEnd => 17,
|
184
193
|
:BlockParams => 18,
|
185
|
-
|
186
|
-
|
194
|
+
:BlankLine => 19,
|
195
|
+
:Comment => 20,
|
196
|
+
"(" => 21,
|
197
|
+
")" => 22 }
|
187
198
|
|
188
|
-
racc_nt_base =
|
199
|
+
racc_nt_base = 23
|
189
200
|
|
190
201
|
racc_use_result_var = true
|
191
202
|
|
@@ -225,6 +236,8 @@ Racc_token_to_s_table = [
|
|
225
236
|
"BlockBegin",
|
226
237
|
"BlockEnd",
|
227
238
|
"BlockParams",
|
239
|
+
"BlankLine",
|
240
|
+
"Comment",
|
228
241
|
"\"(\"",
|
229
242
|
"\")\"",
|
230
243
|
"$start",
|
@@ -235,6 +248,7 @@ Racc_token_to_s_table = [
|
|
235
248
|
"pipeline",
|
236
249
|
"block_stmt",
|
237
250
|
"stmts2",
|
251
|
+
"stmts2_w_comment",
|
238
252
|
"stmt_w_substitutions",
|
239
253
|
"command_w_heredoc",
|
240
254
|
"internal_eval",
|
@@ -254,202 +268,232 @@ Racc_debug_parser = false
|
|
254
268
|
|
255
269
|
# reduce 1 omitted
|
256
270
|
|
257
|
-
module_eval(<<'.,.,', 'grammar.y',
|
271
|
+
module_eval(<<'.,.,', 'grammar.y', 22)
|
258
272
|
def _reduce_2(val, _values, result)
|
259
|
-
result =
|
273
|
+
result = NoOpNode
|
260
274
|
result
|
261
275
|
end
|
262
276
|
.,.,
|
263
277
|
|
264
278
|
module_eval(<<'.,.,', 'grammar.y', 25)
|
265
279
|
def _reduce_3(val, _values, result)
|
280
|
+
result = StatementsNode.new(val[0], val[2])
|
281
|
+
result
|
282
|
+
end
|
283
|
+
.,.,
|
284
|
+
|
285
|
+
module_eval(<<'.,.,', 'grammar.y', 27)
|
286
|
+
def _reduce_4(val, _values, result)
|
266
287
|
result = StatementsNode.new(val[0])
|
267
288
|
result
|
268
289
|
end
|
269
290
|
.,.,
|
270
291
|
|
271
|
-
# reduce
|
292
|
+
# reduce 5 omitted
|
272
293
|
|
273
|
-
module_eval(<<'.,.,', 'grammar.y',
|
274
|
-
def
|
294
|
+
module_eval(<<'.,.,', 'grammar.y', 31)
|
295
|
+
def _reduce_6(val, _values, result)
|
275
296
|
result = ConditionalNode.new(val[1].value, val[0], val[2])
|
276
297
|
result
|
277
298
|
end
|
278
299
|
.,.,
|
279
300
|
|
280
|
-
# reduce 6 omitted
|
281
|
-
|
282
301
|
# reduce 7 omitted
|
283
302
|
|
284
|
-
|
285
|
-
def _reduce_8(val, _values, result)
|
286
|
-
result = val[0].tap { |range_node| range_node.tail = BlockNode.new(nil, val[2]) }
|
287
|
-
result
|
288
|
-
end
|
289
|
-
.,.,
|
303
|
+
# reduce 8 omitted
|
290
304
|
|
291
305
|
module_eval(<<'.,.,', 'grammar.y', 36)
|
292
306
|
def _reduce_9(val, _values, result)
|
293
|
-
result = val[0].tap { |range_node| range_node.tail = BlockNode.new(nil, val[
|
307
|
+
result = val[0].tap { |range_node| range_node.tail = BlockNode.new(nil, val[2]) }
|
294
308
|
result
|
295
309
|
end
|
296
310
|
.,.,
|
297
311
|
|
298
312
|
module_eval(<<'.,.,', 'grammar.y', 38)
|
299
313
|
def _reduce_10(val, _values, result)
|
300
|
-
result = BlockNode.new(val[
|
314
|
+
result = val[0].tap { |range_node| range_node.tail = BlockNode.new(nil, val[3], params: val[2].value) }
|
301
315
|
result
|
302
316
|
end
|
303
317
|
.,.,
|
304
318
|
|
305
319
|
module_eval(<<'.,.,', 'grammar.y', 40)
|
306
320
|
def _reduce_11(val, _values, result)
|
307
|
-
result = BlockNode.new(val[0], val[
|
321
|
+
result = BlockNode.new(val[0], val[2])
|
308
322
|
result
|
309
323
|
end
|
310
324
|
.,.,
|
311
325
|
|
312
|
-
module_eval(<<'.,.,', 'grammar.y',
|
326
|
+
module_eval(<<'.,.,', 'grammar.y', 42)
|
313
327
|
def _reduce_12(val, _values, result)
|
314
|
-
result =
|
328
|
+
result = BlockNode.new(val[0], val[3], params: val[2].value)
|
315
329
|
result
|
316
330
|
end
|
317
331
|
.,.,
|
318
332
|
|
319
|
-
module_eval(<<'.,.,', 'grammar.y',
|
333
|
+
module_eval(<<'.,.,', 'grammar.y', 45)
|
320
334
|
def _reduce_13(val, _values, result)
|
335
|
+
result = RangeNode.new(val[0])
|
336
|
+
result
|
337
|
+
end
|
338
|
+
.,.,
|
339
|
+
|
340
|
+
module_eval(<<'.,.,', 'grammar.y', 48)
|
341
|
+
def _reduce_14(val, _values, result)
|
321
342
|
result = PipelineNode.new(val[0], val[2])
|
322
343
|
result
|
323
344
|
end
|
324
345
|
.,.,
|
325
346
|
|
326
|
-
# reduce
|
347
|
+
# reduce 15 omitted
|
348
|
+
|
349
|
+
# reduce 16 omitted
|
350
|
+
|
351
|
+
module_eval(<<'.,.,', 'grammar.y', 53)
|
352
|
+
def _reduce_17(val, _values, result)
|
353
|
+
result = StatementsNode.new(val[0], CommentNode.new(val[1]))
|
354
|
+
result
|
355
|
+
end
|
356
|
+
.,.,
|
357
|
+
|
358
|
+
module_eval(<<'.,.,', 'grammar.y', 55)
|
359
|
+
def _reduce_18(val, _values, result)
|
360
|
+
result = CommentNode.new(val[0])
|
361
|
+
result
|
362
|
+
end
|
363
|
+
.,.,
|
327
364
|
|
328
|
-
module_eval(<<'.,.,', 'grammar.y',
|
329
|
-
def
|
365
|
+
module_eval(<<'.,.,', 'grammar.y', 58)
|
366
|
+
def _reduce_19(val, _values, result)
|
330
367
|
result = val[1]
|
331
368
|
result
|
332
369
|
end
|
333
370
|
.,.,
|
334
371
|
|
335
|
-
module_eval(<<'.,.,', 'grammar.y',
|
336
|
-
def
|
372
|
+
module_eval(<<'.,.,', 'grammar.y', 60)
|
373
|
+
def _reduce_20(val, _values, result)
|
337
374
|
result = ConcatenationNode.new(val[0], val[1])
|
338
375
|
result
|
339
376
|
end
|
340
377
|
.,.,
|
341
378
|
|
342
|
-
# reduce
|
379
|
+
# reduce 21 omitted
|
343
380
|
|
344
|
-
# reduce
|
381
|
+
# reduce 22 omitted
|
345
382
|
|
346
|
-
# reduce
|
383
|
+
# reduce 23 omitted
|
347
384
|
|
348
|
-
module_eval(<<'.,.,', 'grammar.y',
|
349
|
-
def
|
385
|
+
module_eval(<<'.,.,', 'grammar.y', 66)
|
386
|
+
def _reduce_24(val, _values, result)
|
350
387
|
result = val[0] ; val[0].tail = val[1]
|
351
388
|
result
|
352
389
|
end
|
353
390
|
.,.,
|
354
391
|
|
355
|
-
# reduce
|
392
|
+
# reduce 25 omitted
|
356
393
|
|
357
|
-
module_eval(<<'.,.,', 'grammar.y',
|
358
|
-
def
|
394
|
+
module_eval(<<'.,.,', 'grammar.y', 70)
|
395
|
+
def _reduce_26(val, _values, result)
|
359
396
|
result = CommandSubstitutionNode.new(val[1])
|
360
397
|
result
|
361
398
|
end
|
362
399
|
.,.,
|
363
400
|
|
364
|
-
module_eval(<<'.,.,', 'grammar.y',
|
365
|
-
def
|
401
|
+
module_eval(<<'.,.,', 'grammar.y', 73)
|
402
|
+
def _reduce_27(val, _values, result)
|
366
403
|
val[0].heredoc = val[1] ; result = val[0]
|
367
404
|
result
|
368
405
|
end
|
369
406
|
.,.,
|
370
407
|
|
371
|
-
# reduce
|
408
|
+
# reduce 28 omitted
|
372
409
|
|
373
|
-
module_eval(<<'.,.,', 'grammar.y',
|
374
|
-
def
|
410
|
+
module_eval(<<'.,.,', 'grammar.y', 76)
|
411
|
+
def _reduce_29(val, _values, result)
|
412
|
+
result = RedirectionNode.new(val[0].value, val[0].attrs[:target])
|
413
|
+
result
|
414
|
+
end
|
415
|
+
.,.,
|
416
|
+
|
417
|
+
module_eval(<<'.,.,', 'grammar.y', 79)
|
418
|
+
def _reduce_30(val, _values, result)
|
375
419
|
val[0].redirects << RedirectionNode.new(val[1].value, val[1].attrs[:target]) ; result = val[0]
|
376
420
|
result
|
377
421
|
end
|
378
422
|
.,.,
|
379
423
|
|
380
|
-
# reduce
|
424
|
+
# reduce 31 omitted
|
381
425
|
|
382
|
-
# reduce
|
426
|
+
# reduce 32 omitted
|
383
427
|
|
384
|
-
# reduce
|
428
|
+
# reduce 33 omitted
|
385
429
|
|
386
|
-
module_eval(<<'.,.,', 'grammar.y',
|
387
|
-
def
|
430
|
+
module_eval(<<'.,.,', 'grammar.y', 85)
|
431
|
+
def _reduce_34(val, _values, result)
|
388
432
|
result = EnvWrapperNode.new(val[0], val[1])
|
389
433
|
result
|
390
434
|
end
|
391
435
|
.,.,
|
392
436
|
|
393
|
-
module_eval(<<'.,.,', 'grammar.y',
|
394
|
-
def
|
437
|
+
module_eval(<<'.,.,', 'grammar.y', 88)
|
438
|
+
def _reduce_35(val, _values, result)
|
395
439
|
val[0].add_var(val[1].value, val[2].value) ; result = val[0]
|
396
440
|
result
|
397
441
|
end
|
398
442
|
.,.,
|
399
443
|
|
400
|
-
module_eval(<<'.,.,', 'grammar.y',
|
401
|
-
def
|
444
|
+
module_eval(<<'.,.,', 'grammar.y', 90)
|
445
|
+
def _reduce_36(val, _values, result)
|
402
446
|
result = EnvNode.new(val[0].value, val[1].value)
|
403
447
|
result
|
404
448
|
end
|
405
449
|
.,.,
|
406
450
|
|
407
|
-
# reduce
|
451
|
+
# reduce 37 omitted
|
408
452
|
|
409
|
-
module_eval(<<'.,.,', 'grammar.y',
|
410
|
-
def
|
453
|
+
module_eval(<<'.,.,', 'grammar.y', 95)
|
454
|
+
def _reduce_38(val, _values, result)
|
411
455
|
result = CommandNode.new(val[0].value)
|
412
456
|
result
|
413
457
|
end
|
414
458
|
.,.,
|
415
459
|
|
416
|
-
module_eval(<<'.,.,', 'grammar.y',
|
417
|
-
def
|
460
|
+
module_eval(<<'.,.,', 'grammar.y', 97)
|
461
|
+
def _reduce_39(val, _values, result)
|
418
462
|
result = CommandNode.new(val[0].value, val[1].flatten)
|
419
463
|
result
|
420
464
|
end
|
421
465
|
.,.,
|
422
466
|
|
423
|
-
module_eval(<<'.,.,', 'grammar.y',
|
424
|
-
def
|
467
|
+
module_eval(<<'.,.,', 'grammar.y', 99)
|
468
|
+
def _reduce_40(val, _values, result)
|
425
469
|
result = CommandNode.new(val[0].value, literal:true)
|
426
470
|
result
|
427
471
|
end
|
428
472
|
.,.,
|
429
473
|
|
430
|
-
module_eval(<<'.,.,', 'grammar.y',
|
431
|
-
def
|
474
|
+
module_eval(<<'.,.,', 'grammar.y', 101)
|
475
|
+
def _reduce_41(val, _values, result)
|
432
476
|
result = CommandNode.new(val[0].value, val[1].flatten, literal:true)
|
433
477
|
result
|
434
478
|
end
|
435
479
|
.,.,
|
436
480
|
|
437
|
-
module_eval(<<'.,.,', 'grammar.y',
|
438
|
-
def
|
481
|
+
module_eval(<<'.,.,', 'grammar.y', 104)
|
482
|
+
def _reduce_42(val, _values, result)
|
439
483
|
result = [ArgumentNode.new(val[0].value)]
|
440
484
|
result
|
441
485
|
end
|
442
486
|
.,.,
|
443
487
|
|
444
|
-
module_eval(<<'.,.,', 'grammar.y',
|
445
|
-
def
|
488
|
+
module_eval(<<'.,.,', 'grammar.y', 106)
|
489
|
+
def _reduce_43(val, _values, result)
|
446
490
|
result = [val[0], ArgumentNode.new(val[1].value)].flatten
|
447
491
|
result
|
448
492
|
end
|
449
493
|
.,.,
|
450
494
|
|
451
|
-
module_eval(<<'.,.,', 'grammar.y',
|
452
|
-
def
|
495
|
+
module_eval(<<'.,.,', 'grammar.y', 109)
|
496
|
+
def _reduce_44(val, _values, result)
|
453
497
|
result = InternalEvalNode.new(val[0].value)
|
454
498
|
result
|
455
499
|
end
|
@@ -9,6 +9,37 @@ describe Yap::Shell::Parser::Lexer do
|
|
9
9
|
[tag, Yap::Shell::Parser::Lexer::Token.new(tag, val, lineno:lineno, attrs:attrs)]
|
10
10
|
end
|
11
11
|
|
12
|
+
describe "blank lines" do
|
13
|
+
describe "" do
|
14
|
+
it { should eq [
|
15
|
+
t(:BlankLine, "", lineno:0)
|
16
|
+
]}
|
17
|
+
end
|
18
|
+
|
19
|
+
describe " " do
|
20
|
+
it { should eq [
|
21
|
+
t(:BlankLine, " ", lineno:0)
|
22
|
+
]}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "comments" do
|
27
|
+
describe "hash symbol and everything there-after is a comment" do
|
28
|
+
describe "#this is a comment" do
|
29
|
+
it { should eq [
|
30
|
+
t(:Comment, "#this is a comment", lineno:0)
|
31
|
+
]}
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "ls #this last part is a comment" do
|
35
|
+
it { should eq [
|
36
|
+
t(:Command, "ls", lineno:0),
|
37
|
+
t(:Comment, "#this last part is a comment", lineno:0)
|
38
|
+
]}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
12
43
|
describe "block expressions" do
|
13
44
|
describe "can follow any command" do
|
14
45
|
describe "ls { this_is_a_block }" do
|
@@ -20,7 +51,7 @@ describe Yap::Shell::Parser::Lexer do
|
|
20
51
|
]}
|
21
52
|
end
|
22
53
|
|
23
|
-
describe "whitespace before
|
54
|
+
describe "whitespace is required before the start of the block, but not after" do
|
24
55
|
describe " ls { this_is_a_block } " do
|
25
56
|
it { should eq [
|
26
57
|
t(:Command, "ls", lineno:0),
|
@@ -30,7 +61,7 @@ describe Yap::Shell::Parser::Lexer do
|
|
30
61
|
]}
|
31
62
|
end
|
32
63
|
|
33
|
-
describe "ls {echo n}" do
|
64
|
+
describe "ls { echo n }" do
|
34
65
|
it { should eq [
|
35
66
|
t(:Command, "ls", lineno:0),
|
36
67
|
t(:BlockBegin, '{', lineno: 0),
|
@@ -39,6 +70,22 @@ describe Yap::Shell::Parser::Lexer do
|
|
39
70
|
t(:BlockEnd, '}', lineno: 0)
|
40
71
|
]}
|
41
72
|
end
|
73
|
+
|
74
|
+
describe "ls {echo n }" do
|
75
|
+
it { should eq [
|
76
|
+
t(:Command, "ls", lineno:0),
|
77
|
+
t(:BlockBegin, '{', lineno: 0),
|
78
|
+
t(:Command, "echo", lineno:0),
|
79
|
+
t(:Argument, "n", lineno:0),
|
80
|
+
t(:BlockEnd, '}', lineno: 0)
|
81
|
+
]}
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "ls s{ echo n}" do
|
85
|
+
it "fails to lex" do
|
86
|
+
expect { subject }.to raise_error
|
87
|
+
end
|
88
|
+
end
|
42
89
|
end
|
43
90
|
end
|
44
91
|
|
@@ -278,11 +325,6 @@ describe Yap::Shell::Parser::Lexer do
|
|
278
325
|
end
|
279
326
|
end
|
280
327
|
|
281
|
-
describe "empty string" do
|
282
|
-
let(:str){ "" }
|
283
|
-
it { should eq [] }
|
284
|
-
end
|
285
|
-
|
286
328
|
describe "string with newlines" do
|
287
329
|
let(:str){ "ls \n\nlib:\ntasks\nyap\nyap.rb" }
|
288
330
|
it { should eq [
|
@@ -404,11 +446,11 @@ describe Yap::Shell::Parser::Lexer do
|
|
404
446
|
]}
|
405
447
|
end
|
406
448
|
|
407
|
-
describe "commands with
|
449
|
+
describe "commands with escaped spaces: ls some\ dir" do
|
408
450
|
let(:str){ 'ls some\ dir' }
|
409
451
|
it { should eq [
|
410
452
|
t(:Command, "ls", lineno:0),
|
411
|
-
t(:Argument, 'some
|
453
|
+
t(:Argument, 'some dir', lineno:0)
|
412
454
|
]}
|
413
455
|
end
|
414
456
|
|
@@ -878,6 +920,20 @@ describe Yap::Shell::Parser::Lexer do
|
|
878
920
|
t(:Redirection, ">", lineno: 0, attrs: { target: "a.txt" }),
|
879
921
|
]}
|
880
922
|
end
|
923
|
+
|
924
|
+
describe "can be the start of a command (for clearing files)" do
|
925
|
+
describe "> a.txt" do
|
926
|
+
it { should eq [
|
927
|
+
t(:Redirection, ">", lineno: 0, attrs: { target: "a.txt" })
|
928
|
+
]}
|
929
|
+
end
|
930
|
+
|
931
|
+
describe ">foo.txt" do
|
932
|
+
it { should eq [
|
933
|
+
t(:Redirection, ">", lineno: 0, attrs: { target: "foo.txt" })
|
934
|
+
]}
|
935
|
+
end
|
936
|
+
end
|
881
937
|
end
|
882
938
|
|
883
939
|
describe "stderr" do
|
@@ -14,6 +14,8 @@ describe Yap::Shell::Parser do
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
+
it { is_expected.to parse "" }
|
18
|
+
it { is_expected.to parse " " }
|
17
19
|
it { is_expected.to parse "ls" }
|
18
20
|
it { is_expected.to parse "echo foo" }
|
19
21
|
it { is_expected.to parse "echo foo ; echo bar baz yep" }
|
@@ -52,9 +54,13 @@ describe Yap::Shell::Parser do
|
|
52
54
|
it { is_expected.to parse "(0..3)" }
|
53
55
|
it { is_expected.to parse "(0..3): echo hi" }
|
54
56
|
it { is_expected.to parse "(0..3) as n: echo hi $n" }
|
55
|
-
it { is_expected.to parse "echo hi ; (0..3) {echo hi $n}" }
|
57
|
+
it { is_expected.to parse "echo hi ; (0..3) {echo hi $n }" }
|
56
58
|
it { is_expected.to parse "echo hi ; (0..3) { echo hi $n } ; echo bye" }
|
57
59
|
it { is_expected.to parse "ls *.rb { |f,g,h| echo $f && echo $h && echo $i }" }
|
60
|
+
it { is_expected.to parse ">foo.txt" }
|
61
|
+
it { is_expected.to parse "echo bar && > foo.txt" }
|
62
|
+
it { is_expected.to parse "#this is a comment" }
|
63
|
+
it { is_expected.to parse "echo foo #this last part is a comment" }
|
58
64
|
|
59
65
|
it { is_expected.to fail_parsing "ls ()" }
|
60
66
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yap-shell-parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Zach Dennis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-03-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -122,3 +122,4 @@ test_files:
|
|
122
122
|
- spec/spec_helper.rb
|
123
123
|
- spec/yap/shell/lexer_spec.rb
|
124
124
|
- spec/yap/shell/parser_spec.rb
|
125
|
+
has_rdoc:
|