dポイントプレゼントキャンペーン実施中!

下のソースを加減乗除だけでなく、余りを求める演算(%)やべき乗演算(^)も使えるようにしたいのですがうまくいきません。
どなたか変更例をお見せできますでしょうか?
#include <stdio.h>
#include <stdlib.h>

#define STACK_MAX 10

/* 配列によるスタック構造 */
double stack[STACK_MAX];
/* スタック頂上の位置(最下部からのオフセット)*/
int stack_top = 0;

/* スタックへのpush */
void stack_push(double val) {
if(stack_top == STACK_MAX) {
/* スタックが満杯になっている */
printf("エラー:スタックが満杯です(Stack overflow)\n");
exit(EXIT_FAILURE);
} else {
/* 渡された値をスタックに積む */
stack[stack_top] = val;
stack_top++;
}
}

/* スタックからpop */
double stack_pop(void)
{
if(stack_top == 0) {
/* スタックには何もない */
printf("エラー:スタックが空なのにpopが呼ばれました"
"(Stack underflow)\n");
exit(EXIT_FAILURE);
return 0;
} else {
/* いちばん上の値を返す */
stack_top--;
return stack[stack_top];
}
}

int main(void) {
char buffer[256];
double cal1, cal2;
int i;

do {
printf("現在のスタック(%d個):", stack_top);
for(i = 0; i < stack_top; i++) {
printf("%0.3f ", stack[i]);
}
printf("\n>");
fgets(buffer, 255, stdin);
switch(buffer[0]) {
case '+':
cal1 = stack_pop();
cal2 = stack_pop();
stack_push(cal2 + cal1);
break;
case '-':
cal1 = stack_pop();
cal2 = stack_pop();
stack_push(cal2 - cal1);
break;
case '*':
cal1 = stack_pop();
cal2 = stack_pop();
stack_push(cal2 * cal1);
break;
case '/':
cal1 = stack_pop();
cal2 = stack_pop();
stack_push(cal2 / cal1);
break;
case '=':
/* =の場合はこのすぐあとでwhile文からも抜ける */
break;
default:
/* 入力された値は数字のはずなので,スタックに積む */
stack_push(atoi(buffer));
break;
}
} while(buffer[0] != '=');

printf("計算結果は%f です。\n",stack_pop());
if(stack_top != 0) {
printf("エラー:スタックにまだ数が残っています\n");
return EXIT_FAILURE;
}

return EXIT_SUCCESS;
}

A 回答 (3件)

以下のものを少し変更して、LL(1)文法のコンパイラコンパイラにかける。



-- Attribute grammar of s
-- ====================================================
GRAMMAR s

SEMANTIC DECLARATIONS
--=====================

TERMINALS
--===========

NUM --1
CELL --2
FUNC --3
"+" --4
"-" --5
"*" --6
"/" --7
"^" --8
"(" --9
")" --10
":" --11
nococosy --12

NONTERMINALS
--=============

s
e
t
f
x
u
o

--=========== Scanner rules =================
RULES

s = e sem
if(isformula)
{*att = FORMULA;}
else
{*att = VALUE;}
push(&curtoken);
break;
endsem.
e = t
{"+" sem push(&curtoken); break; endsem
t sem
token1 = pop();
curtoken.x.value += token1.x.value;
break;
endsem
|"-" sem push(&curtoken); break; endsem
t sem
token1 = pop();
curtoken.x.value = token1.x.value - curtoken.x.value ;
break;
endsem}.
t = f
{"*" sem push(&curtoken); break; endsem
f sem
token1 = pop();
curtoken.x.value *= token1.x.value;
break;
endsem
|"/" sem push(&curtoken); break; endsem
f sem
token1 = pop();
if (curtoken.x.value == 0)
curtoken.x.value = HUGE_VAL;
else
curtoken.x.value = token1.x.value/curtoken.x.value;;
break;
endsem}.
f = x
["^" sem push(&curtoken); break; endsem
f sem
token1 = pop();
curtoken.x.value = pow( token1.x.value, curtoken.x.value,);
break;
endsem ].
x = u
| "-"u sem
curtoken.x.value = -curtoken.x.value;
break;
endsem.
u = CELL sem
curtoken.x.value = cellvalue(curtoken.x.c.col, curtoken.x.c.row);
break;
endsem
[ ":" sem push(&curtoken); break; endsem
CELL
sem
push(&curtoken);
token1 = pop();
token2 = pop();
curtoken.x.value = 0;
if (token1.x.c.row == token2.x.c.row)
{
if (token1.x.c.col < token2.x.c.col)
error = TRUE;
else
{
for (counter = token2.x.c.col; counter <= token1.x.c.col; counter++)
curtoken.x.value += cellvalue(counter, token1.x.c.row);
}
}
else if (token1.x.c.col == token2.x.c.col)
{
if (token1.x.c.row < token2.x.c.row)
error = TRUE;
else
{
for (counter = token2.x.c.row; counter <= token1.x.c.row; counter++)
curtoken.x.value += cellvalue(token1.x.c.col, counter);
}
}
else
error = TRUE;
break;
endsem]
| o.
o = "("e")"
| NUM
| FUNC"(" sem push(&curtoken); break; endsem
e
sem
token1 = pop();
if (strcmp(token1.x.funcname, "ABS") == 0)
curtoken.x.value = fabs(curtoken.x.value);
else if (strcmp(token1.x.funcname, "ACOS") == 0)
curtoken.x.value = acos(curtoken.x.value);
else if (strcmp(token1.x.funcname, "ASIN") == 0)
curtoken.x.value = asin(curtoken.x.value);
else if (strcmp(token1.x.funcname, "ATAN") == 0)
curtoken.x.value = atan(curtoken.x.value);
else if (strcmp(token1.x.funcname, "COSH") == 0)
curtoken.x.value = cosh(curtoken.x.value);
else if (strcmp(token1.x.funcname, "COS") == 0)
curtoken.x.value = cos(curtoken.x.value);
else if (strcmp(token1.x.funcname, "EXP") == 0)
curtoken.x.value = exp(curtoken.x.value);
else if (strcmp(token1.x.funcname, "LOG10") == 0)
curtoken.x.value = log10(curtoken.x.value);
else if (strcmp(token1.x.funcname, "LOG") == 0)
curtoken.x.value = log(curtoken.x.value);
else if (strcmp(token1.x.funcname, "ROUND") == 0)
curtoken.x.value = (int)(curtoken.x.value + 0.5);
else if (strcmp(token1.x.funcname, "POW10") == 0)
curtoken.x.value = pow10(curtoken.x.value);
else if (strcmp(token1.x.funcname, "SINH") == 0)
curtoken.x.value = sinh(curtoken.x.value);
else if (strcmp(token1.x.funcname, "SIN") == 0)
curtoken.x.value = sin(curtoken.x.value);
else if (strcmp(token1.x.funcname, "SQRT") == 0)
curtoken.x.value = sqrt(curtoken.x.value);
else if (strcmp(token1.x.funcname, "SQR") == 0)
curtoken.x.value *= curtoken.x.value;
else if (strcmp(token1.x.funcname, "TANH") == 0)
curtoken.x.value = tanh(curtoken.x.value);
else if (strcmp(token1.x.funcname, "TAN") == 0)
curtoken.x.value = tan(curtoken.x.value);
else if (strcmp(token1.x.funcname, "TRUNC") == 0)
curtoken.x.value = (int)curtoken.x.value;
break;
endsem
")".
ENDGRAM
    • good
    • 0

(1)浮動小数点の剰余を%演算子で計算している可能性


(2)べき乗演算に^演算子(XOR演算子)を使っている可能性

実際にどのように書いてどのように動作したのかは分かりませんので、とりあえず間違えてそうなところを書きました。
    • good
    • 0

> 余りを求める演算(%)やべき乗演算(^)も使えるようにしたいのですがうまくいきません。


どういうコードを書いて、どういう結果になって「うまくいかない」と判断したのでしょうか?
加減乗除ができるなら、少なくとも剰余は同様に求められるはずです。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!