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

    C++轻量级可配置语法分析器(开源) - λ-calculus(惊愕到手了欧耶,GetBlogPostIds.aspx) - 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 }


        点击这里下载。
  • 相关阅读:
    java实现从实体到SQL语句的转换
    Mybatis Plus 入坑(含最新3.X配置)
    Spring cloud config client获取不到配置中心的配置
    Spring Cloud Config-Client 无法获取 Config-Server 在 github 上的配置文件的属性值,竟然是因为
    QMessageBox 的四种用法
    龙芯派二代发布,简化国产软硬件开发难度
    解析Qt元对象系统(五) Q_INVOKABLE与invokeMethod(automatic connection从Qt4.8开始的解释已经与之前不同,发送对象驻足于哪一个线程并不重要,起到决定作用的是接收者对象所驻足的线程以及发射信号(该信号与接受者连接)的线程是不是在同一个线程)good
    解析Qt元对象系统(四) 属性系统(确实比较方便)
    HTML如何让IMG自动适应DIV容器大小
    布隆过滤---判断一个元素在亿级数据中是否存在
  • 原文地址:https://www.cnblogs.com/lexus/p/2874758.html
Copyright © 2011-2022 走看看