版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011583316/article/details/83216684
词法分析
【实验目的】
通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。掌握对字符进行灵活处理的方法。
程序开始变得复杂起来,可能是大家目前编过的程序中最复杂的,但相对于以后的程序来说还是简单的。因此要认真把握这个过渡期的练习。
【实验内容】
编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。并依次输出各个单词的内部编码及单词符号自身值。(遇到错误时可显示“Error”,然后跳过错误部分继续显示)
程序要求:
程序输入/输出示例:
如源程序为C语言。输入如下一段:
main()
{
int a,b;
a = 10;
b = a + 20;
}
要求输出如下图。
(2,”main”)
(5,”(“)
(5,”)“)
(5,”{“)
(1,”int”)
(2,”a”)
(5,”,”)
(2,”b”)
(5,”;”)
(2,”a”)
(4,”=”)
(3,”10”)
(5,”;”)
(2,”b”)
(4,”=”)
(2,”a”)
(4,”+”)
(3,”20”)
(5,”;”)
(5,”)“)
要求:
- 识别保留字:if、int、for、while、do、return、break、continue;
- 单词种别码为1。
- 其他的都识别为标识符;单词种别码为2。
- 常数为无符号整形数;单词种别码为3。
- 运算符包括:+、-、*、/、=、>、<、>=、<=、!= ;单词种别码为4。
- 分隔符包括:,、;、{、}、(、); 单词种别码为5。
代码C语言版
#include <stdio.h>
#include <ctype.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
#define NULL 0
FILE *fp;
char cbuffer;
char *key[8]={"if","int","for","while","do","return","break","continue"};
char *border[6]={",",";","{","}","(",")"};
char *arithmetic[4]={"+","-","*","/"};
char *relation[6]={"<","<=","=",">",">=","!="};
char *consts[20];
char *label[20];
char *digitproc[20]={"10","20"};
int constnum=0,labelnum=0;
int search(char searchchar[],int wordtype)
{
int i=0;
switch (wordtype) {
// 判断是否为保留字
case 1:for (i=0;i<=7;i++)
{
if (strcmp(key[i],searchchar)==0) // 比较两个字符串 相等就 回0
return(i+1); // 返回对应的关键字的数组下标
}
// 判断是否是 2 类标识符
case 2:{for (i=0;i<=5;i++)
{
if (strcmp(border[i],searchchar)==0)
return(i+1);
} return(0);
}
// 判断是否是 3 类表示符
case 3:{for (i=0;i<=3;i++)
{
if (strcmp(arithmetic[i],searchchar)==0)
{
return(i+1);
}
}
return(0);
}
// 判断是否是 4类标识符
case 4:{for (i=0;i<=5;i++)
{
if (strcmp(relation[i],searchchar)==0)
{
return(i+1);
}
}
return(0);
}
// 判断无符号无符号整形数
case 5:for (i=0;i<=7;i++)
{
if (strcmp(digitproc[i],searchchar)==0)
return(i+1);
}
}
}
char alphaprocess(char buffer)
{
int atype=0;
int i=-1;
char alphatp[20];
while ((isalpha(buffer))||(isdigit(buffer))) // 判断 如果是英文字母或数字
{
alphatp[++i]=buffer; // 将其读入字符数组里面
buffer=fgetc(fp); // 继续读取下一个
}
alphatp[i+1]='\0'; // 在后面添加\0
if (atype=search(alphatp,1)>0) // 判断是否有返回 其 他的都识别为标识符;单词种别码为2
{
printf("(1, “%s”)\n",alphatp);
}
else
{
printf("(2, “%s ”)\n",alphatp);
}
return(buffer);
}
char digitprocess(char buffer)
{
int i=-1;
char digittp[20];
int dtype;
while ((isdigit(buffer))) // 判断是否是数字
{
digittp[++i]=buffer; // 读入到 字符数组里
buffer=fgetc(fp); // 继续读入下一个
}
digittp[i+1]='\0'; // 在后面添加\0
printf("(3, “%s ”)\n",digittp); //第三种查找无符号型整型
return(buffer);
}
char otherprocess(char buffer)
{
int i=-1;
char othertp[20];
int otype,otypetp;
othertp[0]=buffer; // 存入0位 (
othertp[1]='\0'; // ( \0
if (otype=search(othertp,3))
{
printf("(4, “%s ”)\n",othertp);
buffer=fgetc(fp);
goto out;
}
if (otype=search(othertp,4))
{
buffer=fgetc(fp);
othertp[1]=buffer;
othertp[2]='\0';
if (otypetp=search(othertp,4)) //关系运算
{
printf("(4, “%s ”)\n\n",othertp);
goto out;
}
else
othertp[1]='\0';
printf("(4, “%s ”)\n",othertp);
goto out;
}
if (otype=search(othertp,2))
{
printf("(5, “%s ”)\n",othertp);
buffer=fgetc(fp);
goto out;
}
if ((buffer!='\n')&&(buffer!=' '))
printf("",buffer);
buffer=fgetc(fp);
out:
return(buffer);
}
int main()
{
if ((fp=fopen("example.c","r"))==NULL)
printf("error");
else
{
cbuffer = fgetc(fp);
while (cbuffer!=EOF)
{
if (isalpha(cbuffer))
cbuffer=alphaprocess(cbuffer);
else if (isdigit(cbuffer))
cbuffer=digitprocess(cbuffer);
else cbuffer=otherprocess(cbuffer);
}
printf("over\n");
getchar();
}
}
/*
识别保留字:if、int、for、while、do、return、break、continue; 1
其他的都识别为标识符;单词种别码为 2。
常数为无符号整形数;单词种别码为 3。
运算符包括:+、-、*、/、=、>、<、>=、<=、!= ;单词种别码为 4。
分隔符包括:,、;、{、}、(、); 单词种别码为 5。*/
代码JAVA版
import java.io.File;
import java.io.FileReader;
/**
* 此程序是通过将文件的字符读取到字符数组中去,然后遍历数组,将读取的字符进行
* 分类并输出
*
*
识别保留字:if、int、for、while、do、return、break、continue; 1
其他的都识别为标识符;单词种别码为 2。
常数为无符号整形数;单词种别码为 3。
运算符包括:+、-、*、/、=、>、<、>=、<=、!= ;单词种别码为 4。
分隔符包括:,、;、{、}、(、); 单词种别码为 5。
* @author 丽丽超可爱
*
*/
public class WordAnalyze {
private String keyWord[] = {"if","int","for","while","do","return","break","continue"};
private char ch;
//判断是否是保留字
boolean isKey(String str)
{
for(int i = 0;i < keyWord.length;i++)
{
if(keyWord[i].equals(str))
return true;
}
return false;
}
//判断是否是字母
boolean isLetter(char letter)
{
if((letter >= 'a' && letter <= 'z')||(letter >= 'A' && letter <= 'Z'))
return true;
else
return false;
}
//判断是否是数字
boolean isDigit(char digit)
{
if(digit >= '0' && digit <= '9')
return true;
else
return false;
}
//词法分析
void analyze(char[] chars)
{
String arr = "";
for(int i = 0;i< chars.length;i++) {
ch = chars[i];
arr = "";
if(ch == ' '||ch == '\t'||ch == '\n'||ch == '\r'){}
else if(isLetter(ch)){
while(isLetter(ch)||isDigit(ch)){
arr += ch;
ch = chars[++i];
}
//回退一个字符
i--;
if(isKey(arr)){
//保留字
System.out.println("(1,"+arr+")");
}
else{
//标识符
System.out.println("(2,"+arr+")");
}
}
else if(isDigit(ch))
{
while(isDigit(ch))
{
arr = arr + ch;
ch = chars[++i];
}
//属于无符号常数
System.out.println("(3,"+arr+")");
}
else switch(ch){
//运算符
case '+':System.out.println("(4,"+ch+")");break;
case '-':System.out.println("(4,"+ch+")");break;
case '*':System.out.println("(4,"+ch+")");break;
case '/':System.out.println("(4,"+ch+")");break;
//分界符
case '(':System.out.println("(5,"+ch+")");break;
case ')':System.out.println("(5,"+ch+")");break;
case '[':System.out.println("(5,"+ch+")");break;
case ']':System.out.println("(5,"+ch+")");break;
case ';':System.out.println("(5,"+ch+")");break;
case '{':System.out.println("(5,"+ch+")");break;
case '}':System.out.println("(5,"+ch+")");break;
//运算符
case '=':{
ch = chars[++i];
if(ch == '=')System.out.println("(4,==)");
else {
System.out.println("(4,=)");
i--;
}
}break;
case '>':{
ch = chars[++i];
if(ch == '=')System.out.println("(4,>=)");
else {
System.out.println("(4,>)");
i--;
}
}break;
case '<':{
ch = chars[++i];
if(ch == '=')System.out.println("(4,<=)");
else {
System.out.println("(4,<)");
i--;
}
}break;
case '!':{
ch = chars[++i];
if(ch == '=')System.out.println("(4,!=)");
else {
i--;
}
}break;
}
}
}
public static void main(String[] args) throws Exception {
File file = new File("C:\\Users\\丽丽超可爱\\Desktop\\example.c");
FileReader reader = new FileReader(file);
int length = (int) file.length();
char buf[] = new char[length+1];
reader.read(buf);
System.out.println(buf); //测试
reader.close();
new WordAnalyze().analyze(buf);
}
}