blob: d519349200ceb6cfa260f53b2834b73b6bad169c [file] [log] [blame]
# Copyright (C) 2013 Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Parser for Blink IDL.
The parser uses the PLY (Python Lex-Yacc) library to build a set of parsing
rules which understand the Blink dialect of Web IDL.
It derives from a standard Web IDL parser, overriding rules where Blink IDL
differs syntactically or semantically from the base parser, or where the base
parser diverges from the Web IDL standard.
Web IDL:
http://www.w3.org/TR/WebIDL/
Web IDL Grammar:
http://www.w3.org/TR/WebIDL/#idl-grammar
PLY:
http://www.dabeaz.com/ply/
Design doc:
http://www.chromium.org/developers/design-documents/idl-compiler#TOC-Front-end
"""
# Disable check for line length and Member as Function due to how grammar rules
# are defined with PLY
#
# pylint: disable=R0201
# pylint: disable=C0301
#
# Disable attribute validation, as lint can't import parent class to check
# pylint: disable=E1101
#
import os.path
import sys
# PLY is in Chromium src/third_party/ply
module_path, module_name = os.path.split(__file__)
third_party = os.path.join(module_path, os.pardir, os.pardir, os.pardir, os.pardir)
# Insert at front to override system libraries, and after path[0] == script dir
sys.path.insert(1, third_party)
from ply import yacc
# Base parser is in Chromium src/tools/idl_parser
tools_dir = os.path.join(module_path, os.pardir, os.pardir, os.pardir, os.pardir, os.pardir, 'tools')
sys.path.append(tools_dir)
from idl_parser.idl_parser import IDLParser # pylint: disable=import-error
from idl_parser.idl_parser import ParseFile as parse_file
from .blink_idl_lexer import BlinkIDLLexer
from . import blink_idl_lexer
class BlinkIDLParser(IDLParser):
def __init__(self,
# common parameters
debug=False,
# local parameters
rewrite_tables=False,
# idl_parser parameters
lexer=None, verbose=False, mute_error=False,
# yacc parameters
outputdir='', optimize=True, write_tables=False,
picklefile=None):
if debug:
# Turn off optimization and caching, and write out tables,
# to help debugging
optimize = False
outputdir = None
picklefile = None
write_tables = True
if outputdir:
picklefile = picklefile or os.path.join(outputdir, 'parsetab.pickle')
if rewrite_tables:
try:
os.unlink(picklefile)
except OSError:
pass
lexer = lexer or BlinkIDLLexer(debug=debug,
outputdir=outputdir,
optimize=optimize)
self.lexer = lexer
self.tokens = lexer.KnownTokens()
# Optimized mode substantially decreases startup time (by disabling
# error checking), and also allows use of Python's optimized mode.
# See: Using Python's Optimized Mode
# http://www.dabeaz.com/ply/ply.html#ply_nn38
#
# |picklefile| allows simpler importing than |tabmodule| (parsetab.py),
# as we don't need to modify sys.path; virtually identical speed.
# See: CHANGES, Version 3.2
# http://ply.googlecode.com/svn/trunk/CHANGES
self.yaccobj = yacc.yacc(module=self,
debug=debug,
optimize=optimize,
write_tables=write_tables,
picklefile=picklefile)
self.parse_debug = debug
self.verbose = verbose
self.mute_error = mute_error
self._parse_errors = 0
self._parse_warnings = 0
self._last_error_msg = None
self._last_error_lineno = 0
self._last_error_pos = 0
################################################################################
def main(argv):
# If file itself executed, cache lex/parse tables
try:
outputdir = argv[1]
except IndexError as err:
print('Usage: %s OUTPUT_DIR' % argv[0])
return 1
blink_idl_lexer.main(argv)
# Important: rewrite_tables=True causes the cache file to be deleted if it
# exists, thus making sure that PLY doesn't load it instead of regenerating
# the parse table.
parser = BlinkIDLParser(outputdir=outputdir, rewrite_tables=True)
if __name__ == '__main__':
sys.exit(main(sys.argv))