| Index: mojo/public/bindings/parse/mojo_parser.py
|
| diff --git a/mojo/public/bindings/parse/mojo_parser.py b/mojo/public/bindings/parse/mojo_parser.py
|
| index 3e8e991b51f447b9ae8972538881944ddfdbc310..9acaee48f223d46a32adbc8eb09c9a39399950ca 100755
|
| --- a/mojo/public/bindings/parse/mojo_parser.py
|
| +++ b/mojo/public/bindings/parse/mojo_parser.py
|
| @@ -9,7 +9,6 @@
|
| import sys
|
| import os.path
|
|
|
| -
|
| # Try to load the ply module, if not, then assume it is in the third_party
|
| # directory.
|
| try:
|
| @@ -26,6 +25,8 @@ except ImportError:
|
| from ply import lex
|
| from ply import yacc
|
|
|
| +from mojo_lexer import Lexer
|
| +
|
|
|
| def ListFromConcat(*items):
|
| """Generate list by concatenating inputs"""
|
| @@ -41,114 +42,13 @@ def ListFromConcat(*items):
|
| return itemsout
|
|
|
|
|
| -class Lexer(object):
|
| -
|
| - # This field is required by lex to specify the complete list of valid tokens.
|
| - tokens = (
|
| - 'NAME',
|
| - 'NUMBER',
|
| -
|
| - 'ORDINAL',
|
| -
|
| - 'HANDLE',
|
| - 'DATAPIPECONSUMER',
|
| - 'DATAPIPEPRODUCER',
|
| - 'MESSAGEPIPE',
|
| -
|
| - 'MODULE',
|
| - 'STRUCT',
|
| - 'INTERFACE',
|
| - 'ENUM',
|
| - 'VOID',
|
| -
|
| - 'LCURLY',
|
| - 'RCURLY',
|
| - 'LPAREN',
|
| - 'RPAREN',
|
| - 'LANGLE',
|
| - 'RANGLE',
|
| - 'LBRACKET',
|
| - 'RBRACKET',
|
| - 'COMMA',
|
| - 'SEMICOLON',
|
| - 'EQUALS',
|
| - )
|
| -
|
| - t_LCURLY = r'{'
|
| - t_RCURLY = r'}'
|
| - t_LPAREN = r'\('
|
| - t_RPAREN = r'\)'
|
| - t_LANGLE = r'<'
|
| - t_RANGLE = r'>'
|
| - t_LBRACKET = r'\['
|
| - t_RBRACKET = r'\]'
|
| - t_COMMA = r','
|
| - t_SEMICOLON = r';'
|
| - t_EQUALS = r'='
|
| - t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'
|
| - t_NUMBER = r'\d+'
|
| - t_ORDINAL = r'@[0-9]*'
|
| -
|
| - def t_HANDLE(self, t):
|
| - r'handle'
|
| - return t
|
| -
|
| - def t_DATAPIPECONSUMER(self, t):
|
| - r'data_pipe_consumer'
|
| - return t
|
| -
|
| - def t_DATAPIPEPRODUCER(self, t):
|
| - r'data_pipe_producer'
|
| - return t
|
| -
|
| - def t_MESSAGEPIPE(self, t):
|
| - r'message_pipe'
|
| - return t
|
| -
|
| - def t_MODULE(self, t):
|
| - r'module'
|
| - return t
|
| -
|
| - def t_STRUCT(self, t):
|
| - r'struct'
|
| - return t
|
| -
|
| - def t_INTERFACE(self, t):
|
| - r'interface'
|
| - return t
|
| -
|
| - def t_ENUM(self, t):
|
| - r'enum'
|
| - return t
|
| -
|
| - def t_VOID(self, t):
|
| - r'void'
|
| - return t
|
| -
|
| - # Ignore C and C++ style comments
|
| - def t_COMMENT(self, t):
|
| - r'(/\*(.|\n)*?\*/)|(//.*(\n[ \t]*//.*)*)'
|
| - pass
|
| -
|
| - # Ignored characters
|
| - t_ignore = " \t"
|
| -
|
| - def t_newline(self, t):
|
| - r'\n+'
|
| - t.lexer.lineno += t.value.count("\n")
|
| -
|
| - def t_error(self, t):
|
| - print("Illegal character '%s'" % t.value[0])
|
| - t.lexer.skip(1)
|
| -
|
| -
|
| class Parser(object):
|
|
|
| def __init__(self, lexer):
|
| self.tokens = lexer.tokens
|
|
|
| def p_module(self, p):
|
| - """module : MODULE NAME LCURLY definitions RCURLY"""
|
| + """module : MODULE NAME LBRACE definitions RBRACE"""
|
| p[0] = ('MODULE', p[2], p[4])
|
|
|
| def p_definitions(self, p):
|
| @@ -179,12 +79,12 @@ class Parser(object):
|
| p[0] = ListFromConcat(p[1], p[3])
|
|
|
| def p_attribute(self, p):
|
| - """attribute : NAME EQUALS NUMBER
|
| + """attribute : NAME EQUALS expression
|
| | NAME EQUALS NAME"""
|
| p[0] = ('ATTRIBUTE', p[1], p[3])
|
|
|
| def p_struct(self, p):
|
| - """struct : attribute_section STRUCT NAME LCURLY struct_body RCURLY SEMICOLON"""
|
| + """struct : attribute_section STRUCT NAME LBRACE struct_body RBRACE SEMI"""
|
| p[0] = ('STRUCT', p[3], p[1], p[5])
|
|
|
| def p_struct_body(self, p):
|
| @@ -195,11 +95,11 @@ class Parser(object):
|
| p[0] = ListFromConcat(p[1], p[2])
|
|
|
| def p_field(self, p):
|
| - """field : typename NAME ordinal SEMICOLON"""
|
| + """field : typename NAME ordinal SEMI"""
|
| p[0] = ('FIELD', p[1], p[2], p[3])
|
|
|
| def p_interface(self, p):
|
| - """interface : attribute_section INTERFACE NAME LCURLY interface_body RCURLY SEMICOLON"""
|
| + """interface : attribute_section INTERFACE NAME LBRACE interface_body RBRACE SEMI"""
|
| p[0] = ('INTERFACE', p[3], p[1], p[5])
|
|
|
| def p_interface_body(self, p):
|
| @@ -210,7 +110,7 @@ class Parser(object):
|
| p[0] = ListFromConcat(p[1], p[2])
|
|
|
| def p_method(self, p):
|
| - """method : VOID NAME LPAREN parameters RPAREN ordinal SEMICOLON"""
|
| + """method : VOID NAME LPAREN parameters RPAREN ordinal SEMI"""
|
| p[0] = ('METHOD', p[2], p[4], p[6])
|
|
|
| def p_parameters(self, p):
|
| @@ -240,13 +140,13 @@ class Parser(object):
|
| p[0] = p[1]
|
|
|
| def p_specializedhandle(self, p):
|
| - """specializedhandle : HANDLE LANGLE specializedhandlename RANGLE"""
|
| + """specializedhandle : HANDLE LT specializedhandlename GT"""
|
| p[0] = "handle<" + p[3] + ">"
|
|
|
| def p_specializedhandlename(self, p):
|
| - """specializedhandlename : DATAPIPECONSUMER
|
| - | DATAPIPEPRODUCER
|
| - | MESSAGEPIPE"""
|
| + """specializedhandlename : DATA_PIPE_CONSUMER
|
| + | DATA_PIPE_PRODUCER
|
| + | MESSAGE_PIPE"""
|
| p[0] = p[1]
|
|
|
| def p_array(self, p):
|
| @@ -260,7 +160,7 @@ class Parser(object):
|
| p[0] = p[1]
|
|
|
| def p_enum(self, p):
|
| - """enum : ENUM NAME LCURLY enum_fields RCURLY SEMICOLON"""
|
| + """enum : ENUM NAME LBRACE enum_fields RBRACE SEMI"""
|
| p[0] = ('ENUM', p[2], p[4])
|
|
|
| def p_enum_fields(self, p):
|
| @@ -274,12 +174,84 @@ class Parser(object):
|
|
|
| def p_enum_field(self, p):
|
| """enum_field : NAME
|
| - | NAME EQUALS NUMBER"""
|
| + | NAME EQUALS expression"""
|
| if len(p) == 2:
|
| p[0] = ('ENUM_FIELD', p[1], None)
|
| else:
|
| p[0] = ('ENUM_FIELD', p[1], p[3])
|
|
|
| + ### Expressions ###
|
| +
|
| + def p_expression(self, p):
|
| + """expression : conditional_expression"""
|
| + p[0] = p[1]
|
| +
|
| + def p_conditional_expression(self, p):
|
| + """conditional_expression : binary_expression
|
| + | binary_expression CONDOP expression COLON conditional_expression"""
|
| + # Just pass the arguments through. I don't think it's possible to preserve
|
| + # the spaces of the original, so just put a single space between them.
|
| + p[0] = ' '.join(p[1:])
|
| +
|
| + # PLY lets us specify precedence of operators, but since we don't actually
|
| + # evaluate them, we don't need that here.
|
| + def p_binary_expression(self, p):
|
| + """binary_expression : unary_expression
|
| + | binary_expression binary_operator binary_expression"""
|
| + p[0] = ' '.join(p[1:])
|
| +
|
| + def p_binary_operator(self, p):
|
| + """binary_operator : TIMES
|
| + | DIVIDE
|
| + | MOD
|
| + | PLUS
|
| + | MINUS
|
| + | RSHIFT
|
| + | LSHIFT
|
| + | LT
|
| + | LE
|
| + | GE
|
| + | GT
|
| + | EQ
|
| + | NE
|
| + | AND
|
| + | OR
|
| + | XOR
|
| + | LAND
|
| + | LOR"""
|
| + p[0] = p[1]
|
| +
|
| + def p_unary_expression(self, p):
|
| + """unary_expression : primary_expression
|
| + | unary_operator expression"""
|
| + p[0] = ''.join(p[1:])
|
| +
|
| + def p_unary_operator(self, p):
|
| + """unary_operator : TIMES
|
| + | PLUS
|
| + | MINUS
|
| + | NOT
|
| + | LNOT"""
|
| + p[0] = p[1]
|
| +
|
| + def p_primary_expression(self, p):
|
| + """primary_expression : constant
|
| + | NAME
|
| + | LPAREN expression RPAREN"""
|
| + p[0] = ''.join(p[1:])
|
| +
|
| + def p_constant(self, p):
|
| + """constant : INT_CONST_DEC
|
| + | INT_CONST_OCT
|
| + | INT_CONST_HEX
|
| + | FLOAT_CONST
|
| + | HEX_FLOAT_CONST
|
| + | CHAR_CONST
|
| + | WCHAR_CONST
|
| + | STRING_LITERAL
|
| + | WSTRING_LITERAL"""
|
| + p[0] = ''.join(p[1:])
|
| +
|
| def p_error(self, e):
|
| print('error: %s'%e)
|
|
|
|
|