以前写过两版算术表达式解析代码,但都是基于栈结构或者树模型的,并不是通用的算法。其实算术表达式解析是最基本的词法分析算法,直到我看了《自制编程语言》里面介绍的递归向下分析法,才明白这种问题的终极解决方案是使用词法分析和语法分析。。
//用于词法定界的头文件 token.h
1 #ifndef _TOKEN_H_VERSION_20140930 2 #define _TOKEN_H_VERSION_20140930 3 4 enum TokenKind{ 5 BAD_TOKEN, 6 NUMBER_TOKEN, 7 ADD_OPERATOR_TOKEN, 8 SUB_OPERATOR_TOKEN, 9 MUL_OPERATOR_TOKEN, 10 DIV_OPERATOR_TOKEN, 11 LEFT_PAREN_TOKEN, 12 RIGHT_PAREN_TOKEN, 13 END_OF_LINE_TOKEN, 14 }; 15 16 #define MAX_TOKEN_SIZE (100) 17 18 struct Token{ 19 TokenKind kind; 20 double value; 21 char str[MAX_TOKEN_SIZE]; 22 }; 23 24 void set_line(char* line); 25 void get_token(Token* token); 26 27 #endif
//词法分析器或者叫单词收割机 lexianalizer.cpp
1 #include "stdafx.h" 2 #include "token.h" 3 #include "stdio.h" 4 #include "stdlib.h" 5 #include "ctype.h" 6 7 static char* st_line; 8 static int st_line_pos; 9 10 typedef enum{ 11 INITIAL_STATUS, 12 IN_INT_PART_STATUS, 13 DOT_STATUS, 14 IN_FRAC_PART_STATUS, 15 }LexerStatus; 16 17 //只是为了获取一个token,里面的循环是忽略空格和读取数字用的 18 void get_token(Token* token) 19 { 20 int out_pos = 0; 21 LexerStatus status = INITIAL_STATUS; 22 char current_char; 23 24 token->kind = BAD_TOKEN; 25 while(st_line[st_line_pos] != '