First pass of pep8'ing the code
diff --git a/demo.py b/demo.py
index 8670650..b709611 100644
--- a/demo.py
+++ b/demo.py
@@ -54,6 +54,5 @@
for t in tests:
if t.startswith('test'):
- print 'parsin %s'%t
+ print 'parsin %s' % t
parser.parse_string(globals()[t])
-
diff --git a/foldemo.py b/foldemo.py
index 8035f85..eb350d7 100644
--- a/foldemo.py
+++ b/foldemo.py
@@ -1,7 +1,6 @@
from plyxproto.logicparser import *
import ply.lex as lex
import ply.yacc as yacc
-import pdb
test_1 = "<true>"
test_2 = "<a | b>"
@@ -15,6 +14,6 @@
lexer = lex.lex(module=FOLLexer(), debug=DEBUG)
parser = yacc.yacc(module=FOLParser(), start='goal', debug=DEBUG)
-for x,v in globals().items():
+for x, v in globals().items():
if x.startswith('test_'):
- print parser.parse(v, lexer = lexer, debug=DEBUG)
+ print parser.parse(v, lexer=lexer, debug=DEBUG)
diff --git a/plyxproto/helpers.py b/plyxproto/helpers.py
index b059c17..2cfc4c3 100644
--- a/plyxproto/helpers.py
+++ b/plyxproto/helpers.py
@@ -1,8 +1,9 @@
class LexHelper:
offset = 0
+
def get_max_linespan(self, p):
- defSpan=[1e60, -1]
- mSpan=[1e60, -1]
+ defSpan = [1e60, -1]
+ mSpan = [1e60, -1]
for sp in range(0, len(p)):
csp = p.linespan(sp)
if csp[0] == 0 and csp[1] == 0:
@@ -10,16 +11,21 @@
csp = p[sp].linespan
else:
continue
- if csp == None or len(csp) != 2: continue
- if csp[0] == 0 and csp[1] == 0: continue
- if csp[0] < mSpan[0]: mSpan[0] = csp[0]
- if csp[1] > mSpan[1]: mSpan[1] = csp[1]
- if defSpan == mSpan: return (0,0)
- return tuple([mSpan[0]-self.offset, mSpan[1]-self.offset])
+ if csp is None or len(csp) != 2:
+ continue
+ if csp[0] == 0 and csp[1] == 0:
+ continue
+ if csp[0] < mSpan[0]:
+ mSpan[0] = csp[0]
+ if csp[1] > mSpan[1]:
+ mSpan[1] = csp[1]
+ if defSpan == mSpan:
+ return (0, 0)
+ return tuple([mSpan[0] - self.offset, mSpan[1] - self.offset])
def get_max_lexspan(self, p):
- defSpan=[1e60, -1]
- mSpan=[1e60, -1]
+ defSpan = [1e60, -1]
+ mSpan = [1e60, -1]
for sp in range(0, len(p)):
csp = p.lexspan(sp)
if csp[0] == 0 and csp[1] == 0:
@@ -27,24 +33,32 @@
csp = p[sp].lexspan
else:
continue
- if csp == None or len(csp) != 2: continue
- if csp[0] == 0 and csp[1] == 0: continue
- if csp[0] < mSpan[0]: mSpan[0] = csp[0]
- if csp[1] > mSpan[1]: mSpan[1] = csp[1]
- if defSpan == mSpan: return (0,0)
- return tuple([mSpan[0]-self.offset, mSpan[1]-self.offset])
+ if csp is None or len(csp) != 2:
+ continue
+ if csp[0] == 0 and csp[1] == 0:
+ continue
+ if csp[0] < mSpan[0]:
+ mSpan[0] = csp[0]
+ if csp[1] > mSpan[1]:
+ mSpan[1] = csp[1]
+ if defSpan == mSpan:
+ return (0, 0)
+ return tuple([mSpan[0] - self.offset, mSpan[1] - self.offset])
def set_parse_object(self, dst, p):
- dst.setLexData(linespan=self.get_max_linespan(p), lexspan=self.get_max_lexspan(p))
+ dst.setLexData(
+ linespan=self.get_max_linespan(p),
+ lexspan=self.get_max_lexspan(p))
dst.setLexObj(p)
+
class Base(object):
parent = None
lexspan = None
linespan = None
def v(self, obj, visitor):
- if obj == None:
+ if obj is None:
return
elif hasattr(obj, "accept"):
obj.accept(visitor)
@@ -64,7 +78,10 @@
obj.parent = parent
# Lexical unit - contains lexspan and linespan for later analysis.
+
+
class LU(Base):
+
def __init__(self, p, idx):
self.p = p
self.idx = idx
@@ -75,20 +92,23 @@
# If string is in the value (raw value) and start and stop lexspan is the same, add real span
# obtained by string length.
if isinstance(self.pval, str) \
- and self.lexspan != None \
+ and self.lexspan is not None \
and self.lexspan[0] == self.lexspan[1] \
and self.lexspan[0] != 0:
- self.lexspan = tuple([self.lexspan[0], self.lexspan[0] + len(self.pval)])
+ self.lexspan = tuple(
+ [self.lexspan[0], self.lexspan[0] + len(self.pval)])
super(LU, self).__init__()
@staticmethod
def i(p, idx):
- if isinstance(p[idx], LU): return p[idx]
- if isinstance(p[idx], str): return LU(p, idx)
+ if isinstance(p[idx], LU):
+ return p[idx]
+ if isinstance(p[idx], str):
+ return LU(p, idx)
return p[idx]
def describe(self):
- return "LU(%s,%s)" % (self.pval, self.lexspan)
+ return "LU(%s,%s)" % (self.pval, self.lexspan)
def __str__(self):
return self.pval
@@ -104,14 +124,17 @@
yield x
# Base node
+
+
class SourceElement(Base):
'''
A SourceElement is the base class for all elements that occur in a Protocol Buffers
file parsed by plyproto.
'''
+
def __init__(self, linespan=[], lexspan=[], p=None):
super(SourceElement, self).__init__()
- self._fields = [] # ['linespan', 'lexspan']
+ self._fields = [] # ['linespan', 'lexspan']
self.linespan = linespan
self.lexspan = lexspan
self.p = p
@@ -141,6 +164,7 @@
def accept(self, visitor):
pass
+
class Visitor(object):
def __init__(self, verbose=False):
@@ -148,7 +172,8 @@
def __getattr__(self, name):
if not name.startswith('visit_'):
- raise AttributeError('name must start with visit_ but was {}'.format(name))
+ raise AttributeError(
+ 'name must start with visit_ but was {}'.format(name))
def f(element):
if self.verbose:
@@ -174,5 +199,3 @@
# visitor.visit_Name(self)
# visitor.visit_Proto(self)
# visitor.visit_LU(self)
-
-
diff --git a/plyxproto/logicparser.py b/plyxproto/logicparser.py
index c246baf..ae8444e 100644
--- a/plyxproto/logicparser.py
+++ b/plyxproto/logicparser.py
@@ -3,20 +3,33 @@
__copyright__ = "Copyright (C) 2017 Open Networking Lab"
__version__ = "1.0"
-import ply.lex as lex
-import ply.yacc as yacc
+from helpers import LexHelper
-from helpers import LexHelper, LU
class FOLParsingError(Exception):
+
def __init__(self, message, error_range):
super(FOLParsingError, self).__init__(message)
self.error_range = error_range
+
class FOLLexer(object):
keywords = ('forall', 'exists', 'True', 'False', 'not', 'in')
- tokens = ['STRING_LITERAL', 'NUM', 'ESCAPE', 'COLON', 'IMPLIES', 'OR', 'AND', 'LPAREN', 'RPAREN', 'EQUALS', 'SYMBOL', 'LT', 'RT', 'STAR'] + [k.upper() for k in keywords]
+ tokens = ['STRING_LITERAL',
+ 'NUM',
+ 'ESCAPE',
+ 'COLON',
+ 'IMPLIES',
+ 'OR',
+ 'AND',
+ 'LPAREN',
+ 'RPAREN',
+ 'EQUALS',
+ 'SYMBOL',
+ 'LT',
+ 'RT',
+ 'STAR'] + [k.upper() for k in keywords]
# literals = '()+-*/=?:,.^|&~!=[]{};<>@%'
t_ignore_LINE_COMMENT = '//.*'
@@ -62,11 +75,11 @@
return t
def t_error(self, t):
- print("Illegal character '{}' ({}) in line {}".format(t.value[0], hex(ord(t.value[0])), t.lexer.lineno))
+ print("Illegal character '{}' ({}) in line {}".format(
+ t.value[0], hex(ord(t.value[0])), t.lexer.lineno))
t.lexer.skip(1)
-
-
-
+
+
class FOLParser(object):
tokens = FOLLexer.tokens
offset = 0
@@ -138,14 +151,14 @@
def p_error(self, p):
error = 'error: {}'.format(p)
- raise FOLParsingError(error, (p.lineno,p.lexpos,len(p.value)))
+ raise FOLParsingError(error, (p.lineno, p.lexpos, len(p.value)))
precedence = (
- ("right", "IMPLIES"),
- ("left", "OR"),
- ("left", "AND"),
- ("right", "COLON"),
- ("right", "NOT"),
- ("right", "STAR"),
- ("right", "ESCAPE"),
- ("nonassoc", "EQUALS", "IN"))
+ ("right", "IMPLIES"),
+ ("left", "OR"),
+ ("left", "AND"),
+ ("right", "COLON"),
+ ("right", "NOT"),
+ ("right", "STAR"),
+ ("right", "ESCAPE"),
+ ("nonassoc", "EQUALS", "IN"))
diff --git a/plyxproto/model.py b/plyxproto/model.py
index d19eeff..39618a3 100644
--- a/plyxproto/model.py
+++ b/plyxproto/model.py
@@ -1,8 +1,15 @@
from helpers import Base, SourceElement
+
class PackageStatement(SourceElement):
+
def __init__(self, name, linespan=None, lexspan=None, p=None):
- super(PackageStatement, self).__init__(linespan=linespan, lexspan=lexspan, p=p)
+ super(
+ PackageStatement,
+ self).__init__(
+ linespan=linespan,
+ lexspan=lexspan,
+ p=p)
self._fields += ['name']
self.name = name
Base.p(self.name, self)
@@ -10,9 +17,16 @@
def accept(self, visitor):
visitor.visit_PackageStatement(self)
+
class ImportStatement(SourceElement):
+
def __init__(self, name, linespan=None, lexspan=None, p=None):
- super(ImportStatement, self).__init__(linespan=linespan, lexspan=lexspan, p=p)
+ super(
+ ImportStatement,
+ self).__init__(
+ linespan=linespan,
+ lexspan=lexspan,
+ p=p)
self._fields += ['name']
self.name = name
Base.p(self.name, self)
@@ -20,9 +34,16 @@
def accept(self, visitor):
visitor.visit_ImportStatement(self)
+
class OptionStatement(SourceElement):
+
def __init__(self, name, value, linespan=None, lexspan=None, p=None):
- super(OptionStatement, self).__init__(linespan=linespan, lexspan=lexspan, p=p)
+ super(
+ OptionStatement,
+ self).__init__(
+ linespan=linespan,
+ lexspan=lexspan,
+ p=p)
self._fields += ['name', 'value']
self.name = name
Base.p(self.name, self)
@@ -32,9 +53,16 @@
def accept(self, visitor):
visitor.visit_OptionStatement(self)
+
class FieldDirective(SourceElement):
+
def __init__(self, name, value, linespan=None, lexspan=None, p=None):
- super(FieldDirective, self).__init__(linespan=linespan, lexspan=lexspan, p=p)
+ super(
+ FieldDirective,
+ self).__init__(
+ linespan=linespan,
+ lexspan=lexspan,
+ p=p)
self._fields += ['name', 'value']
self.name = name
Base.p(self.name, self)
@@ -47,9 +75,16 @@
self.v(self.value, visitor)
visitor.visit_FieldDirective_post(self)
+
class FieldType(SourceElement):
+
def __init__(self, name, linespan=None, lexspan=None, p=None):
- super(FieldType, self).__init__(linespan=linespan, lexspan=lexspan, p=p)
+ super(
+ FieldType,
+ self).__init__(
+ linespan=linespan,
+ lexspan=lexspan,
+ p=p)
self._fields += ['name']
self.name = name
Base.p(self.name, self)
@@ -58,10 +93,27 @@
if visitor.visit_FieldType(self):
self.v(self.name, visitor)
+
class LinkDefinition(SourceElement):
- def __init__(self, link_type, src_port, name, through, dst_port, linespan=None, lexspan=None, p=None):
- super(LinkDefinition, self).__init__(linespan=linespan, lexspan=lexspan, p=p)
- self._fields += ['link_type', 'src_port', 'name', 'dst_port', 'through']
+
+ def __init__(
+ self,
+ link_type,
+ src_port,
+ name,
+ through,
+ dst_port,
+ linespan=None,
+ lexspan=None,
+ p=None):
+ super(
+ LinkDefinition,
+ self).__init__(
+ linespan=linespan,
+ lexspan=lexspan,
+ p=p)
+ self._fields += ['link_type', 'src_port',
+ 'name', 'dst_port', 'through']
self.link_type = link_type
Base.p(self.link_type, self)
@@ -78,12 +130,30 @@
Base.p(self.dst_port, self)
def accept(self, visitor):
- visitor.visit_LinkDefinition(self)
+ visitor.visit_LinkDefinition(self)
+
class FieldDefinition(SourceElement):
- def __init__(self, field_modifier, ftype, name, policy, fieldId, fieldDirective, linespan=None, lexspan=None, p=None):
- super(FieldDefinition, self).__init__(linespan=linespan, lexspan=lexspan, p=p)
- self._fields += ['field_modifier', 'ftype', 'name', 'fieldId', 'policy', 'fieldDirective']
+
+ def __init__(
+ self,
+ field_modifier,
+ ftype,
+ name,
+ policy,
+ fieldId,
+ fieldDirective,
+ linespan=None,
+ lexspan=None,
+ p=None):
+ super(
+ FieldDefinition,
+ self).__init__(
+ linespan=linespan,
+ lexspan=lexspan,
+ p=p)
+ self._fields += ['field_modifier', 'ftype',
+ 'name', 'fieldId', 'policy', 'fieldDirective']
self.name = name
Base.p(self.name, self)
self.field_modifier = field_modifier
@@ -107,9 +177,16 @@
self.v(self.fieldDirective, visitor)
visitor.visit_FieldDefinition_post(self)
+
class EnumFieldDefinition(SourceElement):
+
def __init__(self, name, fieldId, linespan=None, lexspan=None, p=None):
- super(EnumFieldDefinition, self).__init__(linespan=linespan, lexspan=lexspan, p=p)
+ super(
+ EnumFieldDefinition,
+ self).__init__(
+ linespan=linespan,
+ lexspan=lexspan,
+ p=p)
self._fields += ['name', 'fieldId']
self.name = name
Base.p(self.name, self)
@@ -121,9 +198,16 @@
self.v(self.name, visitor)
self.v(self.fieldId, visitor)
+
class ReduceDefinition(SourceElement):
+
def __init__(self, name, body, linespan=None, lexspan=None, p=None):
- super(ReduceDefinition, self).__init__(linespan=linespan, lexspan=lexspan, p=p)
+ super(
+ ReduceDefinition,
+ self).__init__(
+ linespan=linespan,
+ lexspan=lexspan,
+ p=p)
self._fields += ['name', 'body']
self.name = name
Base.p(self.name, self)
@@ -137,8 +221,14 @@
class MapDefinition(SourceElement):
+
def __init__(self, name, body, linespan=None, lexspan=None, p=None):
- super(MapDefinition, self).__init__(linespan=linespan, lexspan=lexspan, p=p)
+ super(
+ MapDefinition,
+ self).__init__(
+ linespan=linespan,
+ lexspan=lexspan,
+ p=p)
self._fields += ['name', 'body']
self.name = name
Base.p(self.name, self)
@@ -152,8 +242,14 @@
class PolicyDefinition(SourceElement):
+
def __init__(self, name, body, linespan=None, lexspan=None, p=None):
- super(PolicyDefinition, self).__init__(linespan=linespan, lexspan=lexspan, p=p)
+ super(
+ PolicyDefinition,
+ self).__init__(
+ linespan=linespan,
+ lexspan=lexspan,
+ p=p)
self._fields += ['name', 'body']
self.name = name
Base.p(self.name, self)
@@ -165,9 +261,16 @@
self.v(self.name, visitor)
self.v(self.body, visitor)
+
class EnumDefinition(SourceElement):
+
def __init__(self, name, body, linespan=None, lexspan=None, p=None):
- super(EnumDefinition, self).__init__(linespan=linespan, lexspan=lexspan, p=p)
+ super(
+ EnumDefinition,
+ self).__init__(
+ linespan=linespan,
+ lexspan=lexspan,
+ p=p)
self._fields += ['name', 'body']
self.name = name
Base.p(self.name, self)
@@ -179,8 +282,16 @@
self.v(self.name, visitor)
self.v(self.body, visitor)
+
class LinkSpec(SourceElement):
- def __init__(self, field_spec, link_spec, linespan=None, lexspan=None, p=None):
+
+ def __init__(
+ self,
+ field_spec,
+ link_spec,
+ linespan=None,
+ lexspan=None,
+ p=None):
super(LinkSpec, self).__init__(linespan=linespan, lexspan=lexspan, p=p)
self._fields += ['link_def', 'field_def']
self.link_def = link_spec
@@ -194,9 +305,24 @@
self.v(self.field_def, visitor)
visitor.visit_LinkSpec_post(self)
+
class MessageDefinition(SourceElement):
- def __init__(self, name, policy, bases, body, linespan=None, lexspan=None, p=None):
- super(MessageDefinition, self).__init__(linespan=linespan, lexspan=lexspan, p=p)
+
+ def __init__(
+ self,
+ name,
+ policy,
+ bases,
+ body,
+ linespan=None,
+ lexspan=None,
+ p=None):
+ super(
+ MessageDefinition,
+ self).__init__(
+ linespan=linespan,
+ lexspan=lexspan,
+ p=p)
self._fields += ['name', 'policy', 'bases', 'body']
self.name = name
@@ -236,9 +362,16 @@
visitor.visit_MessageDefinition_post(self)
"""
+
class MessageExtension(SourceElement):
+
def __init__(self, name, body, linespan=None, lexspan=None, p=None):
- super(MessageExtension, self).__init__(linespan=linespan, lexspan=lexspan, p=p)
+ super(
+ MessageExtension,
+ self).__init__(
+ linespan=linespan,
+ lexspan=lexspan,
+ p=p)
self._fields += ['name', 'body']
self.name = name
Base.p(self.name, self)
@@ -251,9 +384,23 @@
self.v(self.body, visitor)
visitor.visit_MessageExtension_post(self)
+
class MethodDefinition(SourceElement):
- def __init__(self, name, name2, name3, linespan=None, lexspan=None, p=None):
- super(MethodDefinition, self).__init__(linespan=linespan, lexspan=lexspan, p=p)
+
+ def __init__(
+ self,
+ name,
+ name2,
+ name3,
+ linespan=None,
+ lexspan=None,
+ p=None):
+ super(
+ MethodDefinition,
+ self).__init__(
+ linespan=linespan,
+ lexspan=lexspan,
+ p=p)
self._fields += ['name', 'name2', 'name3']
self.name = name
Base.p(self.name, self)
@@ -269,9 +416,16 @@
self.v(self.name3, visitor)
visitor.visit_MethodDefinition_post(self)
+
class ServiceDefinition(SourceElement):
+
def __init__(self, name, body, linespan=None, lexspan=None, p=None):
- super(ServiceDefinition, self).__init__(linespan=linespan, lexspan=lexspan, p=p)
+ super(
+ ServiceDefinition,
+ self).__init__(
+ linespan=linespan,
+ lexspan=lexspan,
+ p=p)
self._fields += ['name', 'body']
self.name = name
Base.p(self.name, self)
@@ -284,12 +438,20 @@
self.v(self.body, visitor)
visitor.visit_ServiceDefinition_post(self)
+
class ExtensionsMax(SourceElement):
pass
+
class ExtensionsDirective(SourceElement):
+
def __init__(self, fromVal, toVal, linespan=None, lexspan=None, p=None):
- super(ExtensionsDirective, self).__init__(linespan=linespan, lexspan=lexspan, p=p)
+ super(
+ ExtensionsDirective,
+ self).__init__(
+ linespan=linespan,
+ lexspan=lexspan,
+ p=p)
self._fields += ['fromVal', 'toVal']
self.fromVal = fromVal
Base.p(self.fromVal, self)
@@ -302,6 +464,7 @@
self.v(self.toVal, visitor)
visitor.visit_ExtensionsDirective_post(self)
+
class Literal(SourceElement):
def __init__(self, value, linespan=None, lexspan=None, p=None):
@@ -312,6 +475,7 @@
def accept(self, visitor):
visitor.visit_Literal(self)
+
class Name(SourceElement):
def __init__(self, value, linespan=None, lexspan=None, p=None):
@@ -336,18 +500,23 @@
def accept(self, visitor):
visitor.visit_Name(self)
+
class DotName(Name):
elements = []
+
def __init__(self, elements, linespan=None, lexspan=None, p=None):
- super(DotName, self).__init__('.'.join([str(x) for x in elements]), linespan=linespan, lexspan=lexspan, p=p)
+ super(DotName, self).__init__(
+ '.'.join([str(x) for x in elements]), linespan=linespan, lexspan=lexspan, p=p)
self._fields += ['elements']
self.elements = elements
self.deriveLex()
def deriveLex(self):
- if isinstance(self.elements, list) and len(self.elements)>0:
- self.lexspan = (min([x.lexspan[0] for x in self.elements if x.lexspan[0] != 0]), max([x.lexspan[1] for x in self.elements if x.lexspan[1] != 0]))
- self.linespan = (min([x.linespan[0] for x in self.elements if x.linespan[0] != 0]), max([x.linespan[1] for x in self.elements if x.linespan[1] != 0]))
+ if isinstance(self.elements, list) and len(self.elements) > 0:
+ self.lexspan = (min([x.lexspan[0] for x in self.elements if x.lexspan[0] != 0]), max(
+ [x.lexspan[1] for x in self.elements if x.lexspan[1] != 0]))
+ self.linespan = (min([x.linespan[0] for x in self.elements if x.linespan[0] != 0]), max(
+ [x.linespan[1] for x in self.elements if x.linespan[1] != 0]))
elif hasattr(self.elements, "lexspan"):
self.lexspan = self.elements.lexspan
self.linespan = self.elements.linespan
@@ -357,10 +526,16 @@
def accept(self, visitor):
visitor.visit_DotName(self)
+
class ProtoFile(SourceElement):
def __init__(self, body, linespan=None, lexspan=None, p=None):
- super(ProtoFile, self).__init__(linespan=linespan, lexspan=lexspan, p=p)
+ super(
+ ProtoFile,
+ self).__init__(
+ linespan=linespan,
+ lexspan=lexspan,
+ p=p)
self._fields += ['body']
self.body = body
Base.p(self.body, self)
diff --git a/plyxproto/parser.py b/plyxproto/parser.py
index 6213a07..e976727 100755
--- a/plyxproto/parser.py
+++ b/plyxproto/parser.py
@@ -6,34 +6,96 @@
import ply.lex as lex
import ply.yacc as yacc
-from .model import *
-import pdb
+from .model import (
+ DotName,
+ EnumDefinition,
+ EnumFieldDefinition,
+ ExtensionsDirective,
+ ExtensionsMax,
+ FieldDefinition,
+ FieldDirective,
+ FieldType,
+ ImportStatement,
+ LinkDefinition,
+ LinkSpec,
+ Literal,
+ MapDefinition,
+ MessageDefinition,
+ MessageExtension,
+ MethodDefinition,
+ Name,
+ OptionStatement,
+ PackageStatement,
+ PolicyDefinition,
+ ProtoFile,
+ ReduceDefinition,
+ ServiceDefinition,
+)
+
from helpers import LexHelper, LU
from logicparser import FOLParser, FOLLexer, FOLParsingError
import ast
+
class PythonError(Exception):
pass
+
class ParsingError(Exception):
+
def __init__(self, message, error_range):
super(ParsingError, self).__init__(message)
self.error_range = error_range
class ProtobufLexer(object):
- keywords = ('double', 'float', 'int32', 'int64', 'uint32', 'uint64', 'sint32', 'sint64',
- 'fixed32', 'fixed64', 'sfixed32', 'sfixed64', 'bool', 'string', 'bytes',
- 'message', 'required', 'optional', 'repeated', 'enum', 'extensions', 'max', 'extend',
- 'to', 'package', '_service', 'rpc', 'returns', 'true', 'false', 'option', 'import', 'manytoone', 'manytomany', 'onetoone', 'policy', 'map', 'reduce')
+ keywords = (
+ 'double',
+ 'float',
+ 'int32',
+ 'int64',
+ 'uint32',
+ 'uint64',
+ 'sint32',
+ 'sint64',
+ 'fixed32',
+ 'fixed64',
+ 'sfixed32',
+ 'sfixed64',
+ 'bool',
+ 'string',
+ 'bytes',
+ 'message',
+ 'required',
+ 'optional',
+ 'repeated',
+ 'enum',
+ 'extensions',
+ 'max',
+ 'extend',
+ 'to',
+ 'package',
+ '_service',
+ 'rpc',
+ 'returns',
+ 'true',
+ 'false',
+ 'option',
+ 'import',
+ 'manytoone',
+ 'manytomany',
+ 'onetoone',
+ 'policy',
+ 'map',
+ 'reduce')
tokens = [
'POLICYBODY',
'NAME',
'NUM',
'STRING_LITERAL',
- #'LINE_COMMENT', 'BLOCK_COMMENT',
+ # 'LINE_COMMENT', 'BLOCK_COMMENT',
'LBRACE', 'RBRACE', 'LBRACK', 'RBRACK',
'LPAR', 'RPAR', 'EQ', 'SEMI', 'DOT',
'ARROW', 'COLON', 'COMMA', 'SLASH',
@@ -41,7 +103,6 @@
'STARTTOKEN'
] + [k.upper() for k in keywords]
-
def t_POLICYBODY(self, t):
r'< (.|\n)*? [^-]>'
t.lexer.lineno += t.value.count('\n')
@@ -53,6 +114,7 @@
t_STRING_LITERAL = r'\"([^\\\n]|(\\.))*?\"'
t_ignore_LINE_COMMENT = '//.*'
+
def t_BLOCK_COMMENT(self, t):
r'/\*(.|\n)*?\*/'
t.lexer.lineno += t.value.count('\n')
@@ -62,7 +124,6 @@
t_LBRACK = '\\['
t_RBRACK = '\\]'
-
t_LPAR = '\\('
t_RPAR = '\\)'
t_EQ = '='
@@ -79,7 +140,7 @@
def t_NAME(self, t):
'[A-Za-z_$][A-Za-z0-9_+$]*'
if t.value in ProtobufLexer.keywords:
- #print "type: %s val %s t %s" % (t.type, t.value, t)
+ # print "type: %s val %s t %s" % (t.type, t.value, t)
t.type = t.value.upper()
return t
@@ -92,13 +153,14 @@
t.lexer.lineno += len(t.value) / 2
def t_error(self, t):
- print("Illegal character '{}' ({}) in line {}".format(t.value[0], hex(ord(t.value[0])), t.lexer.lineno))
+ print("Illegal character '{}' ({}) in line {}".format(
+ t.value[0], hex(ord(t.value[0])), t.lexer.lineno))
t.lexer.skip(1)
def srcPort(x):
if (x):
- return [FieldDirective(Name('port'),x)]
+ return [FieldDirective(Name('port'), x)]
else:
return []
@@ -107,8 +169,12 @@
tokens = ProtobufLexer.tokens
offset = 0
lh = LexHelper()
- fol_lexer = lex.lex(module=FOLLexer())#, optimize=1)
- fol_parser = yacc.yacc(module=FOLParser(), start='goal', outputdir='/tmp', debug=0)
+ fol_lexer = lex.lex(module=FOLLexer()) # , optimize=1)
+ fol_parser = yacc.yacc(
+ module=FOLParser(),
+ start='goal',
+ outputdir='/tmp',
+ debug=0)
def setOffset(self, of):
self.offset = of
@@ -118,11 +184,11 @@
'''empty :'''
pass
- def p_field_modifier(self,p):
+ def p_field_modifier(self, p):
'''field_modifier : REQUIRED
| OPTIONAL
| REPEATED'''
- p[0] = LU.i(p,1)
+ p[0] = LU.i(p, 1)
def p_primitive_type(self, p):
'''primitive_type : DOUBLE
@@ -140,23 +206,23 @@
| BOOL
| STRING
| BYTES'''
- p[0] = LU.i(p,1)
+ p[0] = LU.i(p, 1)
def p_link_type(self, p):
'''link_type : ONETOONE
| MANYTOONE
| MANYTOMANY'''
- p[0] = LU.i(p,1)
+ p[0] = LU.i(p, 1)
def p_field_id(self, p):
'''field_id : NUM'''
- p[0] = LU.i(p,1)
+ p[0] = LU.i(p, 1)
def p_rvalue(self, p):
'''rvalue : NUM
| TRUE
| FALSE'''
- p[0] = LU.i(p,1)
+ p[0] = LU.i(p, 1)
def p_rvalue3(self, p):
'''rvalue : STRING_LITERAL'''
@@ -177,7 +243,7 @@
def p_field_directives(self, p):
'''field_directives : LBRACK field_directive_times RBRACK'''
p[0] = p[2]
- #self.lh.set_parse_object(p[0], p)
+ # self.lh.set_parse_object(p[0], p)
def p_field_directive(self, p):
'''field_directive : NAME EQ rvalue'''
@@ -204,13 +270,13 @@
'''csv : empty'''
def p_csv(self, p):
- '''csv : dotname
+ '''csv : dotname
| csv COMMA dotname'''
if len(p) == 2:
- p[0] = [LU(p,1)]
+ p[0] = [LU(p, 1)]
else:
- p[0] = p[1] + [LU(p,3)]
+ p[0] = p[1] + [LU(p, 3)]
def p_field_directive_times(self, p):
'''field_directive_times : field_directive_plus'''
@@ -224,17 +290,17 @@
'''field_directive_plus : field_directive
| field_directive_plus COMMA field_directive'''
if len(p) == 2:
- p[0] = [LU(p,1)]
+ p[0] = [LU(p, 1)]
else:
- p[0] = p[1] + [LU(p,3)]
+ p[0] = p[1] + [LU(p, 3)]
def p_dotname(self, p):
'''dotname : NAME
| dotname DOT NAME'''
if len(p) == 2:
- p[0] = [LU(p,1)]
+ p[0] = [LU(p, 1)]
else:
- p[0] = p[1] + [LU(p,3)]
+ p[0] = p[1] + [LU(p, 3)]
# Hack for cases when there is a field named 'message' or 'max'
def p_fieldName(self, p):
@@ -242,13 +308,13 @@
| NAME
| MESSAGE
| MAX'''
- p[0] = Name(LU.i(p,1))
+ p[0] = Name(LU.i(p, 1))
self.lh.set_parse_object(p[0], p)
p[0].deriveLex()
def p_field_type(self, p):
'''field_type : primitive_type'''
- p[0] = FieldType(LU.i(p,1))
+ p[0] = FieldType(LU.i(p, 1))
self.lh.set_parse_object(p[0], p)
def p_field_type2(self, p):
@@ -260,7 +326,7 @@
def p_slash_name(self, p):
'''slash_name : SLASH dotname'''
p[0] = p[2]
- #self.lh.set_parse_object(p[0], p)
+ # self.lh.set_parse_object(p[0], p)
def p_slash_name2(self, p):
'''slash_name : empty'''
@@ -279,21 +345,45 @@
def p_link_definition(self, p):
'''link_definition : field_modifier link_type field_name policy_opt ARROW dotname slash_name colon_fieldname EQ field_id field_directives SEMI'''
p[0] = LinkSpec(
- FieldDefinition(LU.i(p,1), Name('int32'), LU.i(p, 3), LU.i(p,4), LU.i(p, 10), [FieldDirective(Name('type'), Name('link')), FieldDirective(Name('model'),LU.i(p, 6))] + srcPort(LU.i(p,8)) + LU.i(p,11)),
- LinkDefinition(LU.i(p,2), LU.i(p,3), LU.i(p,6), LU.i(p,7), LU.i(p,8)))
+ FieldDefinition(
+ LU.i(
+ p, 1), Name('int32'), LU.i(
+ p, 3), LU.i(
+ p, 4), LU.i(
+ p, 10), [
+ FieldDirective(
+ Name('type'), Name('link')), FieldDirective(
+ Name('model'), LU.i(
+ p, 6))] + srcPort(
+ LU.i(
+ p, 8)) + LU.i(
+ p, 11)), LinkDefinition(
+ LU.i(
+ p, 2), LU.i(
+ p, 3), LU.i(
+ p, 6), LU.i(
+ p, 7), LU.i(
+ p, 8)))
self.lh.set_parse_object(p[0], p)
# Root of the field declaration.
def p_field_definition(self, p):
'''field_definition : field_modifier field_type field_name policy_opt EQ field_id field_directives SEMI'''
- p[0] = FieldDefinition(LU.i(p,1), LU.i(p,2), LU.i(p, 3), LU.i(p,4), LU.i(p,6), LU.i(p,7))
+ p[0] = FieldDefinition(
+ LU.i(
+ p, 1), LU.i(
+ p, 2), LU.i(
+ p, 3), LU.i(
+ p, 4), LU.i(
+ p, 6), LU.i(
+ p, 7))
self.lh.set_parse_object(p[0], p)
# Root of the enum field declaration.
def p_enum_field(self, p):
'''enum_field : field_name EQ NUM SEMI'''
- p[0] = EnumFieldDefinition(LU.i(p, 1), LU.i(p,3))
+ p[0] = EnumFieldDefinition(LU.i(p, 1), LU.i(p, 3))
self.lh.set_parse_object(p[0], p)
def p_enum_body_part(self, p):
@@ -344,10 +434,12 @@
def p_policy_definition(self, p):
'''policy_definition : POLICY NAME POLICYBODY'''
try:
- fol = self.fol_parser.parse(p[3], lexer = self.fol_lexer)
- except FOLParsingError, e:
+ fol = self.fol_parser.parse(p[3], lexer=self.fol_lexer)
+ except FOLParsingError as e:
lineno, lexpos, length = e.error_range
- raise ParsingError("Policy parsing error in policy %s"%p[2], (p.lineno(3) + lineno,lexpos + p.lexpos(3), length))
+ raise ParsingError(
+ "Policy parsing error in policy %s" %
+ p[2], (p.lineno(3) + lineno, lexpos + p.lexpos(3), length))
p[0] = PolicyDefinition(Name(LU.i(p, 2)), fol)
self.lh.set_parse_object(p[0], p)
@@ -355,7 +447,7 @@
# enum_definition ::= 'enum' ident '{' { ident '=' integer ';' }* '}'
def p_enum_definition(self, p):
'''enum_definition : ENUM NAME LBRACE enum_body_opt RBRACE'''
- p[0] = EnumDefinition(Name(LU.i(p, 2)), LU.i(p,4))
+ p[0] = EnumDefinition(Name(LU.i(p, 2)), LU.i(p, 4))
self.lh.set_parse_object(p[0], p)
def p_extensions_to(self, p):
@@ -370,13 +462,13 @@
# extensions_definition ::= 'extensions' integer 'to' integer ';'
def p_extensions_definition(self, p):
'''extensions_definition : EXTENSIONS NUM TO extensions_to SEMI'''
- p[0] = ExtensionsDirective(LU.i(p,2), LU.i(p,4))
+ p[0] = ExtensionsDirective(LU.i(p, 2), LU.i(p, 4))
self.lh.set_parse_object(p[0], p)
# message_extension ::= 'extend' ident '{' message_body '}'
def p_message_extension(self, p):
'''message_extension : EXTEND NAME LBRACE message_body RBRACE'''
- p[0] = MessageExtension(Name(LU.i(p, 2)), LU.i(p,4))
+ p[0] = MessageExtension(Name(LU.i(p, 2)), LU.i(p, 4))
self.lh.set_parse_object(p[0], p)
def p_message_body_part(self, p):
@@ -389,12 +481,14 @@
| message_extension'''
p[0] = p[1]
- # message_body ::= { field_definition | enum_definition | message_definition | extensions_definition | message_extension }*
+ # message_body ::= { field_definition | enum_definition |
+ # message_definition | extensions_definition | message_extension }*
def p_message_body(self, p):
'''message_body : empty'''
p[0] = []
- # message_body ::= { field_definition | enum_definition | message_definition | extensions_definition | message_extension }*
+ # message_body ::= { field_definition | enum_definition |
+ # message_definition | extensions_definition | message_extension }*
def p_message_body2(self, p):
'''message_body : message_body_part
| message_body message_body_part'''
@@ -407,13 +501,27 @@
# message_definition = MESSAGE_ - ident("messageId") + LBRACE + message_body("body") + RBRACE
def p_message_definition(self, p):
'''message_definition : MESSAGE NAME policy_opt csv_expr LBRACE message_body RBRACE'''
- p[0] = MessageDefinition(Name(LU.i(p, 2)), LU.i(p,3), LU.i(p, 4), LU.i(p,6))
+ p[0] = MessageDefinition(
+ Name(
+ LU.i(
+ p, 2)), LU.i(
+ p, 3), LU.i(
+ p, 4), LU.i(
+ p, 6))
self.lh.set_parse_object(p[0], p)
- # method_definition ::= 'rpc' ident '(' [ ident ] ')' 'returns' '(' [ ident ] ')' ';'
+ # method_definition ::= 'rpc' ident '(' [ ident ] ')' 'returns' '(' [
+ # ident ] ')' ';'
def p_method_definition(self, p):
'''method_definition : RPC NAME LPAR NAME RPAR RETURNS LPAR NAME RPAR'''
- p[0] = MethodDefinition(Name(LU.i(p, 2)), Name(LU.i(p, 4)), Name(LU.i(p, 8)))
+ p[0] = MethodDefinition(
+ Name(
+ LU.i(
+ p, 2)), Name(
+ LU.i(
+ p, 4)), Name(
+ LU.i(
+ p, 8)))
self.lh.set_parse_object(p[0], p)
def p_method_definition_opt(self, p):
@@ -432,11 +540,11 @@
# service_definition = SERVICE_ - ident("serviceName") + LBRACE + ZeroOrMore(Group(method_definition)) + RBRACE
def p_service_definition(self, p):
'''service_definition : _SERVICE NAME LBRACE method_definition_opt RBRACE'''
- p[0] = ServiceDefinition(Name(LU.i(p, 2)), LU.i(p,4))
+ p[0] = ServiceDefinition(Name(LU.i(p, 2)), LU.i(p, 4))
self.lh.set_parse_object(p[0], p)
# package_directive ::= 'package' ident [ '.' ident]* ';'
- def p_package_directive(self,p):
+ def p_package_directive(self, p):
'''package_directive : PACKAGE dotname SEMI'''
p[0] = PackageStatement(Name(LU.i(p, 2)))
self.lh.set_parse_object(p[0], p)
@@ -444,7 +552,7 @@
# import_directive = IMPORT_ - quotedString("importFileSpec") + SEMI
def p_import_directive(self, p):
'''import_directive : IMPORT STRING_LITERAL SEMI'''
- p[0] = ImportStatement(Literal(LU.i(p,2)))
+ p[0] = ImportStatement(Literal(LU.i(p, 2)))
self.lh.set_parse_object(p[0], p)
def p_option_rvalue(self, p):
@@ -455,20 +563,20 @@
def p_option_rvalue2(self, p):
'''option_rvalue : STRING_LITERAL'''
- p[0] = Literal(LU(p,1))
+ p[0] = Literal(LU(p, 1))
def p_option_rvalue3(self, p):
'''option_rvalue : NAME'''
- p[0] = Name(LU.i(p,1))
+ p[0] = Name(LU.i(p, 1))
# option_directive = OPTION_ - ident("optionName") + EQ + quotedString("optionValue") + SEMI
def p_option_directive(self, p):
'''option_directive : OPTION NAME EQ option_rvalue SEMI'''
- p[0] = OptionStatement(Name(LU.i(p, 2)), LU.i(p,4))
+ p[0] = OptionStatement(Name(LU.i(p, 2)), LU.i(p, 4))
self.lh.set_parse_object(p[0], p)
# topLevelStatement = Group(message_definition | message_extension | enum_definition | service_definition | import_directive | option_directive | package_definition)
- def p_topLevel(self,p):
+ def p_topLevel(self, p):
'''topLevel : message_definition
| message_extension
| enum_definition
@@ -496,7 +604,7 @@
# parser = Optional(package_directive) + ZeroOrMore(topLevelStatement)
def p_protofile(self, p):
'''protofile : statements'''
- p[0] = ProtoFile(LU.i(p,1))
+ p[0] = ProtoFile(LU.i(p, 1))
self.lh.set_parse_object(p[0], p)
# Parsing starting point
@@ -505,13 +613,18 @@
p[0] = p[2]
def p_error(self, p):
- raise ParsingError("Parsing Error", (p.lineno,p.lexpos,len(p.value)))
+ raise ParsingError("Parsing Error", (p.lineno, p.lexpos, len(p.value)))
+
class ProtobufAnalyzer(object):
def __init__(self):
self.lexer = lex.lex(module=ProtobufLexer())
- self.parser = yacc.yacc(module=ProtobufParser(), start='goal', debug=0, outputdir='/tmp')
+ self.parser = yacc.yacc(
+ module=ProtobufParser(),
+ start='goal',
+ debug=0,
+ outputdir='/tmp')
def tokenize_string(self, code):
self.lexer.input(code)
@@ -519,7 +632,7 @@
print(token)
def tokenize_file(self, _file):
- if type(_file) == str:
+ if isinstance(_file, str):
_file = file(_file)
content = ''
for line in _file:
@@ -532,7 +645,7 @@
return self.parser.parse(prefix + code, lexer=self.lexer, debug=debug)
def parse_file(self, _file, debug=0):
- if type(_file) == str:
+ if isinstance(_file, str):
_file = file(_file)
content = ''
for line in _file:
diff --git a/setup.py b/setup.py
index fd3cf5e..fa753ac 100644
--- a/setup.py
+++ b/setup.py
@@ -9,23 +9,21 @@
from setuptools import setup
-setup(name='plyxproto',
- version='3.0.0',
- description='xproto parser and processor',
- author='Dusan Klinec (original protobuf parser), Sapan Bhatia (xproto extensions)',
- author_email='sapan@opennetworking.org',
- url='https://github.com/sb98052/plyprotobuf',
- license='Apache Software License',
-
- classifiers=[
- 'Development Status :: 5 - Production/Stable',
- 'Intended Audience :: Developers',
- 'Topic :: Software Development :: Build Tools',
- 'License :: OSI Approved :: Apache Software License',
- 'Programming Language :: Python :: 2',
- 'Programming Language :: Python :: 2.7'
- ],
- keywords='xproto protobuf xos parser',
- packages=['plyxproto'],
- install_requires=['ply']
- )
+setup(
+ name='plyxproto',
+ version='3.0.0',
+ description='xproto parser and processor',
+ author='Dusan Klinec (original protobuf parser), Sapan Bhatia (xproto extensions), Zack Williams (maintenance)',
+ author_email='sapan@opennetworking.org',
+ url='https://github.com/sb98052/plyprotobuf',
+ license='Apache Software License',
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Intended Audience :: Developers',
+ 'Topic :: Software Development :: Build Tools',
+ 'License :: OSI Approved :: Apache Software License',
+ 'Programming Language :: Python :: 2',
+ 'Programming Language :: Python :: 2.7'],
+ keywords='xproto protobuf xos parser',
+ packages=['plyxproto'],
+ install_requires=['ply'])