实验3:算符优先分析法

  • 实验目的

1.掌握算符优先分析法的基本原理

2.掌握算符优先分析表的构造方法

3.掌握算符优先驱动程序的构造方法

4.加深对算符优先分析法的理解

  • 实验内容及要求

已知某算符优先文法中相邻终结符间的优先关系如下表:

+

-

*

/

i

(

)

#

+

·>

·>

·>

·>

-

·>

·>

·>

·>

*

·>

·>

·>

·>

·>

·>

/

·>

·>

·>

·>

·>

·>

i

·>

·>

·>

·>

·>

·>

(

)

·>

·>

·>

·>

·>

·>

#

本次实验要求根据算符优先关系表编制一个算符优先分析程序,以便对任意输入的符号串进行分析。要求所编制的算符优先分析程序输出的格式如下:

  1. 算符优先分析程序,编制人:姓名,学号,班级

(2) 输入一以#结束的符号串(可包括+-*/()i#等符号,如i+i*i#):在此位置输入符号串

(3) 对该输入串的算符优先分析过程输出如下:

步骤

剩余输入串

优先关系

动作

1

#

i+i*i#

# <· i

移进i

2

...

...

...

...

  1. 判定结果:输入符号串为合法符号串(或者为非法符号串)。

注意:(1) 在“动作”一列中如果是规约则写明规约串;如果为移进则写明移进的终结符;如分析异常出错则写为“出错”;若成功结束则写为“成功”。

  1. 在此位置输入符号串为用户自行输入的符号串,其中允许使用运算符(+、-、*、\)、分割符(括号)、字符i,结束符#;如:i+i*i#。     
  2. 如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好)。

注意:此代码为速成品,存在诸多问题,仅供参考

#include <iostream>
#include <string>
#include <stack>
#include <vector>
#include <iomanip>

using namespace std;
string inputStr;
stack<char> sta1;//全部字符
stack<char> sta2;//仅含终结符
int i;
int index=1;
string shengYuChuanPrint( string str,int flag ){
    string newstr="";
    for( int i=flag;i<str.length();i++ ){
        newstr+=str[i];
    }
    return newstr;
}
string stackPrint(stack<char> p){
	vector<char> vec;
    while( !p.empty() ){
        vec.push_back(p.top());
        p.pop();
    }
    string str1="";
    for( int i=vec.size()-1;i>=0;--i ){
        str1+=vec[i];
    }
    return str1;
}

int panDuanYouXianJi(char leftChr,char rightChr){//0表示左=右,1表示左>右,-1左<右,2表示空
    if( leftChr=='+' ){
        if ( rightChr=='+' ){
            return 1;
        }
        else if( rightChr=='-' ){
            return 1;
        }
        else if( rightChr=='*' ){
            return -1;
        }
        else if( rightChr=='/' ){
            return -1;
        }
        else if( rightChr=='i' ){
            return -1;
        }
        else if( rightChr=='(' ){
            return -1;
        }
        else if( rightChr==')' ){
            return 1;
        }
        else if( rightChr=='#' ){
            return 1;
        }
        else{
            cout << "error" <<endl;
        }
    }
    else if( leftChr=='-' ){
        if ( rightChr=='+' ){
            return 1;
        }
        else if( rightChr=='-' ){
            return 1;
        }
        else if( rightChr=='*' ){
            return -1;
        }
        else if( rightChr=='/' ){
            return -1;
        }
        else if( rightChr=='i' ){
            return -1;
        }
        else if( rightChr=='(' ){
            return -1;
        }
        else if( rightChr==')' ){
            return 1;
        }
        else if( rightChr=='#' ){
            return 1;
        }
        else{
            cout << "error" <<endl;
        }
    }
    else if( leftChr=='*' ){
        if ( rightChr=='+' ){
            return 1;
        }
        else if( rightChr=='-' ){
            return 1;
        }
        else if( rightChr=='*' ){
            return 1;
        }
        else if( rightChr=='/' ){
            return 1;
        }
        else if( rightChr=='i' ){
            return -1;
        }
        else if( rightChr=='(' ){
            return -1;
        }
        else if( rightChr==')' ){
            return 1;
        }
        else if( rightChr=='#' ){
            return 1;
        }
        else{
            cout << "error" <<endl;
        }
    }
    else if( leftChr=='/' ){
        if ( rightChr=='+' ){
            return 1;
        }
        else if( rightChr=='-' ){
            return 1;
        }
        else if( rightChr=='*' ){
            return 1;
        }
        else if( rightChr=='/' ){
            return 1;
        }
        else if( rightChr=='i' ){
            return -1;
        }
        else if( rightChr=='(' ){
            return -1;
        }
        else if( rightChr==')' ){
            return 1;
        }
        else if( rightChr=='#' ){
            return 1;
        }
        else{
            cout << "error" <<endl;
        }
    }
    else if( leftChr=='i' ){
        if ( rightChr=='+' ){
            return 1;
        }
        else if( rightChr=='-' ){
            return 1;
        }
        else if( rightChr=='*' ){
            return 1;
        }
        else if( rightChr=='/' ){
            return 1;
        }
        else if( rightChr==')' ){
            return 1;
        }
        else if( rightChr=='#' ){
            return 1;
        }
        else{
            cout << "error" <<endl;
        }
    }
    else if( leftChr=='(' ){
        if ( rightChr=='+' ){
            return -1;
        }
        else if( rightChr=='-' ){
            return -1;
        }
        else if( rightChr=='*' ){
            return -1;
        }
        else if( rightChr=='/' ){
            return -1;
        }
        else if( rightChr=='i' ){
            return -1;
        }
        else if( rightChr=='(' ){
            return -1;
        }
        else if( rightChr==')' ){
            return 0;
        }
        else{
            cout << "error" <<endl;
        }
    }
    else if( leftChr==')' ){
        if ( rightChr=='+' ){
            return 1;
        }
        else if( rightChr=='-' ){
            return 1;
        }
        else if( rightChr=='*' ){
            return 1;
        }
        else if( rightChr=='/' ){
            return 1;
        }
        else if( rightChr==')' ){
            return 1;
        }
        else if( rightChr=='#' ){
            return 1;
        }
        else{
            cout << "error" <<endl;
        }
    }
    else if( leftChr=='#' ){
        if ( rightChr=='+' ){
            return -1;
        }
        else if( rightChr=='-' ){
            return -1;
        }
        else if( rightChr=='*' ){
            return -1;
        }
        else if( rightChr=='/' ){
            return -1;
        }
        else if( rightChr=='i' ){
            return -1;
        }
        else if( rightChr=='(' ){
            return -1;
        }
        else if( rightChr=='#' ){
            return 0;
        }
        else{
            cout << "error" <<endl;
        }
    }
    else{
        return 2;
    }
}

void guiyue(){
    while( panDuanYouXianJi(sta2.top(),inputStr[i])==1 ){
        cout << setw(12) <<left<<index
            << setw(12) <<left<< stackPrint(sta1)
            << setw(12) <<left<< shengYuChuanPrint(inputStr,i)
            << sta2.top()<<">"<<inputStr[i]
            << "     "
            << "归约"
            << endl;
            index++;
        if( sta2.top()=='i' ){
            sta1.pop();
            sta2.pop();
            sta1.push('F');
            while( panDuanYouXianJi(sta2.top(),inputStr[i])==-1 ){
                cout << setw(12) <<left<<index
                << setw(12) <<left<< stackPrint(sta1)
                << setw(12) <<left<< shengYuChuanPrint(inputStr,i)
                << sta2.top()<<"<"<<inputStr[i]
                << "     "
                << "移进"<<inputStr[i]
                << endl;
                sta1.push(inputStr[i]);
                sta2.push(inputStr[i]);
                i++;
                index++;
            }
            while( panDuanYouXianJi(sta2.top(),inputStr[i])==0 ){
                if( inputStr[i]=='#'&& sta2.top()=='#'){
                    cout << setw(12) <<left<<index
                    << setw(12) <<left<< stackPrint(sta1)
                    << setw(12) <<left<< shengYuChuanPrint(inputStr,i)
                    << sta2.top()<<"="<<inputStr[i]
                    << "     "
                    << "接受"
                    << endl;
                    sta1.push(inputStr[i]);
                    sta2.push(inputStr[i]);
                    i++;
                    index++;
                    exit(0);
                }
                else{
                    cout << setw(12) <<left<<index
                    << setw(12) <<left<< stackPrint(sta1)
                    << setw(12) <<left<< shengYuChuanPrint(inputStr,i)
                    << sta2.top()<<"="<<inputStr[i]
                    << "     "
                    << "移进"<<inputStr[i]
                    << endl;
                    sta1.push(inputStr[i]);
                    sta2.push(inputStr[i]);
                    i++;
                    index++;
                }

            }
            guiyue();
        }
        else if( sta2.top()=='+'||sta2.top()=='-'||sta2.top()=='*'||sta2.top()=='/'){
            sta2.pop();
            sta1.pop();
            sta1.pop();
            sta1.pop();
            sta1.push('F');
            while( panDuanYouXianJi(sta2.top(),inputStr[i])==-1 ){
                cout << setw(12) <<left<<index
                << setw(12) <<left<< stackPrint(sta1)
                << setw(12) <<left<< shengYuChuanPrint(inputStr,i)
                << sta2.top()<<"<"<<inputStr[i]
                << "     "
                << "移进"<<inputStr[i]
                << endl;
                sta1.push(inputStr[i]);
                sta2.push(inputStr[i]);
                i++;
                index++;
            }
            while( panDuanYouXianJi(sta2.top(),inputStr[i])==0 ){
                if( inputStr[i]=='#'&& sta2.top()=='#'){
                    cout << setw(12) <<left<<index
                    << setw(12) <<left<< stackPrint(sta1)
                    << setw(12) <<left<< shengYuChuanPrint(inputStr,i)
                    << sta2.top()<<"="<<inputStr[i]
                    << "     "
                    << "接受"
                    << endl;
                    sta1.push(inputStr[i]);
                    sta2.push(inputStr[i]);
                    i++;
                    index++;
                    exit(0);
                }
                else{
                    cout << setw(12) <<left<<index
                    << setw(12) <<left<< stackPrint(sta1)
                    << setw(12) <<left<< shengYuChuanPrint(inputStr,i)
                    << sta2.top()<<"="<<inputStr[i]
                    << "     "
                    << "移进"<<inputStr[i]
                    << endl;
                    sta1.push(inputStr[i]);
                    sta2.push(inputStr[i]);
                    i++;
                    index++;
                }
            }
            guiyue();
        }
        else if( sta2.top()=='#' ){
            break;
        }
    }
}
void DFA( string str ){
    inputStr=str;
    sta1.push('#');
    sta2.push('#');
    for( i=0;i<inputStr.length(); ){
        if( panDuanYouXianJi(sta2.top(),inputStr[i])==-1 ){
            cout << setw(12) <<left<<index
                << setw(12) <<left<< stackPrint(sta1)
                << setw(12) <<left<< shengYuChuanPrint(inputStr,i)
                << sta2.top()<<"<"<<inputStr[i]
                << "     "
                << "移进"<<inputStr[i]
                << endl;
            sta1.push(inputStr[i]);
            sta2.push(inputStr[i]);
            ++i;
            index++;
        }
        else if( panDuanYouXianJi(sta2.top(),inputStr[i])==0 ){
            if( inputStr[i]=='#'&& sta2.top()=='#'){
                cout << setw(12) <<left<<index
                << setw(12) <<left<< stackPrint(sta1)
                << setw(12) <<left<< shengYuChuanPrint(inputStr,i)
                << sta2.top()<<"="<<inputStr[i]
                << "     "
                << "接受"
                << endl;
                sta1.push(inputStr[i]);
                sta2.push(inputStr[i]);
                i++;
                index++;
                exit(0);
            }
            else{
                cout << setw(12) <<left<<index
                << setw(12) <<left<< stackPrint(sta1)
                << setw(12) <<left<< shengYuChuanPrint(inputStr,i)
                << sta2.top()<<"="<<inputStr[i]
                << "     "
                << "移进"<<inputStr[i]
                << endl;
                sta1.push(inputStr[i]);
                sta2.push(inputStr[i]);
                i++;
                index++;
            }
        }
        else{
            guiyue();
        }
    }
}

int main()
{
    string str;
    cout << "编制人:***,软件**,21**********" <<endl;
    cout << "请输入目标串" << endl;
    cin >> str;
    DFA(str);
    return 0;
}

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值