⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cparser.c

📁 3D游戏场景编辑器
💻 C
📖 第 1 页 / 共 2 页
字号:
		case	KW_VOID:
			if	(publishing)
				CParser_Error(p, ERR_SYNTAXERROR);
			ScanExpecting(p, &t, TK_STAR);
			CParser_ParsePrivatePtrDecl(p, tp, &t);
			break;

		case	KW_INT:
		case	KW_FLOAT:
		case	KW_GE_FLOAT:
		case	KW_GE_RGB:
		case	KW_VEC3D:
		case	KW_BOOLEAN:
			fieldTp = Type_FindTypeByName(p->cpTypes, t.tIden);
			if	(!fieldTp)
				CParser_Error(p, ERR_UNDEFINEDTYPE, t.tIden->idenSpelling);
			Scanner_Scan(p->cpScanner, &t);
			if	(t.tKind == TK_STAR)
			{
				if	(publishing)
					CParser_Error(p, ERR_SYNTAXERROR, t.tIden->idenSpelling);
				else
					CParser_ParsePrivatePtrDecl(p, tp, &t);
			}
			else if	(t.tKind == TK_IDEN)
			{
				fieldSym = SymTab_CreateSymbol(p->cpSymbolTable, tp->tpScope, t.tIden, fieldTp);
				Type_AddTypeField(tp, fieldSym, (unsigned short)(publishing ? F_TF_PUBLISHED : 0));
				ScanExpecting(p, &t, TK_SEMI);
			}
			else
			{
				CParser_Error(p, ERR_SYNTAXERROR, t.tIden->idenSpelling);
			}
			break;

		case	KW_GE_MODEL:
			ScanExpecting(p, &t, TK_STAR);
			ScanExpecting(p, &t, TK_IDEN);
			fieldTp = Type_FindTypeByName(p->cpTypes, Iden_HashName(p->cpIdenHashTable, "<model>", 7));
			if	(!fieldTp)
				CParser_Error(p, ERR_UNDEFINEDTYPE, "<model>");
			fieldSym = SymTab_CreateSymbol(p->cpSymbolTable, tp->tpScope, t.tIden, fieldTp);
			Type_AddTypeField(tp, fieldSym, (unsigned short)(publishing ? F_TF_PUBLISHED : 0));
			ScanExpecting(p, &t, TK_SEMI);
			break;

		case	KW_CHAR:
			ScanExpecting(p, &t, TK_STAR);
			ScanExpecting(p, &t, TK_IDEN);
			fieldTp = Type_FindTypeByName(p->cpTypes, Iden_HashName(p->cpIdenHashTable, "<string>", 8));
			if	(!fieldTp)
				CParser_Error(p, ERR_UNDEFINEDTYPE, "<string>");
			fieldSym = SymTab_CreateSymbol(p->cpSymbolTable, tp->tpScope, t.tIden, fieldTp);
			Type_AddTypeField(tp, fieldSym, (unsigned short)(publishing ? F_TF_PUBLISHED : 0));
			ScanExpecting(p, &t, TK_SEMI);
			break;

		default:
			CParser_Error(p, ERR_SYNTAXERROR);
			break;
		}
	}
}

static	void	CParser_ParseType(CParser *p, const char *typeIcon)
{
	Scanner_Token	t;

	Scanner_Scan(p->cpScanner, &t);
	if	(t.tIden->idenKeyword == KW_STRUCT)
		CParser_ParseStruct(p, typeIcon);
}

int	CParser_GetContentsCount(const CParser *p)
{
	assert(p);
	return p->cpBrushContentsCount;
}

void	CParser_GetContentsNameAndValue(const CParser *p, int idx, const char **Name, unsigned long *Value)
{
	assert(p);
	assert(p->cpBrushContents);
	assert(idx < p->cpBrushContentsCount);

	*Name = p->cpBrushContents[idx].Name->idenSpelling;
	*Value = p->cpBrushContents[idx].Value;
}

static	int	CheckBitMask(unsigned long Value, unsigned long Mask)
{
	int	i;
	int	BitCount;

	if	(!(Value & Mask))
		return 0;

	BitCount = 0;
	for	(i = 0; i < sizeof(Value) * 8; i++)
	{
		if	(Value & 1)
			BitCount++;
		Value = Value >> 1;
	}

	if	(BitCount > 1)
		return 0;

	return 1;
}

static	void	CParser_ParseContentsEnum(CParser *p)
{
	Scanner_Token	t;

	Scanner_Scan(p->cpScanner, &t);
	if	(t.tIden->idenKeyword != KW_ENUM)
		CParser_Error(p, ERR_EXPECTEDENUM);

	ScanExpecting(p, &t, TK_LBRACE);
	while	(t.tKind != TK_EOF && t.tKind != TK_ERROR && t.tKind != TK_RBRACE)
	{
		CParser_BrushEnumValue *	NewValues;
		int							idx;
		Iden *						Name;
		int							i;
		unsigned long				Value;

		Scanner_Scan(p->cpScanner, &t);
		if	(t.tKind == TK_RBRACE)
			break;

		if	(t.tKind != TK_IDEN)
			CParser_Error(p, ERR_SYNTAXERROR);
		Name = t.tIden;

		ScanExpecting(p, &t, TK_EQUAL);

		ScanExpecting(p, &t, TK_ICON);
		Value = (unsigned long)t.tICONValue;

		Scanner_Scan(p->cpScanner, &t);
		if	(t.tKind != TK_COMMA && t.tKind != TK_RBRACE)
			CParser_Error(p, ERR_SYNTAXERROR);

		/*
			Make sure that we're in the user mask range, and that there's
			only one bit set.
		*/
		if	(!CheckBitMask(t.tICONValue, CONTENTS_USER_MASK))
			CParser_Error(p, ERR_VALUENOTINRANGE);

		/*
			Check to see if we already have a name that's the same or a value
			that's the same.
		*/
		for	(i = 0; i < p->cpBrushContentsCount; i++)
		{
			if	(Name == p->cpBrushContents[i].Name)
				CParser_Error(p, ERR_BADREDEFINITION);

			if	((unsigned long)t.tICONValue == p->cpBrushContents[i].Value)
				CParser_Error(p, ERR_VALUEUSEDTWICE);
		}

		NewValues = geRam_Realloc(p->cpBrushContents,
								  sizeof(*p->cpBrushContents) * (p->cpBrushContentsCount + 1));
		if	(!NewValues)
			CParser_Error(p, ERR_OUTOFMEMORY);

		p->cpBrushContents = NewValues;
		idx = p->cpBrushContentsCount;
		p->cpBrushContentsCount++;

		p->cpBrushContents[idx].Name	= Name;
		p->cpBrushContents[idx].Value	= t.tICONValue;
	}

	if	(t.tKind != TK_RBRACE)
		CParser_Error(p, ERR_EXPECTEDRBRACE);

	ScanExpecting(p, &t, TK_IDEN);
	ScanExpecting(p, &t, TK_SEMI);
}

static	void	CParser_Parse(CParser *p)
{
	Scanner_Token	t;
	int				parseType;
	int				parseContents;
	char 			typeIcon[MAXPATH];

	if	(setjmp(parserError) != 0)
		return;

	parseType = 0;
	parseContents = 0;
	do
	{
		Scanner_Scan(p->cpScanner, &t);
//		printf("%03d", CScanner_CurrentLine(p->cpScanner));
//		printToken(&t);
		if	(t.tKind == TK_SHARP)
		{
			ScanExpecting(p, &t, TK_IDEN);
			if	(t.tIden->idenKeyword != KW_PRAGMA)
				continue;
			ScanExpecting(p, &t, TK_IDEN);
			if	(!strcmp(t.tIden->idenSpelling, "GE_Type"))
			{
				ScanExpecting(p, &t, TK_LPAREN);
				ScanExpecting(p, &t, TK_LITERALSTRING);
				strcpy(typeIcon, t.tTokenData);
				ScanExpecting(p, &t, TK_RPAREN);
				parseType = 1;
			}

			if	(!strcmp(t.tIden->idenSpelling, "GE_BrushContents"))
			{
				assert(!parseType);
				parseContents = 1;
			}
			Scanner_Scan(p->cpScanner, &t);
		}
		if	(t.tKind != TK_IDEN)
		{
			parseType = 0;
			continue;
		}
		switch	(t.tIden->idenKeyword)
		{
		case	KW_NOTAKEYWORD:
			break;

		case	KW_TYPEDEF:
			if	(parseType)
			{
				parseType = 0;
				CParser_ParseType(p, typeIcon);
			}
			if	(parseContents)
			{
				parseContents = 0;
				CParser_ParseContentsEnum(p);
			}
			break;

		default:
			break;
		}
	}	while	(t.tKind != TK_EOF);
}

void		CParser_ParseFile(CParser *p, const char *file)
{
	assert (p != NULL);
	assert (p->cpScanner != NULL);
	assert (file != NULL);

	if (Scanner_InitFile (p->cpScanner, file, SCANNER_FILE_TEXT, p->cpIdenHashTable))
	{
		CParser_Parse(p);
		Scanner_Uninit (p->cpScanner);
	}
}

void		CParser_ParseMemoryBlock (CParser *p, const char *Block, int length, const char *Name)
{
	assert (p != NULL);
	assert (Block != NULL);
	assert (length >= 0);
	assert (p->cpScanner != NULL);

	if (Scanner_InitMemory (p->cpScanner, Block, length, Name, p->cpIdenHashTable))
	{
		CParser_Parse (p);
		Scanner_Uninit (p->cpScanner);
	}
}

#ifdef	ELIDEBUG
static	void	DumpTypes(Type *tp)
{
	while	(tp)
	{
		Type_DumpType(tp, 1);
		printf("\n");
		tp = tp->tpNext;
	}
}
#endif

Type *		CParser_GetFirstStruct(StructIter *iter, CParser *p)
{
	Type *	tp;

	memset(iter, 0, sizeof(*iter));

	tp = p->cpTypes;
	while	(tp)
	{
		if	(tp->tpTopType == T_STRUCT)
		{
			iter->siType = tp;
			return tp;
		}
		tp = tp->tpNext;
	}
	return NULL;
}

Type *		CParser_GetNextStruct(StructIter *iter)
{
	Type *	tp;

	tp = iter->siType->tpNext;
	while	(tp)
	{
		if	(tp->tpTopType == T_STRUCT)
		{
			iter->siType = tp;
			return tp;
		}
		tp = tp->tpNext;
	}
	iter->siType = tp;
	return NULL;
}

int			CParser_GetFirstField(FieldIter *fi, Type *tp, TopType *tt, const char **tpName, const char **fName, int *published, const char **defaultValue)
{
	assert(tp->tpTopType == T_STRUCT);
	fi->fiCurrentField = tp->t.s.tpFields;
	if	(!fi->fiCurrentField)
		return 0;

	tp = fi->fiCurrentField->tfSymbol->symType;

	if	(tp->tpTopType == T_PTR && tp->t.p.tpPtrType->tpTopType == T_STRUCT)
	{
		tp = tp->t.p.tpPtrType;
		assert(tp->tpTopType == T_STRUCT);
		*tpName = tp->tpName->idenSpelling;
	}
	else
		*tpName = NULL;

	*tt = tp->tpTopType;

	*fName = fi->fiCurrentField->tfSymbol->symName->idenSpelling;

	*published = fi->fiCurrentField->tfFlags & F_TF_PUBLISHED;

	*defaultValue = fi->fiCurrentField->tfDefaultValue;

	return 1;
}

int			CParser_GetNextField(FieldIter *fi, TopType *tt, const char **tpName, const char **fName, int *published, const char **defaultValue)
{
	Type *	tp;

	fi->fiCurrentField = fi->fiCurrentField->tfNext;
	if	(!fi->fiCurrentField)
		return 0;


	tp = fi->fiCurrentField->tfSymbol->symType;

	if	(tp->tpTopType == T_PTR && tp->t.p.tpPtrType->tpTopType == T_STRUCT)
	{
		tp = tp->t.p.tpPtrType;
		assert(tp->tpTopType == T_STRUCT);
		*tpName = tp->tpName->idenSpelling;
	}
	else
		*tpName = NULL;

	*tt = tp->tpTopType;

	*fName = fi->fiCurrentField->tfSymbol->symName->idenSpelling;

	*published = fi->fiCurrentField->tfFlags & F_TF_PUBLISHED;

	*defaultValue = fi->fiCurrentField->tfDefaultValue;

	return 1;
}

const char *CParser_GetTypeName(const Type *tp)
{
	assert(tp->tpTopType == T_STRUCT);
	return tp->tpName->idenSpelling;
}

static	char *	topTypeNames[] =
{
	"int",
	"float",
	"color",
	"point",
	"string",
	"model",
	"ptr",
	"struct",
};

static	void	WriteInt(FILE *fp, int i)
{
	fwrite(&i, 4, 1, fp);
}

static	void	WriteString(FILE *fp, const char *s)
{
	int	len;

	len = strlen(s);

	WriteInt(fp, len);
	fwrite(s, len, 1, fp);
}

int	CParser_WriteTypesToMap(CParser *p, FILE *fp)
{
	StructIter	si;
	FieldIter	fi;
	Type *		tp;

	tp = CParser_GetFirstStruct(&si, p);
	while	(tp)
	{
		int				res;
		int				published;
		TopType			tt;
		const char *	typeName;
		const char *	fieldName;
		const char *	defaultValue;
		int				fieldCount;

		res = CParser_GetFirstField(&fi, tp, &tt, &typeName, &fieldName, &published, &defaultValue);

		fieldCount = 0;
		while	(res)
		{
			fieldCount++;
			res = CParser_GetNextField(&fi, &tt, &typeName, &fieldName, &published, &defaultValue);
		}

		assert(fieldCount != 0);

		/* Adjust for default value pairs and 2 special fields */
		fieldCount = fieldCount * 2 + 2;

		/* Write out num brushes */
		WriteInt(fp, 0);
		/* Write out model motion flag */
		WriteInt(fp, 0);
		/* Write out num fields */
		WriteInt(fp, fieldCount);
		
		/* Write special classname and %typename% fields */
		WriteString(fp, "classname");
		WriteString(fp, "%typedef%");
		WriteString(fp, "%typename%");
		WriteString(fp, CParser_GetTypeName(tp));

		res = CParser_GetFirstField(&fi, tp, &tt, &typeName, &fieldName, &published, &defaultValue);
		while	(res)
		{
			switch (tt)
			{
				case T_STRUCT :
					WriteString(fp, fieldName);
					WriteString(fp, typeName);
					WriteString(fp, "%defaultvalue%");
					WriteString(fp, "");
					break;

				// we treat booleans as if they are ints...
				case T_BOOLEAN :
					WriteString(fp, fieldName);
					WriteString(fp, "int");
					WriteString(fp, "%defaultvalue%");
					WriteString(fp, "");
					break;

				default :
					WriteString(fp, fieldName);
					WriteString(fp, topTypeNames[tt]);
					WriteString(fp, "%defaultvalue%");
					WriteString(fp, "");
					break;
			}
			res = CParser_GetNextField(&fi, &tt, &typeName, &fieldName, &published, &defaultValue);
		}
		tp = CParser_GetNextStruct(&si);
	}

	return 1;
}

const char *	CParser_GetOriginFieldName(Type *tp)
{
	if	(tp->tpOriginField)
		return tp->tpOriginField->tfSymbol->symName->idenSpelling;

	return NULL;
}

const char *	CParser_GetRadiusFieldName(Type *tp)
{
	if (tp->tpRadiusField)
		return tp->tpRadiusField->tfSymbol->symName->idenSpelling;
	return NULL;
}

const char *	CParser_GetAnglesFieldName(Type *tp)
{
	if (tp->tpAnglesField)
		return tp->tpAnglesField->tfSymbol->symName->idenSpelling;
	return NULL;
}

const char *	CParser_GetArcFieldName(Type *tp)
{
	if (tp->tpArcField)
		return tp->tpArcField->tfSymbol->symName->idenSpelling;
	return NULL;
}

const char *	CParser_GetTypeFieldDocumentation(CParser *p, Type *tp, const char *FieldName)
{
	Iden *	id;

	assert(p != NULL);
	assert(tp != NULL);
	assert(FieldName != NULL);

	id = Iden_HashName(p->cpIdenHashTable, FieldName, strlen(FieldName));
	return Type_GetFieldDocumentation(tp, id);
}

const char *	CParser_GetIconName (Type *pType)
{
	return pType->t.s.tpIcon;
}

#if 0
// Testing code
static	char *	topTypeNames[] =
{
	"int",
	"float",
	"color",
	"point",
	"string",
	"model",
	"ptr",
	"struct",
};

void	main(void)
{
	CParser *	p;
	StructIter	si;
	FieldIter	fi;
	Type *		tp;

	p = CParser_Init();

	CParser_ParseFile(p, "foo.h");
//	DumpTypes(p->cpTypes);

	tp = CParser_GetFirstStruct(&si, p);
	while	(tp)
	{
		int				res;
		TopType			tt;
		const char *	typeName;
		const char *	fieldName;

		printf("%s\n{\n", CParser_GetTypeName(tp));

		res = CParser_GetFirstField(&fi, tp, &tt, &typeName, &fieldName);
		while	(res)
		{
			if	(tt == T_STRUCT)
				printf("\t%s\t%s\n", typeName, fieldName);
			else
				printf("\t%s\t%s\n", topTypeNames[tt], fieldName);
			res = CParser_GetNextField(&fi, &tt, &typeName, &fieldName);
		}
		printf("}\n\n");
		tp = CParser_GetNextStruct(&si);
	}
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -