%token NUMBER %type expr %left '=' %left '+' '-' %left '*' '/' %left '^' %right uminus
时间: 2024-05-30 22:09:23 浏览: 115
这是一个 Bison 的语法文件的一部分,其中:
- `%token NUMBER` 定义了一个终结符号 NUMBER,表示数字;
- `%type expr` 定义了一个非终结符号 expr,表示表达式;
- `%left '='` 定义了一个左结合的操作符 =,表示赋值;
- `%left '+' '-'` 定义了左结合的加减法操作符 + 和 -;
- `%left '*' '/'` 定义了左结合的乘除法操作符 * 和 /;
- `%left '^'` 定义了左结合的指数操作符 ^;
- `%right uminus` 定义了一个右结合的操作符 uminus,表示负号。
相关问题
用C语言设计一个简单的计算器,要求能够对输入的数 1.进行+,-,*,/,运算;2.可以带括号( );3.不限定运算式的输入长度.(小白版,用Microsoft Visual C++ 2010 Express运行)
好的,我可以帮你设计一个简单的计算器。
首先,我们需要定义一些数据结构和函数来读取和计算表达式。以下是一个简单的设计:
```c
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX_EXPR_LEN 1000
typedef struct {
char token;
int type;
} Token;
enum {
TOK_INVALID,
TOK_NUMBER,
TOK_PLUS,
TOK_MINUS,
TOK_MULTIPLY,
TOK_DIVIDE,
TOK_LPAREN,
TOK_RPAREN,
TOK_END
};
int get_token(Token *t) {
static char buffer[MAX_EXPR_LEN];
static int pos = 0;
static int len = 0;
while (isspace(buffer[pos])) {
pos++;
}
if (pos >= len) {
fgets(buffer, MAX_EXPR_LEN, stdin);
len = strlen(buffer);
pos = 0;
}
if (isdigit(buffer[pos])) {
int num = 0;
while (isdigit(buffer[pos])) {
num = num * 10 + (buffer[pos] - '0');
pos++;
}
t->token = num;
t->type = TOK_NUMBER;
} else if (buffer[pos] == '+') {
t->token = '+';
t->type = TOK_PLUS;
pos++;
} else if (buffer[pos] == '-') {
t->token = '-';
t->type = TOK_MINUS;
pos++;
} else if (buffer[pos] == '*') {
t->token = '*';
t->type = TOK_MULTIPLY;
pos++;
} else if (buffer[pos] == '/') {
t->token = '/';
t->type = TOK_DIVIDE;
pos++;
} else if (buffer[pos] == '(') {
t->token = '(';
t->type = TOK_LPAREN;
pos++;
} else if (buffer[pos] == ')') {
t->token = ')';
t->type = TOK_RPAREN;
pos++;
} else if (buffer[pos] == '\n') {
t->token = '\n';
t->type = TOK_END;
pos++;
} else {
t->token = buffer[pos];
t->type = TOK_INVALID;
pos++;
}
return t->type;
}
int parse_expr(void);
int parse_number(Token *t) {
if (t->type != TOK_NUMBER) {
printf("Syntax error: expected number\n");
exit(1);
}
int num = t->token;
get_token(t);
return num;
}
int parse_factor(Token *t) {
if (t->type == TOK_NUMBER) {
return parse_number(t);
} else if (t->type == TOK_LPAREN) {
get_token(t);
int result = parse_expr(t);
if (t->type != TOK_RPAREN) {
printf("Syntax error: expected ')'\n");
exit(1);
}
get_token(t);
return result;
} else if (t->type == TOK_PLUS || t->type == TOK_MINUS) {
int op = t->type;
get_token(t);
int result = parse_factor(t);
if (op == TOK_MINUS) {
result = -result;
}
return result;
} else {
printf("Syntax error: expected number or '(' or '+' or '-'\n");
exit(1);
}
}
int parse_term(Token *t) {
int left = parse_factor(t);
while (t->type == TOK_MULTIPLY || t->type == TOK_DIVIDE) {
int op = t->type;
get_token(t);
int right = parse_factor(t);
if (op == TOK_MULTIPLY) {
left *= right;
} else {
left /= right;
}
}
return left;
}
int parse_expr(Token *t) {
int left = parse_term(t);
while (t->type == TOK_PLUS || t->type == TOK_MINUS) {
int op = t->type;
get_token(t);
int right = parse_term(t);
if (op == TOK_PLUS) {
left += right;
} else {
left -= right;
}
}
return left;
}
int main() {
Token t;
int result;
while (1) {
printf("> ");
get_token(&t);
if (t.type == TOK_END) {
break;
}
result = parse_expr(&t);
printf("%d\n", result);
}
return 0;
}
```
这个计算器可以读取并计算一个表达式,支持加减乘除和括号,输入长度不限。你可以在控制台中输入表达式,例如:
```
> 1+2*3
7
> (1+2)*3
9
> 10/3
3
```
请注意,这个计算器还没有处理错误情况,例如输入了无效的字符或者不匹配的括号。你可以自己扩展它来处理这些情况。
解释每一行代码的意思#include <functional> #include <iostream> enum Token { PLUS, MINUS, NUM }; Token curr_tok = NUM; double number_value; double expr(bool get); double term(bool get); double prim(bool get); double error(const std::string& msg) { std::cerr << "error: " << msg << std::endl; return 0.0; } double get_number() { return number_value; } double prim(bool get) { if (get) { // 从输入流中读取下一个 token // 这里简化为直接从标准输入中读取一个 double 值 std::cin >> number_value; curr_tok = NUM; } if (curr_tok == NUM) { return get_number(); } else { return error("syntax error"); } } double term(bool get) { double left = prim(get); while (true) { switch (curr_tok) { case PLUS: left += prim(true); break; case MINUS: left -= prim(true); break; default: return left; } } } double expr(bool get) { double left = term(get); while (true) { switch (curr_tok) { case PLUS: left += term(true); break; case MINUS: left -= term(true); break; default: return left; } } } int main() { bool get = true; double left = expr(get); switch (curr_tok) { case PLUS: left += term(true); break; default: return left; } return 0; }
这段代码是一个简单的四则运算计算器,可以计算加减法。下面是每一行代码的意思:
- 第一行和第二行是引入所需的头文件。
- 第三行定义了一个枚举类型 Token,包含三个值:PLUS,MINUS,NUM。
- 第四行定义了一个变量 curr_tok,类型为 Token,初始值为 NUM。
- 第五行和第六行定义了两个变量 number_value 和 expr_value,分别表示当前读入的数字和表达式的值。
- 第七行和第八行声明了三个函数,分别是 error、get_number 和 prim。
- error 函数用于输出错误信息。
- get_number 函数用于获取当前读入的数字。
- prim 函数用于解析基础表达式,包括获取数字和处理括号。
- term 函数用于解析乘法和除法运算。
- expr 函数用于解析加法和减法运算。
- main 函数是整个程序的入口,从标准输入中读取表达式并计算最终结果。