From 9aacf5aa62eebae0d7293a2c783160009fde043f Mon Sep 17 00:00:00 2001 From: "sra@google.com" Date: Fri, 28 Oct 2011 05:34:41 +0000 Subject: [PATCH] Revert "PEG Parser: under review at http://codereview.chromium.org/8399029" This reverts commit e9f4f54f10af8a0b808b0fd4a1ea54384df0d7d9. BUG= TEST= Review URL: http://codereview.chromium.org//8414016 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@870 260f80e4-7a28-3924-810f-c04153c831b5 --- client/dom/scripts/idlparser.dart | 547 ---------------- client/dom/scripts/idlparser_test.dart | 115 ---- client/dom/scripts/idlrenderer.dart | 181 ------ utils/peg/pegparser.dart | 858 ------------------------- utils/peg/pegparser_test.dart | 346 ---------- 5 files changed, 2047 deletions(-) delete mode 100644 client/dom/scripts/idlparser.dart delete mode 100644 client/dom/scripts/idlparser_test.dart delete mode 100644 client/dom/scripts/idlrenderer.dart delete mode 100644 utils/peg/pegparser.dart delete mode 100644 utils/peg/pegparser_test.dart diff --git a/client/dom/scripts/idlparser.dart b/client/dom/scripts/idlparser.dart deleted file mode 100644 index c65b6a4bd08..00000000000 --- a/client/dom/scripts/idlparser.dart +++ /dev/null @@ -1,547 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -// IDL grammar variants. -final int WEBIDL_SYNTAX = 0; -final int WEBKIT_SYNTAX = 1; -final int FREMONTCUT_SYNTAX = 2; - -/** - * IDLFile is the top-level node in each IDL file. It may contain modules or - * interfaces. - */ -class IDLFile extends IDLNode { - - String filename; - List modules; - List interfaces; - - IDLFile(this.filename, this.modules, this.interfaces); -} - -/** - * IDLModule has an id, and may contain interfaces, type defs andimplements - * statements. - */ -class IDLModule extends IDLNode { - String id; - List interfaces; - List typedefs; - List implementsStatements; - - IDLModule(String this.id, IDLExtAttrs extAttrs, IDLAnnotations annotations, - List elements) { - setExtAttrs(extAttrs); - this.annotations = annotations; - this.interfaces = elements.filter((e) => e is IDLInterface); - this.typedefs = elements.filter((e) => e is IDLTypeDef); - this.implementsStatements = - elements.filter((e) => e is IDLImplementsStatement); - } - - toString() => ''; -} - -class IDLNode { - IDLExtAttrs extAttrs; - IDLAnnotations annotations; - IDLNode(); - - setExtAttrs(IDLExtAttrs ea) { - assert(ea != null); - this.extAttrs = ea != null ? ea : new IDLExtAttrs(); - } -} - -class IDLType extends IDLNode { - String id; - IDLType parameter; - bool nullable = false; - IDLType(String this.id, [IDLType this.parameter, bool this.nullable = false]); - - // TODO: Figure out why this constructor was failing in mysterious ways. - // IDLType.nullable(IDLType base) { - // return new IDLType(base.id, base.parameter, true); - // } - - //String toString() => ''; - String toString() { - String nullableTag = nullable ? '?' : ''; - return ''; - } -} - -class IDLTypeDef extends IDLNode { - String id; - IDLType type; - IDLTypeDef(String this.id, IDLType this.type); - - toString() => ''; -} - -class IDLImplementsStatement extends IDLNode { -} - -class IDLInterface extends IDLNode { - String id; - List parents; - List operations; - List attributes; - List constants; - List snippets; - - bool isSupplemental; - bool isNoInterfaceObject; - bool isFcSuppressed; - - IDLInterface(String this.id, IDLExtAttrs ea, IDLAnnotations ann, - List this.parents, List members) { - setExtAttrs(ea); - this.annotations = ann; - if (this.parents == null) this.parents = []; - - operations = members.filter((e) => e is IDLOperation); - attributes = members.filter((e) => e is IDLAttribute); - constants = members.filter((e) => e is IDLConstant); - snippets = members.filter((e) => e is IDLSnippet); - - isSupplemental = extAttrs.has('Supplemental'); - isNoInterfaceObject = extAttrs.has('NoInterfaceObject'); - isFcSuppressed = extAttrs.has('Suppressed'); - } - - toString() => ''; -} - -class IDLMember extends IDLNode { - String id; - IDLType type; - bool isFcSuppressed; - - IDLMember(String this.id, IDLType this.type, IDLExtAttrs ea, IDLAnnotations ann) { - setExtAttrs(ea); - this.annotations = ann; - - isFcSuppressed = extAttrs.has('Suppressed'); - } -} - -class IDLOperation extends IDLMember { - List arguments; - - // Ignore all forms of raises for now. - List specials; - bool isStringifier; - - IDLOperation(String id, IDLType type, IDLExtAttrs ea, IDLAnnotations ann, - List this.arguments, List this.specials, bool this.isStringifier) - : super(id, type, ea, ann) { - } - - toString() => ''; -} - -class IDLAttribute extends IDLMember { -} - -class IDLConstant extends IDLMember { - var value; - IDLConstant(String id, IDLType type, IDLExtAttrs ea, IDLAnnotations ann, - var this.value) - : super(id, type, ea, ann); -} - -class IDLSnippet extends IDLMember { - String text; - IDLSnippet(IDLAnnotations ann, String this.text) - : super(null, null, new IDLExtAttrs(), ann); -} - -/** Maps string to something. */ -class IDLDictNode { - Map map; - IDLDictNode() { - map = new Map(); - } - - setMap(List associationList) { - if (associationList == null) return; - for (var element in associationList) { - var name = element[0]; - var value = element[1]; - map[name] = value; - } - } - - bool has(String key) => map.containsKey(key); - - formatMap() { - if (map.isEmpty()) - return ''; - StringBuffer sb = new StringBuffer(); - map.forEach((k, v) { - sb.add(' $k'); - if (v != null) { - sb.add('=$v'); - } - }); - return sb.toString(); - } - -} - -class IDLExtAttrs extends IDLDictNode { - IDLExtAttrs([List attrs = const []]) { - setMap(attrs); - } - - toString() => ''; -} - -class IDLArgument extends IDLNode { - String id; - IDLType type; - bool isOptional; - bool isIn; - bool hasElipsis; - IDLArgument(String this.id, IDLType this.type, IDLExtAttrs extAttrs, - bool this.isOptional, bool this.isIn, bool this.hasElipsis) { - setExtAttrs(extAttrs); - } - - toString() => ''; -} - -class IDLAnnotations extends IDLDictNode { - IDLAnnotations(List annotations) { - for (var annotation in annotations) { - map[annotation.id] = annotation; - } - } - - toString() => ''; -} - -class IDLAnnotation extends IDLDictNode { - String id; - IDLAnnotation(String this.id, List args) { - setMap(args); - } - - toString() => ''; -} - -class IDLExtAttrFunctionValue extends IDLNode { - String name; - List arguments; - IDLExtAttrFunctionValue(String this.name, this.arguments); - - toString() => ''; -} - -class IDLParentInterface extends IDLNode {} - -//////////////////////////////////////////////////////////////////////////////// - -class IDLParser { - final int syntax; - Grammar grammar; - var axiom; - - IDLParser([syntax=WEBIDL_SYNTAX]) : syntax = syntax { - grammar = new Grammar(); - axiom = _makeParser(); - } - - _makeParser() { - Grammar g = grammar; - - syntax_switch([WebIDL, WebKit, FremontCut]) { - assert(WebIDL != null && WebKit != null); // Not options, just want names. - if (syntax == WEBIDL_SYNTAX) - return WebIDL; - if (syntax == WEBKIT_SYNTAX) - return WebKit; - if (syntax == FREMONTCUT_SYNTAX) - return FremontCut == null ? WebIDL : FremontCut; - throw new Exception('unsupported IDL syntax $syntax'); - } - - var idStartCharSet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_'; - var idNextCharSet = idStartCharSet + '0123456789'; - var hexCharSet = '0123456789ABCDEFabcdef'; - - var idStartChar = CHAR(idStartCharSet); - var idNextChar = CHAR(idNextCharSet); - - var digit = CHAR('0123456789'); - - var Id = TEXT(LEX('an identifier',[idStartChar, MANY(idNextChar, min:0)])); - - var IN = SKIP(LEX("'in'", ['in',NOT(idNextChar)])); - - var BooleanLiteral = OR(['true', 'false']); - var IntegerLiteral = TEXT(LEX('hex-literal', OR([['0x', MANY(CHAR(hexCharSet))], - [MANY(digit)]]))); - var FloatLiteral = TEXT(LEX('float-literal', [MANY(digit), '.', MANY(digit, min:0)])); - - - var Argument = g['Argument']; - var Module = g['Module']; - var Member = g['Member']; - var Interface = g['Interface']; - var ExceptionDef = g['ExceptionDef']; - var Type = g['Type']; - var TypeDef = g['TypeDef']; - var ImplStmt = g['ImplStmt']; - var ValueTypeDef = g['ValueTypeDef']; - var Const = g['Const']; - var Attribute = g['Attribute']; - var Operation = g['Operation']; - var Snippet = g['Snippet']; - var ExtAttrs = g['ExtAttrs']; - var MaybeExtAttrs = g['MaybeExtAttrs']; - var MaybeAnnotations = g['MaybeAnnotations']; - var ParentInterfaces = g['ParentInterfaces']; - - - final ScopedName = TEXT(LEX('scoped-name', MANY(CHAR(idStartCharSet + '_:.<>')))); - - final ScopedNames = MANY(ScopedName, separator:','); - - // Types - - final IntegerTypeName = OR([ - ['byte', () => 'byte'], - ['int', () => 'int'], - ['long', 'long', () => 'long long'], - ['long', () => 'long'], - ['octet', () => 'octet'], - ['short', () => 'short']]); - - final IntegerType = OR([ - ['unsigned', IntegerTypeName, (name) => new IDLType('unsigned $name')], - [IntegerTypeName, (name) => new IDLType(name)]]); - - final BooleanType = ['boolean', () => new IDLType('boolean')]; - final OctetType = ['octet', () => new IDLType('octet')]; - final FloatType = ['float', () => new IDLType('float')]; - final DoubleType = ['double', () => new IDLType('double')]; - - final SequenceType = ['sequence', '<', Type, '>', - (type) => new IDLType('sequence', type)]; - - final ScopedNameType = [ScopedName, (name) => new IDLType(name)]; - - final NullableType = - [OR([IntegerType, BooleanType, OctetType, FloatType, - DoubleType, SequenceType, ScopedNameType]), - MAYBE('?'), - (type, nullable) => - nullable ? new IDLType(type.id, type.parameter, true) : type]; - - final VoidType = ['void', () => new IDLType('void')]; - final AnyType = ['any', () => new IDLType('any')]; - final ObjectType = ['object', () => new IDLType('object')]; - - Type.def = OR([AnyType, ObjectType, NullableType]); - - final ReturnType = OR([VoidType, Type]); - - var Definition = syntax_switch( - WebIDL: OR([Module, Interface, ExceptionDef, TypeDef, ImplStmt, - ValueTypeDef, Const]), - WebKit: OR([Module, Interface])); - - var Definitions = MANY(Definition, min:0); - - Module.def = syntax_switch( - WebIDL: [MaybeExtAttrs, 'module', Id, '{', Definitions, '}', - SKIP(MAYBE(';')), - (ea, id, defs) => new IDLModule(id, ea, null, defs)], - WebKit: ['module', MaybeExtAttrs, Id, '{', Definitions, '}', - SKIP(MAYBE(';')), - (ea, id, defs) => new IDLModule(id, ea, null, defs)], - FremontCut: [MaybeAnnotations, MaybeExtAttrs, 'module', Id, - '{', Definitions, '}', SKIP(MAYBE(';')), - (ann, ea, id, defs) => new IDLModule(id, ea, ann, defs)]); - - Interface.def = syntax_switch( - WebIDL: [MaybeExtAttrs, 'interface', Id, MAYBE(ParentInterfaces), - MAYBE(['{', MANY0(Member), '}']), ';', - (ea, id, p, ms) => new IDLInterface(id, ea, null, p, ms)], - WebKit: ['interface', MaybeExtAttrs, Id, MAYBE(ParentInterfaces), - MAYBE(['{', MANY0(Member), '}']), ';', - (ea, id, p, ms) => new IDLInterface(id, ea, null, p, ms)], - FremontCut: [MaybeAnnotations, MaybeExtAttrs, 'interface', - Id, MAYBE(ParentInterfaces), - MAYBE(['{', MANY0(Member), '}']), ';', - (ann, ea, id, p, ms) => new IDLInterface(id, ea, ann, p, ms)]); - - Member.def = syntax_switch( - WebIDL: OR([Const, Attribute, Operation, ExtAttrs]), - WebKit: OR([Const, Attribute, Operation]), - FremontCut: OR([Const, Attribute, Operation, Snippet])); - - var InterfaceType = ScopedName; - - var ParentInterface = syntax_switch( - WebIDL: [InterfaceType], - WebKit: [InterfaceType], - FremontCut: [MaybeAnnotations, InterfaceType]); - - ParentInterfaces.def = [':', MANY(ParentInterface, ',')]; - - // TypeDef (Web IDL): - TypeDef.def = ['typedef', Type, Id, ';', (type, id) => new IDLTypeDef(id, type)]; - - // TypeDef (Old-school W3C IDLs) - ValueTypeDef.def = ['valuetype', Id, Type, ';']; - - // Implements Statement (Web IDL): - var ImplStmtImplementor = ScopedName; - var ImplStmtImplemented = ScopedName; - - ImplStmt.def = [ImplStmtImplementor, 'implements', ImplStmtImplemented, ';']; - - var ConstExpr = OR([BooleanLiteral, IntegerLiteral, FloatLiteral]); - - Const.def = syntax_switch( - WebIDL: [MaybeExtAttrs, 'const', Type, Id, '=', ConstExpr, ';', - (ea, type, id, v) => new IDLConstant(id, type, ea, null, v)], - WebKit: ['const', MaybeExtAttrs, Type, Id, '=', ConstExpr, ';', - (ea, type, id, v) => new IDLConstant(id, type, ea, null, v)], - FremontCut: [MaybeAnnotations, MaybeExtAttrs, - 'const', Type, Id, '=', ConstExpr, ';', - (ann, ea, type, id, v) => - new IDLConstant(id, type, ea, ann, v)]); - - // Attributes - - var Stringifier = 'stringifier'; - var AttrGetter = 'getter'; - var AttrSetter = 'setter'; - var ReadOnly = 'readonly'; - var AttrGetterSetter = OR([AttrGetter, AttrSetter]); - - var GetRaises = syntax_switch( - WebIDL: ['getraises', '(', ScopedNames, ')'], - WebKit: ['getter', 'raises', '(', ScopedNames, ')']); - - var SetRaises = syntax_switch( - WebIDL: ['setraises', '(', ScopedNames, ')'], - WebKit: ['setter', 'raises', '(', ScopedNames, ')']); - - var Raises = ['raises', '(', ScopedNames, ')']; - - var AttrRaises = syntax_switch( - WebIDL: MANY(OR([GetRaises, SetRaises])), - WebKit: MANY(OR([GetRaises, SetRaises, Raises]), separator:',')); - - Attribute.def = syntax_switch( - WebIDL: [MaybeExtAttrs, MAYBE(Stringifier), MAYBE(ReadOnly), - 'attribute', Type, Id, MAYBE(AttrRaises), ';'], - WebKit: [MAYBE(Stringifier), MAYBE(ReadOnly), 'attribute', - MaybeExtAttrs, Type, Id, MAYBE(AttrRaises), ';'], - FremontCut: [MaybeAnnotations, MaybeExtAttrs, - MAYBE(AttrGetterSetter), MAYBE(Stringifier), MAYBE(ReadOnly), - 'attribute', Type, Id, MAYBE(AttrRaises), ';' - ]); - - // Operations - - final Special = TEXT(OR(['getter', 'setter', 'creator', 'deleter', 'caller'])); - final Specials = MANY(Special); - - final Optional = 'optional'; - final AnEllipsis = '...'; - - Argument.def = syntax_switch( - WebIDL: SEQ(MaybeExtAttrs, MAYBE(Optional), MAYBE(IN), - MAYBE(Optional), Type, MAYBE(AnEllipsis), Id, - (e, opt1, isin, opt2, type, el, id) => - new IDLArgument(id, type, e, opt1 || opt2, isin, el)), - - WebKit: SEQ(MAYBE(Optional), MAYBE('in'), MAYBE(Optional), - MaybeExtAttrs, Type, Id - (opt1, isin, opt2, e, type, id) => - new IDLArgument(id, type, e, opt1 || opt2, isin, false))); - - final Arguments = MANY0(Argument, ','); - - Operation.def = syntax_switch( - WebIDL: [MaybeExtAttrs, MAYBE(Stringifier), MAYBE(Specials), - ReturnType, MAYBE(Id), '(', Arguments, ')', MAYBE(Raises), ';', - (ea, isStringifier, specials, type, id, args, raises) => - new IDLOperation(id, type, ea, null, args, specials, isStringifier) - ], - WebKit: [MaybeExtAttrs, ReturnType, MAYBE(Id), '(', Arguments, ')', - MAYBE(Raises), ';', - (ea, type, id, args, raises) => - new IDLOperation(id, type, ea, null, args, [], false) - ], - FremontCut: [MaybeAnnotations, MaybeExtAttrs, MAYBE(Stringifier), - MAYBE(Specials), ReturnType, MAYBE(Id), '(', Arguments, ')', - MAYBE(Raises), ';', - (ann, ea, isStringifier, specials, type, id, args, raises) => - new IDLOperation(id, type, ea, ann, args, specials, isStringifier) - ]); - - // Exceptions - - final ExceptionField = [Type, Id, ';']; - final ExceptionMember = OR([Const, ExceptionField, ExtAttrs]); - ExceptionDef.def = ['exception', Id, '{', MANY0(ExceptionMember), '}', ';']; - - // ExtendedAttributes - - var ExtAttrArgList = ['(', MANY0(Argument, ','), ')']; - - var ExtAttrFunctionValue = - [Id, '(', MANY0(Argument, ','), ')', - (name, args) => new IDLExtAttrFunctionValue(name, args) - ]; - - var ExtAttrValue = OR([ExtAttrFunctionValue, - TEXT(LEX('value', MANY(CHAR(idNextCharSet + '&:-|'))))]); - - var ExtAttr = [Id, MAYBE(OR([['=', ExtAttrValue], ExtAttrArgList]))]; - - ExtAttrs.def = ['[', MANY(ExtAttr, ','), ']', - (list) => new IDLExtAttrs(list)];; - - MaybeExtAttrs.def = OR(ExtAttrs, - [ () => new IDLExtAttrs() ] ); - - // Annotations - used in the FremontCut IDL grammar. - - var AnnotationArgValue = TEXT(LEX('xx', MANY(CHAR(idNextCharSet + '&:-|')))); - - var AnnotationArg = [Id, MAYBE(['=', AnnotationArgValue])]; - - var AnnotationBody = ['(', MANY0(AnnotationArg, ','), ')']; - - var Annotation = ['@', Id, MAYBE(AnnotationBody), - (id, body) => new IDLAnnotation(id, body)]; - - MaybeAnnotations.def = [MANY0(Annotation), (list) => new IDLAnnotations(list)]; - - // Snippets - used in the FremontCut IDL grammar. - - final SnippetText = TEXT(LEX('snippet body', MANY0([NOT('}'), CHAR()]))); - Snippet.def = [MaybeAnnotations, 'snippet', '{', SnippetText, '}', ';', - (ann, text) => new IDLSnippet(ann, text)]; - - - grammar.whitespace = - OR([MANY(CHAR(' \t\r\n')), - ['//', MANY0([NOT(CHAR('\r\n')), CHAR()])], - ['#', MANY0([NOT(CHAR('\r\n')), CHAR()])], - ['/*', MANY0([NOT('*/'), CHAR()]), '*/']]); - - // Top level - at least one definition. - return MANY(Definition); - - } -} diff --git a/client/dom/scripts/idlparser_test.dart b/client/dom/scripts/idlparser_test.dart deleted file mode 100644 index a8544c3c5d1..00000000000 --- a/client/dom/scripts/idlparser_test.dart +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -#import('../../../utils/peg/pegparser.dart'); -#source('idlparser.dart'); -#source('idlrenderer.dart'); - -main() { - IDLParser parser = new IDLParser(FREMONTCUT_SYNTAX); - Grammar g = parser.grammar; - - var Type = g['Type']; - - show(g, Type, 'int'); - show(g, Type, 'int ?'); - show(g, Type, 'sequence ?'); - show(g, Type, 'unsigned long long?'); - show(g, Type, 'unsignedlonglong?'); - - - var MaybeAnnotations = g['MaybeAnnotations']; - - show(g, MaybeAnnotations, ''); - show(g, MaybeAnnotations, '@Foo'); - show(g, MaybeAnnotations, '@Foo @Bar'); - show(g, MaybeAnnotations, '@Foo(A,B=1) @Bar'); - - var MaybeExtAttrs = g['MaybeExtAttrs']; - print(MaybeExtAttrs); - - show(g, MaybeExtAttrs, ''); - show(g, MaybeExtAttrs, '[A]'); - - var Module = g['Module']; - - show(g, Module, 'module Harry { const int bob = 30;};'); - show(g, Module, """ -module Harry { [X,Y,Z=99] const int bob = 30; typedef x y; - - interface Thing : SuperA, @Friendly SuperB { - - [Nice] const unsigned long long kFoo = 12345; - [A,B,C,D,E] attribute int attr1; - [F=f(int a),K=99,DartName=Bert] int smudge(int a, int b, double x); - - [X,Y,Z] int xyz([U,V] optional in optional int z); - [P,Q,R] int pqr(); - int op1(); - @Smurf @Beans(B=1,C,A=2) int op2(); - - snippet { yadda - yadda - }; - }; - -//[A] const unsigned long long dweeb = 0xff; - -}; -"""); -} - - - -show(grammar, rule, input) { - print('show: "$input"'); - var ast; - try { - ast = grammar.parse(rule, input); - } catch (var exception) { - if (exception is ParseError) - ast = exception; - else - throw; - } - print('${printList(ast)}'); - print(render(ast)); -} - -void check(grammar, rule, input, expected) { - // If [expected] is String then the result is coerced to string. - // If [expected] is !String, the result is compared directly. - print('check: "$input"'); - var ast; - try { - ast = grammar.parse(rule, input); - } catch (var exception) { - ast = exception; - } - - var formatted = ast; - if (expected is String) - formatted = printList(ast); - - Expect.equals(expected, formatted, "parse: $input"); -} - -// Prints the list in [1,2,3] notation, including nested lists. -void printList(item) { - if (item is List) { - StringBuffer sb = new StringBuffer(); - sb.add('['); - var sep = ''; - for (var x in item) { - sb.add(sep); - sb.add(printList(x)); - sep = ','; - } - sb.add(']'); - return sb.toString(); - } - if (item == null) - return 'null'; - return item.toString(); -} diff --git a/client/dom/scripts/idlrenderer.dart b/client/dom/scripts/idlrenderer.dart deleted file mode 100644 index 4b81f0e7db8..00000000000 --- a/client/dom/scripts/idlrenderer.dart +++ /dev/null @@ -1,181 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -List sorted(Iterable input, [compare, key]) { - comparator(compare, key) { - if (compare == null && key == null) - return (a, b) => a.compareTo(b); - if (compare == null) - return (a, b) => key(a).compareTo(key(b)); - if (key == null) - return compare; - return (a, b) => compare(key(a), key(b)); - } - List copy = new List.from(input); - copy.sort(comparator(compare, key)); - return copy; -} - -render(idl_node, [indent_str=' ']) { - var output = ['']; - var indent_stack = []; - - //indented(action()) { - indented(action) { - indent_stack.add(indent_str); - action(); - indent_stack.removeLast(); - } - - sort(nodes) => sorted(nodes, key: (a) => a.id); - - var w; // For some reason mutually recursive local functions don't work. - - wln([node=null]) { - w(node); - output.add('\n'); - } - - w = (node, [list_separator]) { - /* - Writes the given node. - - Args: - node -- a string, IDLNode instance or a list of such. - list_separator -- if provided, and node is a list, - list_separator will be written between the list items. - */ - if (node == null) { - return; - } else if (node is String) { - if (output.last().endsWith('\n')) - output.addAll(indent_stack); - output.add(node); - } else if (node is List) { - var separator = null; - for (var element in node) { - w(separator); - separator = list_separator; - w(element); - } - } else if (node is IDLFile) { - w(node.modules); - w(node.interfaces); - } else if (node is IDLModule) { - w(node.annotations); - w(node.extAttrs); - wln('module ${node.id} {'); - indented(() { - w(node.interfaces); - w(node.typedefs); - }); - wln('};'); - } else if (node is IDLInterface) { - w(node.annotations); - w(node.extAttrs); - w('interface ${node.id}'); - indented(() { - if (!node.parents.isEmpty()) { - wln(' :'); - w(node.parents, ',\n'); - } - wln(' {'); - section(list, comment) { - if (list != null && !list.isEmpty()) { - wln(); - wln(comment); - w(sort(list)); - } - } - section(node.constants, '/* Constants */'); - section(node.attributes, '/* Attributes */'); - section(node.operations, '/* Operations */'); - section(node.snippets, '/* Snippets */'); - }); - wln('};'); - } else if (node is IDLParentInterface) { - w(node.annotations); - w(node.type.id); - } else if (node is IDLAnnotations) { - for (var name in sorted(node.map.getKeys())) { - IDLAnnotation annotation = node.map[name]; - var args = annotation.map; - if (args.isEmpty()) { - w('@$name'); - } else { - var formattedArgs = []; - for (var argName in sorted(args.getKeys())) { - var argValue = args[argName]; - if (argValue == null) - formattedArgs.add(argName); - else - formattedArgs.add('$argName=$argValue'); - } - w('@$name(${Strings.join(formattedArgs,',')})'); - } - w(' '); - } - } else if (node is IDLExtAttrs) { - if(!node.map.isEmpty()) { - w('['); - var sep = null; - for (var name in sorted(node.map.getKeys())) { - w(sep); - sep = ', '; - w(name); - var value = node.map[name]; - if (value != null) { - w('='); - w(value); - } - } - w('] '); - } - } else if (node is IDLAttribute) { - w(node.annotations); - w(node.extAttrs); - if (node.isFcGetter) - w('getter '); - if (node.isFcSetter) - w('setter '); - wln('attribute ${node.type.id} ${node.id};'); - } else if (node is IDLConstant) { - w(node.annotations); - w(node.extAttrs); - wln('const ${node.type.id} ${node.id} = ${node.value};'); - } else if (node is IDLSnippet) { - w(node.annotations); - wln('snippet {${node.text}};'); - } else if (node is IDLOperation) { - w(node.annotations); - w(node.extAttrs); - if (node.specials != null && !node.specials.isEmpty()) { - w(node.specials, ' '); - w(' '); - } - w('${node.type.id} ${node.id}'); - w('('); - w(node.arguments, ', '); - wln(');'); - } else if (node is IDLArgument) { - w(node.extAttrs); - w('in '); - if (node.isOptional) - w('optional '); - w('${node.type.id} ${node.id}'); - } else if (node is IDLExtAttrFunctionValue) { - w(node.name); - w('('); - w(node.arguments, ', '); - w(')'); - } else if (node is IDLTypeDef) { - wln('typedef ${node.type.id} ${node.id};'); - } else { - w('// $node\n'); - } - }; - - w(idl_node); - return Strings.concatAll(output); -} diff --git a/utils/peg/pegparser.dart b/utils/peg/pegparser.dart deleted file mode 100644 index da98b4a050a..00000000000 --- a/utils/peg/pegparser.dart +++ /dev/null @@ -1,858 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -#library('Peg Parser'); - -/* - * The following functions are combinators for building Rules. - * - * A rule is one of the following - * - A String which matches the string literally. - * - A Symbol which matches the symbol's definition. - * - A list of rules with an optional reducing function, which matches a sequence. - * - The result of calling one of the combinators. - * - * Some rules are 'value-generating' rules, they return an 'abstract syntax - * tree' with the match. If a rule is not value-generating [:null:] is the - * value. - * - * A Symbol is always a value-generating rule. If the value is not required, use - * [:SKIP(aSymbol):] in place of [:aSymbol:]. - * - * A String is not a value-generating rule but can be converted into one by - * using [:TEXT('string'):] in place of [:'string':]. - * - * A list or sequence is value-generating depending on the subrules. The - * sequence is value-generating if any of the subrules are value-generating or - * if there is a reducing function. If no reducing function is given, the value - * returned depends on the number of value-generating subrules. If there is - * only one value generating subrule, that provideds the value for the sequence. - * If there are more, then the value is a list of the values of the - * value-generating subrules. - */ - -/** - * Matches one character by a predicate on the character code. - * If [spec] is an int, that character is matched. - * If [spec] is a function it is used - * - * Example [: CHARCODE((code) => 48 <= code && code <= 57) :] recognizes an - * ASCII digit. - * - * CHARCODE does not generate a value. - */ -_Rule CHARCODE(spec, [name]) { - if (spec is int) - return new _CharCodeRule((code) => code == spec, name); - else - return new _CharCodeRule(spec, name); -} - -/** - * Matches one of the [characters]. - * - * CHAR does not generate a value. - */ -_Rule CHAR([characters]) { - if (characters == null) - return const _AnyCharRule(); - if (characters is int) - return CHARCODE(characters); - - // Find the range of character codes and construct an array of flags for codes - // within the range. - List codes = characters.charCodes(); - codes.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); - int lo = codes[0]; - int hi = codes[codes.length - 1]; - if (lo == hi) - return CHARCODE(lo); - int len = hi - lo + 1; - var flags = new List(len); - for (int i = 0; i < len; ++i) - flags[i] = false; - for (int code in codes) - flags[code - lo] = true; - - return CHARCODE((code) => code >= lo && code <= hi && flags[code - lo]); -} - -/** - * Matches the end of the input. - * - * END does not generate a value. - */ -_Rule get END() => new _EndOfInputRule(); - -/** - * Throws an exception. - */ -_Rule ERROR(String message) => new _ErrorRule(message); - -/** - * Matches [rule] but does not consume the input. Useful for matching a right - * context. - * - * AT does not generate a value. - */ -_Rule AT(rule) => new _ContextRule(_compile(rule)); - -/** - * Matches when [rule] does not match. No input is consumed. - * - * NOT does not generate a value. - */ -_Rule NOT(rule) => new _NegativeContextRule(_compile(rule)); - -/** - * Matches [rule] but generates no value even if [rule] generates a value. - * - * SKIP never generates a value. - */ -_Rule SKIP(rule) => new _SkipRule(_compile(rule)); - -/** - * Matches [rule] in a lexical context where whitespace is not automatically - * skipped. Useful for matching what would normally be considered to be tokens. - * [name] is a user-friendly description of what is being matched and is used in - * error messages. - * - * LEX(rule) - * LEX(name, rule) - * - * LEX does not generate a value. If a value is required, wrap LEX with TEXT. - */ -_Rule LEX(arg1, [arg2]) { - if (arg2 == null) - return new _LexicalRule(arg1 is String ? arg1 : null, _compile(arg1)); - else - return new _LexicalRule(arg1, _compile(arg2)); -} - -/** - * Matches [rule] and generates a value from the matched text. If the [rule] - * matches, then TEXT(rule) matches and has a value derived from the string - * fragment that was matched. The default derived value is the string fragment. - * - * TEXT always generates a value. - */ -_Rule TEXT(rule, [extractor]) => - new _TextValueRule(_compile(rule), - extractor == null - ? (string, start, end) => string.substring(start, end) - : extractor); - -/** - * Matches an optional rule. - * - * MAYBE is a value generating matcher. - * - * If [rule] is value generating then the value is the value generated by [rule] - * if it matches, and [:null:] if it does not. - * - * If [rule] is not value generatinge then the value is [:true:] if [rule] - * matches and [:false:] if it does not. - */ -_Rule MAYBE(rule) => new _OptionalRule(_compile(rule)); - -/** - * MANY(rule) matches [rule] [min] or more times. - * [min] must be 0 or 1. - * If [separator] is provided it is used to match a separator between matches of - * [rule]. - * - * MANY is a value generating matcher. The value is a list of the matches of - * [rule]. The list may be empty if [:min == 0:]. - */ -_Rule MANY(rule, [separator = null, int min = 1]) { - assert(0 <= min && min <= 1); - return new _RepeatRule(_compile(rule), _compileOptional(separator), min); -} - -/** - * Matches [rule] zero or more times. Shorthand for [:MANY(rule, min:0):] - * TODO: retire min: parameter? - * - * MANY0 is a value generating matcher. - */ -_Rule MANY0(rule, [separator = null]) { - return new _RepeatRule(_compile(rule), _compileOptional(separator), 0); -} - -/** - * Matches [rules] in order until one succeeds. - * - * OR is value-generating. - */ -_Rule OR([a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z]) => - _compileMultiRule( - (a is List && b == null) // Backward compat. OR([a, b]) => OR(a, b). - ? a - : _unspread(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z), - false, - (compiledRules, valueCount, reducer) => - new _ChoiceRule(compiledRules)); - - - -_Rule SEQ([a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z]) => - _compile(_unspread(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z)); - -/** - * Matches [rule] - */ -_Rule MEMO(rule) => new _MemoRule(_compile(rule)); - -_Rule TAG(tag, rule) => _compile([rule, (ast) => [tag, ast]]); - - -class ParseError implements Exception { - const ParseError(String this._message); - String toString() => _message; - final String _message; -} - -/** - * A grammar is a collection of symbols and rules that may be used to parse an - * input. - */ -class Grammar { - Map _symbols; - - /** This rule may be set by the user to define whitespace. */ - _Rule _whitespace; - - _Rule get whitespace() => _whitespace; - void set whitespace(rule) { _whitespace = _compile(rule); } - - Grammar() { - _symbols = new Map(); - whitespace = CHAR(' \t\r\n'); - } - - /** - * operator [] is used to find or create symbols. Symbols may appear in rules - * to define recursive rules. - */ - Symbol operator [](String name) { - if (_symbols.containsKey(name)) - return _symbols[name]; - Symbol s = new Symbol(name, this); - _symbols[name] = s; - return s; - } - - /** - * Parses the input string and returns the parsed AST, or throws an exception - * if the input can't be parsed. - */ - parse(root, String text) { - for (var symbol in _symbols.getValues()) - if (symbol._rule == null) - print('${symbol.name} is undefined'); - - var state = new _ParserState(text, whitespace: whitespace); - var match = _compile(root).match(state, 0); - if (match == null) - return diagnose(state); - var pos = match[0]; - pos = _skip_whitespace(state, pos); - if (pos == state._end) - return match[1]; - // TODO: Make this complain about expecting end of file. - return diagnose(state); - } - - diagnose(state) { - var message = 'unexpected error'; - if (!state.max_rule.isEmpty()) { - var s = new Set(); - for (var rule in state.max_rule) - s.add(rule.description()); - var tokens = new List.from(s); - tokens.sort((a, b) => - a.startsWith("'") == b.startsWith("'") - ? a.compareTo(b) - : a.startsWith("'") ? +1 : -1); - var expected = Strings.join(tokens, ' or '); - var found = state.max_pos == state._end ? 'end of file' - : "'${state._text[state.max_pos]}'"; - message = 'Expected $expected but found $found'; - } - int start = state.max_pos; - int end = start; - while (start >= 1 && state._text[start - 1] != '\n') --start; - while (end < state._text.length && state._text[end] != '\n') ++end; - var line = state._text.substring(start, end); - var indicator = ''; - for (var i = 0; i < line.length && start + i < state.max_pos; i++) - indicator = indicator + ' '; - indicator = indicator + '^'; - // TODO: Convert to an exception. - print(message); - print(line); - print(indicator); - return null; - } -} - -class Symbol { - final String name; - final Grammar grammar; - _Rule _rule; - - Symbol(this.name, this.grammar); - - void set def(rule) { - assert(_rule == null); // Assign once. - _rule = _compile(rule); - } - - toString() => _rule == null ? '<$name>' : '<$name = $_rule>'; -} - - -class _ParserState { - _ParserState(this._text, [_Rule whitespace = null]) { - _end = this._text.length; - whitespaceRule = whitespace; - max_rule = []; - } - - String _text; - int _end; - - // - bool inWhitespaceMode = false; - _Rule whitespaceRule = null; - - // Used for constructing an error message. - int inhibitExpectedTrackingDepth = 0; - int max_pos = 0; - var max_rule; -} - -/** - * An interface tag for rules. If this tag is on a rule, then the description() - * of the rule is something sensible to put in a message. - */ -interface _Expectable { - String description(); -} - -class _Rule { - const _Rule(); - // Returns null for a match failure or [pos, ast] for success. - match(_ParserState state, int pos) { - if (! state.inWhitespaceMode) { - pos = _skip_whitespace(state, pos); - } - return matchAfterWS(state, pos); - } - - // Faster entry point for matching a sub-rule that is matched to the start - // position of the super-rule. Whitespace has already been skipped so no need - // to try to skip it again. - matchAfterWS(_ParserState state, int pos) { - if (state.inhibitExpectedTrackingDepth == 0) { - // Track position for possible error messaging - if (pos > state.max_pos) { - // Store position and the rule. - state.max_pos = pos; - if (this is _Expectable) { - state.max_rule = [this]; - } else { - state.max_rule = []; - } - } else if (pos == state.max_pos) { - if (this is _Expectable) { - state.max_rule.add(this); - } - } - } - // Delegate the matching logic to the the specialized function. - return _match(state, pos); - } - - // Overridden in subclasses to match the rule. - _match(_ParserState state, int pos) => null; - - // Does the rule generate a value (AST) with the match? - bool get generatesValue() => false; - - get defaultValue() => null; -} - -int _skip_whitespace(state, pos) { - // Returns the next non-whitespace position. - // This is done by matching the optional whitespaceRule with the current text. - if (state.whitespaceRule == null) - return pos; - state.inWhitespaceMode = true; - state.inhibitExpectedTrackingDepth++; - while (true) { - var match = state.whitespaceRule.match(state, pos); - if (match == null) - break; - pos = match[0]; - } - state.inWhitespaceMode = false; - state.inhibitExpectedTrackingDepth--; - return pos; -} - - -_Rule _compileOptional(rule) { - return rule == null ? null : _compile(rule); -} - -_Rule _compile(rule) { - if (rule is _Rule) - return rule; - if (rule is String) - return new _StringRule(rule); - if (rule is Symbol) - return new _SymbolRule(rule); - if (rule is RegExp) - return new _RegExpRule(rule); - if (rule is List) { - return _compileMultiRule( - rule, true, - (compiledRules, valueCount, reducer) => - new _SequenceRule(compiledRules, valueCount, reducer)); - } - throw new Exception('Cannot compile rule: $rule'); -} - -class _EndOfInputRule extends _Rule { - _match(_ParserState state, int pos) { - if (pos == state._end) - return [pos, null]; - return null; - } - - toString() => 'END'; -} - -class _ErrorRule extends _Rule { - String message; - _ErrorRule(String this.message); - _match(_ParserState state, int pos) { - throw new ParseError(message); - } - - toString() => 'ERROR($message)'; -} - -class _CharCodeRule extends _Rule { - Function _predicate; - var _name; - _CharCodeRule(this._predicate, this._name); - _match(_ParserState state, int pos) { - if (pos == state._end) - return null; - int code = state._text.charCodeAt(pos); - if (_predicate(code)) - return [pos + 1, null]; - return null; - } - - toString() => _name == null ? 'CHARCODE($_predicate)' : 'CHARCODE($_name)'; -} - -class _AnyCharRule extends _Rule { - const _AnyCharRule(); - _match(_ParserState state, int pos) { - if (pos == state._end) - return null; - return [pos + 1, null]; - } - - toString() => 'CHAR()'; -} - -class _SymbolRule extends _Rule { - final Symbol _symbol; - _SymbolRule(Symbol this._symbol); - _match(_ParserState state, int pos) { - if (_symbol._rule == null) - throw new Exception("Symbol '${_symbol.name}' is undefined"); - return _symbol._rule.match(state, pos); - } - - bool get generatesValue() => true; - - toString() => '<${_symbol.name}>'; -} - -class _SkipRule extends _Rule { - // A rule that has no value. - _Rule _rule; - _SkipRule(_Rule this._rule); - _match(_ParserState state, int pos) { - var match = _rule.matchAfterWS(state, pos); - if (match == null) - return null; - return [match[0], null]; - } - - toString() => 'TOKEN($_rule)'; -} - -class _StringRule extends _Rule implements _Expectable { - final String _string; - int _len; - _StringRule(this._string) { - _len = _string.length; - } - - _match(_ParserState state, int pos) { - if (pos + _len > state._end) - return null; - for (int i = 0; i < _len; i++) { - if (state._text.charCodeAt(pos + i) != _string.charCodeAt(i)) - return null; - } - return [pos + _len, null]; - } - - //get defaultValue() => _string; - - toString() => '"$_string"'; - - description() => "'$_string'"; -} - -class _RegExpRule extends _Rule { - RegExp _re; - _RegExpRule(this._re) { - // There is no convenient way to match an anchored substring. - throw new Exception('RegExp matching not supported'); - } - - toString() => '"$_re"'; -} - -class _LexicalRule extends _Rule implements _Expectable { - final String _name; - final _Rule _rule; - - _LexicalRule(String this._name, _Rule this._rule); - - _match(_ParserState state, int pos) { - state.inWhitespaceMode = true; - state.inhibitExpectedTrackingDepth++; - var match = _rule.matchAfterWS(state, pos); - state.inhibitExpectedTrackingDepth--; - state.inWhitespaceMode = false; - return match; - } - - toString() => _name; - - description() => _name == null ? '?' : _name; -} - -class _TextValueRule extends _Rule { - final _Rule _rule; - final _extract; // Function - - _TextValueRule(_Rule this._rule, Function this._extract); - - _match(_ParserState state, int pos) { - var match = _rule.matchAfterWS(state, pos); - if (match == null) { - return null; - } - var endPos = match[0]; - return [endPos, _extract(state._text, pos, endPos)]; - } - - bool get generatesValue() => true; - - toString() => 'TEXT($_rule)'; -} - -_Rule _compileMultiRule(List rules, - bool allowReducer, - finish(compiledRules, valueCount, reducer)) { - int valueCount = 0; - List compiledRules = new List<_Rule>(); - Function reducer; - for (var rule in rules) { - if (reducer != null) - throw new Exception('Reducer must be last in sequence: $rule'); - if (rule is Function) { - if (allowReducer) - reducer = rule; - else - throw new Exception('Bad rule: "$rule"'); - } else { - _Rule compiledRule = _compile(rule); - if (compiledRule.generatesValue) - ++valueCount; - compiledRules.add(compiledRule); - } - } - return finish(compiledRules, valueCount, reducer); -} - -String _formatMultiRule(String functor, List rules) { - var sb = new StringBuffer(functor); - sb.add('('); - var separator = ''; - for (var rule in rules) { - sb.add(separator); - sb.add(rule); - separator = ','; - } - sb.add(')'); - return sb.toString(); -} - -class _SequenceRule extends _Rule { - // This rule matches the component rules in order. - final List<_Rule> _rules; - final int _generatingSubRules = 0; - final Function _reducer; - bool _generatesValue; - _SequenceRule(List<_Rule> this._rules, - int this._generatingSubRules, - Function this._reducer) { - _generatesValue = _generatingSubRules > 0 || _reducer != null; - } - - _match(state, pos) { - var sequence = []; - for (var rule in _rules) { - var match = rule.match(state, pos); - if (match == null) - return null; - if (rule.generatesValue) { - var ast = match[1]; - sequence.add(ast); - } - pos = match[0]; - } - if (_reducer == null) { - if (_generatingSubRules == 0) - return [pos, null]; - if (_generatingSubRules == 1) - return [pos, sequence[0]]; - return [pos, sequence]; - } else { - return [pos, _apply(_reducer, sequence)]; - } - } - - bool get generatesValue() => _generatesValue; - - toString() => _formatMultiRule('SEQ', _rules); -} - -class _ChoiceRule extends _Rule { - // This rule matches the first component rule that matches. - List<_Rule> _rules; - _ChoiceRule(List<_Rule> this._rules); - - _match(state, pos) { - for (var rule in _rules) { - var match = rule.match(state, pos); - if (match != null) { - /* - if (!rule.generatesValue) { - var value = rule.defaultValue; - if (value != null) - return [match[0], value]; - } - */ - return match; - } - } - return null; - } - - bool get generatesValue() => true; - - toString() => _formatMultiRule('OR', _rules); -} - -class _OptionalRule extends _Rule { - _Rule _rule; - _OptionalRule(_Rule this._rule); - _match(_ParserState state, int pos) { - var match = _rule.match(state, pos); - if (_rule.generatesValue) - return match == null - ? [pos, null] - : match; - return match == null - ? [pos, false] - : [match[0], true]; - } - - bool get generatesValue() => true; - - toString() => 'MAYBE($_rule)'; -} - -class _ContextRule extends _Rule { - _Rule _rule; - _ContextRule(_Rule this._rule); - _match(_ParserState state, int pos) { - // TODO: protect error state. - var match = _rule._match(state, pos); - if (match == null) - return null; - return [pos, null]; - } - - toString() => 'AT($_rule)'; -} - -class _NegativeContextRule extends _Rule { - _Rule _rule; - _NegativeContextRule(_Rule this._rule); - _match(_ParserState state, int pos) { - // TODO: protect error state. - var match = _rule._match(state, pos); - if (match == null) - return [pos, null]; - return null; - } - - toString() => 'NOT($_rule)'; -} - -class _RepeatRule extends _Rule { - // Matches zero, one or more items. - _Rule _rule; - _Rule _separator; - int _min; - - _RepeatRule(this._rule, this._separator, this._min); - - _match(state, pos) { - // First match. - var match = _rule.match(state, pos); - if (match == null) - if (_min == 0) - return [pos, []]; - else - return null; - pos = match[0]; - var result = [match[1]]; - - // Subsequent matches: - while (true) { - var newPos = pos; - if (_separator != null) { - match = _separator.match(state, pos); - if (match == null) - return [pos, result]; - newPos = match[0]; - } - match = _rule.match(state, newPos); - if (match == null) - return [pos, result]; - pos = match[0]; - result.add(match[1]); - } - } - - bool get generatesValue() => true; - - toString() => 'MANY(min:$_min, $_rule${_separator==null?'':", sep: $_separator"})'; -} - -class _MemoRule extends _Rule { - final _Rule _rule; - - var parseInstance; - - // A map from position to result. Can this be replaced with something - // smaller? - // TODO: figure out how to discard the map and parseInstance after parsing. - Map map; - - _MemoRule(this._rule); - - _match(state, pos) { - // See if we are still parsing the same input. Relies on the fact that the - // input is a string and strings are immutable. - if (parseInstance !== state._text) { - map = new Map(); - parseInstance = state._text; - } - // TODO: does this have to check or preserve parse state (like - // inWhitespaceMode, error position info etc?) - // Stored result can be null (memoized failure). - if (map.containsKey(pos)) { - return map[pos]; - } - var match = _rule.match(state, pos); - map[pos] = match; - return match; - } - - bool get generatesValue() => _rule.generatesValue; - - toString() => 'MEMO($_rule)'; -} - -_apply(fn, List args) { - switch (args.length) { - case 0: return fn(); - case 1: return fn(args[0]); - case 2: return fn(args[0], args[1]); - case 3: return fn(args[0], args[1], args[2]); - case 4: return fn(args[0], args[1], args[2], args[3]); - case 5: return fn(args[0], args[1], args[2], args[3], args[4]); - case 6: return fn(args[0], args[1], args[2], args[3], args[4], - args[5]); - case 7: return fn(args[0], args[1], args[2], args[3], args[4], - args[5], args[6]); - case 8: return fn(args[0], args[1], args[2], args[3], args[4], - args[5], args[6], args[7]); - case 9: return fn(args[0], args[1], args[2], args[3], args[4], - args[5], args[6], args[7], args[8]); - case 10: return fn(args[0], args[1], args[2], args[3], args[4], - args[5], args[6], args[7], args[8], args[9]); - - default: - throw new Exception('Too many arguments in _apply: $args'); - } -} - -List _unspread(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z) { - List list = new List(); - add(element) { if (element != null) list.add(element); } - add(a); - add(b); - add(c); - add(d); - add(e); - add(f); - add(g); - add(h); - add(i); - add(j); - add(k); - add(l); - add(m); - add(n); - add(o); - add(p); - add(q); - add(r); - add(s); - add(t); - add(u); - add(v); - add(w); - add(x); - add(y); - add(z); - return list; -} diff --git a/utils/peg/pegparser_test.dart b/utils/peg/pegparser_test.dart deleted file mode 100644 index 98cd3dc2605..00000000000 --- a/utils/peg/pegparser_test.dart +++ /dev/null @@ -1,346 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -#import('pegparser.dart'); - -testParens() { - Grammar g = new Grammar(); - Symbol a = g['A']; - - a.def = ['(', MANY(a, min:0), ')', (a) => a]; - - check(g, a, "", null); - check(g, a, "()", '[]'); - check(g, a, "(()())", '[[],[]]'); - check(g, a, "(()((()))())", '[[],[[[]]],[]]'); -} - -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), - '*/']; - print(blockComment); - - var a = MANY(TEXT('x')); - - g.whitespace = OR([g.whitespace, blockComment]); - - check(g, a, "x /**/ x", '[x,x]'); - check(g, a, "x /*/**/*/ x", '[x,x]'); - check(g, a, "x /*/***/ x", 'EOF in block comment'); - check(g, a, "x /*/*/x**/**/ x", '[x,x]'); - - check(g, a, @""" -/* Comment */ -/* Following comment with /* nested comment*/ */ -x -/* x in comment */ -x /* outside comment */ -""", - '[x,x]'); -} - -testTEXT() { - Grammar g = new Grammar(); - - // TEXT grabs the parsed text, - 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'); - - // Custom processing of the TEXT substring. - var binaryNumber = - TEXT(LEX(MANY(OR(['0','1']))), - (str, start, end) { - var r = 0; - var zero = '0'.charCodeAt(0); - for (int i = start; i < end; i++) - r = r * 2 + (str.charCodeAt(i) - zero); - return r; - }); - - check(g, binaryNumber, ' 10101 ', 21); - check(g, binaryNumber, '1010111', 87); - check(g, binaryNumber, '1010 111', null); -} - -testOR() { - // OR matches the first match. - Grammar g = new Grammar(); - check(g, OR([['a', NOT(END), () => 1], - ['a', () => 2], - ['a', () => 3]]), - 'a', 2); -} - -testCODE() { - Grammar g = new Grammar(); - var a = TEXT(LEX('thing', MANY(CHAR('bcd')))); - - 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. -} - -testC() { - // Curried tree builders. - binary(operation) => (second) => (first) => [operation, first, second]; - unary(operation) => () => (first) => [operation, first]; - reform(a, fns) { - var r = a; - for (var fn in fns) - r = fn(r); - return r; - } - - Grammar g = new Grammar(); - - Symbol expression = g['expression']; - Symbol postfix_e = g['postfix_e']; - Symbol unary_e = g['unary_e']; - Symbol cast_e = g['cast_e']; - Symbol mult_e = g['mult_e']; - Symbol add_e = g['add_e']; - Symbol shift_e = g['shift_e']; - Symbol relational_e = g['relational_e']; - Symbol equality_e = g['equality_e']; - Symbol cond_e = g['cond_e']; - Symbol assignment_e = g['assignment_e']; - - // Lexical elements. - var idStartChar = CHAR( - @"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); - var idNextChar = CHAR( - @"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, ',', 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.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 '&', '&' - 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]; - - //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]]]; - - 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]; - - 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)(x,2)', '[apply,[apply,a,[1]],[x,2]]'); - check(g, expression, 'a(1,2())', '[apply,a,[1,[apply,2,[]]]]'); - - check(g, expression, '++a++', '[preinc,[postinc,a]]'); - check(g, expression, 'a++++b', null); - check(g, expression, 'a++ ++b', null); - check(g, expression, 'a+ +++b', '[add,a,[preinc,[uplus,b]]]'); - check(g, expression, 'a+ + ++b', '[add,a,[uplus,[preinc,b]]]'); - check(g, expression, 'a+ + + +b', '[add,a,[uplus,[uplus,[uplus,b]]]]'); - check(g, expression, 'a+ ++ +b', '[add,a,[preinc,[uplus,b]]]'); - check(g, expression, 'a++ + +b', '[add,[postinc,a],[uplus,b]]'); - check(g, expression, 'a+++ +b', '[add,[postinc,a],[uplus,b]]'); - - check(g, expression, '((T)f)(x)', '[apply,[cast,T,f],[x]]'); - check(g, expression, '(T)f(x)', '[cast,T,[apply,f,[x]]]'); - - check(g, expression, 'a++*++b', '[mult,[postinc,a],[preinc,b]]'); - - check(g, expression, 'a<<1>>++b', '[shl,[shr,a,1],[preinc,b]]'); - - 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', '[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, '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; - try { - ast = grammar.parse(rule, input); - } catch (var exception) { - if (exception is ParseError) - ast = exception; - else - throw; - } - print('${printList(ast)}'); -} - -void check(grammar, rule, input, expected) { - // If [expected] is String then the result is coerced to string. - // If [expected] is !String, the result is compared directly. - print('check: "$input"'); - var ast; - try { - ast = grammar.parse(rule, input); - } catch (var exception) { - ast = exception; - } - - var formatted = ast; - if (expected is String) - formatted = printList(ast); - - Expect.equals(expected, formatted, "parse: $input"); -} - -// Prints the list in [1,2,3] notation, including nested lists. -void printList(item) { - if (item is List) { - StringBuffer sb = new StringBuffer(); - sb.add('['); - var sep = ''; - for (var x in item) { - sb.add(sep); - sb.add(printList(x)); - sep = ','; - } - sb.add(']'); - return sb.toString(); - } - if (item == null) - return 'null'; - return item.toString(); -} - -main() { - testCODE(); - testParens(); - testOR(); - testTEXT(); - testBlockComment(); - testC(); -}