《编译原理》实验报告
班级:计C104
姓名:李云霄
学号:108490

实验一  词法分析程序实现
一、实验目的与要求
通过编写和调试一个词法分析程序,掌握在对程序设计语言的源程序进行扫描的过程中,将字符形式的源程序流转化为一个由各类单词符号组成的流的词法分析方法。
二、实验内容
选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来。
输入:由无符号数和+,-,*/, ( , ) 构成的算术表达式,如1.5E+2100
输出:对识别出的每一单词均单行输出其类别码(无符号数的值暂不要求计算)。
三、实现方法与环境
1、首先设计识别各类单词的状态转换图。
描述无符号常数的确定、最小化状态转换图如图1所示。其中编号012,…,6代表非终结符号<printf怎么实现的无符号数><余留无符号数><十进小数><小数部分><指数部分><整指数><余留整指数> 126为终态,分别代表整数、小数和科学计数的识别结束状态。
1 文法G[<无符号数>]的状态转换图
其中编号012,…,6代表非终结符号<无符号数><余留无符号数><十进小数><
数部分><指数部分><整指数><余留整指数> 126为终态,分别代表整数、小数和科学计数的识别结束状态。
在一个程序设计语言中,一般都含有若干类单词符号,为此可首先为每类单词建立一张状态转换图,然后将这些状态转换图合并成一张统一的状态图,即得到了一个有限自动机,再进行必要的确定化和状态数最小化处理,最后据此构造词法分析程序。
四则运算算术符号的识别很简单,直接在状态图的0状态分别引出相应标记的矢线至一个新的终态即可。根据自己的习惯,也可以将其转换为状态矩阵形式。
2、词法分析程序编写
根据描述语言中各类单词的文法状态转换图或状态矩阵,利用某种语言(C语言或JAVA语言)直接编写词法分析程序。
3、词法分析程序测试
用于测试扫描器的实例源文件中应有词法正确的,也应有错误的字符串,对于输入的测试用例的源程序文件,以对照的形式将扫描器的分析结果信息在输出文件中表示出来。
4、实验源程序
#include"stdafx.h"
#include<stdio.h>
#include<string>
char test[100],comp[100];
char ch;
int num,p;
void scan();
void main()
{
    p=0;
    printf("Please input string and  Use '#' as an finish operator :\n");
    do
    {
        scanf_s("%c",&ch);
        test[++p]=ch;
    }
    while(ch!='#');
    p=0;       
    ch=test[++p];
    while(ch=='\n' || ch==' ')
    ch=test[++p];
    int m=1;
    while(m)
    {
        switch(ch)
        {           
        case '0':scan();break;
        case '1':scan();break;
        case '2':scan();break;
        case '3':scan();break;
        case '4':scan();break;
        case '5':scan();break;
        case '6':scan();break;
        case '7':scan();break;
        case '8':scan();break;
        case '9':scan();break;
        case '+':num=2;printf("\n(类别码:%d,值:%c)",num,ch);comp[m++]=ch;ch=test[++p];break;
        case '-':num=3;printf("\n(类别码:%d,值:%c)",num,ch);comp[m++]=ch;ch=test[++p];break;
        case '*':num=4;printf("\n(类别码:%d,值:%c)",num,ch);comp[m++]=ch;ch=test[++p];break;
        case '/':num=5;printf("\n(类别码:%d,值:%c)",num,ch);comp[m++]=ch;ch=test[++p];break;
        case '(':num=6;printf("\n(类别码:%d,值:%c)",num,ch);comp[m++]=ch;ch=test[++p];break;
        case ')':num=7;printf("\n(类别码:%d,值:%c)",num,ch);comp[m++]=ch;ch=test[++p];break;
        case '#':m=0;break;
        default :num=0;printf("\n(非法符号:%d,值:%c)",num,ch);comp[m++]=ch;ch=test[++p];break;
        }
    }
}
void scan()
{     
       
        int m=0;
        while(ch>='0'&&ch<='9')
        {
            comp[m++]=ch;
            ch=test[++p];
            if(ch=='E'|| ch=='e')
            {
            comp[m++]=ch;
            ch=test[++p];   
            comp[m++]=ch;
            ch=test[++p];
            }
            if(ch=='.')
            {
            comp[m++]=ch;
            ch=test[++p];
            }
        }
        num=1;
        printf("\n(类别码:%d,值:%s)",num,comp);   
        for (int n=m;n>=0;n--)
            comp[n]='\0';
}
5、实验过程
六、实验结果
7、实验心得
实验一很艰难:我一眼就能看出来的事,破电脑愣是读不出来
总结:程序来自网络,截图绝对原创。

实验二  语法分析程序实现
一、实验目的与要求
通过设计、编制、调试典型的SLR1)语法分析程序,实现对实验一所得词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。
二、实验内容
选择对各种常见高级程序设计语言都较为通用的语法结构无符号数的算术四则运算作为分析对象,给出其文法描述(注意应与所采用的语法分析方法比较贴近),设计并实现一个完整的语法分析程序。
输入由实验一输出的单词类别串,如131
输出对于所输入的源程序,如果输入符号串是给定文法定义的合法句子,则输出“RIGHT”,并且给出每一步归约的过程;如果不是句子,即输入串有错误,则输出“ERROR”,并且显示已经归约出的各个文法符号,以及必要的出错说明信息。
三、实现方法与环境
1、首先根据算术四则运算的语法定义,构造SLR1)分析表。
无符号数的算术四则运算的语法可表示为:
E->E+T| E-T|T
T->T*F| T/F|F
F->(E)|i
2、语法分析程序编写
设置输入缓冲区、状态栈、符号栈,并根据SLR1)分析表利用某种语言(C语言或JAVA语言)直接编写移进、归约、接受子程序,编写语法分析程序。
3、语法分析程序测试
用于测试的实例源文件中应有语法正确的,也应有语法错误的符号串,以对照的形式将分析结果信息在输出文件中表示出来。
4、实验源程序
#include "StdAfx.h"
#include<iostream>
using namespace std;
#include<stdio.h>
#include<string.h>
#define MAX 150      //词洙_法ぁ_??表括_??大洙_容╕量?
#define MAXBUF 255  //o????大洙_o??
void term();
void lrparser();
void statement();
void yucu();
void expression();
void factor();
char prog[MAXBUF],token[MAX]; 
char ch;
int syn,p,m,n,sum,kk;
char * rwtab[6]={"begin","if","then","while","do","end"};
//////////////////////////////////////////////////////////
/*词洙_法ぁ_扫Α_描è程ì序ò:阰*/
void scaner()
{
for(m=0;m<MAX;m++)
  token[m]=NULL;
  m=0;sum=0;
  ch=prog[p++];
  while(ch==' ')ch=prog[p++];
  if((ch<='z'&&ch>='a')||(ch<='Z'&&ch>='A'))
  {
  while((ch<='z'&&ch>='a')||(ch<='Z'&&ch>='A')||(ch<='9'&&ch>='0'))
  {
    token[m++]=ch;
    ch=prog[p++];  //读á取??????
    }
  token[m++]='\0';
  ch=prog[--p];
  syn=10;
  for(n=0;n<6;n++)
      if(strcmp(token,rwtab[n])==0)
      {
        syn=n+1;  //??syn值μ
        break;
        }
    }
  else
      if((ch<='9'&&ch>='0'))
        {
          sum=0;
          while((ch<='9'&&ch>='0'))
          {
          sum=sum*10+ch-'0';
          ch=prog[p++];
          }
          ch=prog[--p];
          syn=11;
          }
      else
        switch(ch)
          {
          case '<':m=0;token[m++]=ch;
                  ch=prog[p++];

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。