嗯,没有那么多时间看^_^
我这是为Code::Blocks实现预处理分析时的一个表达式计算模块。
卡在一元处理符上了。
目前的实现,对 (15 + 25) * 2 的处理是正确的。
这是输出的LOG:
000019. CalcPreprocessor() : Base Expression : (15 + 25) * 2
000020. FixArgument() : src='(15 + 25)'.
000021. FixArgument() : dst='(15 + 25)'.
000022. CalcPreprocessor() : Final Expression : (15 + 25)*2
000023. GetToken() : Current Char:'(', m_Position: 1
000024. GetToken() : Current Char:'1', m_Position: 2
000025. GetToken() : Last Char: '('
000026. GetToken() : Current Token: "(", m_Position: 1
000027. GetToken() : Current Char:'1', m_Position: 2
000028. GetToken() : Current Char:'5', m_Position: 3
000029. GetToken() : Last Char: '1'
000030. GetToken() : Current Char:' ', m_Position: 4
000031. GetToken() : Current Char:'+', m_Position: 5
000032. GetToken() : Last Char: '5'
000033. GetToken() : Current Token: "15", m_Position: 4
000034. GetToken() : Current Char:'+', m_Position: 5
000035. GetToken() : Current Char:' ', m_Position: 6
000036. GetToken() : Current Char:'2', m_Position: 7
000037. GetToken() : Last Char: '+'
000038. GetToken() : Current Token: "+", m_Position: 6
000039. GetToken() : Current Char:'2', m_Position: 7
000040. GetToken() : Current Char:'5', m_Position: 8
000041. GetToken() : Last Char: '2'
000042. GetToken() : Current Char:')', m_Position: 9
000043. GetToken() : Last Char: '5'
000044. GetToken() : Current Token: "25", m_Position: 8
000045. GetToken() : Current Char:')', m_Position: 9
000046. GetToken() : Current Char:'*', m_Position: 10
000047. GetToken() : Last Char: ')'
000048. GetToken() : Current Token: ")", m_Position: 9
000049. GetToken() : Current Char:'*', m_Position: 10
000050. GetToken() : Current Char:'2', m_Position: 11
000051. GetToken() : Last Char: '*'
000052. GetToken() : Current Token: "*", m_Position: 10
000053. GetToken() : Current Char:'2', m_Position: 11
000054. GetToken() : Current Token: "2", m_Position: 11
000055. ConvertToPostfixExpressione() : PostfixExpressione : 15 25 + 2 *
可以看到从:
000022. CalcPreprocessor() : Final Expression : (15 + 25)*2
到:
000055. ConvertToPostfixExpressione() : PostfixExpressione : 15 25 + 2 *
这个表达式的转换是正确的。
但对一元操作符的处理还没有完成,而且思路比较乱,没有找到好办法。
尤其是类似:!(!(15 + 25) - 40) 这种嵌套计算时!
这是目前的代码:
expression.h
/*
* This file is part of the Code::Blocks IDE and licensed under the GNU General Public License, version 3
* http://www.gnu.org/licenses/gpl-3.0.html
*/
#ifndef EXPRESSION_H
#define EXPRESSION_H
#include "tokenizer.h"
#include "token.h"
class ExpressionNode
{
public:
enum ExpressionNodeType
{
Unknown, // Unknown
Plus, // +
Subtract, // -
MultiPly, // *
Divide, // /
LParentheses, // (
RParentheses, // )
Mod, // %
Power, // ^
BitwiseAnd, // &
BitwiseOr, // |
And, // &&
Or, // ||
Not, // !
Equal, // ==
Unequal, // !=
GT, // >
LT, // <
GTOrEqual, // >=
LTOrEqual, // <=
LShift, // <<
RShift, // >>
Numeric, // Numeric
};
ExpressionNode(wxString value);
ExpressionNodeType GetType() const { return m_Type; }
wxString GetValue() const { return m_Value; }
wxString GetUnitary() const { return m_Unitary; }
int GetPriority() const { return m_Priority; }
void SetUnitary(wxString unitary) { m_Unitary = unitary; }
static ExpressionNodeType ParseNodeType(wxString value);
static int GetNodeTypePriority(ExpressionNodeType nodeType);
static bool IsUnitaryNode(ExpressionNodeType nodeType);
private:
wxString m_Value;
ExpressionNodeType m_Type;
wxString m_Unitary;
int m_Priority;
int m_Numeric;
};
class ExpressionParser
{
public:
ExpressionParser(wxString expression);
wxString GetToken();
bool NotEOF();
bool IsWhiteSpace(wxChar ch);
bool IsCongener(wxChar ch1, wxChar ch2);
bool IsDoubleOperator(wxChar ch1, wxChar ch2);
private:
const wxString m_Expression;
size_t m_Position;
};
class Expression
{
public:
Expression();
void ConvertToPostfixExpression(wxString expression);
bool CalcPostfixExpression();
bool GetResult() const { return m_Result; }
bool GetStatus() const { return m_Status; }
private:
typedef std::list<ExpressionNode> ExpressionNodeList;
ExpressionNodeList m_PostfixExpression;
bool m_Result;
bool m_Status;
};
#endif // EXPRESSION_H