zoukankan      html  css  js  c++  java
  • 第十二次作业

    一、实验目的:

    利用C语言编制递归下降分析程序,并对简单语言进行语法分析。

    编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。

    二、实验原理

    每个非终结符都对应一个子程序。

    该子程序根据下一个输入符号(SELECT集)来确定按照哪一个产生式进行处理,再根据该产生式的右端:

    • 每遇到一个终结符,则判断当前读入的单词是否与该终结符相匹配,若匹配,再读取下一个单词继续分析;不匹配,则进行出错处理
    • 每遇到一个非终结符,则调用相应的子程序

    三、实验要求说明

    输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出“error”,并指出语法错误的类型及位置。

    例如:

    输入begin a:=9;x:=2*3;b:=a+x end #

    输出success

    输入x:=a+b*c  end #

    输出‘end' error

    四、实验步骤

    1.待分析的语言的语法(参考P90)

    2.将其改为文法表示,至少包含

    –语句

    –条件

    –表达式

    3. 消除其左递归

    4. 提取公共左因子

    5. SELECT集计算

    6. LL(1)文法判断

    7. 递归下降分析程序


    #include "wordscan.h"

    void lrparser();
    void yucu();
    void statement();
    void expression();
    void term();
    void factor();
    int kk=0;

    void lrparser() {
    if (syn==1) { //begin
    scaner();
    yucu();
    if (syn==6) { //end
    scaner();
    if (syn==0 && kk==0) printf("success ");
    } else {
    if(kk!=1) printf("error,lose 'end' ! ");
    kk=1;
    }
    } else {
    printf("error,lose 'begin' ! ");
    kk=1;
    }
    return;
    }

    void yucu() {
    statement();
    while(syn==26) {
    scaner();
    statement();
    }
    return;
    }

    void statement() {
    if (syn==10) { //为标识符
    scaner();
    if (syn==18) { //为 :=
    scaner();
    expression();
    } else {
    printf("error!");
    kk=1;
    }
    } else {
    printf("error!");
    kk=1;
    }
    return;
    }


    void expression() {
    term();
    while(syn==13 || syn==14) {
    scaner();
    term();
    }
    return;
    }


    void term() {
    factor();
    while(syn==15 || syn==16) {
    scaner();
    factor();
    }
    return;
    }


    void factor() {
    if(syn==10 || syn==11)scaner(); //为标识符或整常数时,读下一个单词符号
    else if(syn==27) {
    scaner();
    expression();
    if(syn==28)scaner();
    else {
    printf(" ')' 错误 ");
    kk=1;
    }
    } else {
    printf("表达式错误 ");
    kk=1;
    }
    return;
    }


    void main() {
    p=0;int i;
    printf("********************语法分析程序*************** ");
    printf("请输入源程序: ");
    do {
    scanf("%c",&ch);
    prog[p++]=ch;
    } while(ch!='#');
    p=0;
    scaner();
    lrparser();
    printf("语法分析结束! ");
    getch();
    }

    2.?编写扫描子程序?? wordscan.h

    #include "string.h"

    char prog[80],token[8];
    int syn,p,m,n,sum=0;
    char ch;
    char *rwtab[6]= {"begin","if","then","while","do","end"};
    void scaner() {
    m=0;
    for(n=0; n<8; n++) token[n]=NULL;
    ch=prog[p++];
    while(ch==' ') ch=prog[p++];
    if((ch>='a' && ch<='z') ||(ch>='A' && ch<='Z')) {
    while((ch>='a' && ch<='z') ||(ch>='A' && ch<='Z')||(ch>='0' && ch<='9')) {
    token[m++]=ch;
    ch=prog[p++];
    }
    token[m++]='';
    syn=10;
    p=p-1; //回退一个字符
    for(n=0; n<6; n++) {
    if(strcmp(token,rwtab[n])==0) {
    syn=n+1;
    break;
    }
    }
    } else if(ch>='0' && ch<='9') {
    sum=0;
    while(ch>='0' && ch<='9') {
    sum=sum*10+ch-'0';
    ch=prog[p++];
    }
    p=p-1;
    syn=11;
    } else {
    switch(ch) {
    case '<':
    m=0;
    token[m++]=ch;
    ch=prog[p];
    if(ch=='>') {
    syn=21;
    token[m++]=ch;
    } else if(ch=='=') {
    syn=22;
    token[m++]=ch;
    } else {
    syn=20;
    p=p-1;
    }
    p=p+1;
    token[m]='';
    break;
    case '>':
    m=0;
    token[m++]=ch;
    ch=prog[p++];
    if(ch=='=') {
    syn=24;
    token[m++]=ch;
    } else {
    syn=23;
    p=p-1;
    }
    break;
    case ':':
    m=0;
    token[m++]=ch;
    ch=prog[p++];
    if(ch=='=') {
    syn=18;
    token[m++]=ch;
    } else {
    syn=17;
    p=p-1;
    }
    break;
    case '+':
    syn=13;
    token[0]=ch;
    break;
    case '-':
    syn=14;
    token[0]=ch;
    break;
    case '*':
    syn=15;
    token[0]=ch;
    break;
    case '/':
    syn=16;
    token[0]=ch;
    break;
    case ';':
    syn=26;
    token[0]=ch;
    break;
    case '(':
    syn=27;
    token[0]=ch;
    break;
    case ')':
    syn=28;
    token[0]=ch;
    break;
    case '=':
    syn=25;
    token[0]=ch;
    break;
    case '#':
    syn=0;
    token[0]=ch;
    break;
    default:
    syn=-1;
    }
    }

  • 相关阅读:
    css解决display:inline-block;产生的缝隙(间隙)
    js二进制与十进制互转
    js获取HTTP的请求头信息
    安装WampServer时出现的问题(丢失VCRUNTIME140.dll或MSVCR110.dll)以及解决办法
    学习安装并配置前端自动化工具Gulp
    解决overflow:hidden在安卓微信页面没有效果的办法
    Python 调用 ES、Solr、Phoenix
    Python 调用 Hprose接口、Dubbo接口、Java方法
    Python调用Redis
    robot用例执行常用命令(转)
  • 原文地址:https://www.cnblogs.com/LipengC/p/11957957.html
Copyright © 2011-2022 走看看