11e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#!/usr/bin/env python
21e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)# Copyright 2013 The Chromium Authors. All rights reserved.
31e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
41e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)# found in the LICENSE file.
51e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
61e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)"""Generates a syntax tree from a Mojo IDL file."""
71e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
81e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
91e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)import sys
101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)import os.path
111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)# Try to load the ply module, if not, then assume it is in the third_party
141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)# directory.
151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)try:
161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  # Disable lint check which fails to find the ply module.
171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  # pylint: disable=F0401
181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  from ply import lex
191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  from ply import yacc
201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)except ImportError:
211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  module_path, module_name = os.path.split(__file__)
221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  third_party = os.path.join(
231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      module_path, os.pardir, os.pardir, os.pardir, os.pardir, 'third_party')
241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  sys.path.append(third_party)
251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  # pylint: disable=F0401
261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  from ply import lex
271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  from ply import yacc
281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)def ListFromConcat(*items):
311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  """Generate list by concatenating inputs"""
321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  itemsout = []
331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  for item in items:
341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if item is None:
351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      continue
361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if type(item) is not type([]):
371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      itemsout.append(item)
381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    else:
391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      itemsout.extend(item)
401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return itemsout
421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class Lexer(object):
451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  # This field is required by lex to specify the complete list of valid tokens.
471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  tokens = (
481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    'NAME',
491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    'NUMBER',
501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    'ARRAY',
521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    'ORDINAL',
531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    'MSGPIPE',
55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    'MSGPIPEARRAY',
56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    'MODULE',
581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    'STRUCT',
591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    'INTERFACE',
60d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    'ENUM',
611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    'VOID',
621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    'LCURLY',
641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    'RCURLY',
651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    'LPAREN',
661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    'RPAREN',
671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    'LBRACKET',
681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    'RBRACKET',
691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    'COMMA',
701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    'SEMICOLON',
711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    'EQUALS',
721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  )
731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  t_LCURLY     = r'{'
751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  t_RCURLY     = r'}'
761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  t_LPAREN     = r'\('
771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  t_RPAREN     = r'\)'
781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  t_LBRACKET   = r'\['
791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  t_RBRACKET   = r'\]'
801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  t_COMMA      = r','
811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  t_SEMICOLON  = r';'
821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  t_EQUALS     = r'='
831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  t_NAME       = r'[a-zA-Z_][a-zA-Z0-9_]*'
841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  t_ARRAY      = r'[a-zA-Z_][a-zA-Z0-9_]*\[\]'
851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  t_NUMBER     = r'\d+'
861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  t_ORDINAL    = r'@[0-9]*'
871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  def t_MSGPIPE(self, t):
89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    r'handle<message_pipe>'
90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return t
91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  def t_MSGPIPEARRAY(self, t):
93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    r'handle<message_pipe>\[\]'
94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return t
95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def t_MODULE(self, t):
971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    r'module'
981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return t
991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def t_STRUCT(self, t):
1011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    r'struct'
1021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return t
1031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def t_INTERFACE(self, t):
1051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    r'interface'
1061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return t
1071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
108d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  def t_ENUM(self, t):
109d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    r'enum'
110d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    return t
111d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)
1121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def t_VOID(self, t):
1131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    r'void'
1141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return t
1151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  # Ignore C and C++ style comments
1171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def t_COMMENT(self, t):
1181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    r'(/\*(.|\n)*?\*/)|(//.*(\n[ \t]*//.*)*)'
1191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    pass
1201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  # Ignored characters
1221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  t_ignore = " \t"
1231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def t_newline(self, t):
1251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    r'\n+'
1261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    t.lexer.lineno += t.value.count("\n")
1271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def t_error(self, t):
1291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    print("Illegal character '%s'" % t.value[0])
1301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    t.lexer.skip(1)
1311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class Parser(object):
1341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def __init__(self, lexer):
1361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    self.tokens = lexer.tokens
1371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def p_module(self, p):
1391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    """module : MODULE NAME LCURLY definitions RCURLY"""
1401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    p[0] = ('MODULE', p[2], p[4])
1411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def p_definitions(self, p):
1431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    """definitions : definition definitions
1441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                   |"""
1451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if len(p) > 1:
1461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      p[0] = ListFromConcat(p[1], p[2])
1471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def p_definition(self, p):
1491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    """definition : struct
150d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)                  | interface
151d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)                  | enum"""
1521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    p[0] = p[1]
1531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def p_attribute_section(self, p):
1551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    """attribute_section : LBRACKET attributes RBRACKET
1561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                         | """
1571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if len(p) > 3:
1581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      p[0] = p[2]
1591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def p_attributes(self, p):
1611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    """attributes : attribute
1621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                  | attribute COMMA attributes
1631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                  | """
1641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if len(p) == 2:
1651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      p[0] = ListFromConcat(p[1])
1661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    elif len(p) > 3:
1671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      p[0] = ListFromConcat(p[1], p[3])
1681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def p_attribute(self, p):
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    """attribute : NAME EQUALS NUMBER
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 | NAME EQUALS NAME"""
1721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    p[0] = ('ATTRIBUTE', p[1], p[3])
1731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def p_struct(self, p):
1751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    """struct : attribute_section STRUCT NAME LCURLY fields RCURLY SEMICOLON"""
1761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    p[0] = ('STRUCT', p[3], p[1], p[5])
1771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def p_fields(self, p):
1791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    """fields : field fields
1801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)              |"""
1811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if len(p) > 1:
1821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      p[0] = ListFromConcat(p[1], p[2])
1831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def p_field(self, p):
1851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    """field : typename NAME ordinal SEMICOLON"""
1861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    p[0] = ('FIELD', p[1], p[2], p[3])
1871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def p_interface(self, p):
189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    """interface : attribute_section INTERFACE NAME LCURLY methods RCURLY SEMICOLON"""
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    p[0] = ('INTERFACE', p[3], p[1], p[5])
1911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def p_methods(self, p):
1931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    """methods : method methods
1941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)               | """
1951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if len(p) > 1:
1961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      p[0] = ListFromConcat(p[1], p[2])
1971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def p_method(self, p):
1991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    """method : VOID NAME LPAREN parameters RPAREN ordinal SEMICOLON"""
2001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    p[0] = ('METHOD', p[2], p[4], p[6])
2011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def p_parameters(self, p):
2031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    """parameters : parameter
2041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                  | parameter COMMA parameters
2051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                  | """
206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if len(p) == 1:
207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      p[0] = []
208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    elif len(p) == 2:
209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      p[0] = ListFromConcat(p[1])
2101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    elif len(p) > 3:
2111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      p[0] = ListFromConcat(p[1], p[3])
2121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def p_parameter(self, p):
2141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    """parameter : typename NAME ordinal"""
2151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    p[0] = ('PARAM', p[1], p[2], p[3])
2161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def p_typename(self, p):
2181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    """typename : NAME
219a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                | ARRAY
220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                | MSGPIPE
221a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                | MSGPIPEARRAY"""
2221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    p[0] = p[1]
2231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def p_ordinal(self, p):
2251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    """ordinal : ORDINAL
2261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)               | """
2271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if len(p) > 1:
2281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      p[0] = p[1]
2291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
230d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  def p_enum(self, p):
231d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    """enum : ENUM NAME LCURLY enum_fields RCURLY SEMICOLON"""
232d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    p[0] = ('ENUM', p[2], p[4])
233d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)
234d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  def p_enum_fields(self, p):
235d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    """enum_fields : enum_field
236d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)                   | enum_field COMMA enum_fields
237d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)                   |"""
238d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    if len(p) == 2:
239d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      p[0] = ListFromConcat(p[1])
240d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    elif len(p) > 3:
241d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      p[0] = ListFromConcat(p[1], p[3])
242d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)
243d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  def p_enum_field(self, p):
244d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    """enum_field : NAME
245d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)                  | NAME EQUALS NUMBER"""
246d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    if len(p) == 2:
247d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      p[0] = ('ENUM_FIELD', p[1], None)
248d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    else:
249d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      p[0] = ('ENUM_FIELD', p[1], p[3])
250d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)
2511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def p_error(self, e):
2521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    print('error: %s'%e)
2531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)def Parse(filename):
2561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  lexer = Lexer()
2571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  parser = Parser(lexer)
2581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  lex.lex(object=lexer)
2601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  yacc.yacc(module=parser, debug=0, write_tables=0)
2611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  tree = yacc.parse(open(filename).read())
2631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return tree
2641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)def Main():
2671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if len(sys.argv) < 2:
2681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    print("usage: %s filename" % (sys.argv[0]))
2691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    sys.exit(1)
2701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  tree = Parse(filename=sys.argv[1])
2711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  print(tree)
2721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)if __name__ == '__main__':
2751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  Main()
276