计算四则运算表达式

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; }

 

以上是关于计算四则运算表达式的主要内容,如果未能解决你的问题,请参考以下文章

C语言进行四则运算计算器的代码问题。

IDG | 四则运算表达式计算

计算四则运算表达式(Java语言实现)

表达式计算-----------eval()运算符

java面向对象课程设计-数学表达式计算器

四则运算单元测试