自学内容网 自学内容网

SCAU 编译原理 实验二 语法分析

目录

一、实验目的

二、实验要求

1. 待分析的简单语言的语法用扩充的BNF表示如下:

2.实验要求说明

三、源码


一、实验目的

采用实验1的简单语言,设计并实现含多条简单赋值语句的语法分析程序,要求有一定的出错提示(什么位置什么错)与错误恢复功能。

二、实验要求

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

1. 待分析的简单语言的语法用扩充的BNF表示如下:

(1)<程序)::=begin<语句串>end

(2)<语句串)::=<语句>|;<语句》

(3)<语句)::=<赋值语句》

(4)<赋值语句)::=ID:=(表达式)

(5)<表达式)::=<项)|+<项)|-<项》

(6)<项)::=<因子)|*<因子)|/<因子>

(7)<因子)::= IDI NUMI(<表达式>)

2.实验要求说明


输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打印“suc-cess”,否则输出“error”。

例如:

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

输出 success

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

输出 error

三、源码

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

//函数申明

void match();          //匹配的方法

void Bparser();     //匹配begin

void Pre();           //对语法进行预处理

void statement();   //匹配语法声明

void expression();  //匹配运算符

void term();        //匹配*/运算符

void factor();      //匹配括号

char temp[500],test[500];

char ch;

char a;

const char *keyword[6]= {"begin","if","then","while","do","end"};   //存储保留字

int i=0,num,n,ednum=0,bnum=0,k=0;

//匹配的方法

void match() {

    ch=temp[i++];

    while(ch==' ') {

        ch=temp[i++];

    }

    if((ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z')) {        //保留字与标识符判断

        n=0;

        num=10;

        a=ch;

        while((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||(ch>='0'&&ch<='9')) { //字符串数组复制

            test[n++]=ch;

            ch=temp[i++];

        }

        test[n++]='\0';

        for(n=0; n<6; n++) {

            if(strcmp(test,keyword[n])==0) {  //判断两个字符串是否一致

                num=n+1;

                printf("[%s,%d]\n",test,num);

                if(num==1) {

                    bnum=1;//begin存在

                }

                if(num==6) {

                    ednum=1;//end存在

                }

                break;

            }

        }

        i--;

        if(num==10) {

            ch=a;

            printf("[%c,%d]\n",ch,num);

        }

    }

    if(ch>='0'&&ch<='9') {    //数字判断

        num=11;

        printf("[%c,%d]\n",ch,num);

    } else {

        switch(ch) {    //运算符界符的判断

            case '#':

                num=0;printf("[%c,%d]\n",ch,num);break;

            case '+':

                num=13;printf("[%c,%d]\n",ch,num);break;

            case '-':

                num=14;printf("[%c,%d]\n",ch,num);break;

            case '*':

                num=15;printf("[%c,%d]\n",ch,num);break;

            case '/':

                num=16;printf("[%c,%d]\n",ch,num);break;

            case ':':

                ch=temp[i++];

                if(ch=='=') {

                    num=18;

                    printf("[:%c,%d]\n",ch,num);

                } else {

                    i--;

                    ch=temp[i];

                    num=17;

                    printf("[%c,%d]\n",ch,num);

                }

                break;

                

            case '<':

                ch=temp[i++];

                if(ch=='=') {

                    num=21;

                    printf("[<%c,%d]\n",ch,num);

                } else if(ch='>') {

                    num=22;

                    printf("[<%c,%d]\n",ch,num);

                } else {

                    i--;

                    ch=temp[i];

                    num=20;

                    printf("[%c,%d]\n",ch,num);

                }

                break;

            case '>':

                ch=temp[i++];

                if(ch=='=') {

                    num=24;

                    printf("[>%c,%d]\n",ch,num);

                } else {

                    i--;

                    ch=temp[i];

                    num=23;

                    printf("[%c,%d]\n",ch,num);

                }

                break;

            case '=':

                num=25;printf("[%c,%d]\n",ch,num);break;

            case ';':

                num=26;printf("[%c,%d]\n",ch,num);break;

            case '(':

                num=27;printf("[%c,%d]\n",ch,num);break;

            case ')':

                num=28;printf("[%c,%d]\n",ch,num);break;

        }

    }

}

//对语法进行预处理,当匹配到分号时,进行一次match匹配下一个字符

void Pre() {   

    statement();

    while(num==26) {

        match();

        statement();

    }

    return;

}

//匹配begin、end

void Bparser() {   

    if(num==1) { //begin

        match();

        Pre();

        if(num==6){ //end

            match();

            if(num==0 && k==0){

                printf("【Success】分析完成!\n");

            }

        }else if(num==0 && ednum!=1){

            printf("【error】缺失'end'\n");

            k=1;

        }

    }else{

        Pre();

        printf("【error】缺失'begin'\n");

    }

    return;

}

//匹配语法声明

void statement() {  

    if (num==10) {   

        match();

        if(num==18) { //为 :=

            match();

            expression();

        } else {

            printf("【error】缺失符号':='\n");

            k=1;

        }

    }else{

        printf("【error】'表达式错误'\n");

        k=1;

    }

    return;

}

//匹配+-运算符

void expression() {  

    term();

    while(num==13||num==14) {

        match();

        term();

    }

    return;

}

//匹配*/运算符

void term() {   

    factor();

    while(num==15||num==16) {

        match();

        factor();

    }

    return;

}

//为标识符或整常数时,读下一个单词符号

void factor() {  

    if(num==10||num==11) {

        match();

    } else if(num==27) {

        match();

        expression();

        if(num==28) {

            match();

        } else {

            printf(" 【error】缺失')' \n");

            k=1;

        }

    } else {

        printf("【error】'表达式错误'\n");

        k=1;

    }

    return;

}

int main() {

    printf("\t\n请输入程序,以#号结束:\n");

    ch=getchar();

    while(ch!='#') {

        temp[i]=ch;

        ch=getchar();

        i++;

    }

    temp[i]='#';

    i++;

    temp[i]='\0';

    i=0;

    match();

    Bparser();

}


原文地址:https://blog.csdn.net/csdn3043663729/article/details/143623514

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!