#include <stdio.h>
#include "string.h"
enum symbol {
nul, ident, number, plus, minus,
times, slash, oddsym, eql, neq,
lss, leq, gtr, geq, lparen,
rparen, comma, semicolon, period, becomes,
beginsym, endsym, ifsym, thensym, whilesym,
writesym, readsym, dosym, callsym, constsym,
varsym, procsym,
};
#define al 10 /* 符号的最大长度 */
#define norw 13 /* 关键字个数 */
#define nmax 14 /* number的最大位数 */
#define fctnum 8
char line[81]; /* 读取行缓冲区 */
#define getchdo if(-1 == getch()) return -1
FILE* fin;
char fname[al];
enum symbol ssym[256]; /* 单字符的符号值 */
char word[norw][al]; /* 保留字 */
enum symbol wsym[norw]; /* 保留字对应的符号值 */
int err; /* 错误计数器 */
int cc, ll; /* getch使用的计数器,cc表示当前字符(ch)的位置 */
int cx; /* 虚拟机代码指针, 取值范围[0, cxmax-1]*/
char ch; /* 获取字符的缓冲区,getch 使用 */
char a[al+1]; /* 临时符号, 多出的一个字节用于存放0 */
char id[al+1]; /* 当前ident, 多出的一个字节用于存放0 */
enum symbol sym; /* 当前的符号 */
int num; /* 当前number */
void error(int n);
int getch();
void init();
int getsym();
int main()
{
printf("Input pl/0 file? ");
scanf("%s", fname); /* 输入文件名 */
fin = fopen(fname, "r");
if (fin)
{
init(); /* 初始化 */
err = 0;
cc = cx = ll = 0;
ch = ' ';
do
{
getsym();
if(sym==1)//标识符 种别及其本身
{
printf("(%d,'%s')", sym, a );
}
else if(sym==2)// 无符号整数 种别及其本身
{
printf("(%d,'%d')", sym, num );
}
else
{
printf("(%d)", sym);//其他(保留字,分界符,操作符等)的种别
}
} while (sym != 18);//"."的种别是18
printf("\n");
fclose(fin);
}
else
{
printf("Can't open file!\n");
}
printf("\n");
return 0;
}
void error(int n)
{
char space[81];
memset(space,32,81);
space[cc-1]=0; //出错时当前符号已经读完,所以cc-1
printf("****%s!%d\n", space, n);
err++;
}
int getch()
{
if (cc == ll)
{
if (feof(fin))
{
printf("program incomplete");
return -1;
}
ll=0;
cc=0;
//printf("%d ", cx);
ch = ' ';
while (ch != 10)
{
//fscanf(fin,"%c", &ch)
//richard
if (EOF == fscanf(fin,"%c", &ch))
{
line[ll] = 0;
break;
}
//end richard
//printf("%c", ch);
line[ll] = ch;
ll++;
}
printf("\n");//每读取一行
}
ch = line[cc];
cc++;
return 0;
}
void init()
{
int i;
/* 设置单字符符号 */
for (i=0; i<=255; i++)
{
ssym[i] = nul;
}
ssym['+'] = plus;
ssym['-'] = minus;
ssym['*'] = times;
ssym['/'] = slash;
ssym['('] = lparen;
ssym[')'] = rparen;
ssym['='] = eql;
ssym[','] = comma;
ssym['.'] = period;
ssym['#'] = neq;
ssym[';'] = semicolon;
/* 设置保留字名字,按照字母顺序,便于折半查找 */
strcpy(&(word[0][0]), "begin");
strcpy(&(word[1][0]), "call");
strcpy(&(word[2][0]), "const");
strcpy(&(word[3][0]), "do");
strcpy(&(word[4][0]), "end");
strcpy(&(word[5][0]), "if");
strcpy(&(word[6][0]), "odd");
strcpy(&(word[7][0]), "procedure");
strcpy(&(word[8][0]), "read");
strcpy(&(word[9][0]), "then");
strcpy(&(word[10][0]), "var");
strcpy(&(word[11][0]), "while");
strcpy(&(word[12][0]), "write");
/* 设置保留字符号 */
wsym[0] = beginsym;
wsym[1] = callsym;
wsym[2] = constsym;
wsym[3] = dosym;
wsym[4] = endsym;
wsym[5] = ifsym;
wsym[6] = oddsym;
wsym[7] = procsym;
wsym[8] = readsym;
wsym[9] = thensym;
wsym[10] = varsym;
wsym[11] = whilesym;
wsym[12] = writesym;
}
int getsym()
{
int i,j,k;
/* the original version lacks "\r", thanks to foolevery */
while (ch==' ' || ch==10 || ch==13 || ch==9) /* 忽略空格、换行、回车和TAB */
{
getchdo;
}
if (ch>='a' && ch<='z')
{ /* 名字或保留字以a..z开头 */
k = 0;
do {
if(k<al)
{
a[k] = ch;
k++;
}
getchdo;
} while (ch>='a' && ch<='z' || ch>='0' && ch<='9');
a[k] = 0;
strcpy(id, a);
i = 0;
j = norw-1;
do { /* 搜索当前符号是否为保留字 */
k = (i+j)/2;
if (strcmp(id,word[k]) <= 0)
{
j = k - 1;
}
if (strcmp(id,word[k]) >= 0)
{
i = k + 1;
}
} while (i <= j);
if (i-1 > j)
{
sym = wsym[k];
}
else
{
sym = ident; /* 搜索失败则,是名字或数字 */
}
}
else
{
if (ch>='0' && ch<='9')
{ /* 检测是否为数字:以0..9开头 */
k = 0;
num = 0;
sym = number;
do {
num = 10*num + ch - '0';
k++;
getchdo;
} while (ch>='0' && ch<='9'); /* 获取数字的值 */
k--;
if (k > nmax)
{
error(30);
}
}
else
{
if (ch == ':') /* 检测赋值符号 */
{
getchdo;
if (ch == '=')
{
sym = becomes;
getchdo;
}
else
{
sym = nul; /* 不能识别的符号 */
}
}
else
{
if (ch == '<') /* 检测小于或小于等于符号 */
{
getchdo;
if (ch == '=')
{
sym = leq;
getchdo;
}
else
{
sym = lss;
}
}
else
{
if (ch=='>') /* 检测大于或大于等于符号 */
{
getchdo;
if (ch == '=')
{
sym = geq;
getchdo;
}
else
{
sym = gtr;
}
}
else
{
sym = ssym[ch]; /* 当符号不满足上述条件时,全部按照单字符符号处理 */
//getchdo;
//richard
if (sym != period)
{
getchdo;
}
//end richard
}
}
}
}
}
return 0;
}
没有合适的资源?快使用搜索试试~ 我知道了~
PL0词法分析程序_PL0词法分析_
共6个文件
tmp:3个
pl0:1个
cpp:1个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
5星 · 超过95%的资源 6 下载量 35 浏览量
2021-10-01
14:55:32
上传
评论 3
收藏 45KB ZIP 举报
温馨提示
三、 实验要求 1. 使用 PL/0 语言编写程序,实现输出斐波那契数列前 20 项数值。 2. 从 PL/0 编译程序源码中抽出词法分析部分,构建 PL/0 独立词法分析程序。功能:输入为 PL/0 源程序, 输出为单词符号的序列;对于标识符和无符号整数,显示单词种别和单词自身的值两项内容;对于其他单词符 号,仅显示其单词种别。 3. 使用 AutoFlowchart 画出独立词法分析程序的程序流程图,并分析每部分的功能和特点。
资源推荐
资源详情
资源评论
收起资源包目录
PL0词法分析程序.zip (6个子文件)
PL0词法分析程序
词法.exe 134KB
fib.pl0 144B
fa1.tmp 200B
fas.tmp 0B
fa.tmp 0B
词法.cpp 6KB
共 6 条
- 1
呼啸庄主
- 粉丝: 83
- 资源: 4696
下载权益
C知道特权
VIP文章
课程特权
开通VIP
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
- 1
- 2
前往页