提交 564244cb 创建 作者: 赵鹏翀's avatar 赵鹏翀

init template

上级
/Debug
/Release
#include "NFAFragmentStack.h"
/*
功能:
初始化栈。
参数:
pS -- 栈的指针
*/
void InitNFAFragmentStack(NFAFragmentStack* pS)
{
pS->top = -1;
}
/*
功能:
将元素入栈。
参数:
pS -- 栈的指针
Elem -- 入栈的元素
返回值:
*/
void PushNFAFragment(NFAFragmentStack* pS, NFAFragment Elem)
{
//
// 栈满,入栈失败。
//
if(MAX_STACK_LENGTH - 1 <= pS->top)
return;
pS->top++;
pS->buffer[pS->top] = Elem; // 将元素插入栈顶
return;
}
/*
功能:
将栈顶元素出栈
参数:
pS -- 栈的指针
返回值:
如果出栈成功返回出栈元素的值。
如果出栈失败返回 -1。
*/
NFAFragment PopNFAFragment(NFAFragmentStack* pS)
{
int pos;
NFAFragment fragment = {0, 0};
//
// 栈为空,出栈失败
//
if(NFAFragmentStackEmpty(pS))
return fragment;
pos = pS->top;
pS->top--;
return pS->buffer[pos];
}
/*
功能:
判断栈是否为空。
参数:
pQ -- 栈的指针
返回值:
如果栈空返回 1(真)
如果栈非空返回 0(假)
*/
int NFAFragmentStackEmpty(NFAFragmentStack* pS)
{
return -1 == pS->top ? 1 : 0;
}
#ifndef _NFAFRAGMENTSTACK_H_
#define _NFAFRAGMENTSTACK_H_
//
// 在此处包含 C 标准库头文件
//
//
// 在此处包含其他头文件
//
#include "RegexpToNFA.h"
//
// 在此处定义数据结构
//
#define MAX_STACK_LENGTH 1024 // 栈的最大长度
// 栈
typedef struct _NFAFragmentStack{
NFAFragment buffer[MAX_STACK_LENGTH]; // 栈的缓冲区
int top; // 指示栈顶的位置,而不是栈中元素的个数
}NFAFragmentStack;
//
// 在此处声明函数
//
void InitNFAFragmentStack(NFAFragmentStack* pS);
void PushNFAFragment(NFAFragmentStack* pS, NFAFragment Elem);
NFAFragment PopNFAFragment(NFAFragmentStack* pS);
int NFAFragmentStackEmpty(NFAFragmentStack* pS);
//
// 在此处声明全局变量
//
#endif /* _NFAFRAGMENTSTACK_H_ */
<?xml version="1.0" encoding="gb2312"?>
<OSLProject Version="1.00" Name="RegexpToNFA" SubjectID="11c951f4-9b13-40e1-8b73-39ba7d73b89b" ProjectTemplateID="4c23da0f-8ae2-4370-bf9f-8c3fc656b942">
<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\RegexpToNFA_Demo.o&quot;"/>
<Tool Name="PostBuildEventTool"/>
<VisualContext>
<WatchPoints>
<WatchPoint FunctionName="post2nfa" ObserverID="568B665B-0108-4b33-8D02-F6C797E1ABBB">
</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=".\NFAFragmentStack.h">
</File>
<File RelativePath=".\RegexpToNFA.h">
</File>
<File RelativePath=".\RegexpToPost.h">
</File>
</Filter>
<Filter Name="Դļ" Filter="cpp;c;cc;cxx">
<File RelativePath=".\main.c">
</File>
<File RelativePath=".\NFAFragmentStack.c">
</File>
<File RelativePath=".\RegexpToPost.c">
</File>
</Filter>
</Files>
</OSLProject>
#ifndef _REGEXPTONFA_H_
#define _REGEXPTONFA_H_
//
// 在此处包含 C 标准库头文件
//
#include <stdio.h>
//
// 在此处包含其他头文件
//
//
// 在此处定义数据结构
//
typedef struct _NFAState{
char Transform; // 状态间转换的标识,用 '$' 表示 'ε-转换'
struct _NFAState *Next1; // 指向下一个状态
struct _NFAState *Next2; // 指向下一个状态
int Name; // 状态名称
int AcceptFlag; // 是否为接受状态的标志,1 表示是接受状态 0 表示不是接受状态
}NFAState;
// Fragment 结构是一个 NFA 的片段
typedef struct _NFAFragment{
NFAState *StartState; // 开始状态
NFAState *AcceptState; // 接受状态
}NFAFragment;
//
// 在此处声明函数
//
NFAState* CreateNFAState();
NFAState* post2nfa(char *postfix);
NFAFragment MakeNFAFragment(NFAState *StartState, NFAState *AcceptState);
//
// 在此声明全局变量
//
extern int nstate;
extern const char VoidTrans;
extern char* regexp;
#endif /* _REGEXPTONFA_H_ */
添加文件
#include "RegexpToPost.h"
/*
功能:
将输入的正则表达式字符串转换成解析树的后续遍历序列。
参数:
re -- 正则表达式指针。
返回值:
解析树的后续遍历序列数组指针。
*/
char* re2post(char *re)
{
int nalt; // 表示解析到这个字符为止,已经有多少个分支结构
int natom; // 表示解析到这个字符为止,已经有多少个原子结构
static char buf[8000];
char *dst;
struct {
int nalt;
int natom;
} paren[100], *p;
p = paren;
dst = buf;
nalt = 0;
natom = 0;
if(strlen(re) >= sizeof buf/2)
return NULL;
for(; *re; re++){
switch(*re){
case '(':
if(natom > 1)
{
--natom;
*dst++ = '.';
}
if(p >= paren+100)
return NULL;
p->nalt = nalt;
p->natom = natom;
p++;
nalt = 0;
natom = 0;
break;
case '|':
if(natom == 0)
return NULL;
while(--natom > 0)
*dst++ = '.';
nalt++;
break;
case ')':
if(p == paren)
return NULL;
if(natom == 0)
return NULL;
while(--natom > 0)
*dst++ = '.';
for(; nalt > 0; nalt--)
*dst++ = '|';
--p;
nalt = p->nalt;
natom = p->natom;
natom++;
break;
case '*':
case '+':
case '?':
if(natom == 0)
return NULL;
*dst++ = *re;
break;
default:
if(natom > 1)
{
--natom;
*dst++ = '.';
}
*dst++ = *re;
natom++;
break;
}
}
if(p != paren)
return NULL;
while(--natom > 0)
*dst++ = '.';
for(; nalt > 0; nalt--)
*dst++ = '|';
*dst = 0;
return buf;
}
#ifndef _REGEXPTOPOST_H_
#define _REGEXPTOPOST_H_
//
// 在此处包含 C 标准库头文件
//
//
// 在此处包含其他头文件
//
#include "RegexpToNFA.h"
//
// 在此处定义数据结构
//
//
// 在此处声明函数
//
char* re2post(char *re);
#endif /* _REGEXPTOPOST_H_ */
#include "RegexpToNFA.h"
#include "RegexpToPost.h"
#include "NFAFragmentStack.h"
NFAFragmentStack FragmentStack; // 栈。用于储存 NFA 片段
char* regexp = "ab"; // 例 1
// char* regexp = "a|b"; // 例 2
// char* regexp = "a*"; // 例 3
// char* regexp = "a?"; // 例 4
// char* regexp = "a+"; // 例 5
// char* regexp = "a(a|1)*";// 例 6
// char* regexp = "(aa|b)*a(a|bb)*";// 例 7
// char* regexp = "(a|b)*a(a|b)?"; // 例 8
int main(int argc, char **argv)
{
char *post;
NFAState *start;
//
// 初始化栈
//
InitNFAFragmentStack(&FragmentStack);
//
// 调用 re2post 函数将正则表达式字符串转换成解析树的后续遍历序列
//
post = re2post(regexp);
//
// 调用 post2nfa 函数将解析树的后续遍历序列转换为 NFA 并返回开始状态
//
start = post2nfa(post);
return 0;
}
/*
功能:
初始化一个状态。
返回值:
状态指针。
*/
int nstate = 1; // 状态名计数器
NFAState* CreateNFAState()
{
NFAState *s = (NFAState*)malloc(sizeof(NFAState));
s->Name = nstate++;
s->Transform = '\0';
s->Next1 = NULL;
s->Next2 = NULL;
s->AcceptFlag = 0;
return s;
}
/*
功能:
将开始状态和接受状态组成一个 Fragment。
参数:
StartState -- 开始状态。
AcceptState -- 接受状态。
返回值:
Fragment 结构体指针。
*/
NFAFragment MakeNFAFragment(NFAState *StartState, NFAState *AcceptState)
{
NFAFragment n = {StartState, AcceptState};
return n;
}
/*
功能:
将解析树的后序序列转换为 NFA。
参数:
postfix -- 解析树的后序序列指针。
返回值:
NFA 的开始状态指针。
*/
const char VoidTrans = '$'; // 表示空转换
NFAState* post2nfa(char *postfix)
{
char *p; // 游标
NFAFragment fragment1, fragment2, fm; // NFA 片段结构体变量
NFAFragment fragment = {0, 0}; // 初始化用于返回的 NFA 片段
NFAState *NewStartState, *NewAcceptState; // 开始状态和接受状态指针
//
// TODO: 在此添加代码
//
return fragment.StartState;
}
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论