日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++程序设计语言(特别版) -- 一个桌面计算器

發布時間:2023/12/10 c/c++ 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++程序设计语言(特别版) -- 一个桌面计算器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

  • 這里要介紹各種語句和表達式,將通過一個桌面計算器的程序做些事情,該計算器提供四種座位浮點數的中綴運算符的標準算術運算。
  • 這個計算器由四個部分組成:一個分析器,一個輸入函數,一個符號表和一個驅動程序。

分析器

program:ENDexpr_list END //END表示輸入結束 expr_list: expression PRINT // PRINT表示分號 expression PRINT expr_list expression: expression + term expression - term term term: term / primary term * primary primary primary: NUMBER NAME NAME = expression - primary (expression)
  • 語法分析器采用通常的遞歸下降的風格。終結符由詞法分析程序get_token()識別,而非終結符由語法分析函數expr(),term()和prim()識別。一旦一個表達式的兩個運算對象都知道,就立即對這個表達式求值。
  • 個人覺得分析器就像是定義程序能接受什么輸入,而這里采用遞歸的形式,例如program代表程序,program可以接受END符號或者expr_list END,而expr_list又繼續遞歸下去可以由其他的組成,直到可以得到一個結束情況。

總代碼

#include<iostream> #include<string> #include<map> #include<cctype> using namespace std; // 將token用他們的字符所對應的整數表示,這樣做既方便有效, // 又能幫助使用排錯系統的人。 enum Token_value { NAME, NUMBER, END, PLUS='+', MINUS='-', MUL='*', DIV='/', PRINT=';', ASSIGN='=', LP='(', RP=')', }; Token_value curr_tok = PRINT; double expr(bool); double term(bool); double prim(bool); Token_value get_token(); double error(const string&); map<string, double> table; int no_of_errors; int main() { table["pi"] = 3.1415924535; table["e"] = 2.178; while(cin) { get_token(); if(curr_tok == END) break; if(curr_tok == PRINT) continue; cout<<expr(false)<<'\n'; } return no_of_errors; } // 每個分析器都有一個bool參數, // 指明該函數是否需要調用get_token()去取得下一個參數 // expr處理加減,一直到不是加減返回left double expr(bool get) { double left = term(get); for(;;) { switch (curr_tok){ case PLUS: left += term(true); break; case MINUS: left += term(true); break; default: return left; } } } // 函數term處理乘除,采用的方式與expr()處理方法一樣 double term(bool get) { double left = prim(get); for(;;) { switch (curr_tok){ case MUL: left *= prim(true); break; case DIV: if (double d = prim(true)) { left /= d; break; } return error("divide by 0"); default: return left; } } } double number_value; string string_value; // prim處理初等項的方式很像expr和term double prim(bool get) { if (get) get_token(); switch(curr_tok) { case NUMBER: { double v = number_value; get_token(); return v; } case NAME: { double& v = table[string_value]; if (get_token() == ASSIGN) v = expr(true); return v; } case MINUS: return -prim(true); case LP: { double e = expr(true); if (curr_tok != RP) return error(" ) expected"); get_token(); return e; } default: return error("primary expected"); } } Token_value get_token() { char ch; do { // 低級輸入,改進輸入 if(!cin.get(ch)) return curr_tok = END; } while(ch != '\n' && isspace(ch)); switch(ch) { case 0: return curr_tok=END; case '\n': return curr_tok=PRINT; case '+': case '-': case '*': case '/': case ';': case '(': case ')': case '=': return curr_tok = Token_value(ch); case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '.': cin.putback(ch); cin>>number_value; return curr_tok = NUMBER; default: if (isalpha(ch)) { string_value = ch; while(cin.get(ch) && isalnum(ch)) string_value.push_back(ch); cin.putback(ch); return curr_tok = NAME; } error("bad token"); return curr_tok = PRINT; } } double error(const string& s) { no_of_errors ++; cerr<<"error: "<<s<<'\n'; return 1; }

擴展

  • 自己的代碼只是簡單的拼接,這里發現一個更好的博客。

轉載于:https://www.cnblogs.com/zhengxingpeng/p/6685763.html

總結

以上是生活随笔為你收集整理的C++程序设计语言(特别版) -- 一个桌面计算器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。