我定义一个加减法则
// 表达式
expression ::= literal | PlusSign | MinusSign | '(' expression ')'
// 加号(执行加法)
PlusSign ::= '+'
// 减号(执行减法)
MinusSign ::= '-'
// 终结符(终结符有数字字符组成)
literal ::= '0' | '1' | '2' | ... {'0' | '1' | '2' | ... }
例如: 这样子构造语法树.
表达式1 + (3 - 1)的语法树就是:
Expression >>>>>literal PlusSign (Expression)>>>>literal PlusSign (literal MinusSign literal )
表达式1 + 2 - (3 - 1)的语法树有两棵分别是:
Expression >>>>>Expression MinusSign (Expression)>>>>literal PlusSign literal MinusSign (literal MinusSign literal )
Expression >>>>>literal PlusSign Expression>>>>literal PlusSign literal - (Expression)>>>literal PlusSign literal MinusSign (literal MinusSign literal )很明显: 完全展开后, 它们是一样的(殊途同归而已)
CASExpression 表达式的抽象类
CPlusSign 加号规则类
CMinusSign 减号规则类
CNumber 终结符类
这里没有上下文类
如图:
图1
class CASExpression { public: CASExpression(); virtual ~CASExpression(); virtual double Interpret() = 0; } /////////////////////////////////////////////////////////////////////////////// class CPlusSign : public CASExpression { public: CPlusSign(CASExpression* pCASExpression1, CASExpression* pCASExpression2); virtual ~CPlusSign(); virtual double Interpret(); private: CASExpression* m_pCASExpression1; CASExpression* m_pCASExpression2; } ... double CPlusSign::Interpret() { // 加法(存在递归) return m_pCASExpression1->Interpret() + m_pCASExpression2->Interpret(); } /////////////////////////////////////////////////////////////////////////////// class CMinusSign : public CASExpression { public: CMinusSign(CASExpression* pCASExpression1, CASExpression* pCASExpression2); virtual ~CMinusSign(); virtual double Interpret(); private: CASExpression* m_pCASExpression1; CASExpression* m_pCASExpression2; } ... double CMinusSign ::Interpret() { // 减法(存在递归) return m_pCASExpression1->Interpret() - m_pCASExpression2->Interpret(); } /////////////////////////////////////////////////////////////////////////////// class CNumber : public CASExpression { public: CNumber(char* pChNumber); virtual ~CNumber(); virtual double Interpret(); private: char* m_pChNumber; } double CNumber::Interpret() { // 终结递归 return attf(m_pChNumber); } /////////////////////////////////////////////////////////////////////////////// // 调用 // 求值表达式10 + (3 - 1.9) // 1. 语法分析, 提取出语法树上的每一个节点 ... // 2. 构建语法树(个人理解在语法分析过程中就会构造出语法树了) // Expression >>>>>literal PlusSign (Expression)>>>>literal PlusSign (literal MinusSign literal ) n1 = new CNumber("10"); n2= new CNumber("3"); n3 = new CNumber("1.9"); pCMinusSign = new CMinusSign(n2, n3 ); pCPlusSign = new CPlusSign(n1 , pCMinusSign ); // 3. 求值 pCPlusSign0>Interpret(); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
表达式1 + (3 - 1)的语法树就是:
Expression >>>>>literal PlusSign (Expression)>>>>literal PlusSign (literal MinusSign literal )
表达式1 + 2 - (3 - 1)的语法树有两棵分别是:
Expression >>>>>Expression MinusSign (Expression)>>>>literal PlusSign literal MinusSign (literal MinusSign literal )
Expression >>>>>literal PlusSign Expression>>>>literal PlusSign literal - (Expression)>>>literal PlusSign literal MinusSign (literal MinusSign literal )很明显: 完全展开后, 它们是一样的(殊途同归而已)
(语法树的构建需要看你的语法分析的算法)
这种模式工作中没怎么使用过. 例如分析一些矢量文件格式, 好像也不怎么需要使用该模式. 个人理解该模式主要对表达式进行求值(不一定是数字, 总之就是求出某表达式的结果), 而适合使用该模式的比较适合表达式中有终结符表达式, 可以嵌套表达式等情况.