java写词法分析程序_设计一个词法分析程序,实现对C程序设计语言的源程序(自定)的词法分析...

本文介绍了一个使用Java编写的词法分析程序,该程序用于对C语言源代码进行词法分析,包括识别保留字、标识符、无符号整数、运算符和界符。程序通过状态转换图进行单词切分和识别,有助于编译器的结构简化和效率提升。
摘要由CSDN通过智能技术生成

源码在最下面

内容:设计并实现一个词法分析器,实现对自己输入的类C语言源程序中的所有单词进行分类,指出其所属类型,实现简单的词法分析操作。

一.运行环境: win10         Microsoft Visual Studio 2010

二.原理:

大多数程序语言的单词符号可以用正规文法来描述,由正规文法可以构造出相应的状态转换图,由此状态转换图就可以方便地识别单词符号,因此由状态转换图就不难构造出相应单词词法分析程序。

依次读入源程序符号,对源程序进行单词切分和识别,直到源程序结束。

三.词法分析程序的输出:

PL/0语言的单词符号分类:

保留字、标识符、无符号整数、运算符、界符

构造状态转换图

对于上述基本符号用以下正规文法规则进行描述

 ::= |

 ::= ··字母|数字|字母

 ::=  +|-|*|/|=

 ::=  ,|;|{|}|(|)

从中可以看出,以上每一条规则所构成文法是一个左线性文法,由此可以画出各自的状态转换图。

c85733e077eabf375e4cba7511ac4780.png

因为词法分析程序是一个子程序,用来识别和分析各类单词符号,并且在识别出一个单词之后,将返回调用程序。故可以将各自状态转换图合并成一张状态转换图。

词法分析程序的构造

有了状态转换图很容易写出词法分析程序,我们可以把词法分析程序作为一个子程序来构造,当语法分析程序需要一个单词符号时就调用这个子程序。每一次调用,词法分析程序就从输入串中识别出一个单词符号。

定义单词种类与词法规则

①标识符:首字符为字母或下划线,其后由字母、数字或下划线组成 注:标识符长度不能超过20个字符。

②无符号整数:由十进制数字组成的一个序列。首位数字不能为0; 注:无符号整数不带正负号。

③ 保留字:procedure、call、begin、end、and、or、if、else、int、float、const、for、new、public、while、long、static、do、read、char、return、using、void、break、include、switch、continue、try、private、var、odd、then、write 注:保留字不区分大小写。

④ 运算符:+、-、 *、 /、 =、 、   <=、  >=、  !=、<>、  ==、#

⑤ 界符:      (   )    , ;{  }

四.将词法分析工作分离的考虑:

1.使整个编译程序的结构更简洁、清晰和条理化。

2.编译程序的效率会改进。

3.增强编译程序的可移植性。

词法分析程序的主要功能是从字符流的源程序中识别单词,它要从左至右逐个字符地扫描源程序,因此它还可完成其他一些任务。比如,滤掉源程序中的注释和空白(由空格、制表符或回车换行字符引起的空白);又如,为了使编译程序能将发现的错误信息与源程序的出错位置联系起来,词法分析程序负责记录新读入的字符行的行号,以便行号与出错信息相关联;再如,在支持宏处理功能的源语言中,可以由词法分析程序完成其预处理等。

例如下面为一段C语言源程序:

#include

void main()

{

int sum,n;

sum=0;

n=1

while(n<=100)

{

sum=sum+n;

n++;

}

printf("sum=",sum);

}

输入上述源程序后以“@”结束。运行输出:

9926a2df0fc850462d44b58c22d24446.png

五.说明:

1.程序运行后可以自己输入C语言源程序,以@符号结束

2. 程序运行过程中,会依次读入源程序符号,对源程序进行单词切分和识别,直到源程序结束。

3.cout是iostream类的一个对象,它重载了<

六.程序源码(用Microsoft Visual Studio 2010测试,真实有效,能正常运行)

#include

#include

#include

#include

#include

using namespace std;

//看是否为数字

bool NUMBER(char A)

{

if (A >= '0'&&A <= '9')

return true;

return false;

}

//看是否为字母

bool LETTER(char A)

{

if ((A >= 'A'&&A <= 'Z') || A >= 'a'&&A <= 'z')

return true;

return false;

}

bool RESERVEDWORD(char *a)

{

if (strcmp(a, "if") == 0||strcmp(a, "main") == 0||strcmp(a, "else") == 0)

{

cout << "保留字, '" << a << "'" << endl;

return true;

}

if (strcmp(a, "int") == 0||strcmp(a, "float") == 0||strcmp(a, "const") == 0)

{

cout << "保留字, '" << a << "'" << endl;

return true;

}

if (strcmp(a, "for") == 0||strcmp(a, "new") == 0||strcmp(a, "public") == 0)

{

cout << "保留字, '" << a << "'" << endl;

return true;

}

if (strcmp(a, "while") == 0||strcmp(a, "long") == 0||strcmp(a, "static") == 0)

{

cout << "保留字, '" << a << "'" << endl;

return true;

}

if (strcmp(a, "do") == 0||strcmp(a, "read") == 0||strcmp(a, "char") == 0)

{

cout << "保留字, '" << a << "'" << endl;

return true;

}

if (strcmp(a, "return") == 0||strcmp(a, "using") == 0||strcmp(a, "void") == 0)

{

cout << "保留字, '" << a << "'" << endl;

return true;

}

if (strcmp(a, "break") == 0||strcmp(a, "include") == 0||strcmp(a, "switch") == 0)

{

cout << "保留字, '" << a << "'" << endl;

return true;

}

if (strcmp(a, "continue") == 0||strcmp(a, "try") == 0||strcmp(a, "private") == 0)

{

cout << "保留字, '" << a << "'" << endl;

return true;

}

if (strcmp(a, "procedure") == 0||strcmp(a, "call") == 0||strcmp(a, "begin") == 0)

{

cout << "保留字, '" << a << "'" << endl;

return true;

}

if (strcmp(a, "end") == 0||strcmp(a, "and") == 0||strcmp(a, "or") == 0)

{

cout << "保留字, '" << a << "'" << endl;

return true;

}

if (strcmp(a, "var") == 0||strcmp(a, "odd") == 0||strcmp(a, "then") == 0)

{

cout << "保留字, '" << a << "'" << endl;

return true;

}

if (strcmp(a, "write") == 0)

{

cout << "保留字, '" << a << "'" << endl;

return true;

}

return false;

}

int main()

{

//保留字;标识符;无符号整数;运算符;界符。

char a;

FILE *f;

char CHAR;

char TOKEN\[120\];

f = fopen("write.txt", "w");   //创建文本文件code,保存输入的程序代码

if (f == NULL)

{

cout << "con't create file" << endl;

exit(0);

}

cout << "\\n请输入源程序  以“@”结束" << endl;

while ((a = getchar()) != '@')   //getchar() 是从控制台接收字符,注意只会接收一个字符

fputc(a, f);

fclose(f);

cout << "over\\n" << endl;

f = fopen("write.txt", "r");

while ((CHAR = fgetc(f)) != EOF)

{

while (CHAR != ' ')

{

if (LETTER(CHAR)) //如果以字母开头

{

int k = 0;

do {

TOKEN\[k\] = CHAR;

k++;

}

while ((CHAR = fgetc(f)) != EOF && CHAR != ' '&&LETTER(CHAR));

if (NUMBER(CHAR))//如果以数字开头

{

do {

TOKEN\[k\] = CHAR;

k++;

}

while ((CHAR = fgetc(f)) != EOF && CHAR != ' '&&NUMBER(CHAR));

}

TOKEN\[k\] = '\\0';

if (!(RESERVEDWORD(TOKEN)))        //判断标识符是否为保留字

cout << "标识符, '" << TOKEN << "'" << endl;

}

if (NUMBER(CHAR))              //整数情况

{

int i = 0;

do {

TOKEN\[i\] = CHAR;

i++;

}

while ((CHAR = fgetc(f)) != EOF && CHAR != ' '&&NUMBER(CHAR));

TOKEN\[i\] = '\\0';

if (!RESERVEDWORD(TOKEN))

cout << "无符号整数, '" << TOKEN << "'" << endl;

}

if (CHAR == '+' || CHAR == '-' || CHAR == '*' || CHAR == '/' || CHAR == '>' || CHAR == '=' || CHAR == '<=' || CHAR == '!='|| CHAR == '==')  //运算符情况

{

cout << "运算符, '" << CHAR << "'" << endl;

}

if (CHAR == ',' || CHAR == ';' || CHAR == '(' || CHAR == ')' || CHAR == '{' || CHAR == '}')   //界符情况

{

printf("界符: %c\\n",CHAR);

}

break;

}

}

fclose(f);

printf("按任意键退出...");

getch();

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值