小型(简化)高级语言分析器前端--编译原理

目录

实验题目

实验内容

待分析的简单语言的词法

各种单词符号的种别码

语法结构定义

程序的输入与输出

测试结果与分析

源代码

实验题目

小型(简化)高级语言分析器前端

实验内容

设计并实现一个一遍扫描的编译前端,将简化高级语言的部分语法成分(含赋值语句、分支语句、循环语句等)翻译成四元式(或三地址代码),还要求有合理的语法出错报错和错误恢复功能。

待分析的简单语言的词法

  1. 关键字:main,if,while所有的关键字都是小写
  2. 运算符和界符: =  +  -  *  /  <  <=  >  >=  ==  !=  ;  (  )  {  }
  3. 其他单词是标识符(ID)和整形常数(NUM),通过以下正规式定义:ID = letter(letter|digit)*          NUM = digit digit*
  4. 空格由空白、制表符和换行符组成。空格一般用来分隔ID、NUM、运算符、界符和关键字,词法分析阶段通常被忽略。

各种单词符号的种别码

单词符号

种别码

main

1

if

2

while

3

letter(letter|digit)*

10

digit digit*

20

=

21

+

22

-

23

*

24

/

25

(

26

)

27

{

28

}

29

;

30

>

31

<

32

>=

33

<=

34

==

35

!=

36

‘\0’

1000

ERROR

-1

语法结构定义

<程序>      ::=  main()’{’<语句串>’}’

<语句串>    ::=  <语句>{;<语句>};

<语句>      ::=  <赋值语句>  |  <条件语句>  |  <循环语句>

<赋值语句>  ::=  ID=<表达式>

<条件语句>  ::=  if<条件><赋值语句>

<循环语句>  ::=  while<条件><赋值语句>

<条件>      ::=  <表达式><关系运算符><表达式>

<表达式>    ::=  <项>{+<项>|-<项>}

<项>        ::=  <因子>{*<因子>|/<因子>}

<因子>      ::=  ID  |  NUM  |  (<表达式>)

<关系运算符>::=  >  |  <  |  >=  |  <=  |  ==  |  !=

程序的输入与输出

输入:在命令提示符中输入所给文法的源程序字符串,以#为结束符。

输出:四元式序列

例如:

 

 

测试用例

main(){ /* 注释ouyonghao */

if A1f>=B20

A1f=314*B20+(C123-Dzx)/Ee;

B20:=ff21;

while A1f != B20

A1f=314*B20+(C123-Dzx)/Ee;

B20=ff21;

}#

测试结果

 

 

源代码

#include <iostream>

#include <cstdio>

#include <cstring>

using namespace std;

typedef struct

{

    int typenum;

    char *word;

} WORD;

typedef struct

{

    char result[20];

    char number_left[20];

    char op[20];

    char number_right[20];

    int statement_number;

} QUATERNION;

char m_getch();

void getbc();

void concat();

int letter();

int digit();

int reserve();

WORD *scanner();

char *newtemp();

void program(WORD *word);//程序

WORD *statement_string(WORD *word);//语句串

WORD *statement(WORD *word);//语句

WORD *assignment_statement(WORD *word);//赋值语句

WORD *conditional_statement(WORD *word);//条件语句

WORD *loop_statement(WORD *word);//循环语句

WORD *condition(WORD *word,char *buffer);//条件

WORD *expression(WORD *word,char *buffer);//表达式

WORD *term(WORD *word,char *buffer);//项

WORD *factor(WORD *word,char *buffer);//因子

WORD *relational_operators(WORD *word,char *buffer);//关系运算符

void set_quaternion(char *result,char *number_left,char *op,char *number_right,int flag);//构建四元式

void get_quaternion();//输出四元式

char input[255];

char token[255]="";

int p_input;

int p_token;

char ch;

int temp_number=0;

int line=1;

int quaternion_number=0;

QUATERNION my_quaternion[100];

char *reserved_word[]= {"main","if","while","ERROR"};

int main()

{

    scanf("%[^#]",input);

    p_input=0;

    WORD *oneword;

    oneword=scanner();

    program(oneword);

    get_quaternion();

    return 0;

}

void filter()

{

    int start=p_input-1;

    if(ch=='/')

    {

        m_getch();

        if(ch=='/')

        {

            m_getch();

            while(ch!='\0'&&ch!='\n')

                m_getch();

            getbc();

        }

        else if(ch=='*')

        {

            m_getch();

            int flag=0;

            while(ch!='\0')

            {

                if(ch=='*')

                {

                    m_getch();

                    if(ch=='/')

                    {

                        m_getch();

                        getbc();

                        flag=1;

                        break;

                    }

                }

                else m_getch();

            }

            if(flag!=1)

            {

                p_input=start+1;

                ch=m_getch();

                return;

            }

        }

        else p_input--;

    }

}

char m_getch()

{

    ch=input[p_input];

    p_input++;

    return(ch);

}

void getbc()

{

    while(ch==' '||ch==10)

    {

        if(ch=='\n')

            line++;

        ch=input[p_input];

        p_input++;

    }

}

void concat()

{

    token[p_token]=ch;

    p_token++;

    token[p_token]='\0';

}

int letter()

{

    if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z')

        return 1;

    else return 0;

}

int digit()

{

    if(ch>='0'&&ch<='9')

        return 1;

    else return 0;

}

int reserve()

{

    int number=0;

    while(strcmp(reserved_word[number],"ERROR"))

    {

        if(!strcmp(reserved_word[number],token))

            return number+1;

        number++;

    }

    return 10;

}

WORD *scanner()

{

    WORD *myword=(WORD *)malloc(sizeof(WORD));

    myword->typenum=10;

    myword->word="";

    p_token=0;

    m_getch();

    getbc();

    while(ch=='/'&&(input[p_input]=='/'||input[p_input]=='*'))

        filter();

    if(letter())

    {

        while(letter()||digit())

        {

            concat();

            m_getch();

        }

        p_input--;

        myword->typenum=reserve();

        myword->word=token;

        return myword;

    }

    else if(digit())

    {

        while(digit())

        {

            concat();

            m_getch();

        }

        p_input--;

        myword->typenum=20;

        myword->word=token;

        return myword;

    }

    else

    {

        switch(ch)

        {

        case'=':

            m_getch();

            if(ch=='=')

            {

                myword->typenum=35;

                myword->word="==";

                return myword;

            }

            p_input--;

            myword->typenum=21;

            myword->word="=";

            return myword;

            break;

        case'+':

            myword->typenum=22;

            myword->word="+";

            return myword;

            break;

        case'-':

            myword->typenum=23;

            myword->word="-";

            return myword;

            break;

        case'*':

            myword->typenum=24;

            myword->word="*";

            return myword;

            break;

        case'/':

            myword->typenum=25;

            myword->word ="/";

            return myword;

            break;

        case'(':

            myword->typenum=26;

            myword->word="(";

            return myword;

            break;

        case')':

            myword->typenum=27;

            myword->word=")";

            return myword;

            break;

        case'{':

            myword->typenum=28;

            myword->word="{";

            return myword;

            break;

        case'}':

            myword->typenum=29;

            myword->word="}";

            return myword;

            break;

        case';':

            myword->typenum=30;

            myword->word=";";

            return myword;

            break;

        case'>':

            m_getch();

            if(ch=='=')

            {

                myword->typenum=33;

                myword->word=">=";

                return myword;

            }

            p_input--;

            myword->typenum=31;

            myword->word=">";

            return myword;

            break;

        case'<':

            m_getch();

            if(ch=='=')

            {

                myword->typenum=34;

                myword->word="<=";

                return myword;

            }

            p_input--;

            myword->typenum=32;

            myword->word="<";

            return myword;

            break;

        case'!':

            m_getch();

            if(ch=='=')

            {

                myword->typenum=36;

                myword->word="!=";

                return myword;

            }

            p_input--;

            myword->typenum=-1;

            myword->word="ERROR";

            return myword;

            break;

        case'\0':

            myword->typenum = 1000;

            myword->word = "OVER";

            return myword;

            break;

        default:

            myword->typenum=0;

            myword->word="#";

            return myword;

        }

    }

}

char *newtemp()

{

    char *temp;

    char number[20];

    temp = (char *)malloc(20);

    temp_number++;

    sprintf(number,"%d",temp_number);

    strcpy(temp+1,number);

    temp[0] = 't';

    return temp;

}

void program(WORD *word)//程序

{

    if(word==NULL)return;

    WORD *temp_word;

    if(word->typenum!=1)

        cout<<"第"<<line<<"行,main错误"<<endl;

    temp_word=scanner();

    if(temp_word==NULL)return;

    if(temp_word->typenum!=26)

        cout<<"第"<<line<<"行,(错误"<<endl;

    temp_word=scanner();

    if(temp_word==NULL)return;

    if(temp_word->typenum!=27)

        cout<<"第"<<line<<"行,)错误"<<endl;

    temp_word=scanner();

    if(temp_word==NULL)return;

    if(temp_word->typenum!=28)

        cout<<"第"<<line<<"行,{错误"<<endl;

    temp_word=scanner();

    temp_word=statement_string(temp_word);

    if(temp_word==NULL)return;

    if(temp_word->typenum!=29)

        cout<<"第"<<line<<"行,}错误"<<endl;

    return;

}

WORD *statement_string(WORD *word)//语句串

{

    if(word==NULL)return NULL;

    WORD *temp_word;

    temp_word=statement(word);

    if(temp_word==NULL)return NULL;

    while(temp_word->typenum==30)

    {

        temp_word=scanner();

        temp_word=statement(temp_word);

        if(temp_word==NULL)return NULL;

    }

    return temp_word;

}

WORD *statement(WORD *word)//语句

{

    if(word==NULL)return NULL;

    WORD *temp_word;

    if(word->typenum==10)temp_word=assignment_statement(word);

    else if(word->typenum==2)temp_word=conditional_statement(word);

    else if(word->typenum==3)temp_word=loop_statement(word);

    return temp_word;

}

WORD *assignment_statement(WORD *word)//赋值语句

{

    if(word == NULL)return NULL;

    char result[20],number_left[20],buffer[255];

    WORD *temp_word;

    if(word->typenum==10)

    {

        strcpy(result,word->word);

        temp_word = scanner();

        if(temp_word->typenum==21)

        {

            temp_word = scanner();

            temp_word = expression(temp_word,buffer);

            if(temp_word == NULL)return NULL;

            strcpy(number_left,buffer);

            set_quaternion(result,number_left,"#","#",0);

            return temp_word;

        }

    }

    cout<<"第"<<line<<"行,表达式错误"<<endl;

    WORD *theword = scanner();

    while(theword->typenum!=30)theword=scanner();

    return theword;

}

WORD *conditional_statement(WORD *word)//条件语句

{

    if(word == NULL)return NULL;

    WORD *temp_word;

    if(word->typenum==2)

    {

        char goto_place_1[20],goto_place_2[20],buffer[255];

        int temp=quaternion_number+2;

        sprintf(goto_place_1,"%d",temp+1);

        set_quaternion("if","#","goto",goto_place_1,0);

        set_quaternion("goto","#","#","#",0);

        temp_word=scanner();

        temp_word=condition(temp_word,buffer);

        strcpy(my_quaternion[temp-2].number_left,buffer);

        temp_word=assignment_statement(temp_word);

        sprintf(goto_place_2,"%d",quaternion_number+1);

        strcpy(my_quaternion[temp-1].number_left,goto_place_2);

        return temp_word;

    }

    cout<<"第"<<line<<"行,条件语句错误"<<endl;

    WORD *theword = scanner();

    while(theword->typenum!=30)theword=scanner();

    return theword;

}

WORD *loop_statement(WORD *word)//循环语句

{

    if(word == NULL)return NULL;

    WORD *temp_word;

    if(word->typenum==3)

    {

        char goto_place_1[20],goto_place_2[20],goto_place_3[20],buffer[255];

        int temp_1=quaternion_number;

        int temp_2=quaternion_number+2;

        sprintf(goto_place_1,"%d",temp_2+1);

        set_quaternion("if","#","goto",goto_place_1,0);

        set_quaternion("goto","#","#","#",0);

        temp_word=scanner();

        temp_word=condition(temp_word,buffer);

        strcpy(my_quaternion[temp_2-2].number_left,buffer);

        temp_word=assignment_statement(temp_word);

        sprintf(goto_place_2,"%d",quaternion_number+2);

        strcpy(my_quaternion[temp_2-1].number_left,goto_place_2);

        sprintf(goto_place_3,"%d",temp_1+1);

        set_quaternion("goto",goto_place_3,"#","#",0);

        return temp_word;

    }

    cout<<"第"<<line<<"行,循环语句错误"<<endl;

    WORD *theword = scanner();

    while(theword->typenum!=30)theword=scanner();

    return theword;

}

WORD *condition(WORD *word,char *buffer)//条件

{

    WORD *temp_word;

    char buff1[255],buff2[255],buff3[255];

    if(word->typenum==10||word->typenum==20)

    {

        strcpy(buff1,word->word);

        temp_word = scanner();

    }

    temp_word=relational_operators(temp_word,buff2);

    if(temp_word->typenum==10||temp_word->typenum==20)

    {

        strcpy(buff3,temp_word->word);

        temp_word = scanner();

    }

    strcat(buff1,buff2);

    strcat(buff1,buff3);

    strcpy(buffer,buff1);

    return temp_word;

}

WORD *expression(WORD *word,char *buffer)//表达式

{

    WORD *temp_word;

    char buff[255];

    temp_word=term(word,buff);

    if(temp_word == NULL)return NULL;

    char *result,*number_left,*op,*number_right;

    result = (char *)malloc(20);

    number_left = (char *)malloc(20);

    op = (char *)malloc(20);

    number_right = (char *)malloc(20);

    strcpy(number_left,buff);

    while(temp_word->typenum == 22 || temp_word->typenum == 23)

    {

        strcpy(op,temp_word->word);

        temp_word = scanner();

        temp_word = term(temp_word,buff);

        if(temp_word == NULL)return NULL;

        strcpy(number_right,buff);

        set_quaternion(result,number_left,op,number_right,1);

        strcpy(number_left,result);

    }

    strcpy(buffer,number_left);

    return temp_word;

}

WORD *term(WORD *word,char *buffer)//项

{

    WORD *temp_word;

    char buff[255];

    temp_word = factor(word,buff);

    if(temp_word == NULL)return NULL;

    char *result,*number_left,*op,*number_right;

    result = (char *)malloc(20);

    number_left = (char *)malloc(20);

    op = (char *)malloc(20);

    number_right = (char *)malloc(20);

    strcpy(number_left,buff);

    while(temp_word->typenum == 24 || temp_word->typenum == 25)

    {

        strcpy(op,temp_word->word);

        temp_word = scanner();

        temp_word = factor(temp_word,buff);

        if(temp_word == NULL)return NULL;

        strcpy(number_right,buff);

        set_quaternion(result,number_left,op,number_right,1);

        strcpy(number_left,result);

    }

    strcpy(buffer,number_left);

    return temp_word;

}

WORD *factor(WORD *word,char *buffer)//因子

{

    char *number;

    WORD *temp_word;

    number = (char *)malloc(20);

    strcpy(number,"");

    if(word == NULL)return NULL;

    if(word->typenum == 10||word->typenum==20)

    {

        strcpy(number,word->word);

        temp_word = scanner();

    }

    else if(word->typenum == 26)

    {

        temp_word = scanner();

        temp_word = expression(temp_word,number);

        if(temp_word == NULL)return NULL;

        if(temp_word->typenum == 27)

            temp_word = scanner();

        else

        {

            cout<<"第"<<line<<"行,)错误"<<endl;

            strcpy(buffer,number);

            WORD *theword = scanner();

            while(theword->typenum!=30)theword=scanner();

            return theword;

        }

    }

    strcpy(buffer,number);

    return temp_word;

}

WORD *relational_operators(WORD *word,char *buffer)//关系运算符

{

    WORD *temp_word;

    if(word == NULL)return NULL;

    if(word->typenum>=31&&word->typenum<=36)

    {

        strcpy(buffer,word->word);

        temp_word = scanner();

        return temp_word;

    }

    else cout<<"第"<<line<<"行,关系运算符错误"<<endl;

    return word;

}

void set_quaternion(char *result,char *number_left,char *op,char *number_right,int flag)//构建四元式

{

    strcpy(my_quaternion[quaternion_number].number_left,number_left);

    strcpy(my_quaternion[quaternion_number].op,op);

    strcpy(my_quaternion[quaternion_number].number_right,number_right);

    if(flag == 1)

    {

        char *temp = newtemp();

        strcpy(result,temp);

        strcpy(my_quaternion[quaternion_number].result,result);

    }

    else strcpy(my_quaternion[quaternion_number].result,result);

    quaternion_number++;

    return ;

}

void get_quaternion()//输出四元式

{

    for(int i=0; i<quaternion_number; i++)

        cout<<i+1<<"----"<<my_quaternion[i].result<<"  "<<my_quaternion[i].number_left<<"  "<<my_quaternion[i].op<<"  "<<my_quaternion[i].number_right<<endl;

    return;

}

 

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

欧永昊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值