zoukankan      html  css  js  c++  java
  • 【转】C++轻量级可配置语法分析器

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


    以下是将一个四则运算式子的字符串进行词法分析,分割成记号之后求值的代码:

      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 }
  • 相关阅读:
    C#博客记录二
    C#博客记录一
    label语句
    css选择器
    关于访问对象属性的小问题
    特殊符号unicode编码
    不换行
    正则表达式中的exec()方法
    正则表达式中两种定义方式中的反斜杠
    js删除对象数组
  • 原文地址:https://www.cnblogs.com/xuangong/p/2122670.html
Copyright © 2011-2022 走看看