編譯原理實現的計算器
『壹』 用java寫的計算器的程序!不需要界面!
用java寫的計算器的程序,主要是通過控制台輸入,主要方法是使用scanner類來接收用戶從鍵盤輸入的一個算式,通過分解算式,存入兩個字元串,判斷中間的的符號,進行相應計算,如下代碼:
System.out.println("-----------------------------------");
System.out.println("請輸入一個算術表達式,如:45*23");
Scannerin=newScanner(System.in);//接收用戶從鍵盤輸入的字元
Stringstr=in.nextLine();
StringBufferbuffer=newStringBuffer();//保存左側的數字
StringBufferbuffer1=newStringBuffer();//保存右側的數字
chart='';//保存運算符
for(inti=0;i<str.length();i++){
if(str.charAt(i)=='+'||str.charAt(i)=='-'
||str.charAt(i)=='*'||str.charAt(i)=='/'){
t=str.charAt(i);//識別是什麼運算符
for(intj=i+1;j<str.length();j++){
buffer1.append(str.charAt(j));
}
break;
}else{
buffer.append(str.charAt(i));
}
}
Stringc=buffer.toString();
Stringd=buffer1.toString();
doublea=Double.parseDouble(c);
doubleb=Double.parseDouble(d);
doublesum=0;
if(t=='+'){
sum=a+b;
}
if(t=='-'){
sum=a-b;
}
if(t=='*'){
sum=a*b;
}
if(t=='/'){
sum=a/b;
}
System.out.println("程序運算...");
System.out.println(c+t+d+"="+sum);
System.out.print("-----------------------------------");
運行結果如下:
『貳』 用c或c++編寫一個具有計算器功能的程序,要求一次性輸入一行要求算式,輸入「=」輸出結果,有什麼好的思路
可以用2叉樹寫。
定義運算式結構體類型,比如:
typedefstructyunsuan
{
//如果是單一運算,比如1+2,那麼num1=1;num2=2;
intnum1;//左兒子運算符為0的時候直接取該值
intnum2;//右兒子運算符為0的時候直接取該值,為NULL說明只有一個數值運算
structyunsuan*father;//父親:如果上層還有運算式,指向上層
structyunsuan*brother;//兄弟:如果同級還有其他運算式,指向該運算式結構
//如果是復合運算,為其創建左兒子,右兒子,指向兒子,並讓兒子指向父親
structyunsuan*left;//左兒子
structyunsuan*right;//右兒子
charfh;//運算符號
}YS;
根據優先順序解析多運算符的式子,比如2^2+(√4-1)。
從運算順序最低的運算符號開始先找到'+',創建樹頂點結構體,fh='+';father=NULL;brother=NULL;left=(2^2)的結構體;right=(√4-1)的結構體;
(2^2)的結構體:fh='^';num1=2;num2=2;father=最頂端的結構體;brother=(√4-1)的結構體;left=新建節點fh置0;right=新建節點fh置0;
(√4-1)的結構體:fh='-';num2=1;father=最頂端的結構體;brother=(2^2)的結構體;left=√4的結構體;right=新建節點fh置0;
√4的結構體:fh='√';num1=4;father=(√4-1)的結構體;brother=NULL;left=新建節點fh置0;right=NULL;
依次類推,以上只是說明樹形結構建立。
你解析字元串,從運算順序最後的字元開始拆分並創建樹的最頂層節點,然後依次往下建立樹。
最後可以用遞歸函數或循環,遍歷樹各節點進行運算。
『叄』 (高分)求一個正確lex和yacc編的計算器(編譯原理)
網上多的是,大多可以運行。關鍵是你要在Linux下分別將 lex和yacc文件用 flex 和 bison 編譯成對應的c文件,然後在windows下用VC或者Codeblock的IDE下編寫界面,連接剛才對應的c文件,生成exe交給老師。
『肆』 請教:用vc6.0編一個簡單計算器的基本流程
我就不說界面了,光給個核心演算法吧,支持表達式,比如(23+3*43)*2+4*(2+2)
原理?搜索關鍵詞:編譯原理,EBNF
/*
simple integer arithmetic calculator according to the EBNF
<exp> -> <term>{<addop><term>}
<addop>->+|-
<term>-><factor>{<mulop><factor>}
<mulop> -> *
<factor> -> ( <exp> )| Number
Input a line of text from stdin
Outputs "Error" or the result.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
char token;/*global token variable*/
/*function prototypes for recursive calls*/
int exp(void);
int term(void);
int factor(void);
void error(void)
{
fprintf(stderr,"Error\n");
exit(1);
}
void match(char expectedToken)
{
if(token==expectedToken)token=getchar();
else error();
}
main()
{
int result;
token = getchar();/*load token with first character for lookahead*/
result = exp();
if(token=='\n')/*check for end of line */
printf("Result = %d\n",result);
else error();/*extraneous cahrs on line*/
return 0;
}
int exp(void)
{
int temp = term();
while((token=='+')||(token=='-'))
switch(token)
{
case '+':
match('+');
temp+=term();
break;
case '-':
match('-');
temp-=term();
break;
}
return temp;
}
int term(void)
{
int temp = factor();
while (token=='*')
{
match('*');
temp*=factor();
}
return temp;
}
int factor(void)
{
int temp;
if(token=='('){
match('(');
temp = exp();
match(')');
}
else if(isdigit(token)){
ungetc(token,stdin);
scanf("%d",&temp);
token = getchar();
}
else error();
return temp;
}
『伍』 這個用C語言寫的計算器的思路是什麼
對初學編程者來說,這個程序的原理確實難了點,因為它用到了編譯原理的知識.
即如果設一個四則運算表達式的形式為S,那麼它一定是一個以等號結尾的運算式,即S->exp=,->是推導符號.
運算式exp又可以繼續推導成
exp->exp+term|exp-term|term
exp表示加減運算,term表示乘除運算.這個推導式反映了乘除的優先順序比加減高.
即要先計算乘除式的結果,再來加減.
term可以推導如下:
term->term*factor|term/factor|factor
factor->num|(E)
factor是數字或者一個被括弧括住的運算式,表示最高優先順序.
數字本身是不帶運算的,是原子性的,肯定是最高優先順序.
括弧是被規定了優先計算.
這個程序的代碼就是按照上面的推導式,用遞歸方式來分析運算式的.
『陸』 簡單計算器的編寫
這是個支持表達式的計算器,代碼很短。
可以輸入類似(3+3*2)*5+6這樣的表達式,自己看吧。
不懂其中的原理來找我,或者自助一下,學點編譯原理的知識,一定要懂EBNF,EBNF不知道是什麼東西?那就google一下吧。
/*
simple integer arithmetic calculator according to the EBNF
<exp> -> <term>{<addop><term>}
<addop>->+|-
<term>-><factor>{<mulop><factor>}
<mulop> -> *
<factor> -> ( <exp> )| Number
Input a line of text from stdin
Outputs "Error" or the result.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
char token;/*global token variable*/
/*function prototypes for recursive calls*/
int exp(void);
int term(void);
int factor(void);
void error(void)
{
fprintf(stderr,"Error\n");
exit(1);
}
void match(char expectedToken)
{
if(token==expectedToken)token=getchar();
else error();
}
main()
{
int result;
token = getchar();/*load token with first character for lookahead*/
result = exp();
if(token=='\n')/*check for end of line */
printf("Result = %d\n",result);
else error();/*extraneous cahrs on line*/
return 0;
}
int exp(void)
{
int temp = term();
while((token=='+')||(token=='-'))
switch(token)
{
case '+':
match('+');
temp+=term();
break;
case '-':
match('-');
temp-=term();
break;
}
return temp;
}
int term(void)
{
int temp = factor();
while (token=='*')
{
match('*');
temp*=factor();
}
return temp;
}
int factor(void)
{
int temp;
if(token=='('){
match('(');
temp = exp();
match(')');
}
else if(isdigit(token)){
ungetc(token,stdin);
scanf("%d",&temp);
token = getchar();
}
else error();
return temp;
}
『柒』 怎麼用VB程序做計算器啊
其實比較簡單啦,用一個窗體就可以實現啦!
我自己寫的,你可以看看
Option Explicit
Dim strNumber As String
Dim strPoint As String
Dim dblNum1 As Double
Dim intOperator As Integer
'清除結果
Private Sub cmdGT_Click()
txtDisplay.Text = "0."
strNumber = ""
strPoint = "."
intOperator = 7
End Sub
'輸入數字
Private Sub cmdNumber_Click(Index As Integer)
strNumber = strNumber & cmdNumber(Index).Caption
txtDisplay.Text = strNumber & strPoint
End Sub
Private Sub cmdOnOff_Click()
End
End Sub
'運算過程
Private Sub cmdOperator_Click(Index As Integer)
Dim dblnum2 As Double
'是第一次單擊運算符時,將輸入的值先賦給第一個數,否則賦值給第二個數進行運算
If intOperator = 7 Then
dblNum1 = CDbl(txtDisplay.Text)
Else
dblnum2 = CDbl(Val(txtDisplay.Text))
'根據輸入的符號進行運算
'求普通運算
Select Case intOperator
Case 0
dblNum1 = dblNum1 + dblnum2
Case 1
dblNum1 = dblNum1 - dblnum2
Case 2
dblNum1 = dblNum1 * dblnum2
Case 3
If dblnum2 <> 0 Then
dblNum1 = dblNum1 / dblnum2
Else
MsgBox "除數不能為「0」!請重新輸入除數。", vbOKOnly + vbInformation, "除零錯誤"
Index = intOperator
End If
Case 6
dblNum1 = dblNum1 * dblnum2 / 100
End Select
End If
'取得當前輸入的運算符,以做下次運算
intOperator = Index
strNumber = ""
txtDisplay = CStr(dblNum1)
'判斷是否為文本框中的數字加點
If Not txtDisplay Like "*.*" Then
txtDisplay.Text = txtDisplay.Text & "."
End If
End Sub
Private Sub cmdOtherOper_Click(Index As Integer)
Dim dblNum As Double
'求平方根,平方,
dblNum = CDbl(Val(txtDisplay.Text))
Select Case Index
Case 0
'驗證數據是否有效
If dblNum >= 0 Then
txtDisplay.Text = CStr(Sqr(dblNum))
Else
MsgBox "負數不能開平方根!", _
vbOKOnly + vbCritical, "開平方根錯誤"
End If
Case 1
txtDisplay.Text = CStr(dblNum ^ 2)
End Select
'判斷是否為文本框中的數字加點
If Not txtDisplay Like "*.*" Then
txtDisplay.Text = txtDisplay.Text & "."
End If
End Sub
Private Sub cmdPoint_Click()
strNumber = strNumber & strPoint
strPoint = ""
End Sub
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
'使被按下的數字鍵的對應按鈕取得焦點
Select Case KeyCode
Case 48 To 57
cmdNumber(KeyCode - 48).SetFocus
Case 96 To 105
cmdNumber(KeyCode - 96).SetFocus
Case Else
'使按下的符號鍵對應的按鈕取得焦點
If KeyCode = 107 Or (Shift = vbShiftMask And KeyCode = 187) Then
cmdOperator(0).SetFocus
cmdOperator_Click (0)
ElseIf KeyCode = 109 Or KeyCode = 189 Then
cmdOperator(1).SetFocus
cmdOperator_Click (1)
ElseIf KeyCode = 106 Or (Shift = vbShiftMask And KeyCode = 56) Then
cmdOperator(2).SetFocus
cmdOperator_Click (2)
ElseIf KeyCode = 111 Or KeyCode = 191 Then
cmdOperator(3).SetFocus
cmdOperator_Click (3)
ElseIf KeyCode = 13 Then
cmdOperator(7).SetFocus
cmdOperator_Click (7)
ElseIf KeyCode = 8 Then
cmdGT.SetFocus
Call cmdGT_Click
End If
End Select
End Sub
Private Sub Form_KeyPress(KeyAscii As Integer)
'將合法的數據輸入到文本框
Select Case KeyAscii
Case 48 To 58
'調用數字鍵點擊處理程序
cmdNumber_Click KeyAscii - 48
KeyAscii = 0
Case 46
'調用小數點輸入
cmdPoint_Click
KeyAscii = 0
Case 13
'當敲擊回車時,不能觸發Form的 KeyUp 事件,因此在這里設置文本框的焦點
txtDisplay.SetFocus
Case Else
KeyAscii = 0
End Select
End Sub
Private Sub Form_KeyUp(KeyCode As Integer, Shift As Integer)
txtDisplay.SetFocus
End Sub
Private Sub Form_Load()
strNumber = ""
strPoint = "."
intOperator = 7
End Sub
『捌』 怎麼用C++設計一個簡單的計算機
你說的是設計一個能運算的計算器吧?
下面是代碼:
// The desk calulator
// includes character-level input (sec6.1.3) and
// command line input (sec6.1.7),
// but no namespaces and
// no exceptions
// pp 107-119, sec 6.1, A Desk Calculator
// uses += rather than push_back() for string
// to work around standard library bug
// uses istrstream from <strstream> rather than istringstream from <sstream>
// to work around standard library bug
// No guarantees offered. Constructive comments to [email protected]
/*
program:
END // END is end-of-input
expr_list END
expr_list:
expression PRINT // PRINT is semicolon
expression PRINT expr_list
expression:
expression + term
expression - term
term
term:
term / primary
term * primary
primary
primary:
NUMBER
NAME
NAME = expression
- primary
( expression )
*/
#include <string>
#include <cctype>
#include<iostream>
#include<map>
//#include<sstream> // string streams
#include<strstream> // C-style string streams
using namespace std;
istream* input; // pointer to input stream
int no_of_errors; // note: default initialized to 0
double error(const char* s)
{
no_of_errors++;
cerr << "error: " << s << '\n';
return 1;
}
enum Token_value {
NAME, NUMBER, END,
PLUS='+', MINUS='-', MUL='*', DIV='/',
PRINT=';', ASSIGN='=', LP='(', RP=')'
};
Token_value curr_tok = PRINT;
double number_value;
string string_value;
Token_value get_token()
{
char ch;
do { // skip whitespace except '\en'
if(!input->get(ch)) return curr_tok = END;
} while (ch!='\n' && isspace(ch));
switch (ch) {
case ';':
case '\n':
return curr_tok=PRINT;
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 '.':
input->putback(ch);
*input >> number_value;
return curr_tok=NUMBER;
default: // NAME, NAME=, or error
if (isalpha(ch)) {
string_value = ch;
while (input->get(ch) && isalnum(ch))
string_value += ch; // string_value.push_back(ch);
// to work around library bug
input->putback(ch);
return curr_tok=NAME;
}
error("bad token");
return curr_tok=PRINT;
}
}
map<string,double> table;
double expr(bool); // cannot do without
double prim(bool get) // handle primaries
{
if (get) get_token();
switch (curr_tok) {
case NUMBER: // floating-point constant
{ 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: // unary minus
return -prim(true);
case LP:
{ double e = expr(true);
if (curr_tok != RP) return error(") expected");
get_token(); // eat ')'
return e;
}
default:
return error("primary expected");
}
}
double term(bool get) // multiply and divide
{
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 expr(bool get) // add and subtract
{
double left = term(get);
for (;;) // ``forever''
switch (curr_tok) {
case PLUS:
left += term(true);
break;
case MINUS:
left -= term(true);
break;
default:
return left;
}
}
int main(int argc, char* argv[])
{
switch (argc) {
case 1: // read from standard input
input = &cin;
break;
case 2: // read argument string
// input = new istringstream(argv[1]);
input = new istrstream(argv[1]);
break;
default:
error("too many arguments");
return 1;
}
table["pi"] = 3.1415926535897932385; // insert predefined names
table["e"] = 2.7182818284590452354;
while (*input) {
get_token();
if (curr_tok == END) break;
if (curr_tok == PRINT) continue;
cout << expr(false) << '\n';
}
if (input != &cin) delete input;
return no_of_errors;d
}
『玖』 用c++編寫一個簡單的計算器
你的這個要求絕對不會有人滿足的。因為你的這個要求不只是一個編寫一個最簡單的計算器問題。
主要是在編寫這個程序的過程中,還涉及到了計算機軟體專業中的「編譯原理」這門課程的其中重要知識。即:表達式的分析與求值(即:何時將相應的數字、以及運算符壓入堆棧,何時又需要將相應的數字、以及運算符彈出堆棧)、以及對運算符優先順序的處理(例如:括弧的最優先最高、乘除法的優先順序高於加減法)。
所以說你的這個要求可以說是:至少是一個大作業了。而且了,另外還有一個別的任何人無法滿足你的原因就是:對於編寫任何程序來說,都是必須要通過自己上機編寫程序源代碼、編譯、鏈接、通過花費很多的時間和精力去調試,最終才能夠得出程序的正確運行結果。