计算四则运算表达式
Posted INnoVation-V2
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了计算四则运算表达式相关的知识,希望对你有一定的参考价值。
#token.h# #ifndef TOKEN_H_INCLUDED #define TOKEN_H_INCLUDED typedef enum { BAD_TOKEN, NUMBER_TOKEN, ADD_OPERATER_TOKEN, SUB_OPERATER_TOKEN, MUL_OPERATER_TOKEN, DIV_OPERATER_TOKEN, END_OF_LINE_TOKEN } TokenKind; #define MAX_TOKEN_SIZE 100 typedef struct { TokenKind kind; double value; char str[MAX_TOKEN_SIZE]; } Token; void set_line(char *line); void get_token(Token *token); #endif //TOKEN_H_INCLUDED
#lexicalanalyzer.c# #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include "token.h" static char *st_line; static int st_line_pos; typedef enum { INITAL_STATUS, IN_INT_PART_STATUS, DOT_STATUS, IN_FRAC_PART_STATUS } LexerStatus; //词法分析,分割字符 void get_token(Token *token) { int out_pos = 0; LexerStatus status = INITAL_STATUS; char current_char; token->kind = BAD_TOKEN; while (st_line[st_line_pos] != ‘\0‘) { //将第st_line_pos个st_line赋值给current_char current_char = st_line[st_line_pos]; if ((status == IN_INT_PART_STATUS || status == IN_FRAC_PART_STATUS) && !isdigit(current_char) && current_char != ‘.‘) { token->kind = NUMBER_TOKEN; sscanf(token->str, "%lf", &token->value); return; } if (isspace(current_char)) { if (current_char == ‘\n‘) { token->kind = END_OF_LINE_TOKEN; return; } st_line_pos++; continue; } if (out_pos >= MAX_TOKEN_SIZE - 1) { fprintf(stderr, "token too long.\n"); exit(1); } token->str[out_pos] = st_line[st_line_pos]; st_line_pos++; out_pos++; token->str[out_pos] = ‘\0‘; if (current_char == ‘+‘) { token->kind = ADD_OPERATER_TOKEN; return; } else if (current_char == ‘-‘) { token->kind = SUB_OPERATER_TOKEN; return; } else if (current_char == ‘*‘) { token->kind = MUL_OPERATER_TOKEN; return; } else if (current_char == ‘/‘) { token->kind = DIV_OPERATER_TOKEN; return; } else if (isdigit(current_char)) { if (status == INITAL_STATUS) { status = IN_INT_PART_STATUS; } else if (status == DOT_STATUS) { status = IN_FRAC_PART_STATUS; } } else if (current_char == ‘.‘) { if (status == IN_INT_PART_STATUS) { status = DOT_STATUS; } else { fprintf(stderr, "syntax error\n"); exit(1); } } else { fprintf(stderr, "bad character(%c)\n", current_char); exit(1); } } } //将行号初始化,将读入的表达式复制给st_line,将st_line_pos初始化为0 void set_line(char *line) { st_line = line; st_line_pos = 0; } //测试代码 //void //parse_line(char *buf) { // Token token; // set_line(buf); // for (;;) { // get_token(&token); // if (token.kind == END_OF_LINE_TOKEN) { // break; // } else { // printf("kind ..%d,str..%s\n", token.kind, token.str); // } // } //} // //int //main(int argc, char **argv) { // char buf[1024]; // while (fgets(buf, 1024, stdin) != NULL) { // parse_line(buf); // } // return 0; //}
#parser.c# #include <stdio.h> #include <stdlib.h> #include "token.h" #define LINE_BUF_SIZE 1024 static Token st_look_ahead_token; static int st_look_ahead_token_exists;
//获得下一个运算符或数字 static void my_get_token(Token *token) { if (st_look_ahead_token_exists) { *token = st_look_ahead_token; st_look_ahead_token_exists = 0; } else { get_token(token); } }
//临时存储运算符 static void unget_token(Token *token) { st_look_ahead_token = *token; st_look_ahead_token_exists = 1; } double parse_expression(void);
//获取数值 static double parse_primary_expression() { Token token; my_get_token(&token); if (token.kind == NUMBER_TOKEN) { return token.value; } fprintf(stderr, "syntax error.\n"); exit(1); return 0.0; }
//乘除运算函数 static double parse_term() { double v1; double v2; Token token; v1 = parse_primary_expression(); for (;;) { my_get_token(&token); if (token.kind != MUL_OPERATER_TOKEN && token.kind != DIV_OPERATER_TOKEN) { unget_token(&token); break; } v2 = parse_primary_expression(); if (token.kind == MUL_OPERATER_TOKEN) { v1 *= v2; } else if (token.kind == DIV_OPERATER_TOKEN) { v1 /= v2; } } return v1; } //加减运算函数 double parse_expression() { double v1; double v2; Token token; v1 = parse_term(); for (;;) { my_get_token(&token); if (token.kind != ADD_OPERATER_TOKEN && token.kind != SUB_OPERATER_TOKEN) { unget_token(&token); break; } v2 = parse_term(); if (token.kind == ADD_OPERATER_TOKEN) { v1 += v2; } else if (token.kind == SUB_OPERATER_TOKEN) { v1 -= v2; } else { unget_token(&token); } } return v1; } double parse_line(void) { double value; st_look_ahead_token_exists = 0; value = parse_expression(); return value; } int main(int argc, char **argv) { char line[LINE_BUF_SIZE]; double value; while (fgets(line, LINE_BUF_SIZE, stdin) != NULL) { set_line(line); value = parse_line(); printf(">>%f\n", value); } return 0; }
以上是关于计算四则运算表达式的主要内容,如果未能解决你的问题,请参考以下文章