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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b1f871f25358079c9bb5bfda0d59b77504b36b88
4
- data.tar.gz: ae41ab9e03b55318f48c9fd739448600c30e545c
3
+ metadata.gz: 56c11c5e48960b86e262bf7b4c6dddf59cbbce51
4
+ data.tar.gz: 0120fd57b88b3ec458a5a88f9d6187e37ca33190
5
5
  SHA512:
6
- metadata.gz: 2b6dc9b5ebfee853ef445c1f8a60ed9e9ca8d81365497f2ae5fda0e64721ffa215c451ebd1cd95c8485759fa918d0085c7b8dfc75a1cbf7be823d2969e6f8356
7
- data.tar.gz: fd2670a3b93ec221a664a71e0280ef79b5cf25f7a968abde4d2655188f89c5bbcf2de784f574f3a8ecd4355ab007ea1fcadc7d7253477b12e02962d0e37a4c34
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;\|\(\)\{\}\[\]\&\!\\\<`][^\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))\s*/
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*(\{)\s*(?:\|\s*([A-z0-9,\s]+)\s*\|)?/
63
- BLOCK_END = /\A\s*(\})\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
 
@@ -3,7 +3,7 @@ require 'yap/shell/parser'
3
3
  module Yap
4
4
  module Shell
5
5
  module Parser
6
- VERSION = "0.3.1"
6
+ VERSION = "0.4.0"
7
7
  end
8
8
  end
9
9
  end
@@ -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', 115)
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
- 21, 22, 25, 25, 23, 28, 14, 52, 33, 19,
49
- 25, 14, 55, 7, 21, 22, 51, 9, 23, 54,
50
- 59, 21, 22, 19, 25, 14, 25, 7, 21, 22,
51
- 38, 9, 23, 35, 57, 52, 60, 19, 36, 14,
52
- 26, 7, 21, 22, 26, 9, 23, 52, 27, 25,
53
- 42, 19, 27, 14, 21, 22, 53, 29, 23, 9,
54
- 29, 33, 25, 19, 33, 14, 24, 7, 21, 22,
55
- 49, 9, 23, 14, 39, 28, nil, 19, nil, 14,
56
- nil, 7, 21, 22, nil, 9, 23, nil, nil, nil,
57
- nil, 19, nil, 14, 21, 22, nil, nil, 23, 9,
58
- nil, nil, nil, 19, nil, 14, nil, 7, 21, 22,
59
- nil, 9, 23, nil, nil, nil, nil, 19, nil, 14,
60
- nil, 7, 21, 22, nil, 9, 23, nil, nil, nil,
61
- nil, 19, nil, 14, nil, 7, nil, nil, 47, 9 ]
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, 46, 31, 0, 44, 8, 32, 13, 0,
65
- 56, 0, 46, 0, 49, 49, 31, 0, 49, 38,
66
- 56, 18, 18, 49, 48, 49, 58, 49, 47, 47,
67
- 18, 49, 47, 15, 48, 40, 58, 47, 15, 47,
68
- 3, 47, 29, 29, 43, 47, 29, 41, 3, 34,
69
- 24, 29, 43, 29, 28, 28, 34, 5, 28, 29,
70
- 45, 22, 2, 28, 21, 28, 1, 28, 14, 14,
71
- 28, 28, 14, 50, 19, 4, nil, 14, nil, 14,
72
- nil, 14, 26, 26, nil, 14, 26, nil, nil, nil,
73
- nil, 26, nil, 26, 9, 9, nil, nil, 9, 26,
74
- nil, nil, nil, 9, nil, 9, nil, 9, 25, 25,
75
- nil, 9, 25, nil, nil, nil, nil, 25, nil, 25,
76
- nil, 25, 27, 27, nil, 25, 27, nil, nil, nil,
77
- nil, 27, nil, 27, nil, 27, nil, nil, 27, 27 ]
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, 66, 55, 32, 59, 48, nil, nil, -7, 92,
81
- nil, nil, nil, 4, 66, 28, nil, nil, 19, 62,
82
- nil, 60, 57, nil, 50, 106, 80, 120, 52, 40,
83
- nil, -4, 3, nil, 42, nil, nil, nil, 7, nil,
84
- 31, 43, nil, 36, -11, 51, -5, 26, 17, 12,
85
- 60, nil, nil, nil, nil, nil, 3, nil, 19, nil,
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
- -40, -40, -1, -3, -4, -6, -7, -12, -14, -40,
90
- -17, -18, -19, -21, -40, -24, -26, -27, -28, -40,
91
- -32, -33, -35, -39, -40, -40, -40, -40, -40, -40,
92
- -16, -40, -20, -37, -40, -23, -25, -29, -40, -31,
93
- -34, -36, 61, -2, -40, -5, -40, -40, -40, -40,
94
- -13, -15, -38, -22, -30, -10, -40, -8, -40, -11,
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, 30, 32, 45, 44, 50, 43, 1, 37, 31,
99
- 40, 41, nil, nil, 34, nil, nil, nil, nil, nil,
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, 30, nil, nil, nil, 56, nil, 58 ]
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, 8, 12, 5, 4, 7, 3, 1, 15, 2,
106
- 12, 12, nil, nil, 2, nil, nil, nil, nil, nil,
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, 8, nil, nil, nil, 2, nil, 2 ]
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, -19, -21, -23, nil, -24, -7, nil,
113
- nil, nil, -11, nil, nil, -10, 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, 3, 4, 5, 6, 8, 10, 11,
117
- 12, 13, nil, 15, 16, 17, 18, 20 ]
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, :_reduce_none,
128
- 4, 27, :_reduce_8,
129
- 5, 27, :_reduce_9,
130
- 4, 27, :_reduce_10,
131
- 5, 27, :_reduce_11,
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
- 3, 28, :_reduce_15,
136
- 2, 28, :_reduce_16,
137
- 1, 28, :_reduce_none,
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, 29, :_reduce_20,
141
- 1, 29, :_reduce_none,
142
- 3, 32, :_reduce_22,
143
- 2, 30, :_reduce_23,
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, 34, :_reduce_25,
146
- 1, 34, :_reduce_none,
147
- 1, 34, :_reduce_none,
148
- 1, 34, :_reduce_none,
149
- 2, 35, :_reduce_29,
150
- 3, 37, :_reduce_30,
151
- 2, 37, :_reduce_31,
152
- 1, 36, :_reduce_none,
153
- 1, 38, :_reduce_33,
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
- 1, 38, :_reduce_35,
156
- 2, 38, :_reduce_36,
157
- 1, 33, :_reduce_37,
158
- 2, 33, :_reduce_38,
159
- 1, 31, :_reduce_39 ]
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 = 40
170
+ racc_reduce_n = 45
162
171
 
163
- racc_shift_n = 61
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
- "(" => 19,
186
- ")" => 20 }
194
+ :BlankLine => 19,
195
+ :Comment => 20,
196
+ "(" => 21,
197
+ ")" => 22 }
187
198
 
188
- racc_nt_base = 21
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', 23)
271
+ module_eval(<<'.,.,', 'grammar.y', 22)
258
272
  def _reduce_2(val, _values, result)
259
- result = StatementsNode.new(val[0], val[2])
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 4 omitted
292
+ # reduce 5 omitted
272
293
 
273
- module_eval(<<'.,.,', 'grammar.y', 29)
274
- def _reduce_5(val, _values, result)
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
- module_eval(<<'.,.,', 'grammar.y', 34)
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[3], params: val[2].value) }
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[0], val[2])
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[3], params: val[2].value)
321
+ result = BlockNode.new(val[0], val[2])
308
322
  result
309
323
  end
310
324
  .,.,
311
325
 
312
- module_eval(<<'.,.,', 'grammar.y', 43)
326
+ module_eval(<<'.,.,', 'grammar.y', 42)
313
327
  def _reduce_12(val, _values, result)
314
- result = RangeNode.new(val[0])
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', 46)
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 14 omitted
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', 50)
329
- def _reduce_15(val, _values, result)
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', 52)
336
- def _reduce_16(val, _values, result)
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 17 omitted
379
+ # reduce 21 omitted
343
380
 
344
- # reduce 18 omitted
381
+ # reduce 22 omitted
345
382
 
346
- # reduce 19 omitted
383
+ # reduce 23 omitted
347
384
 
348
- module_eval(<<'.,.,', 'grammar.y', 58)
349
- def _reduce_20(val, _values, result)
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 21 omitted
392
+ # reduce 25 omitted
356
393
 
357
- module_eval(<<'.,.,', 'grammar.y', 62)
358
- def _reduce_22(val, _values, result)
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', 65)
365
- def _reduce_23(val, _values, result)
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 24 omitted
408
+ # reduce 28 omitted
372
409
 
373
- module_eval(<<'.,.,', 'grammar.y', 69)
374
- def _reduce_25(val, _values, result)
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 26 omitted
424
+ # reduce 31 omitted
381
425
 
382
- # reduce 27 omitted
426
+ # reduce 32 omitted
383
427
 
384
- # reduce 28 omitted
428
+ # reduce 33 omitted
385
429
 
386
- module_eval(<<'.,.,', 'grammar.y', 75)
387
- def _reduce_29(val, _values, result)
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', 78)
394
- def _reduce_30(val, _values, result)
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', 80)
401
- def _reduce_31(val, _values, result)
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 32 omitted
451
+ # reduce 37 omitted
408
452
 
409
- module_eval(<<'.,.,', 'grammar.y', 85)
410
- def _reduce_33(val, _values, result)
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', 87)
417
- def _reduce_34(val, _values, result)
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', 89)
424
- def _reduce_35(val, _values, result)
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', 91)
431
- def _reduce_36(val, _values, result)
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', 94)
438
- def _reduce_37(val, _values, result)
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', 96)
445
- def _reduce_38(val, _values, result)
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', 99)
452
- def _reduce_39(val, _values, result)
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/after the range doesn't matter" do
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 a escaped args: ls some\ dir" do
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\ dir', lineno:0)
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.3.1
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-02-12 00:00:00.000000000 Z
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: