📄 cparser.c
字号:
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 + -