diff options
author | noelallen@google.com <noelallen@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-12 18:48:47 +0000 |
---|---|---|
committer | noelallen@google.com <noelallen@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-12 18:48:47 +0000 |
commit | ac7b49d82dee3e690968139b610553386f6f1f3c (patch) | |
tree | 3701977bff91385289785992d6f016aa2ed66ee9 /tools/idl_parser/idl_node.py | |
parent | 7a54a4316797f7afebeb013b20631f90bba9eecb (diff) | |
download | chromium_src-ac7b49d82dee3e690968139b610553386f6f1f3c.zip chromium_src-ac7b49d82dee3e690968139b610553386f6f1f3c.tar.gz chromium_src-ac7b49d82dee3e690968139b610553386f6f1f3c.tar.bz2 |
Add WebIDL and Pepper compliant lexer/parser tool.
This CL is the first step towards supporting automatic doc
generation. This lexer more closely follows the WebIDL
spec.
Please review idl_node, idl_parser, idl_node
idl_log.py is unchanged from the original
This is a complete re-write of the original lexer/parser, as well as simplifications to IDLNode.
All *.in and *.idl files are for test purposes only.
To test: python idl_lexer.py OR python idl_parser.py
NOTRY=true
R=sehr@chromium.org
BUG=224150
Review URL: https://codereview.chromium.org/13498002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@193973 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/idl_parser/idl_node.py')
-rwxr-xr-x | tools/idl_parser/idl_node.py | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/tools/idl_parser/idl_node.py b/tools/idl_parser/idl_node.py new file mode 100755 index 0000000..2e31d9a --- /dev/null +++ b/tools/idl_parser/idl_node.py @@ -0,0 +1,217 @@ +#!/usr/bin/env python +# Copyright (c) 2012 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import sys + +# +# IDL Node +# +# IDL Node defines the IDLAttribute and IDLNode objects which are constructed +# by the parser as it processes the various 'productions'. The IDLAttribute +# objects are assigned to the IDLNode's property dictionary instead of being +# applied as children of The IDLNodes, so they do not exist in the final tree. +# The AST of IDLNodes is the output from the parsing state and will be used +# as the source data by the various generators. +# + + +# +# CopyToList +# +# Takes an input item, list, or None, and returns a new list of that set. +def CopyToList(item): + # If the item is 'Empty' make it an empty list + if not item: + item = [] + + # If the item is not a list + if type(item) is not type([]): + item = [item] + + # Make a copy we can modify + return list(item) + + +# IDLSearch +# +# A temporary object used by the parsing process to hold an Extended Attribute +# which will be passed as a child to a standard IDLNode. +# +class IDLSearch(object): + def __init__(self): + self.depth = 0 + + def Enter(self, node): + pass + + def Exit(self, node): + pass + + +# IDLAttribute +# +# A temporary object used by the parsing process to hold an Extended Attribute +# which will be passed as a child to a standard IDLNode. +# +class IDLAttribute(object): + def __init__(self, name, value): + self._cls = 'Property' + self.name = name + self.value = value + + def __str__(self): + return '%s=%s' % (self.name, self.value) + + def GetClass(self): + return self._cls + +# +# IDLNode +# +# This class implements the AST tree, providing the associations between +# parents and children. It also contains a namepsace and propertynode to +# allow for look-ups. IDLNode is derived from IDLRelease, so it is +# version aware. +# +class IDLNode(object): + def __init__(self, cls, filename, lineno, pos, children=None): + self._cls = cls + self._properties = { + 'ERRORS' : [], + 'WARNINGS': [], + 'FILENAME': filename, + 'LINENO' : lineno, + 'POSSITION' : pos, + } + + self._children = [] + self._parent = None + self.AddChildren(children) + +# +# +# + # Return a string representation of this node + def __str__(self): + name = self.GetProperty('NAME','') + return '%s(%s)' % (self._cls, name) + + def GetLogLine(self, msg): + filename, lineno = self.GetFileAndLine() + return '%s(%d) : %s\n' % (filename, lineno, msg) + + # Log an error for this object + def Error(self, msg): + self.GetProperty('ERRORS').append(msg) + sys.stderr.write(self.GetLogLine('error: ' + msg)) + + # Log a warning for this object + def Warning(self, msg): + self.GetProperty('WARNINGS').append(msg) + sys.stdout.write(self.GetLogLine('warning:' + msg)) + + # Return file and line number for where node was defined + def GetFileAndLine(self): + return self.GetProperty('FILENAME'), self.GetProperty('LINENO') + + def GetClass(self): + return self._cls + + def GetName(self): + return self.GetProperty('NAME') + + def GetParent(self): + return self._parent + + def Traverse(self, search, filter_nodes): + if self._cls in filter_nodes: + return '' + + search.Enter(self) + search.depth += 1 + for child in self._children: + child.Traverse(search, filter_nodes) + search.depth -= 1 + search.Exit(self) + + + def Tree(self, filter_nodes=None, accept_props=None): + class DumpTreeSearch(IDLSearch): + def __init__(self, props): + IDLSearch.__init__(self) + self.out = [] + self.props = props + + def Enter(self, node): + tab = ''.rjust(self.depth * 2) + self.out.append(tab + str(node)) + if self.props: + for key, value in node.GetProperties().iteritems(): + proplist = [] + if key in self.props: + proplist.append(tab + ' %s: %s' % (key, str(value))) + if proplist: + self.out.append(tab + ' PROPERTIES') + self.out.extend(proplist) + + if filter_nodes == None: + filter_nodes = ['Comment', 'Copyright'] + + search = DumpTreeSearch(accept_props) + self.Traverse(search, filter_nodes) + return search.out + +# +# Search related functions +# + # Check if node is of a given type + def IsA(self, *typelist): + if self._cls in typelist: + return True + return False + + # Get a list of all children + def GetChildren(self): + return self._children + + def GetListOf(self, *keys): + out = [] + for child in self.GetChildren(): + if child.GetClass() in keys: + out.append(child) + return out + + def GetOneOf(self, *keys): + out = self.GetListOf(*keys) + if out: + return out[0] + return None + + def AddChildren(self, children): + children = CopyToList(children) + for child in children: + if not child: + continue + if type(child) == IDLAttribute: + self.SetProperty(child.name, child.value) + continue + if type(child) == IDLNode: + child._parent = self + self._children.append(child) + continue + raise RuntimeError('Adding child of type .\n' % type(child).__name__) + + +# +# Property Functions +# + def SetProperty(self, name, val): + self._properties[name] = val + + def GetProperty(self, name, default=None): + return self._properties.get(name, default) + + def GetProperties(self): + return self._properties |