编译原理 词法分析器

输入以#结束,不能输入没有定义的字符。

1、 待分析的简单的词法

1)关键字共9个:

   main,int,char,if,,else,for,while,do,end

所有的关键字都是小写。

2)运算符和界符

  = ** <= , >= := ,/

3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义:

ID = IsLetter (IsLetter  IsDigit*)

NUM = IsDigit  IsDigit*

illegal= IsDigit  IsLetter*(还包括一些没有定义的字符)

2.各种单词符号对应的种别码

单词符号

种别编码

单词符号

种别编码

Illegal(不合法标识符)

0

*

14

Main

1

**

15

int

2

;

16

char

3

(

17

if

4

)

18

else

5

{

19

for

6

}

20

while

7

<

21

do

8

<=

22

end

9

>

23

ID(标识符)

10

>=

24

NUM(常数)

11

:

25

=

12

:=

26

+

13

/

27

源代码


#include <stdio.h>
#include <string.h>
#define N 100


char ch[100];


int Getchar();
void Reserve(int m,int n);
int IsLetter(int m);
int IsDigit(int n);


void main()
{


printf("请输入:\n");
gets(ch);  //得到输入的字符
Getchar();


}
//将小标前移,记录字母的下标
int Getchar()
{
int len=0,i=0,j=0;
while(ch[len]!='#')
len++;
while(ch[i]!='#')
{
if(len==0)
printf("请输入字符:");
else
{
while(ch[i]==' ')//如果字符串的最前面是空格,则继续搜索,直到遇到字符串为止
i++;
}
j=i; //将遇到的第一个数的小标赋值给j
if(IsLetter(i))//如果第一个数为字母
{
i++; //数组下标向前移一位
while(IsLetter(i)||IsDigit(i))//判断向前移的那位只要不是空格就向前移一位,直到接受到的字符为空格为止
i++;
}

else if(IsDigit(i))// 如果第一个数为数字
{
i++;
while(IsDigit(i)||IsLetter(i))//如果接下来的数也为数字,记录其下标
i++;
}
else if(ch[i]=='=')
i++;
else if(ch[i]=='+')
i++;
else if(ch[i]=='*')
{
i++;
if(ch[i]=='*')
i++;
}
else if(ch[i]==';')
i++;
else if(ch[i]=='(')
i++;
else if(ch[i]==')')
i++;
else if(ch[i]=='{')
i++;
else if(ch[i]=='}')
i++;
else if(ch[i]=='<')
{
i++;
if(ch[i]=='=')
i++;
}
else if(ch[i]=='>')
{
i++;
if(ch[i]=='=')
i++;
}
else if(ch[i]==':')
{
i++;
if(ch[i]=='=')
i++;
}
else if(ch[i]=='/')
i++;
else
i++;
Reserve(j,i);
}
return 0;
}
//记录种类编码,打印出每个字符串极其所对应的种类编码
void Reserve(int m,int n)
{
int i,t,syn=0;
char str[N];
char *key[9]={"main","int","char","if","else","for","while","do","end"};
t=n-m;
strncpy(str,ch+m,t);//一行字符串以空格为分复制到str中
str[t]='\0';
if(IsLetter(m))// 若str的第一个数为字母
{
for(i=0;i<9;i++)
if((strcmp(str,key[i]))==0)//与关键字做比较
syn=i+1;
if(syn==0) //若没有相匹配的关键字,则为标识符
syn=10;
}
else if(IsDigit(m))
{
m++;
while(IsDigit(m))
m++;
if(m<n)
syn=0;
else
syn=11;
}
else if(ch[m]=='=')
syn=12;
else if(ch[m]=='+')
syn=13;
else if(ch[m]=='*')
{
if(ch[m]==ch[m+1])
syn=15;
else
syn=14;
}
else if(ch[m]==';')
syn=16;
else if(ch[m]=='(')
syn=17;
else if(ch[m]==')')
syn=18;
else if(ch[m]=='{')
syn=19;
else if(ch[m]=='}')
syn=20;
else if(ch[m]=='<')
{
if(ch[m+1]=='=')
syn=22;
else
syn=21;
}
else if(ch[m]=='>')
{
if(ch[m+1]=='=')
syn=24;
else
syn=23;
}
else if(ch[m]==':')
{
if(ch[m+1]=='=')
syn=26;
else
syn=25;
}  
else if(ch[m]=='/')
syn=27;
else
syn=0;
printf("(%-10s %5d)\n",str,syn);
}


//判断是不是字母
int IsLetter(int m)
{
if(((ch[m]>='a')&& (ch[m]<='z'))||((ch[m]>='A')&& (ch[m]<='Z')))
return 1;
else 
return 0;
}
//判断是不是数字
int IsDigit(int n)
{
if((ch[n]>='0') && (ch[n]<='9'))
return 1;
else
return 0;
}

运行结果





















































































词法分析 一、实验目的: 通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。 编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。并依次输出各个单词的内部编单词符号自身值。(遇到错误时可显示“Error”,然后跳过错误部分继续显示) 二、实验说明 1、 词法分析器的功能和输出格式 词法分析器的功能是输入源程序,输出单词符号。词法分析器单词符号常常表示成以下的二元式(单词种别单词符号的属性值)。本实验中,采用的是一类符号一种别的方式。 2、 单词的BNF表示 -> ->|| |ε -> -> |ε -> + -> - -> > -> >= 三、实验要求 (一)准备: 1.阅读课本有关章节,明确语言的语法,写出基本保留字、标识符、常数、运算符、分隔符和程序例。 2.初步编制好程序。 3.准备好多组测试数据。 (二)上课上机: 将源代码拷贝到机上调试,发现错误,再修改完善。 第二次上机调试通过。 (三)程序要求: 程序输入/输出示例: 如源程序为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语言子集的源程序作为词法分析程序的输入数据。在词法分析中,自文件头开始扫描源程序字符,一旦发现符合“单词”定义的源程序字符串时,将它翻译成固定长度的单词内部表示,并查填适当的信息表。经过词法分析后,源程序字符串(源程序的外部表示)被翻译成具有等长信息的单词串(源程序的内部表示),并产生两个表格:常数表和标识符表,它们分别包含了源程序中的所有常数和所有标识符。 0.定义部分:定义常量、变量、数据结构。 1.初始化:从文件将源程序全部输入到字符缓冲区中。 2.取单词前:去掉多余空白。 3.取单词后:去掉多余空白(可选,看着办)。 4.取单词:利用实验一的成果读出单词的每一个字符,组成单词,分析类型。(关键是如何判断取单词结束?取到的单词是什么类型的单词?)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值