parser 2.0.0.beta8 → 2.0.0.beta9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ccb29ca45008c480f7d06bebc486b5a6c4137a83
4
- data.tar.gz: ad0be62764cf0e9ee5ad18e3d353adaac06e0951
3
+ metadata.gz: db31925f63c3bfa1d7dcd31e2da5a4d9093956cb
4
+ data.tar.gz: c320c20f73ae66ecd8264b69fbdbebe200e203ef
5
5
  SHA512:
6
- metadata.gz: b305ef3b909c5aabf17957dd55a72441c47482b280bc6ab3253dd732be9643366f3012c11c95286ec3ea7de10ab69972e80f607b9c8afa7bd3c37732817060b0
7
- data.tar.gz: 1d1d3b29136fa4ba6faf37fa09a98f396294055cc14cf296ee9cfb6c0ca77f490a9cb306721ea0e311913bd66a43cc2cc371fc558f8c4a222809d072a4a752f8
6
+ metadata.gz: b76ad89767945e8f83931e9968ff2a7f980498e29d0aba637ca6d1c6abf186deb2d75d50525ffba120c2fbd252a9b8fec3f988c17575414430d46f901bf1c515
7
+ data.tar.gz: 21b368d7bb373c2ee197b711ed80d659041a7220b79586d6a295889761604f2d50bc2558aba57325bd24e39fe37e2f8ea3df31a2c83e261f6eaf9f5fbfba34ee
@@ -1,6 +1,25 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ v2.0.0.beta9 (2013-06-28)
5
+ -------------------------
6
+
7
+ API modifications:
8
+ * ruby{18,19,20,21}.y: removed obsolete warnings and linting. (Peter Zotov)
9
+
10
+ Features implemented:
11
+ * builders/default: add keyword source range for BEGIN/END (fixes #85). (Peter Zotov)
12
+
13
+ Bugs fixed:
14
+ * lexer.rl: "t=1;(a)?t:T" context sensitivity in expr_value (fixes #87). (Peter Zotov)
15
+ * lexer.rl: keywords as labels, e.g. "unless:" (fixes #83, #84). (Peter Zotov)
16
+ * lexer.rl: rectify usage of c_space/c_space_nl (fixes #81). (Peter Zotov)
17
+ * ruby{18,19,20,21}.y: fix warnings for class/module in method body. (Peter Zotov)
18
+ * lexer.rl: fix warning for ?\s. (Peter Zotov)
19
+ * lexer.rl: expr_fname emits expr_beg-like keywords (fixes #82). (Peter Zotov)
20
+ * lexer.rl: get rid of harmful nondeterminism in w_space (fixes #80). (Peter Zotov)
21
+ * lexer/explanation: 1.8, 1.9 compatibility (fixes #76). (Peter Zotov)
22
+
4
23
  v2.0.0.beta8 (2013-06-24)
5
24
  -------------------------
6
25
 
data/README.md CHANGED
@@ -11,8 +11,10 @@ ruby_parser.
11
11
 
12
12
  ## Installation
13
13
 
14
+ Most recent version of Parser is 2.0; however, per [release schedule](https://github.com/whitequark/parser/issues/51), it stays in the beta status for a while. However, it handles much more input than stable 1.x branch, and for new work it is advisable to use the beta versions.
15
+
14
16
  ~~~
15
- $ gem install parser
17
+ $ gem install parser --pre
16
18
  ~~~
17
19
 
18
20
  ## Usage
@@ -117,6 +119,14 @@ $ ruby-parse -E -e "2+2"
117
119
 
118
120
  Documentation for parser is available online on [rdoc.info](http://rdoc.info/github/whitequark/parser).
119
121
 
122
+ ## Known issues
123
+
124
+ ### Void value expressions
125
+
126
+ So-called "void value expressions" are not handled by Parser. For a description of what a void value expression is, see [this gist](https://gist.github.com/JoshCheek/5625007) and [this Parser issue](https://github.com/whitequark/parser/issues/72).
127
+
128
+ It is not clear which rules this piece of static analysis follows, or which problem does it solve. It is not implemented because there is no clear specification allowing us to verify the behavior.
129
+
120
130
  ## Contributors
121
131
 
122
132
  * Peter Zotov ([whitequark][])
@@ -1,5 +1,5 @@
1
- AST and Source Location RFC
2
- ===========================
1
+ AST and Source Location
2
+ =======================
3
3
 
4
4
  ## Literals
5
5
 
@@ -27,8 +27,8 @@ To use a custom node class you have to override the method
27
27
  `Parser::Builders::Default#n`:
28
28
 
29
29
  class MyBuilder < Parser::Builders::Default
30
- def n(type, children, source_map)
31
- return MyNodeClass.new(type, children, :source_map => source_map)
30
+ def n(type, children, location)
31
+ return MyNodeClass.new(type, children, :location => location)
32
32
  end
33
33
  end
34
34
 
@@ -59,7 +59,6 @@ module Parser
59
59
  # Lexer errors
60
60
  :unicode_point_too_large => 'invalid Unicode codepoint (too large)',
61
61
  :invalid_escape => 'invalid escape character syntax',
62
- :invalid_escape_use => 'invalid character syntax; use ?%{escape}',
63
62
  :incomplete_escape => 'incomplete character syntax',
64
63
  :invalid_hex_escape => 'invalid hex escape',
65
64
  :invalid_unicode_escape => 'invalid Unicode escape',
@@ -78,6 +77,7 @@ module Parser
78
77
  :embedded_document => 'embedded document meats end of file (and they embark on a romantic journey)',
79
78
 
80
79
  # Lexer warnings
80
+ :invalid_escape_use => 'invalid character syntax; use ?%{escape}',
81
81
  :ambiguous_literal => 'ambiguous first argument; parenthesize arguments or add whitespace to the right',
82
82
  :ambiguous_prefix => "`%{prefix}' interpreted as argument prefix",
83
83
 
@@ -104,8 +104,6 @@ module Parser
104
104
  :masgn_as_condition => 'multiple assignment in conditional context',
105
105
 
106
106
  # Parser warnings
107
- :end_in_method => 'END in method; use at_exit',
108
- :space_before_lparen => "don't put space before argument parentheses",
109
107
  :useless_else => 'else without rescue is useless',
110
108
  }.freeze
111
109
 
@@ -743,12 +743,12 @@ module Parser
743
743
 
744
744
  def preexe(preexe_t, lbrace_t, compstmt, rbrace_t)
745
745
  n(:preexe, [ compstmt ],
746
- block_map(loc(preexe_t), lbrace_t, rbrace_t))
746
+ keyword_map(preexe_t, lbrace_t, [], rbrace_t))
747
747
  end
748
748
 
749
749
  def postexe(postexe_t, lbrace_t, compstmt, rbrace_t)
750
750
  n(:postexe, [ compstmt ],
751
- block_map(loc(postexe_t), lbrace_t, rbrace_t))
751
+ keyword_map(postexe_t, lbrace_t, [], rbrace_t))
752
752
  end
753
753
 
754
754
  # Exception handling
@@ -344,18 +344,18 @@ class Parser::Lexer
344
344
  'BEGIN' => :klBEGIN, 'END' => :klEND,
345
345
  }
346
346
 
347
- %w(class module def undef begin end then elsif else ensure case when
348
- for break next redo retry in do return yield super self nil true
349
- false and or not alias __FILE__ __LINE__ __ENCODING__).each do |keyword|
350
- KEYWORDS[keyword] = :"k#{keyword.upcase}"
351
- end
352
-
353
347
  KEYWORDS_BEGIN = {
354
348
  'if' => :kIF, 'unless' => :kUNLESS,
355
349
  'while' => :kWHILE, 'until' => :kUNTIL,
356
350
  'rescue' => :kRESCUE
357
351
  }
358
352
 
353
+ %w(class module def undef begin end then elsif else ensure case when
354
+ for break next redo retry in do return yield super self nil true
355
+ false and or not alias __FILE__ __LINE__ __ENCODING__).each do |keyword|
356
+ KEYWORDS_BEGIN[keyword] = KEYWORDS[keyword] = :"k#{keyword.upcase}"
357
+ end
358
+
359
359
  %%{
360
360
  # %
361
361
 
@@ -370,7 +370,8 @@ class Parser::Lexer
370
370
  # for scanners.
371
371
 
372
372
  action do_nl {
373
- # Record position of a newline for precise line and column reporting.
373
+ # Record position of a newline for precise location reporting on tNL
374
+ # tokens.
374
375
  #
375
376
  # This action is embedded directly into c_nl, as it is idempotent and
376
377
  # there are no cases when we need to skip it.
@@ -484,6 +485,8 @@ class Parser::Lexer
484
485
  class_var_v = '@@' c_alnum+;
485
486
  instance_var_v = '@' c_alnum+;
486
487
 
488
+ label = bareword [?!]? ':';
489
+
487
490
  #
488
491
  # === ESCAPE SEQUENCE PARSING ===
489
492
  #
@@ -918,7 +921,15 @@ class Parser::Lexer
918
921
  w_space =
919
922
  c_space+
920
923
  | '\\' e_heredoc_nl
921
- | '#' %{ @sharp_s = p - 1 } c_line* %{ emit_comment(@sharp_s, p) }
924
+ ;
925
+
926
+ w_comment =
927
+ '#' %{ @sharp_s = p - 1 } c_line* %{ emit_comment(@sharp_s, p) }
928
+ ;
929
+
930
+ w_space_comment =
931
+ w_space
932
+ | w_comment
922
933
  ;
923
934
 
924
935
  # A newline in non-literal context always interoperates with
@@ -935,9 +946,14 @@ class Parser::Lexer
935
946
  #
936
947
  # is equivalent to `foo = "bar\n" + 2`.
937
948
 
938
- w_newline = e_heredoc_nl;
949
+ w_newline =
950
+ e_heredoc_nl;
939
951
 
940
- w_space_newline = w_space | w_newline;
952
+ w_any =
953
+ w_space
954
+ | w_comment
955
+ | w_newline
956
+ ;
941
957
 
942
958
 
943
959
  #
@@ -992,6 +1008,18 @@ class Parser::Lexer
992
1008
  @paren_nest -= 1
993
1009
  };
994
1010
 
1011
+ # Ruby >=1.9.2 is context-sensitive wrt/ local identifiers.
1012
+ action local_ident {
1013
+ emit(:tIDENTIFIER)
1014
+
1015
+ if !version?(18) &&
1016
+ !@static_env.nil? && @static_env.declared?(tok)
1017
+ fnext expr_end; fbreak;
1018
+ else
1019
+ fnext expr_arg; fbreak;
1020
+ end
1021
+ }
1022
+
995
1023
  # Variable lexing code is accessed from both expressions and
996
1024
  # string interpolation related code.
997
1025
  #
@@ -1043,7 +1071,7 @@ class Parser::Lexer
1043
1071
  #
1044
1072
  expr_fname := |*
1045
1073
  keyword
1046
- => { emit(KEYWORDS[tok]);
1074
+ => { emit(KEYWORDS_BEGIN[tok]);
1047
1075
  fnext expr_endfn; fbreak; };
1048
1076
 
1049
1077
  constant
@@ -1073,7 +1101,7 @@ class Parser::Lexer
1073
1101
  ':'
1074
1102
  => { fhold; fgoto expr_beg; };
1075
1103
 
1076
- w_space_newline;
1104
+ w_any;
1077
1105
 
1078
1106
  c_any
1079
1107
  => { fhold; fgoto expr_end; };
@@ -1087,11 +1115,11 @@ class Parser::Lexer
1087
1115
  # Transitions to `expr_end` afterwards.
1088
1116
  #
1089
1117
  expr_endfn := |*
1090
- bareword ':'
1118
+ label
1091
1119
  => { emit(:tLABEL, tok(@ts, @te - 1))
1092
1120
  fnext expr_beg; fbreak; };
1093
1121
 
1094
- w_space;
1122
+ w_space_comment;
1095
1123
 
1096
1124
  c_any
1097
1125
  => { fhold; fgoto expr_end; };
@@ -1123,7 +1151,7 @@ class Parser::Lexer
1123
1151
  => { emit_table(PUNCTUATION)
1124
1152
  fnext expr_arg; fbreak; };
1125
1153
 
1126
- w_space_newline;
1154
+ w_any;
1127
1155
 
1128
1156
  c_any
1129
1157
  => { fhold; fgoto expr_end; };
@@ -1141,7 +1169,7 @@ class Parser::Lexer
1141
1169
 
1142
1170
  # cmd (1 + 2)
1143
1171
  # See below the rationale about expr_endarg.
1144
- c_space+ e_lparen
1172
+ w_space+ e_lparen
1145
1173
  => { emit(:tLPAREN_ARG, '(', @te - 1, @te)
1146
1174
  fnext expr_beg; fbreak; };
1147
1175
 
@@ -1153,13 +1181,13 @@ class Parser::Lexer
1153
1181
 
1154
1182
  # meth [...]
1155
1183
  # Array argument. Compare with indexing `meth[...]`.
1156
- c_space+ e_lbrack
1184
+ w_space+ e_lbrack
1157
1185
  => { emit(:tLBRACK, '[', @te - 1, @te)
1158
1186
  fnext expr_beg; fbreak; };
1159
1187
 
1160
1188
  # cmd {}
1161
1189
  # Command: method call without parentheses.
1162
- c_space* e_lbrace
1190
+ w_space* e_lbrace
1163
1191
  => {
1164
1192
  if @lambda_stack.last == @paren_nest
1165
1193
  p = @ts - 1
@@ -1176,11 +1204,11 @@ class Parser::Lexer
1176
1204
 
1177
1205
  # a ?b
1178
1206
  # Character literal.
1179
- c_space+ '?'
1207
+ w_space+ '?'
1180
1208
  => { fhold; fgoto expr_beg; };
1181
1209
 
1182
1210
  # a %{1}, a %[1] (but not "a %=1=" or "a % foo")
1183
- c_space+ ( '%' [^= ]
1211
+ w_space+ ( '%' [^= ]
1184
1212
  # a /foo/ (but not "a / foo" or "a /=foo")
1185
1213
  | '/' ( c_any - c_space_nl - '=' )
1186
1214
  # a <<HEREDOC
@@ -1190,7 +1218,7 @@ class Parser::Lexer
1190
1218
 
1191
1219
  # x /1
1192
1220
  # Ambiguous regexp literal.
1193
- c_space+ '/'
1221
+ w_space+ '/'
1194
1222
  => {
1195
1223
  diagnostic :warning, Parser::ERRORS[:ambiguous_literal],
1196
1224
  range(@te - 1, @te)
@@ -1200,7 +1228,7 @@ class Parser::Lexer
1200
1228
 
1201
1229
  # x *1
1202
1230
  # Ambiguous splat, kwsplat or block-pass.
1203
- c_space+ %{ tm = p } ( '+' | '-' | '*' | '&' | '**' )
1231
+ w_space+ %{ tm = p } ( '+' | '-' | '*' | '&' | '**' )
1204
1232
  => {
1205
1233
  message = Parser::ERRORS[:ambiguous_prefix] % { :prefix => tok(tm, @te) }
1206
1234
  diagnostic :warning, message,
@@ -1212,36 +1240,44 @@ class Parser::Lexer
1212
1240
 
1213
1241
  # x ::Foo
1214
1242
  # Ambiguous toplevel constant access.
1215
- c_space+ '::'
1243
+ w_space+ '::'
1216
1244
  => { fhold; fhold; fgoto expr_beg; };
1217
1245
 
1218
1246
  # x:b
1219
1247
  # Symbol.
1220
- c_space* ':'
1248
+ w_space* ':'
1221
1249
  => { fhold; fgoto expr_beg; };
1222
1250
 
1251
+ w_space+ label
1252
+ => { p = @ts - 1; fgoto expr_beg; };
1253
+
1223
1254
  #
1224
1255
  # AMBIGUOUS TOKENS RESOLVED VIA EXPR_END
1225
1256
  #
1226
1257
 
1227
1258
  # a ? b
1228
1259
  # Ternary operator.
1229
- c_space+ '?' c_space_nl
1260
+ w_space+ '?' c_space_nl
1230
1261
  => { fhold; fhold; fgoto expr_end; };
1231
1262
 
1232
1263
  # x + 1: Binary operator or operator-assignment.
1233
- c_space* operator_arithmetic
1264
+ w_space* operator_arithmetic
1234
1265
  ( '=' | c_space_nl )? |
1235
1266
  # x rescue y: Modifier keyword.
1236
- c_space+ keyword_modifier |
1267
+ w_space+ keyword_modifier |
1237
1268
  # Miscellanea.
1238
- c_space* punctuation_end
1269
+ w_space* punctuation_end
1239
1270
  => {
1240
1271
  p = @ts - 1
1241
1272
  fgoto expr_end;
1242
1273
  };
1243
1274
 
1244
- w_space* w_newline
1275
+ w_space;
1276
+
1277
+ w_comment
1278
+ => { fgoto expr_end; };
1279
+
1280
+ w_newline
1245
1281
  => { fhold; fgoto expr_end; };
1246
1282
 
1247
1283
  c_any
@@ -1274,7 +1310,7 @@ class Parser::Lexer
1274
1310
  => { emit(:kDO_BLOCK)
1275
1311
  fnext expr_value; };
1276
1312
 
1277
- w_space;
1313
+ w_space_comment;
1278
1314
 
1279
1315
  c_any
1280
1316
  => { fhold; fgoto expr_end; };
@@ -1292,7 +1328,8 @@ class Parser::Lexer
1292
1328
  => { emit_table(KEYWORDS)
1293
1329
  fnext expr_beg; fbreak; };
1294
1330
 
1295
- w_space;
1331
+ w_space_comment;
1332
+
1296
1333
  w_newline
1297
1334
  => { fhold; fgoto expr_end; };
1298
1335
 
@@ -1433,10 +1470,9 @@ class Parser::Lexer
1433
1470
  '?' c_space_nl
1434
1471
  => {
1435
1472
  escape = { " " => '\s', "\r" => '\r', "\n" => '\n', "\t" => '\t',
1436
- "\v" => '\v', "\f" => '\f' }[tok[@ts + 1]]
1473
+ "\v" => '\v', "\f" => '\f' }[tok[1]]
1437
1474
  message = Parser::ERRORS[:invalid_escape_use] % { :escape => escape }
1438
- diagnostic :warning, message,
1439
- range(@ts, @ts + 1)
1475
+ diagnostic :warning, message, range
1440
1476
 
1441
1477
  p = @ts - 1
1442
1478
  fgoto expr_end;
@@ -1488,7 +1524,7 @@ class Parser::Lexer
1488
1524
  # RUBY 1.9 HASH LABELS
1489
1525
  #
1490
1526
 
1491
- bareword [?!]? ':' ( c_any - ':' )
1527
+ label ( any - ':' )
1492
1528
  => {
1493
1529
  fhold;
1494
1530
 
@@ -1515,23 +1551,13 @@ class Parser::Lexer
1515
1551
 
1516
1552
  # a = 42; a [42]: Indexing.
1517
1553
  # def a; end; a [42]: Array argument.
1518
- call_or_var
1519
- => {
1520
- emit(:tIDENTIFIER)
1521
-
1522
- if !version?(18) &&
1523
- !@static_env.nil? && @static_env.declared?(tok)
1524
- fnext expr_end; fbreak;
1525
- else
1526
- fnext expr_arg; fbreak;
1527
- end
1528
- };
1554
+ call_or_var => local_ident;
1529
1555
 
1530
1556
  #
1531
1557
  # WHITESPACE
1532
1558
  #
1533
1559
 
1534
- w_space_newline;
1560
+ w_any;
1535
1561
 
1536
1562
  e_heredoc_nl '=begin' ( c_space | c_eol )
1537
1563
  => { p = @ts - 1
@@ -1556,11 +1582,11 @@ class Parser::Lexer
1556
1582
  #
1557
1583
  expr_value := |*
1558
1584
  # a:b: a(:b), a::B, A::B
1559
- bareword ':' (c_any - ':')
1585
+ label (any - ':')
1560
1586
  => { p = @ts - 1
1561
1587
  fgoto expr_end; };
1562
1588
 
1563
- w_space;
1589
+ w_space_comment;
1564
1590
 
1565
1591
  c_any
1566
1592
  => { fhold; fgoto expr_beg; };
@@ -1573,7 +1599,7 @@ class Parser::Lexer
1573
1599
  # STABBY LAMBDA
1574
1600
  #
1575
1601
 
1576
- '->' c_space*
1602
+ '->'
1577
1603
  => {
1578
1604
  emit_table(PUNCTUATION, @ts, @ts + 2)
1579
1605
 
@@ -1616,7 +1642,7 @@ class Parser::Lexer
1616
1642
  => { emit_table(KEYWORDS)
1617
1643
  fnext expr_fname; fbreak; };
1618
1644
 
1619
- 'class' c_space_nl* '<<'
1645
+ 'class' w_any* '<<'
1620
1646
  => { emit(:kCLASS, 'class', @ts, @ts + 5)
1621
1647
  emit(:tLSHFT, '<<', @te - 2, @te)
1622
1648
  fnext expr_value; fbreak; };
@@ -1770,9 +1796,7 @@ class Parser::Lexer
1770
1796
  => { emit_table(PUNCTUATION)
1771
1797
  fnext expr_dot; fbreak; };
1772
1798
 
1773
- call_or_var
1774
- => { emit(:tIDENTIFIER)
1775
- fnext expr_arg; fbreak; };
1799
+ call_or_var => local_ident;
1776
1800
 
1777
1801
  call_or_var ambiguous_fid_suffix
1778
1802
  => { emit(:tFID, tok(@ts, tm), @ts, tm)
@@ -1783,11 +1807,11 @@ class Parser::Lexer
1783
1807
  # OPERATORS
1784
1808
  #
1785
1809
 
1786
- ( e_lparen |
1787
- operator_arithmetic |
1788
- operator_rest
1789
- ) %{ tm = p } c_space_nl*
1790
- => { emit_table(PUNCTUATION, @ts, tm)
1810
+ ( e_lparen
1811
+ | operator_arithmetic
1812
+ | operator_rest
1813
+ )
1814
+ => { emit_table(PUNCTUATION)
1791
1815
  fnext expr_beg; fbreak; };
1792
1816
 
1793
1817
  e_rbrace | e_rparen | ']'
@@ -1815,7 +1839,8 @@ class Parser::Lexer
1815
1839
  # WHITESPACE
1816
1840
  #
1817
1841
 
1818
- w_space;
1842
+ w_space_comment;
1843
+
1819
1844
  w_newline
1820
1845
  => { fgoto leading_dot; };
1821
1846
 
@@ -1848,7 +1873,7 @@ class Parser::Lexer
1848
1873
 
1849
1874
  any
1850
1875
  => { emit(:tNL, nil, @newline_s, @newline_s + 1)
1851
- fnext line_begin; fhold; fbreak; };
1876
+ fhold; fnext line_begin; fbreak; };
1852
1877
  *|;
1853
1878
 
1854
1879
  #
@@ -1872,7 +1897,7 @@ class Parser::Lexer
1872
1897
  *|;
1873
1898
 
1874
1899
  line_begin := |*
1875
- w_space_newline;
1900
+ w_any;
1876
1901
 
1877
1902
  '=begin' ( c_space | c_eol )
1878
1903
  => { @eq_begin_s = @ts
@@ -2,10 +2,19 @@ module Parser
2
2
 
3
3
  module Lexer::Explanation
4
4
 
5
+ def self.included(klass)
6
+ klass.class_exec do
7
+ alias_method :state_before_explanation=, :state=
8
+ alias_method :advance_before_explanation, :advance
9
+
10
+ remove_method :state=, :advance
11
+ end
12
+ end
13
+
5
14
  # Like #advance, but also pretty-print the token and its position
6
15
  # in the stream to `stdout`.
7
16
  def advance
8
- type, (val, range) = super
17
+ type, (val, range) = advance_before_explanation
9
18
 
10
19
  puts decorate(range,
11
20
  "\e[0;32m#{type} #{val.inspect}\e[0m",
@@ -18,7 +27,7 @@ module Parser
18
27
  puts " \e[1;33m>>> STATE SET <<<\e[0m " +
19
28
  "#{new_state.to_s.ljust(12)} #{@cond} #{@cmdarg}".rjust(66)
20
29
 
21
- super
30
+ self.state_before_explanation = new_state
22
31
  end
23
32
 
24
33
  private
@@ -150,10 +150,6 @@ rule
150
150
  }
151
151
  | klEND tLCURLY compstmt tRCURLY
152
152
  {
153
- if in_def?
154
- diagnostic(:warning, :end_in_method, val[0])
155
- end
156
-
157
153
  result = @builder.postexe(val[0], val[1], val[2], val[3])
158
154
  }
159
155
  | lhs tEQL command_call
@@ -930,8 +926,6 @@ rule
930
926
  }
931
927
  tRPAREN
932
928
  {
933
- diagnostic(:warning, :space_before_lparen, val[0])
934
-
935
929
  result = [ val[0], [], val[2] ]
936
930
  }
937
931
  | tLPAREN_ARG call_args2
@@ -940,8 +934,6 @@ rule
940
934
  }
941
935
  tRPAREN
942
936
  {
943
- diagnostic(:warning, :space_before_lparen, val[0])
944
-
945
937
  result = [ val[0], val[1], val[3] ]
946
938
  }
947
939
 
@@ -1145,14 +1137,14 @@ rule
1145
1137
  }
1146
1138
  | kCLASS cpath superclass
1147
1139
  {
1148
- if in_def?
1149
- diagnostic(:error, :class_in_def, val[0])
1150
- end
1151
-
1152
1140
  @static_env.extend_static
1153
1141
  }
1154
1142
  bodystmt kEND
1155
1143
  {
1144
+ if in_def?
1145
+ diagnostic(:error, :class_in_def, val[0])
1146
+ end
1147
+
1156
1148
  lt_t, superclass = val[2]
1157
1149
  result = @builder.def_class(val[0], val[1],
1158
1150
  lt_t, superclass,
@@ -1178,14 +1170,14 @@ rule
1178
1170
  }
1179
1171
  | kMODULE cpath
1180
1172
  {
1181
- if in_def?
1182
- diagnostic(:error, :module_in_def, val[0])
1183
- end
1184
-
1185
1173
  @static_env.extend_static
1186
1174
  }
1187
1175
  bodystmt kEND
1188
1176
  {
1177
+ if in_def?
1178
+ diagnostic(:error, :module_in_def, val[0])
1179
+ end
1180
+
1189
1181
  result = @builder.def_module(val[0], val[1],
1190
1182
  val[3], val[4])
1191
1183
 
@@ -168,10 +168,6 @@ rule
168
168
  }
169
169
  | klEND tLCURLY compstmt tRCURLY
170
170
  {
171
- if in_def?
172
- diagnostic(:warning, :end_in_method, val[0])
173
- end
174
-
175
171
  result = @builder.postexe(val[0], val[1], val[2], val[3])
176
172
  }
177
173
  | command_asgn
@@ -1102,14 +1098,14 @@ rule
1102
1098
  }
1103
1099
  | kCLASS cpath superclass
1104
1100
  {
1105
- if in_def?
1106
- diagnostic(:error, :class_in_def, val[0])
1107
- end
1108
-
1109
1101
  @static_env.extend_static
1110
1102
  }
1111
1103
  bodystmt kEND
1112
1104
  {
1105
+ if in_def?
1106
+ diagnostic(:error, :class_in_def, val[0])
1107
+ end
1108
+
1113
1109
  lt_t, superclass = val[2]
1114
1110
  result = @builder.def_class(val[0], val[1],
1115
1111
  lt_t, superclass,
@@ -1135,14 +1131,14 @@ rule
1135
1131
  }
1136
1132
  | kMODULE cpath
1137
1133
  {
1138
- if in_def?
1139
- diagnostic(:error, :module_in_def, val[0])
1140
- end
1141
-
1142
1134
  @static_env.extend_static
1143
1135
  }
1144
1136
  bodystmt kEND
1145
1137
  {
1138
+ if in_def?
1139
+ diagnostic(:error, :module_in_def, val[0])
1140
+ end
1141
+
1146
1142
  result = @builder.def_module(val[0], val[1],
1147
1143
  val[3], val[4])
1148
1144
 
@@ -179,10 +179,6 @@ rule
179
179
  }
180
180
  | klEND tLCURLY compstmt tRCURLY
181
181
  {
182
- if in_def?
183
- diagnostic(:warning, :end_in_method, val[0])
184
- end
185
-
186
182
  result = @builder.postexe(val[0], val[1], val[2], val[3])
187
183
  }
188
184
  | command_asgn
@@ -1139,14 +1135,14 @@ rule
1139
1135
  }
1140
1136
  | kCLASS cpath superclass
1141
1137
  {
1142
- if in_def?
1143
- diagnostic(:error, :class_in_def, val[0])
1144
- end
1145
-
1146
1138
  @static_env.extend_static
1147
1139
  }
1148
1140
  bodystmt kEND
1149
1141
  {
1142
+ if in_def?
1143
+ diagnostic(:error, :class_in_def, val[0])
1144
+ end
1145
+
1150
1146
  lt_t, superclass = val[2]
1151
1147
  result = @builder.def_class(val[0], val[1],
1152
1148
  lt_t, superclass,
@@ -1172,14 +1168,14 @@ rule
1172
1168
  }
1173
1169
  | kMODULE cpath
1174
1170
  {
1175
- if in_def?
1176
- diagnostic(:error, :module_in_def, val[0])
1177
- end
1178
-
1179
1171
  @static_env.extend_static
1180
1172
  }
1181
1173
  bodystmt kEND
1182
1174
  {
1175
+ if in_def?
1176
+ diagnostic(:error, :module_in_def, val[0])
1177
+ end
1178
+
1183
1179
  result = @builder.def_module(val[0], val[1],
1184
1180
  val[3], val[4])
1185
1181
 
@@ -179,10 +179,6 @@ rule
179
179
  }
180
180
  | klEND tLCURLY compstmt tRCURLY
181
181
  {
182
- if in_def?
183
- diagnostic(:warning, :end_in_method, val[0])
184
- end
185
-
186
182
  result = @builder.postexe(val[0], val[1], val[2], val[3])
187
183
  }
188
184
  | command_asgn
@@ -1140,14 +1136,14 @@ rule
1140
1136
  }
1141
1137
  | kCLASS cpath superclass
1142
1138
  {
1143
- if in_def?
1144
- diagnostic(:error, :class_in_def, val[0])
1145
- end
1146
-
1147
1139
  @static_env.extend_static
1148
1140
  }
1149
1141
  bodystmt kEND
1150
1142
  {
1143
+ if in_def?
1144
+ diagnostic(:error, :class_in_def, val[0])
1145
+ end
1146
+
1151
1147
  lt_t, superclass = val[2]
1152
1148
  result = @builder.def_class(val[0], val[1],
1153
1149
  lt_t, superclass,
@@ -1173,14 +1169,14 @@ rule
1173
1169
  }
1174
1170
  | kMODULE cpath
1175
1171
  {
1176
- if in_def?
1177
- diagnostic(:error, :module_in_def, val[0])
1178
- end
1179
-
1180
1172
  @static_env.extend_static
1181
1173
  }
1182
1174
  bodystmt kEND
1183
1175
  {
1176
+ if in_def?
1177
+ diagnostic(:error, :module_in_def, val[0])
1178
+ end
1179
+
1184
1180
  result = @builder.def_module(val[0], val[1],
1185
1181
  val[3], val[4])
1186
1182
 
@@ -103,7 +103,7 @@ module Parser
103
103
  @slop.on 'E', 'explain', 'Explain how the source is tokenized' do
104
104
  ENV['RACC_DEBUG'] = '1'
105
105
 
106
- Lexer.send :prepend, Lexer::Explanation
106
+ Lexer.send :include, Lexer::Explanation
107
107
  end
108
108
  end
109
109
 
@@ -1,3 +1,3 @@
1
1
  module Parser
2
- VERSION = '2.0.0.beta8'
2
+ VERSION = '2.0.0.beta9'
3
3
  end
@@ -25,7 +25,7 @@ Gem::Specification.new do |spec|
25
25
  spec.require_paths = ['lib']
26
26
 
27
27
  spec.add_dependency 'ast', '~> 1.1'
28
- spec.add_dependency 'slop', '~> 3.4'
28
+ spec.add_dependency 'slop', ['~> 3.4', '>= 3.4.5']
29
29
 
30
30
  spec.add_development_dependency 'bundler', '~> 1.2'
31
31
  spec.add_development_dependency 'rake', '~> 0.9'
@@ -121,12 +121,9 @@ module ParseHelper
121
121
  # do nothing; the diagnostic was reported
122
122
  end
123
123
 
124
- # Remove this `if' when no diagnostics fail to render.
125
- if @diagnostics.count != 1
126
- assert_equal 1, @diagnostics.count,
127
- "(#{version}) emits a single diagnostic, not\n" \
128
- "#{@diagnostics.map(&:render).join("\n")}"
129
- end
124
+ assert_equal 1, @diagnostics.count,
125
+ "(#{version}) emits a single diagnostic, not\n" \
126
+ "#{@diagnostics.map(&:render).join("\n")}"
130
127
 
131
128
  emitted_diagnostic = @diagnostics.first
132
129
 
@@ -2173,6 +2173,12 @@ class TestLexer < Minitest::Test
2173
2173
  :tIDENTIFIER, 'foo',
2174
2174
  :tCOLON, ':')
2175
2175
 
2176
+ @lex.state = :expr_endfn
2177
+ util_lex_token("\nfoo: ",
2178
+ :tNL, nil,
2179
+ :tIDENTIFIER, 'foo',
2180
+ :tCOLON, ':')
2181
+
2176
2182
  @lex.state = :expr_endfn
2177
2183
  util_lex_token("\\\nfoo:",
2178
2184
  :tLABEL, 'foo')
@@ -2182,6 +2188,12 @@ class TestLexer < Minitest::Test
2182
2188
  :tNL, nil,
2183
2189
  :tIDENTIFIER, 'foo',
2184
2190
  :tCOLON, ':')
2191
+
2192
+ @lex.state = :expr_endfn
2193
+ util_lex_token("#foo\nfoo: ",
2194
+ :tNL, nil,
2195
+ :tIDENTIFIER, 'foo',
2196
+ :tCOLON, ':')
2185
2197
  end
2186
2198
 
2187
2199
  def test_whitespace_dot
@@ -2509,6 +2521,18 @@ class TestLexer < Minitest::Test
2509
2521
  :tINTEGER, 1)
2510
2522
  end
2511
2523
 
2524
+ def test_bug_expr_arg_label
2525
+ setup_lexer 19
2526
+
2527
+ @lex.state = :expr_arg
2528
+ util_lex_token(" unless:",
2529
+ :tLABEL, 'unless')
2530
+
2531
+ @lex.state = :expr_arg
2532
+ util_lex_token(" unless: ",
2533
+ :tLABEL, 'unless')
2534
+ end
2535
+
2512
2536
  def test_bug_heredoc_continuation
2513
2537
  @lex.state = :expr_arg
2514
2538
  util_lex_token(" <<EOS\nEOS\nend",
@@ -2573,6 +2597,16 @@ class TestLexer < Minitest::Test
2573
2597
  :tCONSTANT, 'CLEANINGS')
2574
2598
  end
2575
2599
 
2600
+ def test_bug_sclass_comment_lshft_label
2601
+ util_lex_token("class # foo\n<< a:b;end",
2602
+ :kCLASS, 'class',
2603
+ :tLSHFT, '<<',
2604
+ :tIDENTIFIER, 'a',
2605
+ :tSYMBOL, 'b',
2606
+ :tSEMI, ';',
2607
+ :kEND, 'end')
2608
+ end
2609
+
2576
2610
  def test_bug_expr_dot_comment
2577
2611
  util_lex_token("foo. #bar\nbaz",
2578
2612
  :tIDENTIFIER, 'foo',
@@ -1330,7 +1330,8 @@ class TestParser < Minitest::Test
1330
1330
  def test_module_invalid
1331
1331
  assert_diagnoses(
1332
1332
  [:error, :module_in_def],
1333
- %q{def a; module Foo; end; end})
1333
+ %q{def a; module Foo; end; end},
1334
+ %q{ ^^^^^^ location})
1334
1335
  end
1335
1336
 
1336
1337
  def test_cpath
@@ -1392,7 +1393,8 @@ class TestParser < Minitest::Test
1392
1393
  def test_class_invalid
1393
1394
  assert_diagnoses(
1394
1395
  [:error, :class_in_def],
1395
- %q{def a; class Foo; end; end})
1396
+ %q{def a; class Foo; end; end},
1397
+ %q{ ^^^^^ location})
1396
1398
  end
1397
1399
 
1398
1400
  def test_sclass
@@ -1425,6 +1427,10 @@ class TestParser < Minitest::Test
1425
1427
  assert_parses(
1426
1428
  s(:def, :String=, s(:args), nil),
1427
1429
  %q{def String=; end})
1430
+
1431
+ assert_parses(
1432
+ s(:def, :until, s(:args), nil),
1433
+ %q{def until; end})
1428
1434
  end
1429
1435
 
1430
1436
  def test_defs
@@ -3382,12 +3388,6 @@ class TestParser < Minitest::Test
3382
3388
  %q{fun (1, 2)},
3383
3389
  %q{},
3384
3390
  %w(1.8))
3385
-
3386
- assert_diagnoses(
3387
- [:warning, :space_before_lparen],
3388
- %q{fun (1, 2)},
3389
- %q{ ^ location},
3390
- %w(1.8))
3391
3391
  end
3392
3392
 
3393
3393
  def test_space_args_none
@@ -3396,12 +3396,6 @@ class TestParser < Minitest::Test
3396
3396
  %q{fun ()},
3397
3397
  %q{},
3398
3398
  %w(1.8))
3399
-
3400
- assert_diagnoses(
3401
- [:warning, :space_before_lparen],
3402
- %q{fun ()},
3403
- %q{ ^ location},
3404
- %w(1.8))
3405
3399
  end
3406
3400
 
3407
3401
  def test_space_args_block
@@ -3615,6 +3609,18 @@ class TestParser < Minitest::Test
3615
3609
  |~~~~~~~~~~~ expression})
3616
3610
  end
3617
3611
 
3612
+ def test_ternary_ambiguous_symbol
3613
+ assert_parses(
3614
+ s(:begin,
3615
+ s(:lvasgn, :t, s(:int, 1)),
3616
+ s(:if, s(:begin, s(:lvar, :foo)),
3617
+ s(:lvar, :t),
3618
+ s(:const, nil, :T))),
3619
+ %q{t=1;(foo)?t:T},
3620
+ %q{},
3621
+ ALL_VERSIONS - %w(1.8))
3622
+ end
3623
+
3618
3624
  def test_if_masgn
3619
3625
  assert_diagnoses(
3620
3626
  [:error, :masgn_as_condition],
@@ -4240,7 +4246,8 @@ class TestParser < Minitest::Test
4240
4246
  assert_parses(
4241
4247
  s(:preexe, s(:int, 1)),
4242
4248
  %q{BEGIN { 1 }},
4243
- %q{ ^ begin
4249
+ %q{~~~~~ keyword
4250
+ | ^ begin
4244
4251
  | ^ end
4245
4252
  |~~~~~~~~~~~ expression})
4246
4253
  end
@@ -4258,14 +4265,10 @@ class TestParser < Minitest::Test
4258
4265
  assert_parses(
4259
4266
  s(:postexe, s(:int, 1)),
4260
4267
  %q{END { 1 }},
4261
- %q{ ^ begin
4268
+ %q{~~~ keyword
4269
+ | ^ begin
4262
4270
  | ^ end
4263
4271
  |~~~~~~~~~ expression})
4264
-
4265
- assert_diagnoses(
4266
- [:warning, :end_in_method],
4267
- %q{def f; END{ 1 }; end},
4268
- %q{ ~~~ location})
4269
4272
  end
4270
4273
 
4271
4274
  #
@@ -4369,26 +4372,38 @@ class TestParser < Minitest::Test
4369
4372
  # Token and comment extraction
4370
4373
  #
4371
4374
 
4372
- def test_comments
4375
+ def assert_parses_with_comments(ast_pattern, source, comments_pattern)
4373
4376
  with_versions(ALL_VERSIONS) do |_ver, parser|
4374
4377
  source_file = Parser::Source::Buffer.new('(comments)')
4375
- source_file.source = "1 + # foo\n 2"
4378
+ source_file.source = source
4376
4379
 
4377
- range = lambda do |from, to|
4378
- Parser::Source::Range.new(source_file, from, to)
4380
+ comments_pattern_here = comments_pattern.map do |(from, to)|
4381
+ range = Parser::Source::Range.new(source_file, from, to)
4382
+ Parser::Source::Comment.new(range)
4379
4383
  end
4380
4384
 
4381
4385
  ast, comments = parser.parse_with_comments(source_file)
4382
4386
 
4383
- assert_equal s(:send, s(:int, 1), :+, s(:int, 2)),
4384
- ast
4387
+ assert_equal ast_pattern, ast
4385
4388
 
4386
- assert_equal [
4387
- Parser::Source::Comment.new(range.call(4, 9))
4388
- ], comments
4389
+ assert_equal comments_pattern_here, comments
4389
4390
  end
4390
4391
  end
4391
4392
 
4393
+ def test_comment_interleaved
4394
+ assert_parses_with_comments(
4395
+ s(:send, s(:int, 1), :+, s(:int, 2)),
4396
+ %Q{1 + # foo\n 2},
4397
+ [ [4, 9] ])
4398
+ end
4399
+
4400
+ def test_comment_single
4401
+ assert_parses_with_comments(
4402
+ s(:send, nil, :puts),
4403
+ %Q{puts # whatever},
4404
+ [ [5, 15] ])
4405
+ end
4406
+
4392
4407
  def test_tokenize
4393
4408
  with_versions(ALL_VERSIONS) do |_ver, parser|
4394
4409
  source_file = Parser::Source::Buffer.new('(tokenize)')
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.beta8
4
+ version: 2.0.0.beta9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Zotov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-06-24 00:00:00.000000000 Z
11
+ date: 2013-06-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ast
@@ -31,6 +31,9 @@ dependencies:
31
31
  - - ~>
32
32
  - !ruby/object:Gem::Version
33
33
  version: '3.4'
34
+ - - '>='
35
+ - !ruby/object:Gem::Version
36
+ version: 3.4.5
34
37
  type: :runtime
35
38
  prerelease: false
36
39
  version_requirements: !ruby/object:Gem::Requirement
@@ -38,6 +41,9 @@ dependencies:
38
41
  - - ~>
39
42
  - !ruby/object:Gem::Version
40
43
  version: '3.4'
44
+ - - '>='
45
+ - !ruby/object:Gem::Version
46
+ version: 3.4.5
41
47
  - !ruby/object:Gem::Dependency
42
48
  name: bundler
43
49
  requirement: !ruby/object:Gem::Requirement
@@ -225,7 +231,6 @@ files:
225
231
  - lib/parser/base.rb
226
232
  - lib/parser/builders/default.rb
227
233
  - lib/parser/compatibility/ruby1_8.rb
228
- - lib/parser/compatibility/slop.rb
229
234
  - lib/parser/current.rb
230
235
  - lib/parser/diagnostic.rb
231
236
  - lib/parser/diagnostic/engine.rb
@@ -1,12 +0,0 @@
1
- # https://github.com/injekt/slop/pull/110
2
- class Slop
3
- def extract_long_flag(objects, config)
4
- flag = objects.first.to_s
5
- if flag =~ /\A(?:--?)?[a-zA-Z0-9][a-zA-Z0-9_.-]+\=?\??\z/
6
- config[:argument] ||= true if flag.end_with?('=')
7
- config[:optional_argument] = true if flag.end_with?('=?')
8
- objects.shift
9
- clean(flag).sub(/\=\??\z/, '')
10
- end
11
- end
12
- end