Index: utils/tests/peg/peg_test.dart |
diff --git a/utils/tests/peg/peg_test.dart b/utils/tests/peg/peg_test.dart |
index b48453b3fec686aef9b3cff037291a61f2e75527..e15648e573322c423b1c8d51f0ec82eb84250c9f 100644 |
--- a/utils/tests/peg/peg_test.dart |
+++ b/utils/tests/peg/peg_test.dart |
@@ -3,6 +3,7 @@ |
// BSD-style license that can be found in the LICENSE file. |
library peg_tests; |
+ |
import 'dart:core' hide Symbol; |
import '../../peg/pegparser.dart'; |
@@ -10,7 +11,7 @@ testParens() { |
Grammar g = new Grammar(); |
Symbol a = g['A']; |
- a.def = ['(', MANY(a, min:0), ')', (a) => a]; |
+ a.def = ['(', MANY(a, min: 0), ')', (a) => a]; |
check(g, a, "", null); |
check(g, a, "()", '[]'); |
@@ -19,20 +20,22 @@ testParens() { |
} |
testBlockComment() { |
- |
// Block comment in whitespace. |
Grammar g = new Grammar(); |
Symbol blockComment = g['blockComment']; |
- blockComment.def = |
- ['/*', |
- MANY(OR([blockComment, |
- [NOT('*/'), CHAR()], |
- [END, ERROR('EOF in block comment')] |
- ]), |
- min: 0), |
- '*/']; |
+ blockComment.def = [ |
+ '/*', |
+ MANY( |
+ OR([ |
+ blockComment, |
+ [NOT('*/'), CHAR()], |
+ [END, ERROR('EOF in block comment')] |
+ ]), |
+ min: 0), |
+ '*/' |
+ ]; |
print(blockComment); |
var a = MANY(TEXT('x')); |
@@ -44,36 +47,36 @@ testBlockComment() { |
check(g, a, "x /*/***/ x", 'EOF in block comment'); |
check(g, a, "x /*/*/x**/**/ x", '[x,x]'); |
- check(g, a, r""" |
+ check( |
+ g, |
+ a, |
+ r""" |
/* Comment */ |
/* Following comment with /* nested comment*/ */ |
x |
/* x in comment */ |
x /* outside comment */ |
""", |
- '[x,x]'); |
+ '[x,x]'); |
} |
testTEXT() { |
Grammar g = new Grammar(); |
// TEXT grabs the parsed text, |
- check(g, TEXT(LEX(MANY(OR(['1','a'])))), ' 1a1 ', '1a1'); |
+ check(g, TEXT(LEX(MANY(OR(['1', 'a'])))), ' 1a1 ', '1a1'); |
// Without the lexical context, TEXT will grab intervening whitespace. |
- check(g, TEXT(MANY(OR(['1','a']))), ' 1a1 ', '1a1'); |
- check(g, TEXT(MANY(OR(['1','a']))), ' 1 a 1 ', '1 a 1'); |
+ check(g, TEXT(MANY(OR(['1', 'a']))), ' 1a1 ', '1a1'); |
+ check(g, TEXT(MANY(OR(['1', 'a']))), ' 1 a 1 ', '1 a 1'); |
// Custom processing of the TEXT substring. |
- var binaryNumber = |
- TEXT(LEX(MANY(OR(['0','1']))), |
- (str, start, end) { |
- var r = 0; |
- var zero = '0'.codeUnitAt(0); |
- for (int i = start; i < end; i++) |
- r = r * 2 + (str.codeUnitAt(i) - zero); |
- return r; |
- }); |
+ var binaryNumber = TEXT(LEX(MANY(OR(['0', '1']))), (str, start, end) { |
+ var r = 0; |
+ var zero = '0'.codeUnitAt(0); |
+ for (int i = start; i < end; i++) r = r * 2 + (str.codeUnitAt(i) - zero); |
+ return r; |
+ }); |
check(g, binaryNumber, ' 10101 ', 21); |
check(g, binaryNumber, '1010111', 87); |
@@ -83,10 +86,15 @@ testTEXT() { |
testOR() { |
// OR matches the first match. |
Grammar g = new Grammar(); |
- check(g, OR([['a', NOT(END), () => 1], |
- ['a', () => 2], |
- ['a', () => 3]]), |
- 'a', 2); |
+ check( |
+ g, |
+ OR([ |
+ ['a', NOT(END), () => 1], |
+ ['a', () => 2], |
+ ['a', () => 3] |
+ ]), |
+ 'a', |
+ 2); |
} |
testCODE() { |
@@ -96,8 +104,8 @@ testCODE() { |
check(g, a, 'bbb', 'bbb'); |
check(g, a, 'ccc', 'ccc'); |
check(g, a, 'ddd', 'ddd'); |
- check(g, a, 'bad', null); // a is outside range. |
- check(g, a, 'bed', null); // e is outside range. |
+ check(g, a, 'bad', null); // a is outside range. |
+ check(g, a, 'bed', null); // e is outside range. |
} |
testC() { |
@@ -106,8 +114,7 @@ testC() { |
unary(operation) => () => (first) => [operation, first]; |
reform(a, fns) { |
var r = a; |
- for (var fn in fns) |
- r = fn(r); |
+ for (var fn in fns) r = fn(r); |
return r; |
} |
@@ -126,128 +133,177 @@ testC() { |
Symbol assignment_e = g['assignment_e']; |
// Lexical elements. |
- var idStartChar = CHAR( |
- r"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); |
- var idNextChar = CHAR( |
- r"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789$_"); |
+ var idStartChar = |
+ CHAR(r"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); |
+ var idNextChar = |
+ CHAR(r"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789$_"); |
var id = TEXT(LEX('identifier', [idStartChar, MANY(idNextChar, min: 0)])); |
var lit = TEXT(LEX('literal', MANY(CHAR('0123456789')))); |
- |
var type_name = id; |
- |
// Expression grammar. |
- var primary_e = OR([id, |
- lit, |
- ['(', expression, ')', (e) => e] |
- ]); |
- |
- var postfixes = OR([['(', MANY(assignment_e, separator: ',', min: 0), ')', binary('apply')], |
- ['++', unary('postinc')], |
- ['--', unary('postdec')], |
- ['.', id, binary('field')], |
- ['->', id, binary('ptr')], |
- ]); |
- |
- postfix_e.def = [primary_e, MANY(postfixes, min:0), reform]; |
- |
- |
- var unary_op = OR([['&', () => 'address'], |
- ['*', () => 'indir'], |
- ['!', () => 'not'], |
- ['~', () => 'not'], |
- ['-', () => 'negate'], |
- ['+', () => 'uplus'], |
- ]); |
+ var primary_e = OR([ |
+ id, |
+ lit, |
+ ['(', expression, ')', (e) => e] |
+ ]); |
+ |
+ var postfixes = OR([ |
+ ['(', MANY(assignment_e, separator: ',', min: 0), ')', binary('apply')], |
+ ['++', unary('postinc')], |
+ ['--', unary('postdec')], |
+ ['.', id, binary('field')], |
+ ['->', id, binary('ptr')], |
+ ]); |
+ |
+ postfix_e.def = [primary_e, MANY(postfixes, min: 0), reform]; |
+ |
+ var unary_op = OR([ |
+ ['&', () => 'address'], |
+ ['*', () => 'indir'], |
+ ['!', () => 'not'], |
+ ['~', () => 'not'], |
+ ['-', () => 'negate'], |
+ ['+', () => 'uplus'], |
+ ]); |
var sizeof = LEX('sizeof', ['sizeof', NOT(idNextChar)]); |
Symbol unary_e_plain = g['unary_e_plain']; |
- unary_e_plain.def = |
- OR([ ['++', unary_e, (e) => ['preinc', e]], |
- ['--', unary_e, (e) => ['predec', e]], |
- [unary_op, cast_e, (o, e) => [o, e]], |
- [sizeof, unary_e, (e) => ['sizeof-expr', e]], |
- [sizeof, '(', type_name , ')', (t) => ['sizeof-type', t]], |
- postfix_e |
- ]); |
+ unary_e_plain.def = OR([ |
+ [ |
+ '++', unary_e, (e) => ['preinc', e] // |
+ ], |
+ [ |
+ '--', unary_e, (e) => ['predec', e] // |
+ ], |
+ [ |
+ unary_op, cast_e, (o, e) => [o, e] // |
+ ], |
+ [ |
+ sizeof, unary_e, (e) => ['sizeof-expr', e] // |
+ ], |
+ [ |
+ sizeof, '(', type_name, ')', (t) => ['sizeof-type', t] // |
+ ], |
+ postfix_e |
+ ]); |
unary_e.def = MEMO(unary_e_plain); |
//unary_e.def = unary_e_plain; |
- cast_e.def = OR([ ['(', type_name, ')', cast_e, (t, e) => ['cast', t, e]], |
- unary_e, |
- ]); |
- |
- var mult_ops = OR([['*', cast_e, binary('mult')], |
- ['/', cast_e, binary('div')], |
- ['%', cast_e, binary('rem')], |
- ]); |
- mult_e.def = [cast_e, MANY(mult_ops, min:0), reform]; |
- |
- var add_ops = OR([['+', mult_e, binary('add')], |
- ['-', mult_e, binary('sub')], |
- ]); |
- add_e.def = [mult_e, MANY(add_ops, min:0), reform]; |
- |
- var shift_ops = OR([['>>', add_e, binary('shl')], |
- ['<<', add_e, binary('shr')], |
- ]); |
- shift_e.def = [add_e, MANY(shift_ops, min:0), reform]; |
- |
- var relational_ops = OR([['<=', shift_e, binary('le')], |
- ['>=', shift_e, binary('ge')], |
- ['<', shift_e, binary('lt')], |
- ['>', shift_e, binary('gt')], |
- ]); |
- relational_e.def = [shift_e, MANY(relational_ops, min:0), reform]; |
- |
- |
- var equality_ops = OR([['==', shift_e, binary('eq')], |
- ['!=', shift_e, binary('ne')], |
- ]); |
- equality_e.def = [relational_e, MANY(equality_ops, min:0), reform]; |
- |
- |
- var bit_and_op = LEX('&', ['&', NOT('&')]); // Don't see '&&' and '&', '&' |
+ cast_e.def = OR([ |
+ [ |
+ '(', type_name, ')', cast_e, (t, e) => ['cast', t, e] // |
+ ], |
+ unary_e, |
+ ]); |
+ |
+ var mult_ops = OR([ |
+ ['*', cast_e, binary('mult')], |
+ ['/', cast_e, binary('div')], |
+ ['%', cast_e, binary('rem')], |
+ ]); |
+ mult_e.def = [cast_e, MANY(mult_ops, min: 0), reform]; |
+ |
+ var add_ops = OR([ |
+ ['+', mult_e, binary('add')], |
+ ['-', mult_e, binary('sub')], |
+ ]); |
+ add_e.def = [mult_e, MANY(add_ops, min: 0), reform]; |
+ |
+ var shift_ops = OR([ |
+ ['>>', add_e, binary('shl')], |
+ ['<<', add_e, binary('shr')], |
+ ]); |
+ shift_e.def = [add_e, MANY(shift_ops, min: 0), reform]; |
+ |
+ var relational_ops = OR([ |
+ ['<=', shift_e, binary('le')], |
+ ['>=', shift_e, binary('ge')], |
+ ['<', shift_e, binary('lt')], |
+ ['>', shift_e, binary('gt')], |
+ ]); |
+ relational_e.def = [shift_e, MANY(relational_ops, min: 0), reform]; |
+ |
+ var equality_ops = OR([ |
+ ['==', shift_e, binary('eq')], |
+ ['!=', shift_e, binary('ne')], |
+ ]); |
+ equality_e.def = [relational_e, MANY(equality_ops, min: 0), reform]; |
+ |
+ var bit_and_op = LEX('&', ['&', NOT('&')]); // Don't see '&&' and '&', '&' |
var bit_or_op = LEX('|', ['|', NOT('|')]); |
- var and_e = [equality_e, MANY([bit_and_op, equality_e, binary('bitand')], min:0), reform]; |
- var xor_e = [and_e, MANY(['^', and_e, binary('bitxor')], min:0), reform]; |
- var or_e = [xor_e, MANY([bit_or_op, xor_e, binary('bitor')], min:0), reform]; |
- |
- var log_and_e = [or_e, MANY(['&&', or_e, binary('and')], min:0), reform]; |
- |
- var log_or_e = [log_and_e, MANY(['||', log_and_e, binary('or')], min:0), reform]; |
+ var and_e = [ |
+ equality_e, |
+ MANY([bit_and_op, equality_e, binary('bitand')], min: 0), |
+ reform |
+ ]; |
+ var xor_e = [ |
+ and_e, |
+ MANY(['^', and_e, binary('bitxor')], min: 0), |
+ reform |
+ ]; |
+ var or_e = [ |
+ xor_e, |
+ MANY([bit_or_op, xor_e, binary('bitor')], min: 0), |
+ reform |
+ ]; |
+ |
+ var log_and_e = [ |
+ or_e, |
+ MANY(['&&', or_e, binary('and')], min: 0), |
+ reform |
+ ]; |
+ |
+ var log_or_e = [ |
+ log_and_e, |
+ MANY(['||', log_and_e, binary('or')], min: 0), |
+ reform |
+ ]; |
//cond_e.def = OR([ [log_or_e, '?', expression, ':', cond_e, |
// (p,a,b) => ['cond', p, a, b]], |
// log_or_e]); |
// Alternate version avoids reparsing log_or_e. |
- cond_e.def = [log_or_e, MAYBE(['?', expression, ':', cond_e]), |
- (p, r) => r == null || r == false ? p : ['cond', p, r[0], r[1]]]; |
+ cond_e.def = [ |
+ log_or_e, |
+ MAYBE(['?', expression, ':', cond_e]), |
+ (p, r) => r == null || r == false ? p : ['cond', p, r[0], r[1]] |
+ ]; |
- var assign_op = OR([['*=', () => 'mulassign'], |
- ['=', () => 'assign']]); |
+ var assign_op = OR([ |
+ ['*=', () => 'mulassign'], |
+ ['=', () => 'assign'] |
+ ]); |
// TODO: Figure out how not to re-parse a unary_e. |
// Order matters - cond_e can't go first since cond_e will succeed on, e.g. 'a'. |
- assignment_e.def = OR([[unary_e, assign_op, assignment_e, |
- (u, op, a) => [op, u, a]], |
- cond_e]); |
- |
- expression.def = [assignment_e, |
- MANY([',', assignment_e, binary('comma')], min:0), |
- reform]; |
+ assignment_e.def = OR([ |
+ [ |
+ unary_e, |
+ assign_op, |
+ assignment_e, |
+ (u, op, a) => [op, u, a] |
+ ], |
+ cond_e |
+ ]); |
+ |
+ expression.def = [ |
+ assignment_e, |
+ MANY([',', assignment_e, binary('comma')], min: 0), |
+ reform |
+ ]; |
show(g, expression, 'a'); |
check(g, expression, 'a', 'a'); |
check(g, expression, '(a)', 'a'); |
check(g, expression, ' ( ( a ) ) ', 'a'); |
- check(g, expression, 'a(~1,2)', '[apply,a,[[not,1],2]]'); |
+ check(g, expression, 'a(~1,2)', '[apply,a,[[not,1],2]]'); |
check(g, expression, 'a(1)(x,2)', '[apply,[apply,a,[1]],[x,2]]'); |
check(g, expression, 'a(1,2())', '[apply,a,[1,[apply,2,[]]]]'); |
@@ -271,22 +327,20 @@ testC() { |
check(g, expression, 'a<1&&b', '[and,[lt,a,1],b]'); |
check(g, expression, 'a<1 & &b', '[bitand,[lt,a,1],[address,b]]'); |
- check(g, expression, |
- 'a ? b ? c : d : e ? f : g', |
- '[cond,a,[cond,b,c,d],[cond,e,f,g]]'); |
+ check(g, expression, 'a ? b ? c : d : e ? f : g', |
+ '[cond,a,[cond,b,c,d],[cond,e,f,g]]'); |
check(g, expression, 'a,b,c', '[comma,[comma,a,b],c]'); |
check(g, expression, 'a=1,b,c', '[comma,[comma,[assign,a,1],b],c]'); |
- check(g, expression, |
- '((((((((((((a))))))))))))=1,b,c', '[comma,[comma,[assign,a,1],b],c]'); |
+ check(g, expression, '((((((((((((a))))))))))))=1,b,c', |
+ '[comma,[comma,[assign,a,1],b],c]'); |
check(g, expression, 'sizeof a', '[sizeof-expr,a]'); |
check(g, expression, 'sizeofa', 'sizeofa'); |
check(g, expression, 'sizeof (a)', '[sizeof-expr,a]'); |
} |
- |
show(grammar, rule, input) { |
print('show: "$input"'); |
var ast; |
@@ -313,13 +367,11 @@ void check(grammar, rule, input, expected) { |
} |
var formatted = ast; |
- if (expected is String) |
- formatted = printList(ast); |
+ if (expected is String) formatted = printList(ast); |
//Expect.equals(expected, formatted, "parse: $input"); |
if (expected != formatted) { |
- throw new ArgumentError( |
- "parse: $input" |
+ throw new ArgumentError("parse: $input" |
"\n expected: $expected" |
"\n found: $formatted"); |
} |
@@ -339,8 +391,7 @@ printList(item) { |
sb.write(']'); |
return sb.toString(); |
} |
- if (item == null) |
- return 'null'; |
+ if (item == null) return 'null'; |
return item.toString(); |
} |