提交 2d05f988 创建 作者: 赵鹏翀's avatar 赵鹏翀

init template

上级
添加文件
/Debug
/Release
<?xml version="1.0" encoding="gb2312"?>
<OSLProject Version="1.00" Name="PickupLeftFactor" SubjectID="11c951f4-9b13-40e1-8b73-39ba7d73b89b" ProjectTemplateID="fd7b8f4b-7528-4253-80dc-138ee36bc953">
<Configurations>
<Configuration Name="Debug">
<Tool Name="PreBuildEventTool"/>
<Tool Name="CustomBuildTool"/>
<Tool Name="GCCCompilerTool" PreprocessorDefinitions="_DEBUG" GenerateDebugInformation="-1"/>
<Tool Name="PreLinkEventTool"/>
<Tool Name="GCCLinkerTool" AdditionalDependencies="&quot;$(CPLInstallDir)Dump\lib\PickupLeftFactor_Demo.o&quot;"/>
<Tool Name="PostBuildEventTool"/>
<VisualContext>
<WatchPoints>
<WatchPoint FunctionName="PickupLeftFactor" ObserverID="909D0AA6-53A4-4383-991F-9C202552E5E4">
</WatchPoint>
</WatchPoints>
</VisualContext>
</Configuration>
<Configuration Name="Release">
<Tool Name="PreBuildEventTool"/>
<Tool Name="CustomBuildTool"/>
<Tool Name="GCCCompilerTool" PreprocessorDefinitions="NDEBUG"/>
<Tool Name="PreLinkEventTool"/>
<Tool Name="GCCLinkerTool"/>
<Tool Name="PostBuildEventTool"/>
</Configuration>
</Configurations>
<Files>
<Filter Name="ͷļ" Filter="h;hpp;hxx">
<File RelativePath=".\PickupLeftFactor.h">
</File>
</Filter>
<Filter Name="Դļ" Filter="cpp;c;cc;cxx">
<File RelativePath=".\main.c">
</File>
</Filter>
</Files>
</OSLProject>
#ifndef _PICKUPLEFTFACTOR_H_
#define _PICKUPLEFTFACTOR_H_
//
// 在此处包含 C 标准库头文件
//
#include <stdio.h>
//
// 在此处包含其他头文件
//
//
// 在此处定义数据结构
//
#define MAX_STR_LENGTH 64
struct _Rule;
typedef struct _RuleSymbol{
struct _RuleSymbol* pNextSymbol; // 指向下一个 Symbol
struct _RuleSymbol* pOther; // 指向下一个 Select
int isToken; // 是否为终结符。1 表示终结符,0 表示非终结符
char TokenName[MAX_STR_LENGTH]; // 终结符的名称。isToken 为 1 时这个域有效
struct _Rule* pRule; // 指向 Symbol 对应的 Rule。isToken 为 0 时这个域有效
}RuleSymbol;
typedef struct _Rule{
char RuleName[MAX_STR_LENGTH]; // 文法的名称
struct _RuleSymbol* pFirstSymbol; // 指向文法的第一个 Select 的第一个 Symbol
struct _Rule* pNextRule; // 指向下一条文法
}Rule;
//
// 在此处声明函数
//
RuleSymbol* GetSymbol(RuleSymbol* pSelect, int index);
int LeftFactorMaxLength(RuleSymbol* pSelectTemplate);
int SymbolCmp(RuleSymbol* pRuleSymbol1, RuleSymbol* pRuleSymbol2);
int NeedPickup(RuleSymbol* pSelectTemplate, int Count, RuleSymbol* pSelect);
void AddSelectToRule(Rule* pRule, RuleSymbol* pRuleSymbol);
void GetUniqueRuleName(Rule* pHead, char* pRuleName);
void PickupLeftFactor(Rule* pHead);
void FreeSelect(RuleSymbol* pSelect);
Rule* InitRules();
Rule* CreateRule(const char* pRuleName);
RuleSymbol* CreateSymbol();
Rule* FindRule(Rule* pHead, const char* RuleName);
void PrintRule(Rule* pHead);
//
// 在此声明全局变量
//
extern const char* VoidSymbol;
extern const char* Postfix;
#endif /* _PICKUPLEFTFACTOR_H_ */
#include "PickupLeftFactor.h"
const char* VoidSymbol = "$"; // "ε"
const char* Postfix = "'";
int main(int argc, char* argv[])
{
//
// 调用 InitRules 函数初始化文法
//
Rule* pHead = InitRules();
//
// 输出提取左因子之前的文法
//
printf("Before Pickup Left Factor:\n");
PrintRule(pHead);
//
// 调用 PickupLeftFactor 函数对文法提取左因子
//
PickupLeftFactor(pHead);
//
// 输出提取左因子之后的文法
//
printf("\nAfter Pickup Left Factor:\n");
PrintRule(pHead);
return 0;
}
/*
功能:
根据下标找到 Select 中的一个 Symbol。
参数:
pSelect -- Select 指针。
index -- 下标。
返回值:
如果存在,返回找到的 Symbol 指针,否则返回 NULL。
*/
RuleSymbol* GetSymbol(RuleSymbol* pSelect, int index)
{
int i = 0;
RuleSymbol* pRuleSymbol;
for(pRuleSymbol = pSelect, i = 0; pRuleSymbol != NULL; pRuleSymbol = pRuleSymbol->pNextSymbol, i++)
{
if(i == index)
return pRuleSymbol;
}
return NULL;
}
/*
功能:
以 SelectTemplate 为模板,确定左因子的最大长度。
参数:
pSelectTemplate -- 作为模板的 Select 指针。
返回值:
左因子的最大长度,如果返回 0 说明不存在左因子。
*/
int LeftFactorMaxLength(RuleSymbol* pSelectTemplate)
{
//
// TODO: 在此添加代码
//
}
/*
功能:
比较两个相同类型(同为终结符或同为非终结符)的 Symbol 是否具有相同的名字。
参数:
pSymbol1 -- Symbol 指针。
pSymbol2 -- Symbol 指针。
返回值:
相同返回 1,不同返回 0。
*/
int SymbolCmp(RuleSymbol* pSymbol1, RuleSymbol* pSymbol2)
{
//
// TODO: 在此添加代码
//
}
/*
功能:
取文法中的一个 Select 与 SelectTemplate 进行比较,判断该 Select 是否需要提取左因子。
参数:
pSelectTemplate -- 作为模板的 Select 指针。
Count -- SelectTemplate 中已确定的左因子的数量。
pSelect -- Select 指针。
返回值:
如果 Select 包含左因子返回 1,否则返回 0。
*/
int NeedPickup(RuleSymbol* pSelectTemplate, int Count, RuleSymbol* pSelect)
{
//
// TODO: 在此添加代码
//
}
/*
功能:
将一个 Select 加入到文法末尾,当 Select 为 NULL 时就将一个ε终结符加入到文法末尾。
参数:
pRule -- 文法指针。
pNewSelect -- Select 指针。
*/
void AddSelectToRule(Rule* pRule, RuleSymbol* pNewSelect)
{
//
// TODO: 在此添加代码
//
}
/*
功能:
将 pRuleName 与文法中的其他 RuleName 比较, 如果相同就增加一个后缀。
参数:
pHead -- Rule 链表的头指针。
pRuleName -- Rule 的名字。
*/
void GetUniqueRuleName(Rule* pHead, char* pRuleName)
{
Rule* pRuleCursor = pHead;
for(; pRuleCursor != NULL;)
{
if(0 == strcmp(pRuleCursor->RuleName, pRuleName))
{
strcat(pRuleName, Postfix);
pRuleCursor = pHead;
continue;
}
pRuleCursor = pRuleCursor->pNextRule;
}
}
/*
功能:
释放一个 Select 的内存。
参数:
pSelect -- 需要释放的 Select 的指针。
*/
void FreeSelect(RuleSymbol* pSelect)
{
//
// TODO: 在此添加代码
//
}
/*
功能:
提取左因子。
参数:
pHead -- 文法的头指针。
*/
void PickupLeftFactor(Rule* pHead)
{
Rule* pRule; // Rule 游标
int isChange; // Rule 是否被提取左因子的标志
RuleSymbol* pSelectTemplate; // Select 游标
Rule* pNewRule; // Rule 指针
RuleSymbol* pSelect; // Select 游标
//
// TODO: 在此添加代码
//
}
/*
功能:
使用给定的数据初始化文法链表
返回值:
文法的头指针
*/
typedef struct _SYMBOL{
int isToken;
char Name[MAX_STR_LENGTH];
}SYMBOL;
typedef struct _RULE_ENTRY{
char RuleName[MAX_STR_LENGTH];
SYMBOL Selects[64][64];
}RULE_ENTRY;
static const RULE_ENTRY rule_table[] =
{
/* A -> abC | abcD | abcE */
{ "A", {
{ { 1, "a" }, { 1, "b" }, { 1, "C" } },
{ { 1, "a" }, { 1, "b" }, { 1, "c" }, { 1, "D" } },
{ { 1, "a" }, { 1, "b" }, { 1, "c" }, { 1, "E" } }
}
}
};
Rule* InitRules()
{
Rule *pHead, *pRule;
RuleSymbol **pSymbolPtr1, **pSymbolPtr2;
int nRuleCount = sizeof(rule_table) / sizeof(rule_table[0]);
int i, j, k;
Rule** pRulePtr = &pHead;
for(i=0; i<nRuleCount; i++)
{
*pRulePtr = CreateRule(rule_table[i].RuleName);
pRulePtr = &(*pRulePtr)->pNextRule;
}
pRule = pHead;
for(i=0; i<nRuleCount; i++)
{
pSymbolPtr1 = &pRule->pFirstSymbol;
for(j=0; rule_table[i].Selects[j][0].Name[0] != '\0'; j++)
{
pSymbolPtr2 = pSymbolPtr1;
for(k=0; rule_table[i].Selects[j][k].Name[0] != '\0'; k++)
{
const SYMBOL* pSymbol = &rule_table[i].Selects[j][k];
*pSymbolPtr2 = CreateSymbol();
(*pSymbolPtr2)->isToken = pSymbol->isToken;
if(1 == pSymbol->isToken)
{
strcpy((*pSymbolPtr2)->TokenName, pSymbol->Name);
}
else
{
(*pSymbolPtr2)->pRule = FindRule(pHead, pSymbol->Name);
if(NULL == (*pSymbolPtr2)->pRule)
{
printf("Init rules error, miss rule \"%s\"\n", pSymbol->Name);
exit(1);
}
}
pSymbolPtr2 = &(*pSymbolPtr2)->pNextSymbol;
}
pSymbolPtr1 = &(*pSymbolPtr1)->pOther;
}
pRule = pRule->pNextRule;
}
return pHead;
}
/*
功能:
创建一个新的 Rule。
参数:
pRuleName -- 文法的名字。
返回值:
Rule 指针
*/
Rule* CreateRule(const char* pRuleName)
{
Rule* pRule = (Rule*)malloc(sizeof(Rule));
strcpy(pRule->RuleName, pRuleName);
pRule->pFirstSymbol = NULL;
pRule->pNextRule = NULL;
return pRule;
}
/*
功能:
创建一个新的 Symbol。
返回值:
RuleSymbol 指针
*/
RuleSymbol* CreateSymbol()
{
RuleSymbol* pSymbol = (RuleSymbol*)malloc(sizeof(RuleSymbol));
pSymbol->pNextSymbol = NULL;
pSymbol->pOther = NULL;
pSymbol->isToken = -1;
pSymbol->TokenName[0] = '\0';
pSymbol->pRule = NULL;
return pSymbol;
}
/*
功能:
根据 RuleName 在文法链表中查找名字相同的文法。
参数:
pHead -- 文法的头指针。
RuleName -- 文法的名字。
返回值:
Rule 指针
*/
Rule* FindRule(Rule* pHead, const char* RuleName)
{
Rule* pRule;
for(pRule = pHead; pRule != NULL; pRule = pRule->pNextRule)
{
if(0 == strcmp(pRule->RuleName, RuleName))
{
break;
}
}
return pRule;
}
/*
功能:
输出文法。
参数:
pHead -- 文法的头指针。
*/
void PrintRule(Rule* pHead)
{
//
// TODO: 在此添加代码
//
}
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论