zoukankan      html  css  js  c++  java
  • 实现一个词法分析器

    一、实验目的:

            设计、编制、调试一个词法分析子程序-识别单词,加深对词法分析原理的理解。

    二、实验要求:

    1.对给定的程序通过词法分析器弄够识别一个个单词符号,并以二元式(单词种别码,单词符号的属性值)显示。而本程序则是通过对给定路径的文件的分析后以单词符号和文字提示显示。

    2.本程序自行规定:

    (1)关键字"begin","end","if","then","else","while","write","read",

    "do", "call","const","char","until","procedure","repeat"

    (2)运算符:"+","-","*","/","="

    (3)界符:"{","}","[","]",";",",",".","(",")",":"

    (4)其他标记 如字符串,表示以字母开头的标识符。
    (5)空格、回车、换行符跳过。

    在屏幕上显示如下:
    ( 1 , 无符号整数)

    ( begin , 关键字 )

    ( if , 关键字 )

    ( +, 运算符 )

    ( ; , 界符 )
    ( a , 普通标识符 )

    三、使用环境:
    Windows下的visual c++6.0;

    四、调试程序:

    1.举例说明

    文件位置:f:、、11.txt

    目标程序如下:

        begin

    x:=9

    if x>0 then x:=x+1;

    while a:=0 do

    b:=2*x/3;

    end;

    2.运行结果:

    编译原理 <wbr>词法分析器 <wbr>实验报告

    五、程序源代码:

    #include <iostream>

    #include<string>

    using namespace std;

    #define  MAX 22          

    char ch =' ';

    string key[15]={"begin","end","if","then","else","while","write","read",

    "do", "call","const","char","until","procedure","repeat"};

    int Iskey(string c){         //关键字判断

       int i;

       for(i=0;i<MAX;i++) {

          if(key[i].compare(c)==0) return 1;

           } 

        return 0;

    }

    int IsLetter(char c) {        //判断是否为字母

        if(((c<='z')&&(c>='a'))||((c<='Z')&&(c>='A'))) return 1;

        else return 0;

    }

    int IsDigit(char c){          //判断是否为数字

         if(c>='0'&&c<='9') return 1;

         else return 0;

    }

    void analyse(FILE *fpin){

        string arr="";          

        while((ch=fgetc(fpin))!=EOF) {

                arr="";        

             if(ch==' '||ch==' '||ch==' '){}     

             else if(IsLetter(ch)){

                     while(IsLetter(ch)||IsDigit(ch)) {

                                    if((ch<='Z')&&(ch>='A')) ch=ch+32;   

                                 arr=arr+ch;

                        ch=fgetc(fpin);

                                   }

                     fseek(fpin,-1L,SEEK_CUR);    

                     if (Iskey(arr)){cout<<arr<<" $关键字"<<endl;}     

                     else  cout<<arr<<" $普通标识符"<<endl;           

                   }

          

                else if(IsDigit(ch)){

                      while(IsDigit(ch)||ch=='.'&&IsDigit(fgetc(fpin))){

                            arr=arr+ch;

                            ch=fgetc(fpin);

                           }

                      fseek(fpin,-1L,SEEK_CUR);

                      cout<<arr<<" $无符号实数"<<endl;  

                 }

           else switch(ch){          

                   case'+':

                   case'-' :

                   case'*' :

                   case'=' :

                   case'/' :cout<<ch<<" $运算符"<<endl;break;

                   case'(' :

                   case')' :

                   case'[' :

                   case']' :               

                   case';' :

                   case'.' :

                   case',' :

                   case'{' :

                   case'}' :cout<<ch<<" $界符"<<endl;break;

                   case':' :{ch=fgetc(fpin);

                            if(ch=='=') cout<<":="<<" $运算符"<<endl;

                            else {cout<<"="<<" $运算符"<<endl;;

                                   fseek(fpin,-1L,SEEK_CUR);}

                            }break;

    case'>' :{ch=fgetc(fpin);

                             if(ch=='=') cout<<">="<<" $运算符"<<endl;

                             if(ch=='>')cout<<">>"<<" $输入控制符"<<endl;

                             else {cout<<">"<<" $运算符"<<endl;

                                 fseek(fpin,-1L,SEEK_CUR);}

                             }break;

                   case'<' :{ch=fgetc(fpin);

                             if(ch=='=')cout<<"<="<<" $运算符"<<endl;

                             else if(ch=='<')cout<<"<<"<<" $输出控制符"<<endl;

                             else if(ch=='>') cout<<"<>"<<" $运算符"<<endl;

                             else{cout<<"<"<<" $运算符"<<endl;

                                fseek(fpin,-1L,SEEK_CUR);}

                            }break;

                  default : cout<<ch<<" $无法识别字符"<<endl;

            }

        }

    }

    void main(){

       char in_fn[30];

       FILE * fpin;

       cout<<"请输入源文件名(包括路径和后缀名):";

       for(;;){

           cin>>in_fn;

           if((fpin=fopen(in_fn,"r"))!=NULL) break;

           else cout<<"文件路径错误!请输入源文件名(包括路径和后缀名):";

         }

       cout<<" ********************分析如下*********************"<<endl;

       analyse(fpin);

       fclose(fpin);

    }

    六、实验心得:

       通过此次实验,让我了解到如何设计、编制并调试词法分析程序,加深对词法分析原理的理解;熟悉了构造词法分析程序的手工方式的相关原理,使用某种高级语言(例如C++语言)直接编写此法分析程序。另外,也让我重新熟悉了C++语言的相关内容,加深了对C++语言的用途的理解。

    高山仰止, 景行行止。 四牡鲱鲱, 六辔如琴。 觏尔新婚, 以慰我心。
  • 相关阅读:
    自己写的一个读取execl的帮助类
    手动获取spring的ApplicationContext和bean对象
    前端开发不容错过的jQuery图片滑块插件(转)
    细说HTML元素的隐藏和显示
    DIV+CSS布局重新学习之使用A标签和CSS制作按钮
    opencv2函数学习之flip:实现图像翻转
    DWZ中Tree树形菜单的treeCheck如何获取返回值解决方案
    DWZ中刷新dialog的方案解决
    DWZ与KindEditor编辑器的整合
    ViewModel在MVC3中的应用:实现多字段表格的部分更新
  • 原文地址:https://www.cnblogs.com/davidshi/p/3337130.html
Copyright © 2011-2022 走看看