Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2168)

Unified Diff: mojo/public/bindings/parse/mojo_parser.py

Issue 130443003: Add support for using expressions as enum values. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: copyright Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « mojo/public/bindings/parse/mojo_lexer.py ('k') | mojo/public/bindings/sample/sample_service.mojom » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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)
« no previous file with comments | « mojo/public/bindings/parse/mojo_lexer.py ('k') | mojo/public/bindings/sample/sample_service.mojom » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698