Chromium Code Reviews| 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..7a5b6c5082e36ce5a4ebb0538945be2e12fd32f6 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,193 @@ 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 |
| + ]); |
|
terry
2017/04/20 13:16:37
Ugh!, old not dartfmt was easier to grasp.
Jacob
2017/04/20 15:33:14
I agree this is not ideal. Added // comments to ma
|
| 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 +343,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 +383,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 +407,7 @@ printList(item) { |
| sb.write(']'); |
| return sb.toString(); |
| } |
| - if (item == null) |
| - return 'null'; |
| + if (item == null) return 'null'; |
| return item.toString(); |
| } |