提交 2378dafb 创建 作者: 赵鹏翀's avatar 赵鹏翀

init template

上级
/Debug
/Release
<?xml version="1.0" encoding="gb2312"?>
<OSLProject Version="1.00" Name="RemoveLeftRecursion" SubjectID="11c951f4-9b13-40e1-8b73-39ba7d73b89b" ProjectTemplateID="55b10cb5-9428-4da5-b75f-1c90042c7c1b">
<Configurations>
<Configuration Name="Debug">
<Tool Name="PreBuildEventTool"/>
<Tool Name="CustomBuildTool"/>
<Tool Name="GCCCompilerTool" PreprocessorDefinitions="_DEBUG" GenerateDebugInformation="-1" AdditionalOptions=""/>
<Tool Name="PreLinkEventTool"/>
<Tool Name="GCCLinkerTool" AdditionalDependencies="&quot;$(CPLInstallDir)Dump\lib\RemoveLeftRecursionNoReplace_Demo.o&quot;"/>
<Tool Name="PostBuildEventTool"/>
<VisualContext>
<WatchPoints>
<WatchPoint FunctionName="RemoveLeftRecursion" ObserverID="DE8BDB2C-CBD8-436c-A94A-BAB028B25D66">
</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=".\RemoveLeftRecursion.h">
</File>
</Filter>
<Filter Name="Դļ" Filter="cpp;c;cc;cxx">
<File RelativePath=".\main.c">
</File>
</Filter>
</Files>
</OSLProject>
#ifndef _REMOVELEFTRECURSIONNOREPLACE_H_
#define _REMOVELEFTRECURSIONNOREPLACE_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;
//
// 在此处声明函数
//
Rule* InitRules();
Rule* CreateRule(const char* pRuleName);
RuleSymbol* CreateSymbol();
Rule* FindRule(Rule* pHead, const char* RuleName);
void AddSymbolToSelect(RuleSymbol* pSelect, RuleSymbol* pNewSymbol);
void AddSelectToRule(Rule* pRule, RuleSymbol* pNewSelect);
void RemoveLeftRecursion(Rule* pHead);
void PrintRule(Rule* pHead);
//
// 在此声明全局变量
//
extern const char* VoidSymbol;
extern const char* Postfix;
#endif /* _REMOVELEFTRECURSIONNOREPLACE_H_ */
#include "RemoveLeftRecursion.h"
const char* VoidSymbol = "$"; // "ε"
const char* Postfix = "'";
int main(int argc, char* argv[])
{
//
// 调用 InitRules 函数初始化文法
//
Rule* pHead = InitRules();
//
// 输出消除左递归之前的文法
//
printf("Before Remove Left Recursion:\n");
PrintRule(pHead);
//
// 调用 RemoveLeftRecursion 函数对文法消除左递归
//
RemoveLeftRecursion(pHead);
//
// 输出消除左递归之后的文法
//
printf("\nAfter Remove Left Recursion:\n");
PrintRule(pHead);
return 0;
}
/*
功能:
将一个 Symbol 添加到 Select 的末尾。
参数:
pSelect -- Select 指针。
pNewSymbol -- Symbol 指针。
*/
void AddSymbolToSelect(RuleSymbol* pSelect, RuleSymbol* pNewSymbol)
{
//
// TODO: 在此添加代码
//
}
/*
功能:
将一个 Select 加入到文法末尾。当 Select 为 NULL 时就将一个ε终结符加入到文法末尾。
参数:
pRule -- 文法指针。
pNewSelect -- Select 指针。
*/
void AddSelectToRule(Rule* pRule, RuleSymbol* pNewSelect)
{
//
// TODO: 在此添加代码
//
}
/*
功能:
消除左递归。
参数:
pHead -- 文法链表的头指针。
*/
void RemoveLeftRecursion(Rule* pHead)
{
RuleSymbol* pSelect; // Select 游标
Rule* pNewRule; // Rule 指针
//
// TODO: 在此添加代码
//
return;
}
/*
功能:
使用给定的数据初始化文法链表
返回值:
Rule 指针
*/
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 -> Aa | bA | c | Ad */
{ "A", {
{ { 0, "A" }, { 1, "a" } },
{ { 1, "b" }, { 0, "A" } },
{ { 1, "c" } },
{ { 0, "A" }, { 1, "d" } }
}
}
};
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 指针,否则返回 NULL
*/
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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论