C++轻量级可配置语法分析器(开源) - λ-calculus(惊愕到手了欧耶,GetBlogPostIds.aspx) - C++博客...

C++轻量级可配置语法分析器(开源) - λ-calculus(惊愕到手了欧耶,GetBlogPostIds.aspx) - C++博客

C++轻量级可配置语法分析器(开源) - λ-calculus(惊愕到手了欧耶,GetBlogPostIds.aspx) - C++博客

C++轻量级可配置语法分析器(开源)
    这个分析器包含了四个文件:
    VL_Data_Basic.h(使用了其中的智能指针VL_AutoPtr和一些类型重命名)
    VL_CpData.h(数据结构)
    VL_CpKernel.h/cpp(词法分析器和语法分析器)

    昨天刚写好的,可能有Bug,这个东西供给熟悉编译原理(至少熟悉BNF notation)的人互相学习交流,并不打算作为一个成品出现。以下是将一个四则运算式子的字符串进行词法分析,分割成记号之后求值的代码:
  1  #include  " ..\..\..\..\VL++\Library\Platform\VL_Console.h "
  2  #include  " ..\..\..\..\VL++\Library\Data\Grammar2\VL_CpKernel.h "
  3 
  4  using   namespace  vl;
  5  using   namespace  vl::platform;
  6  using   namespace  vl::grammar;
  7 
  8  enum  Operator
  9  {
 10      opAdd,
 11      opSub,
 12      opMul,
 13      opDiv
 14  };
 15 
 16  enum  TokenID
 17  {
 18      tiNumber,
 19      tiLeft,
 20      tiRight,
 21      tiAdd,
 22      tiSub,
 23      tiMul,
 24      tiDiv
 25  };
 26 
 27  VDouble Number( const  VL_CpToken &  Input)
 28  {
 29       return  VUnicodeString(Input.Start,Input.Length).ToDouble();
 30  }
 31 
 32  Operator Op( const  VL_CpToken &  Input)
 33  {
 34       switch (Input.ID)
 35      {
 36       case  tiAdd: return  opAdd;
 37       case  tiSub: return  opSub;
 38       case  tiMul: return  opMul;
 39       case  tiDiv: return  opDiv;
 40       default : return  (Operator) - 1 ;
 41      }
 42  }
 43 
 44  VDouble RemoveBracket( const  VL_CpPair < VL_CpPair < VL_CpToken , VDouble >  , VL_CpToken >&  Input)
 45  {
 46       return  Input.First.Second;
 47  }
 48 
 49  VDouble Calculate( const  VL_CpPair < VDouble,VL_CpList < VL_CpPair < Operator,VDouble >>>&  Numbers)
 50  {
 51      VDouble Result = Numbers.First;
 52      VL_CpList < VL_CpPair < Operator,VDouble >> ::Node::Ptr Current = Numbers.Second.Head;
 53       while (Current)
 54      {
 55           switch (Current -> Data.First)
 56          {
 57           case  opAdd:
 58              Result += Current -> Data.Second;
 59               break ;
 60           case  opSub:
 61              Result -= Current -> Data.Second;
 62               break ;
 63           case  opMul:
 64              Result *= Current -> Data.Second;
 65               break ;
 66           case  opDiv:
 67              Result /= Current -> Data.Second;
 68               break ;
 69          }
 70          Current = Current -> Next;
 71      }
 72       return  Result;
 73  }
 74 
 75  void  Parse()
 76  {
 77      VL_CpLexer Lexer;
 78      Lexer
 79           << Token( false ,L " ( " ,tiLeft)
 80           << Token( false ,L " ) " ,tiRight)
 81           << Token( false ,L " + " ,tiAdd)
 82           << Token( false ,L " - " ,tiSub)
 83           << Token( false ,L " * " ,tiMul)
 84           << Token( false ,L " / " ,tiDiv)
 85           << Token( false ,_Float,tiNumber)
 86          ;
 87 
 88      _Wrapper < VL_CpTokenNodePtr , VDouble >  Factor,Term,Expr;
 89      Factor     =  (Number <<= Token(tiNumber))  |  (RemoveBracket  <<=  Token(tiLeft)  +  Expr  +  Token(tiRight));
 90      Term     =  Calculate  <<=  Factor  +   * ((Op <<= Token(tiMul) | Token(tiDiv))  +  Factor);
 91      Expr     =  Calculate  <<=  Term  +   * ((Op <<= Token(tiAdd) | Token(tiSub))  +  Term);
 92 
 93      VL_CpParser < VL_CpTokenNodePtr , VDouble >  p = Expr;
 94      VL_CpParser < VL_CpTokenNodePtr , VDouble > ::_FullResult Value = p.Parse(Lexer.Parse(L " (1+2)*(3+4) " ).First.Head);
 95      GetConsole() -> Write(L " 结果:\t " + VUnicodeString(Value.Head -> Data.First) + L " \r\n " );
 96  }
 97 
 98  void  vlmain()
 99  {
100      GetConsole() -> SetTitle(L " Vczh Combinator Parser " );
101      GetConsole() -> SetTestMemoryLeaks( true );
102      GetConsole() -> SetPauseOnExit( true );
103 
104      Parse();
105  }


    点击 这里下载。
posted on 2013-01-24 13:17  lexus 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/lexus/archive/2013/01/24/2874758.html

你可能感兴趣的:(C++轻量级可配置语法分析器(开源) - λ-calculus(惊愕到手了欧耶,GetBlogPostIds.aspx) - C++博客...)