#!python
""" Thrift IDL parser/compiler
    
    This parser uses the Python PLY LALR parser generator to build a parser for the Thrift IDL grammar.

    If a compiles \"thyc\" file exists for a given source \"thrift\" file it computes a hash of the file and determines
    if if it is the source of the \"thyc\" file.  If  so, it simply returns the parse tree previously computed, otherwise it
    parses the source and generates a new \"thyc\" file  (assuming of course the source file contains no errors.)

    When the parser encounters import statements it searches for corresponding \"thrift\" or \"thyc\" files in paths corresponding to
    the specified namespace.

    Author(s): Mark Slee(mclee@facebook.com), Marc Kwiatkowski (marc@facebook.com)

    $Id:
"""

import lex
import os
import pickle
import string
import yacc

class Error(object):

    def __init__(self, start=0, end=0, message=""):
	if len(message) == 0:
	    raise Exception, "NO MESSAGE"
	self.message = message
	self.start = start
	self.end = end
    
    def __str__(self):
	return str(self.start)+": error: "+self.message

class SyntaxError(Error):
    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):

    def __init__(self, definition, message):
	Error.__init__(self, definition.start, definition.end, message)
	self.definition = definition

    def __str__(self):
	return str(self.start)+": error: "+self.message

class ErrorException(Exception):

    def __init__(self, errors=None):
	self.errors = errors

class Definition(object):
    """ Abstract thrift IDL definition unit """

    def __init__(self, symbols=None, name="", id=None):
	if symbols:
	    self.lines(symbols)
	self.name = name
	self.id = id

    def validate(self):
	pass

    def lines(self, symbols):
	self.start = symbols.lineno(1)
	self.end = symbols.lineno(len(symbols) - 1)

class Identifier(Definition):
    """ An Identifier - name and optional integer id """

    def __init__(self, symbols, name, id=None):
	Definition.__init__(self, symbols, name, id)

    def __str__(self):
	result = self.name
	if self.id != 0:
	    result+="="+str(self.id)
	return result


def toCanonicalType(ttype):
    if isinstance(ttype, TypedefType):
	return toCanonicalType(ttype.definitionType)
    else:
	return ttype

def isComparableType(ttype):
    ttype = toCanonicalType(ttype)
    return isinstance(ttype, PrimitiveType) or isinstance(ttype, EnumType)

class Type(Definition):
    """ Abstract Type definition """

    def __init__(self, symbols, name):
	Definition.__init__(self, symbols, name)
	self.name = name

    def __str__(self):
	return self.name

class TypedefType(Type):

    def __init__(self, symbols, name, definitionType):
	Type.__init__(self, symbols, name)
	self.definitionType = definitionType

    def __str__(self):
	return self.name+"<"+str(self.name)+", "+str(self.definitionType)+">"

""" Primitive Types """

class PrimitiveType(Type):

    def __init__(self, name):
	Type.__init__(self, None, name)

STOP_TYPE =  PrimitiveType("stop")
VOID_TYPE =  PrimitiveType("void")
BOOL_TYPE = PrimitiveType("bool")
STRING_TYPE =PrimitiveType("utf7")
UTF7_TYPE = PrimitiveType("utf7")
UTF8_TYPE = PrimitiveType("utf8")
UTF16_TYPE = PrimitiveType("utf16")
BYTE_TYPE = PrimitiveType("u08")
I08_TYPE = PrimitiveType("i08")
I16_TYPE = PrimitiveType("i16")
I32_TYPE = PrimitiveType("i32")
I64_TYPE = PrimitiveType("i64")
U08_TYPE = PrimitiveType("u08")
U16_TYPE = PrimitiveType("u16")
U32_TYPE = PrimitiveType("u32")
U64_TYPE = PrimitiveType("u64")
FLOAT_TYPE = PrimitiveType("float")

PRIMITIVE_MAP = {
    "stop" : STOP_TYPE,
    "void" : VOID_TYPE,
    "bool" : BOOL_TYPE,
    "string": UTF7_TYPE,
    "utf7": UTF7_TYPE,
    "utf8": UTF8_TYPE,
    "utf16": UTF16_TYPE,
    "byte" : U08_TYPE,
    "i08": I08_TYPE,
    "i16": I16_TYPE,
    "i32": I32_TYPE,
    "i64": I64_TYPE,
    "u08": U08_TYPE,
    "u16": U16_TYPE,
    "u32": U32_TYPE,
    "u64": U64_TYPE,
    "float": FLOAT_TYPE
}

""" Collection Types """

class CollectionType(Type):

    def __init__(self, symbols, name):
	Type.__init__(self, symbols, name)

    def validate(self):
	return True

class MapType(CollectionType):

    def __init__(self, symbols, keyType, valueType):
	CollectionType.__init__(self, symbols, "map<"+keyType.name+","+valueType.name +">")
	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 SetType(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 ListType(CollectionType):

    def __init__(self, symbols, valueType):
	CollectionType.__init__(self, symbols, "list<"+valueType.name+">")
	self.valueType = valueType

class EnumType(Definition):

    def __init__(self, symbols, name, enumDefs):
	Definition.__init__(self, symbols, name)
	self.enumDefs = enumDefs

    def validate(self):
	ids = {}
	names = {}
	errors = []

	for enumDef in self.enumDefs:

	    if enumDef.name in names:
 		errors.append(SymanticsError(enumDef, self.name+"."+str(enumDef.name)+" already defined at line "+str(names[enumDef.name].start)))
	    else:
		names[enumDef.name] = enumDef

	    if enumDef.id != None:
		oldEnumDef = ids.get(enumDef.id)
		if oldEnumDef:
		    errors.append(SymanticsError(enumDef, "enum "+self.name+" \""+str(enumDef.name)+"\" uses constant already assigned to \""+oldEnumDef.name+"\""))
		else:
		    ids[enumDef.id] = enumDef
	
	if len(errors):
	    raise ErrorException(errors)

	def assignId(enumDef, currentId, ids):
	    'Finds the next available id number for an enum definition'

	    id= currentId + 1

	    while id in ids:
		id += 1
	    
	    enumDef.id = id

	    ids[enumDef.id] = enumDef

	# assign ids for all enum defs with unspecified ids
	
	currentId = 0
	
	for enumDef in self.enumDefs:
	    if not enumDef.id:
		assignId(enumDef, currentId, ids)
		currentId = enumDef.id

    def __repr__(self):
	return str(self)
	
    def __str__(self):
	return self.name+"<"+string.join(map(lambda enumDef: str(enumDef), self.enumDefs), ", ")

class EnumDef(Definition):

    def __init__(self, symbols, name, id=None):
	Definition.__init__(self, symbols, name, id)

    def __repr__(self):
	return str(self)

    def __str__(self):
	result = self.name
	if self.id:
	    result+= ":"+str(self.id)
	return result


class Field(Definition):

    def __init__(self, symbols, type, identifier):
	Definition.__init__(self, symbols, identifier.name, identifier.id)
	self.type = type
	self.identifier = identifier

    def __str__(self):
	return "<"+str(self.type)+", "+str(self.identifier)+">"

def validateFieldList(fieldList):

    errors = []
    names = {}
    ids = {}

    for field in fieldList:

	if field.name in names:
	    oldField = names[field.name]
	    errors.append(SymanticsError(field, "field \""+field.name+"\" already defined at "+str(oldField.start)))
	else:
	    names[field.name] = field

	if field.id != None:
	    oldField = ids.get(field.id)
	    if oldField:
		errors.append(SymanticsError(field, "field \""+field.name+"\" uses constant already assigned to \""+oldField.name+"\""))
	    else:
		ids[field.id] = field
	
    if len(errors):
	raise ErrorException(errors)

    def assignId(field, currentId, ids):
	'Finds the next available id number for a field'
	id = currentId - 1

	while id in ids:
	    id-= 1
	    
	field.id = id

	ids[field.id] = field
	
	return id

    # assign ids for all fields with unspecified ids
	
    currentId = 0
	
    for field in fieldList:
	if not field.id:
	    currentId = assignId(field, currentId, ids)
	
class StructType(Type):

    def __init__(self, symbols, name, fieldList):
	Type.__init__(self, symbols, name)
	self.fieldList = fieldList

    def validate(self):
	validateFieldList(self.fieldList)

    def __str__(self):
	return self.name+"<"+string.join(map(lambda a: str(a), self.fieldList), ", ")+">"

class Function(Definition):

    def __init__(self, symbols, name, resultStruct, argsStruct, ):
	Definition.__init__(self, symbols, name)
	self.resultStruct = resultStruct
	self.argsStruct = argsStruct

    def validate(self):
	validateFieldList(self.argsStruct.fieldList)

    def args(self):
	return self.argsStruct.fieldList

    def returnType(self):
	return self.resultStruct.fieldList[0].type
    
    def __str__(self):
	return self.name+"("+string.join(map(lambda a: str(a), self.argsStruct), ", ")+") => "+str(self.resultStruct)

class Service(Definition):

    def __init__(self, symbols, name, functionList):
	Definition.__init__(self, symbols, name)
	self.functionList = functionList

    def validate(self):

	errors = []
	functionNames = {}
	for function in self.functionList:
	    if function.name in functionNames:
		oldFunction = functionName[function.name]
		errors.append(SymanticsError(function, "function "+function.name+" already defined at "+str(oldFunction.start)))
	
	if len(errors):
	    raise ErrorException(errors)

    def __str__(self):
	return self.name+"("+string.join(map(lambda a: str(a), self.functionList), ", ")+")"

class Program(object):

    def __init__(self, symbols=None, name="", definitions=None, serviceMap=None, typedefMap=None, enumMap=None, structMap=None, collectionMap=None,
                 primitiveMap=None):

	self.name = name

        if not definitions:
            definitions = []
        self.definitions = definitions

	if not serviceMap:
	    serviceMap = {}
	self.serviceMap = serviceMap

	if not typedefMap:
	    typedefMap = {}
	self.typedefMap = typedefMap

	if not enumMap:
	    enumMap = {}
	self.enumMap = enumMap

	if not structMap:
	    structMap = {}
	self.structMap = structMap

	if not collectionMap:
	    collectionMap = {}
	self.collectionMap = collectionMap

	if not primitiveMap:
	    primitiveMap = PRIMITIVE_MAP
	self.primitiveMap = primitiveMap

    def addDefinition(self, definition, definitionMap, definitionTypeName):
	
	oldDefinition = definitionMap.get(definition.name)
	if oldDefinition:
	    raise ErrorException([SymanticsError(definition, definitionTypeName+" "+definition.name+" is already defined at "+str(oldDefinition.start))])
	else:
	    definitionMap[definition.name] = definition

        # keep an ordered list of definitions so that stub/skel generators can determine the original order

        self.definitions.append(definition)

    def addStruct(self, struct):
	self.addDefinition(struct, self.structMap, "struct")

    def addTypedef(self, typedef):
	self.addDefinition(typedef, self.typedefMap, "typedef")
	
    def addEnum(self, enum):
	self.addDefinition(enum, self.enumMap, "enum")

    def addService(self, service):
	self.addDefinition(service, self.serviceMap, "service")

    def addCollection(self, collection):
	if collection.name in self.collectionMap:
	    return self.collectionMap[collection.name]
	else:
	    self.collectionMap[collection.name] = collection
	    return collection

    def getType(self, parent, symbol):
	""" Get the type definition for a symbol"""
	
	typeName = None

	if isinstance(symbol, Type):
	    return symbol
	elif isinstance(symbol, Field):
	    typeName = symbol.type.name
	elif isinstance(symbol, Identifier):
	    typeName = symbol.name
	else:
	    raise ErrorException([SymanticsError(parent, "unknown symbol \""+str(symbol)+"\"")])

	for map in (self.primitiveMap, self.collectionMap, self.typedefMap, self.enumMap, self.structMap):
	    if typeName in map:
		return map[typeName]

	raise ErrorException([SymanticsError(parent, "\""+typeName+"\"  is not defined.")])

    def hasType(self, parent, symbol):
	""" Determine if a type definition exists for the symbol"""

        return self.getType(parent, symbol) == True

    def validate(self):

	errors = []

        # Verify that struct fields types, collection key and element types, and typedef defined types exists and replaces
        # type names with references to the type objects

	for struct in self.structMap.values():
	    for field in struct.fieldList:
		try:
		    field.type = self.getType(struct, field)
		except ErrorException, e:
		    errors+= e.errors

	for collection in self.collectionMap.values():
            try:
                if isinstance(collection, MapType):
                    collection.keyType = self.getType(collection, collection.keyType)

                collection.valueType = self.getType(collection, collection.valueType)
		
		collection.validate()
            
            except ErrorException, e:
                errors+= e.errors

	for typedef in self.typedefMap.values():
            try:
                typedef.definitionType = self.getType(self, typedef.definitionType)
            
            except ErrorException, e:
                errors+= e.errors

        # Verify that service function result and arg list types exist and replace type name with reference to definition

	for service in self.serviceMap.values():

	    for function in service.functionList:

		for field in function.resultStruct.fieldList:
		    try:
			field.type = self.getType(function, field)
		    except ErrorException, e:
			errors+= e.errors

		for field in function.argsStruct.fieldList:
		    try:
			field.type = self.getType(function, field)
		    except ErrorException, e:
			errors+= e.errors

	if len(errors):
	    raise ErrorException(errors)

class Parser(object):
    
    reserved = ("BYTE",
                # "CONST",
		"DOUBLE",
		"ENUM", 
                # "EXCEPTION",
                # "EXTENDS",
		"I08",
		"I16",
		"I32", 
		"I64",
		"LIST", 
		"MAP",
		"SERVICE", 
		"SET",
                # "STATIC",
		"STRING",
		"STRUCT", 
                # "SYNCHRONIZED",
		"TYPEDEF",
		"U08", 
		"U16",
		"U32", 
		"U64", 
		"UTF16",
		"UTF8",
		"VOID"
                )

    tokens = reserved + (
	# Literals (identifier, integer constant, float constant, string constant, char const)
	'ID', 'ICONST', 'SCONST', 'FCONST', 
	# Operators default=, optional*, variable...
	'ASSIGN',  #'OPTIONAL', 'ELLIPSIS',
	# Delimeters ( ) { } < > , . ; :
	'LPAREN', 'RPAREN',
	'LBRACE', 'RBRACE',
	'LANGLE', 'RANGLE',
	'COMMA' #, 'PERIOD', 'SEMI' , 'COLON'
	)

    precendence = ()

    reserved_map = {}

    for r in reserved:
	reserved_map[r.lower()] = r

    def t_ID(self, t):
	r'[A-Za-z_][\w_]*'
	t.type = self.reserved_map.get(t.value,"ID")
	return t
    
    # Completely ignored characters
    t_ignore           = ' \t\x0c'
    
#    t_OPTIONAL         = r'\*'
    t_ASSIGN           = r'='
	
    # Delimeters
    t_LPAREN           = r'\('
    t_RPAREN           = r'\)'
    t_LANGLE           = r'\<'
    t_RANGLE           = r'\>'
    t_LBRACE           = r'\{'
    t_RBRACE           = r'\}'
    t_COMMA            = r','
#    t_PERIOD           = r'\.'
#    t_SEMI             = r';'
#    t_COLON            = r':'
#    t_ELLIPSIS         = r'\.\.\.'
    
    # Integer literal
    t_ICONST = r'\d+([uU]|[lL]|[uU][lL]|[lL][uU])?'

    # Floating literal
    t_FCONST = r'((\d+)(\.\d+)(e(\+|-)?(\d+))? | (\d+)e(\+|-)?(\d+))([lL]|[fF])?'

    # String literal
    t_SCONST = r'\"([^\\\n]|(\\.))*?\"'

    # Comments
    def t_comment(self, t):
	r'(?:/\*(.|\n)*?\*/)|(?://[^\n]*\n)'
	t.lineno += t.value.count('\n')
	    
    def t_error(self, t):
	print "Illegal character %s" % repr(t.value[0])
	t.skip(1)

    # Newlines
    def t_newline(self, t):
	r'\n+'
	t.lineno += t.value.count("\n")
	
    def p_program(self, p):
	'program : definitionlist'
	pass
    
    def p_definitionlist_1(self, p):
	'definitionlist : definitionlist definition'
	pass

    def p_definitionlist_2(self, p):
	'definitionlist :'
	pass
    
    def p_definition_1(self, p):
	'definition : typedef'
	self.pdebug("p_definition_1", p)
	p[0] = p[1]
	try:
	    self.program.addTypedef(p[0])
	except ErrorException, e:
	    self.errors+= e.errors

    def p_definition_2(self, p):
	'definition : enum'
	self.pdebug("p_definition_2", p)
	p[0] = p[1]
	try:
	    self.program.addEnum(p[0])
	except ErrorException, e:
	    self.errors+= e.errors
    
    def p_definition_3(self, p):
	'definition : struct'
	self.pdebug("p_definition_3", p)
	p[0] = p[1]
	try:
	    self.program.addStruct(p[0])
	except ErrorException, e:
	    self.errors+= e.errors
    
    def p_definition_4(self, p):
	'definition : service'
	self.pdebug("p_definition_4", p)
	p[0] = p[1]
	try:
	    self.program.addService(p[0])
	except ErrorException, e:
	    self.errors+= e.errors

    def p_typedef(self, p):
	'typedef : TYPEDEF definitiontype ID'
	self.pdebug("p_typedef", p)
	p[0] = TypedefType(p, p[3], p[2])
	try:
	    p[0].validate()

	except ErrorException, e:
	    self.errors+= e.errors

    def p_enum(self, p):
	'enum : ENUM ID LBRACE enumdeflist RBRACE'
	self.pdebug("p_enum", p)
	p[0] = EnumType(p, p[2], p[4])

	try:
	    p[0].validate()
	except ErrorException, e:
	    self.errors+= e.errors
	
    def p_enumdeflist_1(self, p):
	'enumdeflist : enumdeflist COMMA enumdef'
	self.pdebug("p_enumdeflist_1", p)
	p[0] = p[1] + (p[3],)

    def p_enumdeflist_2(self, p):
	'enumdeflist : enumdef' 
	self.pdebug("p_enumdeflist_2", p)
	p[0] = (p[1],)

    def p_enumdef_0(self, p):
	'enumdef : ID ASSIGN ICONST'
	self.pdebug("p_enumdef_0", p)
	p[0] = EnumDef(p, p[1], int(p[3]))

    def p_enumdef_1(self, p):
	'enumdef : ID'
	self.pdebug("p_enumdef_1", p)
	p[0] = EnumDef(p, p[1])

    def p_struct(self, p):
	'struct :  STRUCT ID LBRACE fieldlist RBRACE'
	self.pdebug("p_struct", p)
	p[0] = StructType(p, p[2], p[4])

	try:
	    p[0].validate()
	except ErrorException, e:
	    self.errors+= e.errors

    def p_service(self, p):
	'service : SERVICE ID LBRACE functionlist RBRACE'
	self.pdebug("p_service", p)
	p[0] =  Service(p, p[2], p[4])
	try:
	    p[0].validate()
	except ErrorException, e:
	    self.errors+= e.errors

    def p_functionlist_1(self, p):
        'functionlist : functionlist function'
	self.pdebug("p_functionlist_1", p)
	p[0] = p[1] + (p[2],)

    def p_functionlist_2(self, p):
        'functionlist :'
	self.pdebug("p_functionlist_2", p)
	p[0] = ()

    def p_function(self, p):
	'function : functiontype functionmodifiers ID LPAREN fieldlist RPAREN'
	self.pdebug("p_function", p)

	resultStruct = StructType(p, p[3]+"_result", (Field(p, p[1], Identifier(None, "success", 1)),))
	
	p[0] = Function(p, p[3], resultStruct, StructType(p, p[3]+"_args", p[5]))
	try:
	    p[0].validate()
	except ErrorException, e:
	    self.errors+= e.errors

    def p_functionmodifiers(self, p):
	'functionmodifiers :'
	self.pdebug("p_functionmodifiers", p)
	p[0] = ()

    def p_fieldlist_1(self, p):
	'fieldlist : fieldlist COMMA field'
	self.pdebug("p_fieldlist_1", p)
	p[0] = p[1] + (p[3],)

    def p_fieldlist_2(self, p):
	'fieldlist : field'
	self.pdebug("p_fieldlist_2", p)
	p[0] = (p[1],)

    def p_fieldlist_3(self, p):
	'fieldlist :'
	self.pdebug("p_fieldlist_3", p)
	p[0] = ()

    def p_field_1(self, p):
        'field : fieldtype ID ASSIGN ICONST'
	self.pdebug("p_field_1", p)
	p[0] = Field(p, p[1], Identifier(None, p[2], int(p[4])))

    def p_field_2(self, p):
        'field : fieldtype ID'
	self.pdebug("p_field_2", p)
	p[0] = Field(p, p[1], Identifier(None, p[2]))

    def p_definitiontype_1(self, p):
        'definitiontype : basetype'
	self.pdebug("p_definitiontype_1", p)
	p[0] = p[1]

    def p_definitiontype_2(self, p):
        'definitiontype : collectiontype'
	self.pdebug("p_definitiontype_2", p)
	p[0] = p[1]

    def p_functiontype_1(self, p):
        'functiontype : fieldtype'
	self.pdebug("p_functiontype_1", p)
	p[0] = p[1]
		   
    def p_functiontype_2(self, p):
        'functiontype : VOID'
	self.pdebug("p_functiontype_2", p)
	p[0] = self.program.primitiveMap[p[1].lower()]

    def p_fieldtype_1(self, p):
        'fieldtype : ID'
	self.pdebug("p_fieldtype_1", p)
	p[0] = Identifier(p, p[1])

    def p_fieldtype_2(self, p):
        'fieldtype : basetype'
	self.pdebug("p_fieldtype_2", p)
	p[0] = p[1]

    def p_fieldtype_3(self, p):
        'fieldtype : collectiontype'
	self.pdebug("p_fieldtype_3", p)
	p[0] = p[1]

    def p_basetype_1(self, p):
        'basetype : STRING'
	self.pdebug("p_basetype_1", p)
	p[0] = self.program.primitiveMap[p[1].lower()]

    def p_basetype_2(self, p):
        'basetype : BYTE'
	self.pdebug("p_basetype_2", p)
	p[0] = self.program.primitiveMap[p[1].lower()]

    def p_basetype_3(self, p):
        'basetype : I08'
	self.pdebug("p_basetype_3", p)
	p[0] = self.program.primitiveMap[p[1].lower()]

    def p_basetype_4(self, p):
        'basetype : U08'
	self.pdebug("p_basetype_4", p)
	p[0] = self.program.primitiveMap[p[1].lower()]

    def p_basetype_5(self, p):
        'basetype : I16'
	self.pdebug("p_basetype_5", p)
	p[0] = self.program.primitiveMap[p[1].lower()]

    def p_basetype_6(self, p):
        'basetype : U16'
	self.pdebug("p_basetype_6", p)
	p[0] = self.program.primitiveMap[p[1].lower()]

    def p_basetype_7(self, p):
        'basetype : I32'
	self.pdebug("p_basetype_7", p)
	p[0] = self.program.primitiveMap[p[1].lower()]

    def p_basetype_8(self, p):
        'basetype : U32'
	self.pdebug("p_basetype_8", p)
	p[0] = self.program.primitiveMap[p[1].lower()]

    def p_basetype_9(self, p):
        'basetype : I64'
	self.pdebug("p_basetype_9", p)
	p[0] = self.program.primitiveMap[p[1].lower()]

    def p_basetype_10(self, p):
        'basetype : U64'
	self.pdebug("p_basetype_10", p)
	p[0] = self.program.primitiveMap[p[1].lower()]

    def p_basetype_11(self, p):
        'basetype : UTF8'
	self.pdebug("p_basetype_11", p)
	p[0] = self.program.primitiveMap[p[1].lower()]

    def p_basetype_12(self, p):
        'basetype : UTF16'
	self.pdebug("p_basetype_12", p)
	p[0] = self.program.primitiveMap[p[1].lower()]

    def p_basetype_13(self, p):
        'basetype : DOUBLE'
	self.pdebug("p_basetype_13", p)
	p[0] = self.program.primitiveMap[p[1].lower()]

    def p_collectiontype_1(self, p):
        'collectiontype : maptype'
	self.pdebug("p_collectiontype_1", p)
	p[0] = self.program.addCollection(p[1])

    def p_collectiontype_2(self, p):
        'collectiontype : settype'
	self.pdebug("p_collectiontype_2", p)
	p[0] = self.program.addCollection(p[1])

    def p_collectiontype_3(self, p):
        'collectiontype : listtype'
	self.pdebug("p_collectiontype_3", p)
	p[0] = self.program.addCollection(p[1])

    def p_maptype(self, p):
        'maptype : MAP LANGLE fieldtype COMMA fieldtype RANGLE'
	self.pdebug("p_maptype", p)
	p[0] = MapType(p, p[3], p[5])

    def p_settype(self, p):
        'settype : SET LANGLE fieldtype RANGLE'
	self.pdebug("p_settype", p)
	p[0] = SetType(p, p[3])

    def p_listtype(self, p):
        'listtype : LIST LANGLE fieldtype RANGLE'
	self.pdebug("p_listtype", p)
	p[0] = ListType(p, p[3])

    def p_error(self, 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:
	    print(name+"("+string.join(map(lambda t: "<<"+str(t)+">>", p), ", ")+")")

    def __init__(self, **kw):
        self.debug = kw.get('debug', 0)
        self.names = { }
	self.program = Program()
	self.errors = []

        try:
            modname = os.path.split(os.path.splitext(__file__)[0])[1] + "_" + self.__class__.__name__
        except:
            modname = "parser"+"_"+self.__class__.__name__
        self.debugfile = modname + ".dbg"
        self.tabmodule = modname + "_" + "parsetab"
        #print self.debugfile, self.tabmodule

        # Build the lexer and parser
        lex.lex(module=self, debug=self.debug)
        yacc.yacc(module=self,
                  debug=self.debug,
                  debugfile=self.debugfile,
                  tabmodule=self.tabmodule)

    def parsestring(self, s, filename=""):
	yacc.parse(s)

	if len(self.errors) == 0:
	    try:
		self.program.validate()
	    except ErrorException, e:
		self.errors+= e.errors
	    
	if len(self.errors):
	    for error in self.errors:
		print(filename+":"+str(error))

    def parse(self, filename, doPickle=True):

	f = file(filename, "r")

	self.parsestring(f.read(), filename)

        if len(self.errors) == 0 and doPickle:

	    outf = file(os.path.splitext(filename)[0]+".thyc", "w")

	    pickle.dump(self.program, outf)
