return str(self.start)+": error: "+self.message
class SyntaxError(Error):
- def __init__(self, lexToken):
- Error.__init__(self, lexToken.lineno, lexToken.lineno, "syntax error "+str(lexToken.value))
+ def __init__(self, yaccSymbol):
+ if isinstance(yaccSymbol, yacc.YaccSymbol):
+ Error.__init__(self, yaccSymbol.lineno, yaccSymbol.lineno, "syntax error "+str(yaccSymbol.value))
+ else:
+ Error.__init__(self, 1, 1, "syntax error "+str(yaccSymbol))
class SymanticsError(Error):
result+="="+str(self.id)
return result
+
+def toCanonicalType(ttype):
+ if isinstance(ttype, TypeDef):
+ return toCanonicalType(ttype.definitionType)
+ else:
+ return ttype
+
+def isComparableType(ttype):
+ ttype = toCanonicalType(ttype)
+ return isinstance(ttype, PrimitiveType) or isinstance(ttype, Enum)
+
class Type(Definition):
""" Abstract Type definition """
def __init__(self, name):
Type.__init__(self, None, name)
-
STOP_TYPE = PrimitiveType("stop")
VOID_TYPE = PrimitiveType("void")
BOOL_TYPE = PrimitiveType("bool")
def __init__(self, symbols, name):
Type.__init__(self, symbols, name)
+ def validate(self):
+ return True
+
class Map(CollectionType):
def __init__(self, symbols, keyType, valueType):
self.keyType = keyType
self.valueType = valueType
+ def validate(self):
+ if not isComparableType(self.keyType):
+ raise ErrorException([SymanticsError(self, "key type \""+str(self.keyType)+"\" is not a comparable type.")])
+
class Set(CollectionType):
def __init__(self, symbols, valueType):
CollectionType.__init__(self, symbols, "set<"+valueType.name+">")
self.valueType = valueType
+ def validate(self):
+ if not isComparableType(self.valueType):
+ raise ErrorException([SymanticsError(self, "value type \""+str(self.valueType)+"\" is not a comparable type.")])
+
class List(CollectionType):
def __init__(self, symbols, valueType):
collection.keyType = self.getType(collection, collection.keyType)
collection.valueType = self.getType(collection, collection.valueType)
+
+ collection.validate()
except ErrorException, e:
errors+= e.errors
if len(errors):
raise ErrorException(errors)
-
class Parser(object):
p[0] = List(p, p[3])
def p_error(self, p):
- self.errors.append(SyntaxError(p))
+ # p_error is called with an empty token if eof was encountered unexpectedly.
+ if not p:
+ self.errors.append(SyntaxError("Unexpected end of file"))
+ else:
+ self.errors.append(SyntaxError(p))
def pdebug(self, name, p):
if self.debug: