简单的FIRST+集演示程序
- /*
- * 该程序用于计算某个非终结符的 FIRST+ 集合
- * RexfieldVon
- * 2013年6月30日16:02:47
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- /* 三级指针
- * 第一级指向整个产生式组
- * 第二级指向单个产生式
- * 第三级指向产生式符号单元
- * 约定:所有的大写字母为非终结符
- * 假设:无左递归、FIRST集中不会出现重复符号
- */
- char*** GrammerRule;
- /*
- * 初始化文法序列
- */
- void InitizationGrammerRule()
- {
- // 分配表头空间
- GrammerRule = (char***)malloc(sizeof(int) * );
- memset(GrammerRule, '\0', sizeof(int) * );
- // 分配文法空间并写入产生式
- // G -> E
- GrammerRule['G'] = (char**)malloc(sizeof(int) * );
- GrammerRule['G'][] = (char*)malloc();
- memcpy(GrammerRule['G'][], "E\0", ); // E
- GrammerRule['G'][] = NULL;
- // E -> T F
- GrammerRule['E'] = (char**)malloc(sizeof(int) * );
- GrammerRule['E'][] = (char*)malloc();
- memcpy(GrammerRule['E'][], "TF\0", ); // T F
- GrammerRule['E'][] = NULL;
- // F -> '+' T F | '-' T F | e
- GrammerRule['F'] = (char**)malloc(sizeof(int) * );
- GrammerRule['F'][] = (char*)malloc();
- memcpy(GrammerRule['F'][], "+TF\0", ); // '+' T F
- GrammerRule['F'][] = (char*)malloc();
- memcpy(GrammerRule['F'][], "-TF\0", ); // '-' T F
- GrammerRule['F'][] = (char*)malloc();
- memcpy(GrammerRule['F'][], "\0", ); // e (该产生式存在但是为空)
- GrammerRule['F'][] = NULL;
- // T -> A U
- GrammerRule['T'] = (char**)malloc(sizeof(int) * );
- GrammerRule['T'][] = (char*)malloc();
- memcpy(GrammerRule['T'][], "AU\0", ); // A U
- GrammerRule['T'][] = NULL;
- // U -> '*' A U | '/' A U | e
- GrammerRule['U'] = (char**)malloc(sizeof(int) * );
- GrammerRule['U'][] = (char*)malloc();
- memcpy(GrammerRule['U'][], "*AU\0", ); // '*' A U
- GrammerRule['U'][] = (char*)malloc();
- memcpy(GrammerRule['U'][], "/AU\0", ); // '/' A U
- GrammerRule['U'][] = (char*)malloc();
- memcpy(GrammerRule['U'][], "\0", ); // e (该产生式存在但是为空)
- GrammerRule['U'][] = NULL;
- // A -> '(' E ')' | d | n
- GrammerRule['A'] = (char**)malloc(sizeof(int) * );
- GrammerRule['A'][] = (char*)malloc();
- memcpy(GrammerRule['A'][], "(E)\0", ); // '(' E ')'
- GrammerRule['A'][] = (char*)malloc();
- memcpy(GrammerRule['A'][], "d\0", ); // d
- GrammerRule['A'][] = (char*)malloc();
- memcpy(GrammerRule['A'][], "n\0", ); // n
- GrammerRule['A'][] = NULL;
- }
- /*
- * 取得终结符数量
- */
- int GetTerminalCount()
- {
- int i, TerminalCount = ;
- for (i = ; i < ; i++)
- {
- if (GrammerRule[i] != NULL)
- {
- int k = ;
- while (GrammerRule[i][k] != NULL)
- {
- int n = ;
- while (GrammerRule[i][k][n] != '\0')
- {
- char c = GrammerRule[i][k][n];
- if (c < 'A' || c > 'Z')
- {
- TerminalCount++;
- }
- n++;
- }
- k++;
- }
- }
- }
- return TerminalCount;
- }
- /*
- * 递归取得 FIRST 集
- * Token : char 需要打印的符号
- * FIRST : char* FIRST集
- * Ptr : int* FIRST集的位置指针
- */
- void GetFIRST(char Token, char *FIRST, int *Ptr)
- {
- if (Token >= 'A' && Token <= 'Z' && GrammerRule[Token] != NULL)
- {
- int i = ;
- while (GrammerRule[Token][i] != NULL)
- {
- GetFIRST(GrammerRule[Token][i++][], FIRST, Ptr);
- }
- }
- else if (Token < 'A' || Token > 'Z')
- {
- FIRST[*Ptr] = Token;
- *Ptr = *Ptr + ;
- }
- }
- /*
- * 添加符号到 FOLLOW 集
- * FOLLOW : char* FOLLOW集
- * Ptr : int* FOLLOW集的位置指针
- * NewItem : char 将加入的符号
- */
- void AddFOLLOWItem(char *FOLLOW, int *Ptr, char NewItem)
- {
- int i = ;
- for (; i < *Ptr; i++)
- {
- if (FOLLOW[i] == NewItem)
- {
- return ;
- }
- }
- FOLLOW[*Ptr] = NewItem;
- *Ptr = *Ptr + ;
- }
- /*
- * 取得 FOLLOW 集
- * Unterminal : char 需要打印的非终结符
- * FOLLOW : char* FOLLOW集
- * Ptr : int* FOLLOW集的位置指针
- * TerminalCount : int 终结符数量
- */
- void GetFOLLOW(char Unterminal, char *FOLLOW, int *Ptr, int TerminalCount)
- {
- int RuleIndex, ExprIndex, TokenIndex;
- // 开始遍历整个文法
- for (RuleIndex = ; RuleIndex < ; RuleIndex++)
- {
- if (GrammerRule[RuleIndex] == NULL)
- {
- continue;
- }
- // 搜索整个文法找到指定的非终结符
- for (ExprIndex = ; GrammerRule[RuleIndex][ExprIndex] != ; ExprIndex++)
- {
- for (TokenIndex = ; GrammerRule[RuleIndex][ExprIndex][TokenIndex] != '\0'; TokenIndex++)
- {
- if (GrammerRule[RuleIndex][ExprIndex][TokenIndex] == Unterminal)
- {
- char nc = GrammerRule[RuleIndex][ExprIndex][TokenIndex + ];
- if (nc == '\0' && RuleIndex != Unterminal) // 情形三:反复计算:将FOLLOW(P)加入FOLLOW(U)
- {
- GetFOLLOW((char)RuleIndex, FOLLOW, Ptr, TerminalCount);
- }
- else if (nc >= 'A' && nc <= 'Z') // 情形二:间接计算:将FIRST(P)加入FOLLOW(U)
- {
- char *FIRST = (char*)malloc(TerminalCount + );
- memset(FIRST, '\0', TerminalCount + );
- int FIRSTPtr = , InsertPtr;
- GetFIRST(nc, FIRST, &FIRSTPtr);
- for (InsertPtr = ; InsertPtr < FIRSTPtr; InsertPtr++)
- {
- if (FIRST[InsertPtr] != '\0')
- {
- AddFOLLOWItem(FOLLOW, Ptr, FIRST[InsertPtr]);
- }
- else // 对于 P->... U B,FOLLOW ← FIRST(B) - <e> + FOLLOW(P)
- {
- GetFOLLOW((char)RuleIndex, FOLLOW, Ptr, TerminalCount);
- }
- }
- }
- else if (nc != '\0') // 情形一:直接计算:将终结符加入FOLLOW(U)
- {
- AddFOLLOWItem(FOLLOW, Ptr, nc);
- }
- }
- }
- }
- }
- }
- void GetFIRSTPlus(char Unterminal, int Index, char *FIRSTPlus, int *Ptr, int TerminalCount)
- {
- if (GrammerRule[Unterminal][Index] != NULL)
- {
- GetFIRST(GrammerRule[Unterminal][Index][], FIRSTPlus, Ptr);
- int i = ;
- while (i < *Ptr)
- {
- if (FIRSTPlus[i++] == '\0')
- {
- FIRSTPlus[*Ptr] = '\377';
- *Ptr = *Ptr + ;
- GetFOLLOW(Unterminal, FIRSTPlus, Ptr, TerminalCount);
- break;
- }
- }
- }
- }
- /*
- * 打印指定非终结符的 FIRST+ 集
- * Unterminal : char 需要打印的非终结符
- * TerminalCount : int 终结符数量
- */
- void PrintUnterminalFIRSTPlus(char Unterminal, int TerminalCount)
- {
- char *FIRSTPlus = (char*)malloc(TerminalCount + );
- memset(FIRSTPlus, '\0', TerminalCount + );
- int Ptr, Index = , i;
- for (; GrammerRule[Unterminal][Index] != NULL; Index++)
- {
- Ptr = ;
- GetFIRSTPlus(Unterminal, Index, FIRSTPlus, &Ptr, TerminalCount);
- printf("FIRST+(%c, %c): ", Unterminal, GrammerRule[Unterminal][Index][]);
- for (i = ; i < Ptr; i++)
- {
- if (FIRSTPlus[i] == '\377')
- {
- printf("<eof> ");
- }
- else if (FIRSTPlus[i] == '\0')
- {
- printf("<e> ");
- }
- else
- {
- printf("%c ", FIRSTPlus[i]);
- }
- }
- printf("\n");
- }
- }
- int main(int argc, char **argv)
- {
- InitizationGrammerRule(); // 初始化文法
- int TerminalCount = GetTerminalCount();
- PrintUnterminalFIRSTPlus('E', TerminalCount);
- PrintUnterminalFIRSTPlus('F', TerminalCount);
- PrintUnterminalFIRSTPlus('T', TerminalCount);
- PrintUnterminalFIRSTPlus('U', TerminalCount);
- PrintUnterminalFIRSTPlus('A', TerminalCount);
- return ;
- }
简单的FIRST+集演示程序的更多相关文章
- 简单的FOLLOW集演示程序
/* * 该程序用于计算某个非终结符的 FOLLOW 集合 * RexfieldVon * 2013年6月30日16:02:47 */ #include <stdio.h> #includ ...
- 简单的FIRST集演示程序
/* * 该程序用于计算某个非终结符的 FIRST 集合 * RexfieldVon * 2013年6月29日19:53:45 * 2013年7月3日22:01:57 修改 GetFIRST 例程以简 ...
- POJ 2524 (简单并查集) Ubiquitous Religions
题意:有编号为1到n的学生,然后有m组调查,每组调查中有a和b,表示该两个学生有同样的宗教信仰,问最多有多少种不同的宗教信仰 简单并查集 //#define LOCAL #include <io ...
- poj1611 简单并查集
The Suspects Time Limit: 1000MS Memory Limit: 20000K Total Submissions: 32781 Accepted: 15902 De ...
- 1213 How Many Tables(简单并查集)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1213 简单并查集,统计单独成树的数量. 代码: #include <stdio.h> #i ...
- 【简单并查集】Farm Irrigation
Farm Irrigation Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other) Tot ...
- RocketMQ 简单梳理 及 集群部署笔记【转】
一.RocketMQ 基础知识介绍Apache RocketMQ是阿里开源的一款高性能.高吞吐量.队列模型的消息中间件的分布式消息中间件. 上图是一个典型的消息中间件收发消息的模型,RocketMQ也 ...
- 搭建简单的hadoop集群(译文)
本文翻译翻译自http://hadoop.apache.org/docs/r2.8.0/hadoop-project-dist/hadoop-common/ClusterSetup.html 具体的实 ...
- ACM_“打老虎”的背后(简单并查集)
“打老虎”的背后 Time Limit: 2000/1000ms (Java/Others) Problem Description: “习大大”自担任国家主席以来大力反腐倡廉,各地打击贪腐力度也逐步 ...
随机推荐
- 浅谈Android系统的图标设计规范
http://homepage.yesky.com/89/11620089.shtml 目前移动平台的竞争日益激烈,友好的用户界面可以帮助提高用户体验满意度,图标Icon是用户界面中一个重要的组成部分 ...
- HTTP could not register URL http://+:8000/.... Your process does not have access rights to this namespace
windows 7, Visual Studio 2013 在托管 Windows 服务中承载 WCF 服务时报错: HTTP could not register URL http://+:8000 ...
- c#wiform中KeyDown事件
当首次按下键盘上某个键时发生事件. 例如 private void Form1_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Ke ...
- 实现Bootstrap Carousel Fade Transition 淡入淡出效果
html代码: <div id="carousel" class="carousel slide carousel-fade" data-ride=&qu ...
- mysql数据库中编码问题(续)
其实之前的数据库中文乱码问题并没有彻底的解决,虽然在网页上显示正常,但是在数据库中却是乱码,虽然用户看起来没问题,但是自己就遭罪了,而且也是个极大的问题 究其原因,是没注意到一点,就是数据库中表的结构 ...
- tbody 滚动条
ARRIVALS TO BRISTOL - ENGLAND FLIGHT CODE FROM STA ETA Notes T3 4264 ISLE OF MAN 11:40 11:42 LANDED ...
- 关于alarm函数
#include<unistd.h> #include<signal.h> void handler() { printf("Hello\n"); sign ...
- [转载]ecshop 实现订单导出功能 指定订单导出 EXCEL 数据文件
当下很多功能都觉得理所当然,但是实际作为2012年停更的ECSHOP来说,很多功能其实都是缺少的,好比今天的要说的功能 订单导出 这个功能对于现在的产品设计来说,应该属于一个比较常规的功能,但是ECS ...
- Tomcat环境变量的配置
Tomcat web服务器 支持全部JSP以及Servlet规范 主要作用 是提供了一个可以让Jsp和Servlet运行的平台 tomcat环境变量设置 CATALINA_HOME : D:\bran ...
- Drupal7安装完整教程
Drupal7 史前准备工作(安装 AppServ)AppServ 是 PHP 网页架站工具组合包,作者将一些网络上免费的架站资源重新包装成单一的安装程序,以方便初学者快速完成架站,AppServ 所 ...