| Index: trunk/src/mojo/public/bindings/parse/mojo_parser.py
|
| ===================================================================
|
| --- trunk/src/mojo/public/bindings/parse/mojo_parser.py (revision 244236)
|
| +++ trunk/src/mojo/public/bindings/parse/mojo_parser.py (working copy)
|
| @@ -9,6 +9,7 @@
|
| import sys
|
| import os.path
|
|
|
| +
|
| # Try to load the ply module, if not, then assume it is in the third_party
|
| # directory.
|
| try:
|
| @@ -25,9 +26,7 @@
|
| from ply import lex
|
| from ply import yacc
|
|
|
| -from mojo_lexer import Lexer
|
|
|
| -
|
| def ListFromConcat(*items):
|
| """Generate list by concatenating inputs"""
|
| itemsout = []
|
| @@ -42,13 +41,114 @@
|
| 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 LBRACE definitions RBRACE"""
|
| + """module : MODULE NAME LCURLY definitions RCURLY"""
|
| p[0] = ('MODULE', p[2], p[4])
|
|
|
| def p_definitions(self, p):
|
| @@ -79,12 +179,12 @@
|
| p[0] = ListFromConcat(p[1], p[3])
|
|
|
| def p_attribute(self, p):
|
| - """attribute : NAME EQUALS expression
|
| + """attribute : NAME EQUALS NUMBER
|
| | NAME EQUALS NAME"""
|
| p[0] = ('ATTRIBUTE', p[1], p[3])
|
|
|
| def p_struct(self, p):
|
| - """struct : attribute_section STRUCT NAME LBRACE struct_body RBRACE SEMI"""
|
| + """struct : attribute_section STRUCT NAME LCURLY struct_body RCURLY SEMICOLON"""
|
| p[0] = ('STRUCT', p[3], p[1], p[5])
|
|
|
| def p_struct_body(self, p):
|
| @@ -95,11 +195,11 @@
|
| p[0] = ListFromConcat(p[1], p[2])
|
|
|
| def p_field(self, p):
|
| - """field : typename NAME ordinal SEMI"""
|
| + """field : typename NAME ordinal SEMICOLON"""
|
| p[0] = ('FIELD', p[1], p[2], p[3])
|
|
|
| def p_interface(self, p):
|
| - """interface : attribute_section INTERFACE NAME LBRACE interface_body RBRACE SEMI"""
|
| + """interface : attribute_section INTERFACE NAME LCURLY interface_body RCURLY SEMICOLON"""
|
| p[0] = ('INTERFACE', p[3], p[1], p[5])
|
|
|
| def p_interface_body(self, p):
|
| @@ -110,7 +210,7 @@
|
| p[0] = ListFromConcat(p[1], p[2])
|
|
|
| def p_method(self, p):
|
| - """method : VOID NAME LPAREN parameters RPAREN ordinal SEMI"""
|
| + """method : VOID NAME LPAREN parameters RPAREN ordinal SEMICOLON"""
|
| p[0] = ('METHOD', p[2], p[4], p[6])
|
|
|
| def p_parameters(self, p):
|
| @@ -140,13 +240,13 @@
|
| p[0] = p[1]
|
|
|
| def p_specializedhandle(self, p):
|
| - """specializedhandle : HANDLE LT specializedhandlename GT"""
|
| + """specializedhandle : HANDLE LANGLE specializedhandlename RANGLE"""
|
| p[0] = "handle<" + p[3] + ">"
|
|
|
| def p_specializedhandlename(self, p):
|
| - """specializedhandlename : DATA_PIPE_CONSUMER
|
| - | DATA_PIPE_PRODUCER
|
| - | MESSAGE_PIPE"""
|
| + """specializedhandlename : DATAPIPECONSUMER
|
| + | DATAPIPEPRODUCER
|
| + | MESSAGEPIPE"""
|
| p[0] = p[1]
|
|
|
| def p_array(self, p):
|
| @@ -160,7 +260,7 @@
|
| p[0] = p[1]
|
|
|
| def p_enum(self, p):
|
| - """enum : ENUM NAME LBRACE enum_fields RBRACE SEMI"""
|
| + """enum : ENUM NAME LCURLY enum_fields RCURLY SEMICOLON"""
|
| p[0] = ('ENUM', p[2], p[4])
|
|
|
| def p_enum_fields(self, p):
|
| @@ -174,84 +274,12 @@
|
|
|
| def p_enum_field(self, p):
|
| """enum_field : NAME
|
| - | NAME EQUALS expression"""
|
| + | NAME EQUALS NUMBER"""
|
| 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)
|
|
|
|
|