<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    朋的博客

    MySQL資料,Java技術,管理思想,博弈論,Ajax,XP極限編程,H.264,HEVC,HDR
    隨筆 - 86, 文章 - 59, 評論 - 1069, 引用 - 0
    數(shù)據(jù)加載中……

    算術表達式的實現(xiàn)

    /****算術表達式的分析和計算,文件名:Exp_c.cpp****
    ***** 在VC6和Dev-C下調(diào)試通過 ****/
    #include
    #include
    #include
    #include
    #include

    #define EXP_LEN 100 //定義輸入字符緩沖區(qū)的長度

    /*------------出錯代碼的宏定義--------------*/
    #define INVALID_CHAR_TAIL 0 //表達式后跟有非法字符
    #define CHAR_AFTER_RIGHT 1 //右括號后連接非法字符
    #define LEFT_AFTER_NUM 2 //數(shù)字后非法直接連接左括號
    #define INVALID_CHAR_IN 3 //表達式中含有非法字符
    #define NO_RIGHT 4 //缺少右括號
    #define EMPTY_BRACKET 5 //括號內(nèi)無表達式
    #define UNEXPECTED_END 6 //預期外的算術表達式結束

    using namespace std;

    const string ErrCodeStr[]= //表達式出錯信息
    {
    "表達式后跟有非法字符!",
    "右括號后連接非法字符!",
    "數(shù)字后非法直接連接左括號!",
    "表達式中含有非法字符!",
    "缺少右括號!",
    "括號內(nèi)無表達式或表達式不完整!",
    "表達式非法結束或表達式不完整!"
    };

    static char expr[EXP_LEN]; //算術表達式輸入字符緩沖區(qū)
    static int pos; //字符指示器標志:用來保存正在分析的字符的位置
    static jmp_buf errjb; //出錯跳轉緩沖器

    //********以下是函數(shù)聲明*********
    //產(chǎn)生式“E -> T+E | T-E | T”的函數(shù),用來分析加減算術表達式。
    int E_AddSub();
    //產(chǎn)生式“T -> F*T | F/T | F”的函數(shù),用來分析乘除算術表達式。
    int T_MulDiv();
    //產(chǎn)生式“F -> i | (E)”的函數(shù),用來分析數(shù)字和括號內(nèi)的表達式。
    int F_Number();
    //出錯處理函數(shù),可以指出錯誤位置,出錯信息。
    void Error(int ErrCode);

    int main()
    {
    int ans; //保存算術表達式的計算結果
    bool quit=false; //是否退出計算

    do
    {
    //在此設定一個跳轉目標,如果本程序的其他函數(shù)調(diào)用longjmp,
    //執(zhí)行指令就跳轉到這里,從這里繼續(xù)執(zhí)行。
    if(setjmp(errjb)==0) //如果沒有錯誤
    {
    pos=0; //初始化字符指示器為0,即指向輸入字符串的第一個字符。

    cout<<"請輸入一個算術表達式(輸入“Q”或“q”退出):"< cin>>expr; //輸入表達式,填充表達式字符緩沖區(qū)。

    if(expr[0]=='q'||expr[0]=='Q')
    //檢查第一個字符,是否退出?
    quit=true;

    else
    {
    //調(diào)用推導式“E -> T+E | T-E | T”的函數(shù),
    //從起始符號“E”開始推導。
    ans=E_AddSub();

    //此時,程序認為對表達式的語法分析已經(jīng)完畢,下面判斷出錯的原因:

    //如果表達式中的某個右括號后直接跟著數(shù)字或其他字符,
    //則報錯,因為數(shù)字i不屬于FOLLOW())集。
    if(expr[pos-1]==')'&&expr[pos]!='\0')
    Error(CHAR_AFTER_RIGHT);

    //如果表達式中的某個數(shù)字或右括號后直接跟著左括號,
    //則報錯,因為左括號不屬于FOLLOW(E)集。
    if(expr[pos]=='(')
    Error(LEFT_AFTER_NUM);

    //如果結尾有其他非法字符
    if(expr[pos]!='\0')
    Error(INVALID_CHAR_TAIL);

    cout<<"計算得出表達式的值為:"< }
    }
    else
    {
    //setjmp(errjb)!=0的情況:
    cout<<"請重新輸入!"< }
    }
    while(!quit);

    return 0;
    }

    //產(chǎn)生式“E -> T+E | T-E | T”的函數(shù),用來分析加減算術表達式。
    //返回計算結果
    int E_AddSub()
    {
    int rtn=T_MulDiv(); //計算加減算術表達式的左元

    while(expr[pos]=='+'||expr[pos]=='-')
    {
    int op=expr[pos++]; //取字符緩沖區(qū)中當前位置的符號到op
    int opr2=T_MulDiv();//計算加減算術表達式的右元

    //計算求值
    if(op=='+') //如果是"+"號
    rtn+=opr2; //則用加法計算
    else //否則(是"-"號)
    rtn-=opr2; //用減法計算
    }
    return rtn;
    }

    //推導式“T -> F*T | F/T | F”的函數(shù),用來分析乘除算術表達式。
    //返回計算結果
    int T_MulDiv()
    {
    int rtn=F_Number(); //計算乘除算術表達式的左元

    while(expr[pos]=='*'||expr[pos]=='/')
    {
    int op=expr[pos++]; //取字符緩沖區(qū)中當前位置的符號到op
    int opr2=F_Number();//計算乘除算術表達式的右元

    //計算求值
    if(op=='*') //如果是"*"號
    rtn*=opr2; //則用乘法計算
    else //否則(是"\"號)
    rtn/=opr2; //用除法計算
    }
    return rtn;
    }

    //產(chǎn)生式“F -> i | (E)”的函數(shù),用來分析數(shù)字和括號內(nèi)的表達式。
    int F_Number()
    {
    int rtn; //聲明存儲返回值的變量

    //用產(chǎn)生式F->(E)推導:
    if(expr[pos]=='(') //如果字符緩沖區(qū)當前位置的符號是"("
    {
    pos++; //則指示器加一指向下一個符號
    rtn=E_AddSub(); //調(diào)用產(chǎn)生式“E -> T+E | T-E | T”的分析函數(shù)

    if(expr[pos++]!=')')//如果沒有與"("匹配的")"
    Error(NO_RIGHT);//則產(chǎn)生錯誤

    return rtn;
    }


    if(isdigit(expr[pos]))//如果字符緩沖區(qū)中當前位置的字符為數(shù)字
    {
    //則用產(chǎn)生式F -> i推導
    //把字符緩沖區(qū)中當前位置的字符串轉換為整數(shù)
    rtn=atoi(expr+pos);
    //改變指示器的值,跳過字符緩沖區(qū)的數(shù)字部分,找到下一個輸入字符。
    while(isdigit(expr[pos]))
    pos++;
    }
    else //如果不是數(shù)字則產(chǎn)生相應的錯誤
    {
    if(expr[pos]==')') //如果發(fā)現(xiàn)一個")"
    Error(EMPTY_BRACKET); //則是括號是空的,即括號內(nèi)無算術表達式。
    else if(expr[pos]=='\0') //如果此時輸入串結束
    Error(UNEXPECTED_END); //則算術表達式非法結束
    else
    Error(INVALID_CHAR_IN); //否則輸入字符串中含有非法字符
    }

    return rtn;
    }

    //出錯處理函數(shù),輸入錯誤代碼,可以指出錯誤位置,出錯信息。
    void Error(int ErrCode)
    {
    cout<<'\r'; //換行
    while(pos--)
    cout<<' '; //打印空格,把指示錯誤的"^"移到輸入字符串的出錯位置
    cout<<"^ 語法錯誤 ?。?! "
    < <
    longjmp(errjb,1); //跳轉到main()函數(shù)中的setjmp調(diào)用處,并設置setjmp(errjb)的返回值為1
    }

    研究ing,這段時間重新復習數(shù)據(jù)結構了……

    posted on 2005-09-21 21:23 benchensz 閱讀(1789) 評論(1)  編輯  收藏 所屬分類: Java技術

    評論

    # re: 算術表達式的實現(xiàn)[未登錄]  回復  更多評論   

    是錯的啊
    2008-11-15 22:04 | hehe
    主站蜘蛛池模板: 亚洲一区日韩高清中文字幕亚洲 | 亚洲av日韩av无码| 青娱乐在线视频免费观看| 女人张腿给男人桶视频免费版 | 亚洲AV日韩AV永久无码色欲 | 最新国产AV无码专区亚洲| 一级毛片aaaaaa视频免费看| 亚洲高清无码在线观看| j8又粗又长又硬又爽免费视频| 国产亚洲美女精品久久久久| 国产成人综合久久精品免费 | 亚洲欧美黑人猛交群| 免费看少妇作爱视频| 国产成人亚洲精品播放器下载| 国产成人精品免费直播| 九九免费精品视频在这里| 亚洲日韩欧洲乱码AV夜夜摸| 亚洲男人的天堂网站| 又黄又爽无遮挡免费视频| 亚洲熟妇少妇任你躁在线观看| 成人无遮挡毛片免费看| 特级aaaaaaaaa毛片免费视频| 亚洲精品无码99在线观看| 一级毛片不卡片免费观看| 精品亚洲AV无码一区二区三区 | 人妻免费一区二区三区最新| 夜夜亚洲天天久久| 免费网站观看WWW在线观看| 亚洲成人在线电影| 久久久久久国产精品免费免费| 亚洲视频精品在线观看| 成年男女免费视频网站 | 青柠影视在线观看免费| 亚洲精品在线不卡| 国产一级淫片a视频免费观看| 亚洲一区二区三区在线观看网站| 四虎免费永久在线播放| 亚洲成人免费在线| 亚洲风情亚Aⅴ在线发布| 日日操夜夜操免费视频| 亚洲日本va一区二区三区|