Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Lexer and parser additions #7

Merged
merged 2 commits into from over 2 years ago

2 participants

Kit Cambridge Peter van der Zee
Kit Cambridge

I've fixed the tokenizer unit tests and added some basic tests for verifying the size of the parse tree.

added some commits December 23, 2011
Fix the tokenizer unit tests. The `switch` unit test doesn't include …
…an error token, since the tokenizer doesn't validate statements.
04b350c
Add unit tests for determining the size of the parse tree. 6829d01
Peter van der Zee qfox merged commit 51e5290 into from December 24, 2011
Peter van der Zee qfox closed this December 24, 2011
Kit Cambridge

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 2 unique commits by 1 author.

Dec 23, 2011
Fix the tokenizer unit tests. The `switch` unit test doesn't include …
…an error token, since the tokenizer doesn't validate statements.
04b350c
Add unit tests for determining the size of the parse tree. 6829d01
This page is out of date. Refresh to see the latest.
8  Tokenizer.js
@@ -580,10 +580,10 @@ Tokenizer.testSuite = function(arr){
580 580
 	var fail = 0;
581 581
 	for (var i=0; i<arr.length; ++i) {
582 582
 		var test = arr[i], result;
583  
-		var input = test[1];
584  
-		var outputLen = test[2];
585  
-		var regexHints = test[4] ? test[3] : null; // if flags, then len=4
586  
-		var desc = test[4] || test[3];
  583
+		var input = test[0];
  584
+		var outputLen = test[1].length ? test[1][0] : test[1];
  585
+		var regexHints = test[3] ? test[2] : null; // if flags, then len=4
  586
+		var desc = test[3] || test[2];
587 587
 		
588 588
 		var result = new Tokenizer(input).tokens(regexHints); // regexHints can be null, that's ok
589 589
 		if (result.length == outputLen) {
10  ZeParser.js
@@ -2054,10 +2054,14 @@ ZeParser.testSuite = function(tests){
2054 2054
 	var fail = 0;
2055 2055
 	var start = +new Date;
2056 2056
 	for (var i = 0; i < tests.length; ++i) {
2057  
-		var test = tests[i], input = test[0], desc = test[test.length - 1], stack = [];
  2057
+		var test = tests[i], input = test[0], outputLen = test[1].length ? test[1][1] : test[1], desc = test[test.length - 1], stack = [];
2058 2058
 		try {
2059  
-			new ZeParser(input, new Tokenizer(input), stack).parse();
2060  
-			++ok;
  2059
+			var result = ZeParser.parse(input, true);
  2060
+			if (result.length == outputLen) {
  2061
+				++ok;
  2062
+			} else {
  2063
+				++fail;
  2064
+			}
2061 2065
 		} catch (e) {
2062 2066
 			++fail;
2063 2067
 		}
131  tests.js
... ...
@@ -1,5 +1,5 @@
1 1
 // tests for both the tokenizer and parser. Parser test results could be checked tighter.
2  
-// api: [input, token-output-count, ?regex-hints, desc]
  2
+// api: [input, ?[token-output-count, parser-output-count], ?regex-hints, desc]
3 3
 // regex-hints are for tokenizer, will tell for each token whether it might parse regex or not (parser's job)
4 4
 var Tests = [
5 5
 
@@ -13,37 +13,37 @@ var Tests = [
13 13
 ["var varwithfunction;", 4, "Variable Declaration, Identifier Containing Reserved Words, `;`"],
14 14
 ["a + b;", 6, "Addition/Concatenation"],
15 15
 
16  
-["'a'", 1, "Single-Quoted String"],
  16
+["'a'", [1, 2], "Single-Quoted String"],
17 17
 ["'a';", 2, "Single-Quoted String, `;`"], // Taken from the parser test suite.
18 18
 
19  
-["'a\\n'", 1, "Single-Quoted String With Escaped Linefeed"],
  19
+["'a\\n'", [1, 2], "Single-Quoted String With Escaped Linefeed"],
20 20
 ["'a\\n';", 2, "Single-Quoted String With Escaped Linefeed, `;`"], // Taken from the parser test suite.
21 21
 
22  
-["\"a\"", 1, "Double-Quoted String"],
  22
+["\"a\"", [1, 2], "Double-Quoted String"],
23 23
 ["\"a\";", 2, "Double-Quoted String, `;`"], // Taken from the parser test suite.
24 24
 
25  
-["\"a\\n\"", 1, "Double-Quoted String With Escaped Linefeed"],
  25
+["\"a\\n\"", [1, 2], "Double-Quoted String With Escaped Linefeed"],
26 26
 ["\"a\\n\";", 2, "Double-Quoted String With Escaped Linefeed, `;`"], // Taken from the parser test suite.
27 27
 
28  
-["500", 1, "Integer"],
  28
+["500", [1, 2], "Integer"],
29 29
 ["500;", 2, "Integer, `;`"], // Taken from the parser test suite.
30 30
 
31  
-["500.", 1, "Double With Trailing Decimal Point"],
  31
+["500.", [1, 2], "Double With Trailing Decimal Point"],
32 32
 ["500.;", 2, "Double With Trailing Decimal Point"], // Taken from the parser test suite.
33 33
 
34  
-["500.432", 1, "Double With Decimal Component"],
  34
+["500.432", [1, 2], "Double With Decimal Component"],
35 35
 ["500.432;", 2, "Double With Decimal Component, `;`"], // Taken from the parser test suite.
36 36
 
37  
-[".432432", 1, "Number, 0 < Double < 1"],
  37
+[".432432", [1, 2], "Number, 0 < Double < 1"],
38 38
 [".432432;", 2, "Number, 0 < Double < 1, `;`"], // Taken from the parser test suite.
39 39
 
40  
-["(a,b,c)", 7, "Parentheses, Comma-separated identifiers"],
  40
+["(a,b,c)", [7, 8], "Parentheses, Comma-separated identifiers"],
41 41
 ["(a,b,c);", 8, "Parentheses, Comma-separated identifiers, `;`"], // Taken from the parser test suite.
42 42
 
43  
-["[1,2,abc]", 7, "Array literal"],
  43
+["[1,2,abc]", [7, 8], "Array literal"],
44 44
 ["[1,2,abc];", 8, "Array literal, `;`"], // Taken from the parser test suite.
45 45
 
46  
-["{a:1,\"b\":2,c:c}", 13, "Object literal"],
  46
+["{a:1,\"b\":2,c:c}", [13, 19], "Malformed Block"],
47 47
 ["var o = {a:1,\"b\":2,c:c};", 20, "Assignment, Object Literal, `;`"], // Taken from the parser test suite.
48 48
 
49 49
 ["var x;\nvar y;", 9, "2 Variable Declarations, Multiple lines"],
@@ -56,7 +56,7 @@ var Tests = [
56 56
 ["/a/b;", 2, [true, true], "RegExp Literal, Flags, `;`"],
57 57
 ["++x;", 3, "Unary Increment, Prefix, `;`"],
58 58
 [" / /;", 3, [true, true, false], "RegExp, Leading Whitespace, `;`"],
59  
-["/ / / / /", 5, [true, false, false, false, true], "RegExp Containing One Space, Space, Division, Space, RegExp Containing One Space"],
  59
+["/ / / / /", [5, 6], [true, false, false, false, true], "RegExp Containing One Space, Space, Division, Space, RegExp Containing One Space"],
60 60
 
61 61
 // Taken from the parser test suite.
62 62
 
@@ -77,13 +77,19 @@ var Tests = [
77 77
 ["+function(){/regex/;};", 9, [false, false, false, false, false, true, false, false, false], "Unary `+` Operator, Function Expression Containing RegExp and Semicolon, `;`"],
78 78
 
79 79
 // Line Terminators.
  80
+
80 81
 ["\r\n", 1, "CRLF Line Ending = 1 Linefeed"],
81 82
 ["\r", 1, "CR Line Ending = 1 Linefeed"],
82 83
 ["\n", 1, "LF Line Ending = 1 Linefeed"],
83 84
 ["\r\n\n\u2028\u2029\r", 5, "Various Line Terminators"],
84 85
 
85 86
 // Whitespace.
86  
-["a \t\u000b\u000c\u00a0\uFFFFb", 8, "Whitespace"],
  87
+["a \t\u000b\u000c\u00a0\uffffb", [8, 10], "Whitespace"],
  88
+// Additional tests for whitespace...
  89
+
  90
+// http://code.google.com/p/es-lab/source/browse/trunk/tests/parser/parsertests.js?r=86 and 430.
  91
+
  92
+// first tests for the lexer, should also parse as program (when you append a semi)
87 93
 
88 94
 // Comments.
89 95
 ["//foo!@#^&$1234\nbar;", 4, "Line Comment, Linefeed, Identifier, `;`"],
@@ -149,9 +155,9 @@ var Tests = [
149 155
 ["\"\\x55\";", 2, "Double-Quoted String Containing Hex Escape Sequence, `;`"],
150 156
 ["\"\\x55a\";", 2, "Double-Quoted String Containing Hex Escape Sequence and Additional Character, `;`"],
151 157
 ["\"a\\\\nb\";", 2, "Double-Quoted String Containing Escaped Linefeed, `;`"],
152  
-["\";\"", 1, "Double-Quoted String Containing `;`"],
  158
+["\";\"", [1, 2], "Double-Quoted String Containing `;`"],
153 159
 ["\"a\\\nb\";", 2, "Double-Quoted String Containing Reverse Solidus and Linefeed, `;`"],
154  
-["'\\\\'+ ''", 4, "Single-Quoted String Containing Reverse Solidus, `+`, Empty Single-Quoted String"],
  160
+["'\\\\'+ ''", [4, 5], "Single-Quoted String Containing Reverse Solidus, `+`, Empty Single-Quoted String"],
155 161
 
156 162
 // `null`, `true`, and `false`.
157 163
 ["null;", 2, "`null`, `;`"],
@@ -164,11 +170,15 @@ var Tests = [
164 170
 ["/abc[a-z]*def/g;", 2, [true, true], "RegExp Containing Character Range and Quantifier, `;`"],
165 171
 ["/\\b/;", 2, [true, true], "RegExp Containing Control Character, `;`"],
166 172
 ["/[a-zA-Z]/;", 2, [true, true], "RegExp Containing Extended Character Range, `;`"],
  173
+
  174
+// Additional Program Tests.
  175
+
  176
+// RegExps.
167 177
 ["/foo(.*)/g;", 2, [true, false], "RegExp Containing Capturing Group and Quantifier, `;`"],
168 178
 
169 179
 // Array Literals.
170 180
 ["[];", 3, "Empty Array, `;`"],
171  
-["[\b\n\f\r\t\x20];", 9, "Array Containing Whitespace, `;`"],
  181
+["[\b\n\f\r\t\u0020];", [9, 10], "Array Containing Whitespace, `;`"],
172 182
 ["[1];", 4, "Array Containing 1 Element, `;`"],
173 183
 ["[1,2];", 6, "Array Containing 2 Elements, `;`"],
174 184
 ["[1,2,,];", 8, "Array Containing 2 Elisions, `;`"],
@@ -237,7 +247,7 @@ var Tests = [
237 247
 // Comma Operator.
238 248
 ["x, y;", 5, "Comma Operator"],
239 249
 
240  
-// Miscellaneous.
  250
+// ...
241 251
 ["new Date++;", 5, "`new` Operator, Identifier, Postfix Increment, `;`"],
242 252
 ["+x++;", 4, "Unary `+`, Identifier, Postfix Increment, `;`"],
243 253
 
@@ -360,7 +370,7 @@ var Tests = [
360 370
 // `throw` Statement.
361 371
 ["throw x;", 4, "Throw Statement, `;`"],
362 372
 ["throw x\n;", 5, "Throw Statement, Linefeed, `;`"],
363  
-["throw x", 3, "Throw Statement, No `;` (Safari 2 Case)"],
  373
+["throw x", [3, 4], "Throw Statement, No `;` (Safari 2 Case)"],
364 374
 
365 375
 // `try...catch...finally` Statement.
366 376
 ["try { s1; } catch (e) { s2; };", 22, "`try...catch` Statement"],
@@ -380,7 +390,7 @@ var Tests = [
380 390
 ["(function (x) {; });", 13, "Parenthesized Empty Function Expression"],
381 391
 ["(function f(x) { return x; });", 18, "Named Function Expression"],
382 392
 
383  
-// ECMAScript Programs.
  393
+// ECMAScript Program.
384 394
 ["var x; function f(){;}; null;", 17, "Variable Declaration, Function Declaration, `null`, `;`"],
385 395
 [";;", 2, "Program: 2 Empty Statements"],
386 396
 ["{ x; y; z; }", 12, "Program: Block Comprising Semicolon-Delimited Identifiers"],
@@ -388,16 +398,16 @@ var Tests = [
388 398
 ["x;\n/*foo*/\n\t;", 7, "Program: Identifier, Linefeed, Block Comment, Linefeed"],
389 399
 
390 400
 // Automatic Semicolon Insertion
391  
-["continue \n foo;", 6, "Restricted Production: `continue` Statement"],
392  
-["break \n foo;", 6, "Restricted Production: `break` Statement"],
393  
-["return\nfoo;", 4, "Restricted Production: `return` Statement"],
394  
-["throw\nfoo;", 4, "Restricted Production: `throw` Statement"],
395  
-["var x; { 1 \n 2 } 3", 16, "Classic Automatic Semicolon Insertion Case"],
396  
-["ab \t /* hi */\ncd", 7, "Automatic Semicolon Insertion: Block Comment"],
397  
-["ab/*\n*/cd", 3, "Automatic Semicolon Insertion Triggered by Multi-Line Block Comment"],
398  
-["continue /* wtf \n busta */ foo;", 6, "Automatic Semicolon Insertion: `continue` Statement Preceding Multi-Line Block Comment"],
399  
-["function f() { s }", 11, "Automatic Semicolon Insertion: Statement Within Function Declaration"],
400  
-["function f() { return }", 11, "Automatic Semicolon Insertion: `return` Statement Within Function Declaration"],
  401
+["continue \n foo;", [6, 7], "Restricted Production: `continue` Statement"],
  402
+["break \n foo;", [6, 7], "Restricted Production: `break` Statement"],
  403
+["return\nfoo;", [4, 5], "Restricted Production: `return` Statement"],
  404
+["throw\nfoo;", [4, 6], "Restricted Production: `throw` Statement"],
  405
+["var x; { 1 \n 2 } 3", [16, 19], "Classic Automatic Semicolon Insertion Case"],
  406
+["ab \t /* hi */\ncd", [7, 9], "Automatic Semicolon Insertion: Block Comment"],
  407
+["ab/*\n*/cd", [3, 5], "Automatic Semicolon Insertion Triggered by Multi-Line Block Comment"],
  408
+["continue /* wtf \n busta */ foo;", [6, 7], "Automatic Semicolon Insertion: `continue` Statement Preceding Multi-Line Block Comment"],
  409
+["function f() { s }", [11, 12], "Automatic Semicolon Insertion: Statement Within Function Declaration"],
  410
+["function f() { return }", [11, 12], "Automatic Semicolon Insertion: `return` Statement Within Function Declaration"],
401 411
 
402 412
 // Strict Mode.
403 413
 ["\"use strict\"; 'bla'\n; foo;", 9, "Double-Quoted Strict Mode Directive, Program"],
@@ -406,12 +416,13 @@ var Tests = [
406 416
 ["\"use\\n strict\";", 2, "Invalid Strict Mode Directive Containing Linefeed"],
407 417
 ["foo; \"use strict\";", 5, "Invalid Strict Mode Directive Within Program"],
408 418
 
409  
-// Taken from http://es5conform.codeplex.com.
  419
+// Tests from http://es5conform.codeplex.com.
  420
+
410 421
 ["\"use strict\"; var o = { eval: 42};", 17, "Section 8.7.2: `eval` object property name is permitted in strict mode"],
411 422
 ["({foo:0,foo:1});", 12, "Duplicate object property name is permitted in non-strict mode"],
412 423
 ["function foo(a,a){}", 10, "Duplicate argument name is permitted in non-strict mode"],
413  
-["(function foo(eval){})", 10, "`eval` argument name is permitted in non-strict mode"],
414  
-["(function foo(arguments){})", 10, "`arguments` argument name is permitted in non-strict mode"],
  424
+["(function foo(eval){})", [10, 11], "`eval` argument name is permitted in non-strict mode"],
  425
+["(function foo(arguments){})", [10, 11], "`arguments` argument name is permitted in non-strict mode"],
415 426
 
416 427
 // Empty Programs.
417 428
 ["", 0, "Empty Program"],
@@ -426,21 +437,21 @@ var Tests = [
426 437
 ["  /*\nsmeh*/\t\n   ", 8, "Spaces, Block Comment, Linefeeds, and Tabs"],
427 438
 
428 439
 // Trailing Whitespace.
429  
-["a  ", 3, "Trailing Space Characters"],
430  
-["a /* something */", 3, "Trailing Block Comment"],
431  
-["a\n\t// hah", 4, "Trailing Linefeed, Tab, and Line Comment"],
432  
-["/abc/de//f", 2, [true, true], "RegExp With Flags, Trailing Line Comment"],
433  
-["/abc/de/*f*/\n\t", 4, [true, true, true, true], "RegExp With Flags, Trailing Block Comment, Newline, Tab"],
  440
+["a  ", [3, 4], "Trailing Space Characters"],
  441
+["a /* something */", [3, 4], "Trailing Block Comment"],
  442
+["a\n\t// hah", [4, 5], "Trailing Linefeed, Tab, and Line Comment"],
  443
+["/abc/de//f", [2, 3], [true, true], "RegExp With Flags, Trailing Line Comment"],
  444
+["/abc/de/*f*/\n\t", [4, 5], [true, true, true, true], "RegExp With Flags, Trailing Block Comment, Newline, Tab"],
434 445
 
435 446
 // Regression Tests.
436  
-["for (x;function(){ a\nb };z) x;", 21, "`for` Loop: Test Condition Contains Function Body With No Terminating `;`"],
437  
-["c=function(){return;return};", 11, "Function Body: Two `return` Statements; No Terminating `;`"],
438  
-["d\nd()", 5, "Identifier, Newline, Function Call"],
439  
-["for(;;){x=function(){}}", 14, "Function Expression in `for` Loop Body"],
  447
+["for (x;function(){ a\nb };z) x;", [21, 23], "`for` Loop: Test Condition Contains Function Body With No Terminating `;`"],
  448
+["c=function(){return;return};", [11, 12], "Function Body: Two `return` Statements; No Terminating `;`"],
  449
+["d\nd()", [5, 7], "Identifier, Newline, Function Call"],
  450
+["for(;;){x=function(){}}", [14, 15], "Function Expression in `for` Loop Body"],
440 451
 ["for(var k;;){}", 10, "`for` Loop Header: Variable Declaration, Empty Test and Increment Conditions"],
441  
-["({get foo(){ }})", 12, "Empty Getter"],
442  
-["\nreturnr", 2, "Linefeed, Identifier Beginning With `return`"],
443  
-["/ // / /", 4, [true, false, false, true], "RegExp Containing One Space, Division Operator, Space, RegExp Containing One Space"],
  452
+["({get foo(){ }})", [12, 13], "Empty Getter"],
  453
+["\nreturnr", [2, 3], "Linefeed, Identifier Beginning With `return`"],
  454
+["/ // / /", [4, 5], [true, false, false, true], "RegExp Containing One Space, Division Operator, Space, RegExp Containing One Space"],
444 455
 ["trimRight = /\\s+$/;", 6, [false, false, false, false, true, false], "Typical `trimRight` RegExp"],
445 456
 ["trimLeft = /^\\s+/;\n\ttrimRight = /\\s+$/;", 14, [false, false, false, false, true, false, false, false, false, false, false, false, true, false], "`trimLeft` and `trimRight` RegExps"],
446 457
 ["\n\t// Used for trimming whitespace\n\ttrimLeft = /^\\s+/;\n\ttrimRight = /\\s+$/;\t\n", 21, [false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, true, false, false], "Annotated `trimLeft` and `trimRight` RegExps"],
@@ -450,31 +461,31 @@ var Tests = [
450 461
 
451 462
 ["({get:5});", 8, "`get` Used As Standard Property Name"],
452 463
 ["({set:5});", 8, "`get` Used As Standard Property Name"],
453  
-["l !== \"px\" && (d.style(h, c, (k || 1) + l), j = (k || 1) / f.cur() * j, d.style(h, c, j + l)), i[1] && (k = (i[1] === \"-=\" ? -1 : 1) * k + j), f.custom(j, k, l)", 131, "Regression Test: RegExp/Division"],
  464
+["l !== \"px\" && (d.style(h, c, (k || 1) + l), j = (k || 1) / f.cur() * j, d.style(h, c, j + l)), i[1] && (k = (i[1] === \"-=\" ? -1 : 1) * k + j), f.custom(j, k, l)", [131, 132], "Regression Test: RegExp/Division"],
454 465
 
455 466
 ["(/\'/g, \'\\\\\\\'\') + \"'\";'", 14, "Regression Test: Confusing Escape Character Sequence"],
456  
-["/abc\//no_comment", 3, [true, false, false], "RegExp Followed By Line Comment"],
  467
+["/abc\//no_comment", [3, 4], [true, false, false], "RegExp Followed By Line Comment"],
457 468
 ["a: b; c;", 8, "ASI Regression Test: Labeled Identifier, `;`, Identifier, `;`"],
458 469
 ["var x; function f(){ x; function g(){}}", 23, "Function Declaration Within Function Body"],
459  
-["if (x) { break }", 11, "ASI: `if` Statement, `break`"],
460  
-["x.hasOwnProperty()", 5, "Regression Test: Object Property Named `hasOwnProperty`"],
461  
-["(x) = 5", 7, "LHS of Expression Contains Grouping Operator"],
462  
-["(x,x) = 5", 9, "Syntactically Valid LHS Grouping Operator (Expression Will Produce A `ReferenceError` When Interpreted)"],
  470
+["if (x) { break }", [11, 12], "ASI: `if` Statement, `break`"],
  471
+["x.hasOwnProperty()", [5, 6], "Regression Test: Object Property Named `hasOwnProperty`"],
  472
+["(x) = 5", [7, 8], "LHS of Expression Contains Grouping Operator"],
  473
+["(x,x) = 5", [9, 10], "Syntactically Valid LHS Grouping Operator (Expression Will Produce A `ReferenceError` When Interpreted)"],
463 474
 ["switch(x){case 1:}", 10, "Single-`case` `switch` Statement Without Body"],
464  
-["while (x) { ++a\t}", 12, "Prefix Increment Operator, Tab Character Within `while` Loop"],
  475
+["while (x) { ++a\t}", [12, 13], "Prefix Increment Operator, Tab Character Within `while` Loop"],
465 476
 
466  
-["{break}", 3, "ASI: `break`"],
467  
-["{continue}", 3, "ASI: `continue`"],
468  
-["{return}", 3, "ASI: `return`"],
469  
-["{continue a}", 5, "ASI: `continue`, Identifier"],
470  
-["{break b}", 5, "ASI: `break`, Identifier"],
471  
-["{return c}", 5, "ASI: `return`, Identifier"],
  477
+["{break}", [3, 4], "ASI: `break`"],
  478
+["{continue}", [3, 4], "ASI: `continue`"],
  479
+["{return}", [3, 4], "ASI: `return`"],
  480
+["{continue a}", [5, 6], "ASI: `continue`, Identifier"],
  481
+["{break b}", [5, 6], "ASI: `break`, Identifier"],
  482
+["{return c}", [5, 6], "ASI: `return`, Identifier"],
472 483
 
473 484
 ["this.charsX = Gui.getSize(this.textarea).w / this.fontSize.w;", 25, "Complex Division Not Treated as RegExp"],
474 485
 ["(x)/ (y);", 9, "Parenthesized Dividend, Division Operator, Space, Parenthesized Divisor"],
475  
-["/^(?:\\/(?![*\\n\\/])(?:\\[(?:\\\\.|[^\\]\\\\\\n])*\\]|\\\\.|[^\\[\\/\\\\\\n])+\\/[gim]*)$/", 1, [true], "Complex RegExp for Matching RegExps"],
  486
+["/^(?:\\/(?![*\\n\\/])(?:\\[(?:\\\\.|[^\\]\\\\\\n])*\\]|\\\\.|[^\\[\\/\\\\\\n])+\\/[gim]*)$/", [1, 2], [true], "Complex RegExp for Matching RegExps"],
476 487
 ["({a:b}[ohi].iets()++);", 16, "Object Literal With 1 Member, Square Bracket Member Accessor, Dot Member Accessor, Function Call, Postfix Increment"],
477 488
 
478  
-["switch(x){ default: foo; break; case x: break; default: fail; }", 31, "double default should include error token (30+1)"]
  489
+["switch(x){ default: foo; break; case x: break; default: fail; }", [30, 34], "double default should include error token"]
479 490
 
480 491
 ];
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.