现在的位置: 首页 > 综合 > 正文

【编译原理】一个词法分析器源码的剖析

2013年05月16日 ⁄ 综合 ⁄ 共 3492字 ⁄ 字号 评论关闭

一,词法分析器

        作用:读取源程序的输入字符、将他们组成词素,生成并输出一个词法单元序列

二,设计原理

        1)C程序语言的符号分类:关键字、标识符、常数、运算符、界符

        2)词法分析器的二元输出:<单词种别,单词符号属性值>

        3)正规式和状态转换图

 

           4)程序说明:

                               1>main 中打开源码文件,从第一个字符流读取

                               2>如果第一个是字符,则交给letterprocess(str); 处理

                               3>如果第一个是数字,则交给numberprocess(str); 处理

                               4>如果第一个是数字,则交给otherprocess(str); 处理

                               5>注意上述过程中,File *fp每读取一个词素,fp都会移动到下一个词素。对于空格的处理:isspace(ch)检查参数c是否为空格字符,也就是判断是否为空格('')、定位字符

  ('\t')、CR('\r')、换行('\n')、垂直定位字符('\v')或翻页('\f')的情况

                 这个程序输出结果情况汇总:关键字、算术运算符、关系运算符、分割符号、特殊符号、注释符号、逻辑运算符、非法符号

三,程序源码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <malloc.h>
#include <conio.h>
#define NULL 0
FILE *fp;
char ch;
char *keyword[34]={"auto","break","case","char","const","continue","default","do","double", 
"else","enum","extern","float","for","goto","if","int","long","register", 
"return","short","signed","sizeof","static","struct","switch","typedef", "printf",
"union","unsigned","void","volatile","while","main"};
char *operatornum[6]={"+","-","*","/","++","--"};
char *comparison[8]={"<","<=","=",">",">=","<>","==","!="};
char *interpunction[8]={",",";",":=",".","(",")","{","}"};
char *biaoshifu[6]={"%","$","^","&","_","#"};//特殊标识符
char *zhushifu[3]={"//","/*","*/"};//注释符
char *luoji[3]={"&&","||","!"};//逻辑运算符


bool search(char searchstr[],int wordtype)//符号匹配 
{
	int i;
	switch (wordtype)
	{
		case 1:
			for(i=0;i<=33;i++)
			{
      			if(strcmp(keyword[i],searchstr)==0)
       			return(true);
     		}
     		break;
		case 2:
  			for(i=0;i<=5;i++)
  			{
   				if(strcmp(operatornum[i],searchstr)==0)
    			return(true);
	 		}
 		 break;
     		
 		case 3: 
 			for(i=0;i<=7;i++)
   			{
   			 if(strcmp(comparison[i],searchstr)==0)
     			return(true);
 			}
 			break;
   
		case 4: 
			for(i=0;i<=7;i++)
   			{
    			if(strcmp(interpunction[i],searchstr)==0)
     			return(true);
   			}
  
		    break;
		case 5: 
			for(i=0;i<=5;i++)
   			{
    			if(strcmp(biaoshifu[i],searchstr)==0)
     				return(true);
   			}
            break;
		case 6:
			 for(i=0;i<=2;i++)
   		 	 {
   			 	if(strcmp(zhushifu[i],searchstr)==0)
     				return(true);
   		 	}
		    break;
		case 7: 
			for(i=0;i<=2;i++)
			{
    			if(strcmp(luoji[i],searchstr)==0)
     				return(true);
   			}
        break;
    }

	return false;
}

char letterprocess (char ch)//字母处理函数
{
	int i=-1;
	char letter[20];
	while (isalnum(ch)!=0)
	{
  		letter[++i]=ch;
  		ch=fgetc(fp);
	}
	letter[i+1]='\0';
	if (search(letter,1))
	{
  		printf("<%s,关键字>\n",letter);
  		//strcat(letter,"\n");
  		//fputs('<' letter '>\n',outp);
	}
	else
	{
  		printf("<%s,自定义变量>\n",letter);
  		//strcat(letter,"\n");
  		//fputs(letter,outp);
	}

	return(ch);
}

char numberprocess(char ch)//数字处理程序
{
	int i=-1;
	char num[20];
	while (isdigit(ch)!=0)
	{
  		num[++i]=ch;
  		ch=fgetc(fp);
	}
	if(isalpha(ch)!=0)//数字后面是字符 
	{
  		while(isspace(ch)==0)
  		{
   			num[++i]=ch;
            ch=fgetc(fp);
  		}
  		num[i+1]='\0';
  		printf("错误!非法标识符:%s\n",num);
  	goto u;
	}
	num[i+1]='\0';
    printf("<%s,数字>\n",num);

	u: return(ch);
}

char otherprocess(char ch)//其他处理程序 
{
	int i=-1;
	char other[20];
	if (isspace(ch)!=0)
	{
  		ch=fgetc(fp);
  		goto u;
	}
	while ((isspace(ch)==0)&&(isalnum(ch)==0))
	{
  		other[++i]=ch;
  		ch=fgetc(fp);
	}
	other[i+1]='\0';
	if (search(other,2))
  		printf("<%s,算数运算符>\n",other);
	else if (search(other,3))
   		printf("<%s,关系运算符号>\n",other);
	else if (search(other,4))
    	printf("<%s,分隔符号>\n",other);
	else if (search(other,5))
  		printf("<%s,特殊标识符号>\n",other);
    else if (search(other,6))
        printf("<%s,注释符号>\n",other);
    else if (search(other,7))
        printf("<%s,逻辑运算符号>\n",other);
    else 
        printf("错误!非法字符:%s\n",other);
    u: return (ch);
}

int main ()
{
	char str;
	printf("**********************************词法分析器************************************\n");
	if ((fp=fopen("源程序.txt","r"))==NULL)
  		printf("源程序无法打开!\n");
	else
	{
  		str =fgetc(fp);//从流中读取字符 
  		while (str!=EOF)
  		{
   			if (isalpha(str)!=0)//如果是字符    isalpha包含在#include <cctype>
    			str=letterprocess(str);
   		    else
   			{
    			if (isdigit(str)!=0)
     				str=numberprocess(str);
    			else
     				str=otherprocess(str);
  		    }
    
  		};
     printf("词法分析结束,谢谢使用!\n");
     //printf("点任意键退出!\n");
   }
   //c=getch();
   
   return 0;
}

抱歉!评论已关闭.