生活随笔
收集整理的这篇文章主要介绍了
pl/0词法分析器
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
下面是这个分析器的功能:
1、 待分析的简单语言的词法
(1) 关键字:
begin if then while do end
所有关键字都是小写。
(2) 运算符和界符:
: = + – * / < <= <> > >= = ; ( ) #
(3) 其他单词是标识符(ID)和整型常数(NUM),通过以下正规式定义:
ID=letter(letter| digit)*
NUM=digit digit *
(4) 空格由空白、制表符和换行符组成。空格一般用来分隔ID、NUM,运算符、界符和关键字,词法分析阶段通常被忽略。
2、 各种单词符号对应的种别码
词法分析程序的功能
输入:所给文法的源程序字符串。
输出:二元组(syn,token或sum)构成的序列。
其中:syn为单词种别码;
token为存放的单词自身字符串;
sum为整型常数。
#include <iostream>
#include <fstream>
#include <string>
#include <windows.h>using namespace std;#define CODE "E:\\code\\code.txt"
#define RESULT "E:\\code\\result.txt"//token数组用来接收关键字,变量,运算符和界符
//这里限制变量名的长度最多为9
//prog数组存储的是源代码字符串长度
char *prog, token[10];
char ch;
//syn是各个单词符号对应的数字
int syn, p, m = 0, n, line, sum = 0;
//rwtab数组存储的是关键字
char *rwtab1[10] = { "begin","if","then","while","do","end" };
char *rwtab2[4] = { "const","var","procedure","call" };void scaner()
{//规定,标识符只能由字母或数字构成/*共分为三大块,分别是标示符、数字、符号,对应下面的 if else if 和 else*///将全部置空for (n = 0; n<10; n++)//token为已捕获的字符数token[n] = NULL;ch = prog[p++];//这样处理,可以去除空格while (ch == ' '){ch = prog[p];p++;}//在这个if判断中,范围是a-z或者A-Z,因为规定变量只能以字母开头if ((ch >= 'a'&&ch <= 'z') || (ch >= 'A'&&ch <= 'Z')) //可能是标示符或者变量名{m = 0;//这里,是变量的第一个字符以后,可以是字母,数字while ((ch >= '0'&&ch <= '9') || (ch >= 'a'&&ch <= 'z') || (ch >= 'A'&&ch <= 'Z')){token[m++] = ch;ch = prog[p++];}//变量的字符串结束标志token[m++] = '\0';p--;syn = 10;//将识别出来的字符和已定义的标示符作比较, 判断是否是关键字,所有关键字都是小写for (n = 0; n<6; n++)if (strcmp(token, rwtab1[n]) == 0){syn = n + 1;break;}for (n = 0; n < 4;n++){if (strcmp(token, rwtab2[n]) == 0){syn = n + 31;break;}}}else if ((ch >= '0'&&ch <= '9')) //数字 ,如果是数字,就用sum来保存这个数字{sum = 0;while ((ch >= '0'&&ch <= '9')){//这里*10是只考虑十进制数sum = sum * 10 + ch - '0';ch = prog[p++];}p--;syn = 11;//可接收的数字的最大值为32767,如果更大,会报错if (sum>32767)syn = -1;}else switch (ch) //如果是其他的字符{case '<':m = 0;token[m++] = ch;ch = prog[p++];if (ch == '>'){//说明是不等号syn = 21;token[m++] = ch;}else if (ch == '='){//说明是<=syn = 22;token[m++] = ch;}else{//否则,就只是一个<符号syn = 23;//此时p回退一个p--;}break;case '>':m = 0;token[m++] = ch;ch = prog[p++];if (ch == '='){syn = 24;token[m++] = ch;}else{syn = 20;p--;}break;case ':':m = 0;token[m++] = ch;ch = prog[p++];if (ch == '='){//说明是赋值运算符syn = 18;token[m++] = ch;}else{//否则就只是个:syn = 17;p--;}break;case '*':syn = 13;token[0] = ch;break;case '/':syn = 14;token[0] = ch;break;case '+':syn = 15;token[0] = ch;break;case '-':syn = 16;token[0] = ch;break;case '=':syn = 25;token[0] = ch;break;case ';':syn = 26;token[0] = ch;break;case '(':syn = 27;token[0] = ch;break;case ')':syn = 28;token[0] = ch;break;case ',':syn = 29;token[0] = ch;break;case '!':syn = 30;token[0] = ch;break;case '.'://如果接收到的是.,说明到了源代码的结尾,置syn=0,函数结束syn = 0;token[0] = ch;break;case '\n'://如果接收到的是换行符,则syn=-2,行+1syn = -2;break;default://如果接收到的是其他未定义的字符,置syn=-1,会报错。syn = -1;break;}
}/*
读取源代码文件(.txt)
*/
void read()
{FILE *fp;fp = fopen(CODE, "r");fseek(fp, 0, SEEK_END);int file_size;file_size = ftell(fp);fseek(fp, 0, SEEK_SET);prog = (char *)malloc(file_size * sizeof(char));fread(prog, file_size, sizeof(char), fp);//关闭文件流fclose(fp);
}int main()
{int p = 0;int line = 1;ofstream outfile(RESULT);cout<< "加载代码文件中......" << endl;Sleep(3000);//读取源代码文件read();p = 0;outfile << "词法分析的结果为:" << endl;do{scaner();switch (syn){case 11://cout << "(" << syn << "," << sum << ")" << endl;outfile << "(" << syn << "," << sum << ")" << endl;break;case -1://cout << "Error in line " << line << "!" << endl;outfile << "Error in line" << line << "!" << endl;break;case -2:line = line++;break;default://cout << "(" << syn << "," << token << ")" << endl;outfile << "(" << syn << "," << token << ")" << endl;break;}} while (syn != 0);outfile.close();cout << "词法分析完毕,请在result.txt中查看" << endl;system("pause");return 0;
}
pl/0 程序
var m, n, r, q;
procedure gcd;
begin
while r#0 do
begin
q := m / n;
r := m - q * n;
m := n;
n := r;
end;
end;
begin
read(m);
read(n);
if m < n then
begin
r := m;
m := n;
n := r;
end;
begin
r:=1;
call gcd;
write(m);
end;
end.
输出结果
#
#
using---->25
namespace---->25
std---->25
;------->41
int---->7
main---->1
(------->42
)------->43
const---->18
string---->25
str---->25
=------->38
hello---->25
;------->41
const---->18
string---->25
str2---->25
=------->38
world---->25
;------->41
string---->25
n_str---->25
;------->41
n_str---->25
=------->38
str---->25
;------->41
n_str---->25
+------->27
=------->38
str2---->25
;------->41
cout---->25
<------>33
<------>33
n_str---->25
<------>33
<------>33
endl---->25
;------->41
return---->17
0------>26
;------->41
总结
以上是生活随笔 为你收集整理的pl/0词法分析器 的全部内容,希望文章能够帮你解决所遇到的问题。
如果觉得生活随笔 网站内容还不错,欢迎将生活随笔 推荐给好友。