<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
    數據加載中……

    算術表達式的實現

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

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

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

    using namespace std;

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

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

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

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

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

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

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

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

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

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

    //如果表達式中的某個數字或右括號后直接跟著左括號,
    //則報錯,因為左括號不屬于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;
    }

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

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

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

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

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

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

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

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

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

    return rtn;
    }


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

    return rtn;
    }

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

    研究ing,這段時間重新復習數據結構了……

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

    評論

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

    是錯的啊
    2008-11-15 22:04 | hehe
    主站蜘蛛池模板: 中文字幕成人免费高清在线视频| 免费观看四虎精品成人| 久久青草免费91线频观看站街| 亚洲电影日韩精品| 黄网站色视频免费观看45分钟| 午夜私人影院免费体验区| 亚洲无码一区二区三区| 国内外成人免费视频| 亚洲精品无码不卡在线播放| 午夜dj在线观看免费视频| 亚洲精品无播放器在线播放| 国产最新凸凹视频免费| 男女交性无遮挡免费视频| 国产亚洲精品福利在线无卡一 | 亚洲国产高清国产拍精品| 日本久久久免费高清| 日韩毛片一区视频免费| 国产亚洲成AV人片在线观黄桃| 久草免费福利资源站| 亚洲免费在线视频播放| 国产成人无码区免费A∨视频网站 国产成人涩涩涩视频在线观看免费 | 亚洲色大成WWW亚洲女子| 国产免费人视频在线观看免费| 特级毛片在线大全免费播放| 国产成人综合亚洲AV第一页 | 野花高清在线电影观看免费视频| 久久综合久久综合亚洲| 亚洲不卡无码av中文字幕| 女人隐私秘视频黄www免费| 亚洲美女激情视频| 国产小视频在线免费| 国产午夜无码精品免费看| 亚洲国产成人手机在线电影bd| 国产婷婷高清在线观看免费| 任你躁在线精品免费| 日韩亚洲人成在线| 亚洲色大成网站WWW久久九九| 精品免费人成视频app| 成年免费大片黄在线观看com| 亚洲国产一区二区三区青草影视| 在线免费不卡视频|