| Index: client/dom/scripts/idlparser.py
|
| ===================================================================
|
| --- client/dom/scripts/idlparser.py (revision 5796)
|
| +++ client/dom/scripts/idlparser.py (working copy)
|
| @@ -1,442 +0,0 @@
|
| -#!/usr/bin/python
|
| -# 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 re
|
| -import subprocess
|
| -import tempfile
|
| -
|
| -from pegparser import *
|
| -
|
| -# IDL grammar variants.
|
| -WEBIDL_SYNTAX = 0
|
| -WEBKIT_SYNTAX = 1
|
| -FREMONTCUT_SYNTAX = 2
|
| -
|
| -
|
| -class IDLParser(object):
|
| - """IDLParser is a PEG based IDL files parser."""
|
| -
|
| - def __init__(self, syntax=WEBIDL_SYNTAX):
|
| - """Constructor.
|
| -
|
| - Initializes the IDLParser by defining the grammar and initializing
|
| - a PEGParserinstance.
|
| -
|
| - Args:
|
| - syntax -- supports either WEBIDL_SYNTAX (0) or WEBKIT_SYNTAX (1)
|
| - """
|
| - self._syntax = syntax
|
| - self._pegparser = PegParser(self._idl_grammar(),
|
| - self._whitespace_grammar(),
|
| - strings_are_tokens=True)
|
| -
|
| - def _idl_grammar(self):
|
| - """Returns the PEG grammar for IDL parsing."""
|
| -
|
| - # utilities:
|
| - def syntax_switch(w3c_syntax, webkit_syntax, fremontcut_syntax=None):
|
| - """Returns w3c_syntax or web_syntax, depending on the current
|
| - configuration.
|
| - """
|
| - if self._syntax == WEBIDL_SYNTAX:
|
| - return w3c_syntax
|
| - elif self._syntax == WEBKIT_SYNTAX:
|
| - return webkit_syntax
|
| - elif self._syntax == FREMONTCUT_SYNTAX:
|
| - if fremontcut_syntax is not None:
|
| - return fremontcut_syntax
|
| - return w3c_syntax
|
| - else:
|
| - raise RuntimeError('unsupported IDL syntax %s' % syntax)
|
| -
|
| - # The following grammar is based on the Web IDL's LL(1) grammar
|
| - # (specified in: http://dev.w3.org/2006/webapi/WebIDL/#idl-grammar).
|
| - # It is adjusted to PEG grammar, as well as to also support
|
| - # WebKit IDL and FremontCut grammar.
|
| -
|
| - ###################### BEGIN GRAMMAR #####################
|
| -
|
| - def Id():
|
| - return re.compile(r'[\w\_]+')
|
| -
|
| - def _Definitions():
|
| - return MAYBE(MANY(_Definition))
|
| -
|
| - def _Definition():
|
| - return syntax_switch(
|
| - # Web IDL:
|
| - OR(Module, Interface, ExceptionDef, TypeDef, ImplStmt,
|
| - ValueTypeDef, Const),
|
| - # WebKit:
|
| - OR(Module, Interface))
|
| -
|
| - def Module():
|
| - return syntax_switch(
|
| - # Web IDL:
|
| - [MAYBE(ExtAttrs), 'module', Id, '{', _Definitions, '}',
|
| - MAYBE(';')],
|
| - # WebKit:
|
| - ['module', MAYBE(ExtAttrs), Id, '{', _Definitions, '}',
|
| - MAYBE(';')],
|
| - # FremontCut:
|
| - [MAYBE(_Annotations), MAYBE(ExtAttrs), 'module', Id,
|
| - '{', _Definitions, '}', MAYBE(';')])
|
| -
|
| - def Interface():
|
| - return syntax_switch(
|
| - # Web IDL:
|
| - [MAYBE(ExtAttrs), 'interface', Id, MAYBE(_ParentInterfaces),
|
| - MAYBE(['{', MAYBE(MANY(_Member)), '}']), ';'],
|
| - # WebKit:
|
| - ['interface', MAYBE(ExtAttrs), Id, MAYBE(_ParentInterfaces),
|
| - MAYBE(['{', MAYBE(MANY(_Member)), '}']), MAYBE(';')],
|
| - # FremontCut:
|
| - [MAYBE(_Annotations), MAYBE(ExtAttrs), 'interface',
|
| - Id, MAYBE(_ParentInterfaces), MAYBE(['{', MAYBE(MANY(_Member)),
|
| - '}']), ';'])
|
| -
|
| - def _Member():
|
| - return syntax_switch(
|
| - # Web IDL:
|
| - OR(Const, Attribute, Operation, ExtAttrs),
|
| - # WebKit:
|
| - OR(Const, Attribute, Operation),
|
| - # FremontCut:
|
| - OR(Const, Attribute, Operation))
|
| -
|
| - # Interface inheritance:
|
| - def _ParentInterfaces():
|
| - return [':', MANY(ParentInterface, separator=',')]
|
| -
|
| - def ParentInterface():
|
| - return syntax_switch(
|
| - # Web IDL:
|
| - [InterfaceType],
|
| - # WebKit:
|
| - [InterfaceType],
|
| - # FremontCut:
|
| - [MAYBE(_Annotations), InterfaceType])
|
| -
|
| - # TypeDef (Web IDL):
|
| - def TypeDef():
|
| - return ['typedef', Type, Id, ';']
|
| -
|
| - # TypeDef (Old-school W3C IDLs)
|
| - def ValueTypeDef():
|
| - return ['valuetype', Id, Type, ';']
|
| -
|
| - # Implements Statement (Web IDL):
|
| - def ImplStmt():
|
| - return [ImplStmtImplementor, 'implements', ImplStmtImplemented,
|
| - ';']
|
| -
|
| - def ImplStmtImplementor():
|
| - return ScopedName
|
| -
|
| - def ImplStmtImplemented():
|
| - return ScopedName
|
| -
|
| - # Constants:
|
| - def Const():
|
| - return syntax_switch(
|
| - # Web IDL:
|
| - [MAYBE(ExtAttrs), 'const', Type, Id, '=', ConstExpr, ';'],
|
| - # WebKit:
|
| - [MAYBE(ExtAttrs), 'const', Type, Id, '=', ConstExpr, ';'],
|
| - # FremontCut:
|
| - [MAYBE(_Annotations), MAYBE(ExtAttrs), 'const', Type, Id, '=',
|
| - ConstExpr, ';'])
|
| -
|
| - def ConstExpr():
|
| - return OR(_BooleanLiteral,
|
| - _IntegerLiteral,
|
| - _FloatLiteral)
|
| -
|
| - def _BooleanLiteral():
|
| - return re.compile(r'true|false')
|
| -
|
| - def _IntegerLiteral():
|
| - return OR(re.compile(r'(0x)?[0-9ABCDEF]+'),
|
| - re.compile(r'[0-9]+'))
|
| -
|
| - def _FloatLiteral():
|
| - return re.compile(r'[0-9]+\.[0-9]*')
|
| -
|
| - # Attributes:
|
| - def Attribute():
|
| - return syntax_switch(
|
| - # Web IDL:
|
| - [MAYBE(ExtAttrs), MAYBE(Stringifier), MAYBE(ReadOnly),
|
| - 'attribute', Type, Id, MAYBE(_AttrRaises), ';'],
|
| - # WebKit:
|
| - [MAYBE(Stringifier), MAYBE(ReadOnly), 'attribute',
|
| - MAYBE(ExtAttrs), Type, Id, MAYBE(_AttrRaises), ';'],
|
| - # FremontCut:
|
| - [MAYBE(_Annotations), MAYBE(ExtAttrs),
|
| - MAYBE(_AttrGetterSetter), MAYBE(Stringifier), MAYBE(ReadOnly),
|
| - 'attribute', Type, Id, MAYBE(_AttrRaises), ';'])
|
| -
|
| - def _AttrRaises():
|
| - return syntax_switch(
|
| - # Web IDL:
|
| - MANY(OR(GetRaises, SetRaises)),
|
| - # WebKit:
|
| - MANY(OR(GetRaises, SetRaises, Raises), separator=','))
|
| -
|
| - # Special fremontcut feature:
|
| - def _AttrGetterSetter():
|
| - return OR(AttrGetter, AttrSetter)
|
| -
|
| - def AttrGetter():
|
| - return 'getter'
|
| -
|
| - def AttrSetter():
|
| - return 'setter'
|
| -
|
| - def ReadOnly():
|
| - return 'readonly'
|
| -
|
| - def GetRaises():
|
| - return syntax_switch(
|
| - # Web IDL:
|
| - ['getraises', '(', _ScopedNames, ')'],
|
| - # WebKit:
|
| - ['getter', 'raises', '(', _ScopedNames, ')'])
|
| -
|
| - def SetRaises():
|
| - return syntax_switch(
|
| - # Web IDL:
|
| - ['setraises', '(', _ScopedNames, ')'],
|
| - # WebKit:
|
| - ['setter', 'raises', '(', _ScopedNames, ')'])
|
| -
|
| - # Operation:
|
| - def Operation():
|
| - return syntax_switch(
|
| - # Web IDL:
|
| - [MAYBE(ExtAttrs), MAYBE(Static), MAYBE(Stringifier), MAYBE(_Specials),
|
| - ReturnType, MAYBE(Id), '(', _Arguments, ')', MAYBE(Raises),
|
| - ';'],
|
| - # WebKit:
|
| - [MAYBE(ExtAttrs), MAYBE(Static),
|
| - ReturnType, MAYBE(Id), '(', _Arguments, ')',
|
| - MAYBE(Raises), ';'],
|
| - # FremontCut:
|
| - [MAYBE(_Annotations), MAYBE(ExtAttrs), MAYBE(Static), MAYBE(Stringifier),
|
| - MAYBE(_Specials), ReturnType, MAYBE(Id), '(', _Arguments, ')',
|
| - MAYBE(Raises), ';'])
|
| -
|
| - def Static():
|
| - return 'static'
|
| -
|
| - def _Specials():
|
| - return MANY(Special)
|
| -
|
| - def Special():
|
| - return re.compile(r'getter|setter|creator|deleter|caller')
|
| -
|
| - def Stringifier():
|
| - return 'stringifier'
|
| -
|
| - def Raises():
|
| - return ['raises', '(', _ScopedNames, ')']
|
| -
|
| - # Operation arguments:
|
| - def _Arguments():
|
| - return MAYBE(MANY(Argument, ','))
|
| -
|
| - def Argument():
|
| - return syntax_switch(
|
| - # Web IDL:
|
| - [MAYBE(ExtAttrs), MAYBE(Optional), MAYBE('in'),
|
| - MAYBE(Optional), Type, MAYBE(AnEllipsis), Id],
|
| - # WebKit:
|
| - [MAYBE(Optional), MAYBE('in'), MAYBE(Optional),
|
| - MAYBE(ExtAttrs), Type, Id])
|
| -
|
| - def Optional():
|
| - return 'optional'
|
| -
|
| - def AnEllipsis():
|
| - return '...'
|
| -
|
| - # Exceptions (Web IDL).
|
| - def ExceptionDef():
|
| - return ['exception', Id, '{', MAYBE(MANY(_ExceptionMember)), '}',
|
| - ';']
|
| -
|
| - def _ExceptionMember():
|
| - return OR(Const, ExceptionField, ExtAttrs)
|
| -
|
| - def ExceptionField():
|
| - return [Type, Id, ';']
|
| -
|
| - # Types:
|
| - def Type():
|
| - return _Type
|
| -
|
| - def ReturnType():
|
| - return OR(VoidType, _Type)
|
| -
|
| - def InterfaceType():
|
| - return ScopedName
|
| -
|
| - def _Type():
|
| - return OR(AnyArrayType, AnyType, ObjectType, _NullableType)
|
| -
|
| - def _NullableType():
|
| - return [OR(_IntegerType, BooleanType, OctetType, FloatType,
|
| - DoubleType, SequenceType, DOMStringArrayType, ScopedName),
|
| - MAYBE(Nullable)]
|
| -
|
| - def Nullable():
|
| - return '?'
|
| -
|
| - def SequenceType():
|
| - return ['sequence', '<', Type, '>']
|
| -
|
| - def AnyType():
|
| - return 'any'
|
| -
|
| - def AnyArrayType():
|
| - # TODO(sra): Do more general handling of array types.
|
| - return 'any[]'
|
| -
|
| - def ObjectType():
|
| - return re.compile(r'(object|Object)\b') # both spellings.
|
| -
|
| - def VoidType():
|
| - return 'void'
|
| -
|
| - def _IntegerType():
|
| - return [MAYBE(Unsigned), OR(ByteType, IntType, LongLongType,
|
| - LongType, OctetType, ShortType)]
|
| -
|
| - def Unsigned():
|
| - return 'unsigned'
|
| -
|
| - def ShortType():
|
| - return 'short'
|
| -
|
| - def LongLongType():
|
| - return ['long', 'long']
|
| -
|
| - def LongType():
|
| - return 'long'
|
| -
|
| - def IntType():
|
| - return 'int'
|
| -
|
| - def ByteType():
|
| - return 'byte'
|
| -
|
| - def OctetType():
|
| - return 'octet'
|
| -
|
| - def BooleanType():
|
| - return 'boolean'
|
| -
|
| - def FloatType():
|
| - return 'float'
|
| -
|
| - def DoubleType():
|
| - return 'double'
|
| -
|
| - def _ScopedNames():
|
| - return MANY(ScopedName, separator=',')
|
| -
|
| - def ScopedName():
|
| - return re.compile(r'[\w\_\:\.\<\>]+')
|
| -
|
| - def DOMStringArrayType():
|
| - return 'DOMString[]'
|
| -
|
| - # Extended Attributes:
|
| - def ExtAttrs():
|
| - return ['[', MAYBE(MANY(ExtAttr, ',')), ']']
|
| -
|
| - def ExtAttr():
|
| - return [Id, MAYBE(OR(['=', ExtAttrValue], ExtAttrArgList))]
|
| -
|
| - def ExtAttrValue():
|
| - return OR(ExtAttrFunctionValue, re.compile(r'[\w&0-9:\-\|]+'))
|
| -
|
| - def ExtAttrFunctionValue():
|
| - return [Id, ExtAttrArgList]
|
| -
|
| - def ExtAttrArgList():
|
| - return ['(', MAYBE(MANY(Argument, ',')), ')']
|
| -
|
| - # Annotations - used in the FremontCut IDL grammar:
|
| - def _Annotations():
|
| - return MANY(Annotation)
|
| -
|
| - def Annotation():
|
| - return ['@', Id, MAYBE(_AnnotationBody)]
|
| -
|
| - def _AnnotationBody():
|
| - return ['(', MAYBE(MANY(AnnotationArg, ',')), ')']
|
| -
|
| - def AnnotationArg():
|
| - return [Id, MAYBE(['=', AnnotationArgValue])]
|
| -
|
| - def AnnotationArgValue():
|
| - return re.compile(r'[\w&0-9:/\-\.]+')
|
| -
|
| - ###################### END GRAMMAR #####################
|
| -
|
| - # Return the grammar's root rule:
|
| - return MANY(_Definition)
|
| -
|
| - def _whitespace_grammar(self):
|
| - return OR(re.compile(r'\s+'),
|
| - re.compile(r'//.*'),
|
| - re.compile(r'#.*'),
|
| - re.compile(r'/\*.*?\*/', re.S))
|
| -
|
| - def _pre_process(self, content, defines, includePaths):
|
| - """Pre-processes the content using gcc.
|
| -
|
| - WebKit IDLs require pre-processing by gcc. This is done by invoking
|
| - gcc in a sub-process and capturing the results.
|
| -
|
| - Returns:
|
| - The result of running gcc on the content.
|
| -
|
| - Args:
|
| - content -- text to process.
|
| - defines -- an array of pre-processor defines.
|
| - includePaths -- an array of path strings.
|
| - """
|
| - # FIXME: Handle gcc not found, or any other processing errors
|
| - gcc = 'gcc'
|
| - cmd = [gcc, '-E', '-P', '-C', '-x', 'c++'];
|
| - for define in defines:
|
| - cmd.append('-D%s' % define)
|
| - cmd.append('-')
|
| - pipe = subprocess.Popen(cmd, stdin=subprocess.PIPE,
|
| - stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
| - (content, stderr) = pipe.communicate(content)
|
| - return content
|
| -
|
| - def parse(self, content, defines=[], includePaths=[]):
|
| - """Parse the give content string.
|
| -
|
| - The WebKit IDL syntax also allows gcc pre-processing instructions.
|
| - Lists of defined variables and include paths can be provided.
|
| -
|
| - Returns:
|
| - An abstract syntax tree (AST).
|
| -
|
| - Args:
|
| - content -- text to parse.
|
| - defines -- an array of pre-processor defines.
|
| - includePaths -- an array of path strings used by the
|
| - gcc pre-processor.
|
| - """
|
| - if self._syntax == WEBKIT_SYNTAX:
|
| - content = self._pre_process(content, defines, includePaths)
|
| -
|
| - return self._pegparser.parse(content)
|
|
|