??xml version="1.0" encoding="utf-8" standalone="yes"?>久久婷婷五月综合色99啪ak,国产精品内射久久久久欢欢 ,久久伊人精品青青草原日本http://www.shnenglu.com/lwch/category/14952.html【QQ:510134884】【Email:<a href="mailto:lwch748@gmail.com">lwch748@gmail.com</a>?/description>zh-cnWed, 16 Oct 2013 19:25:17 GMTWed, 16 Oct 2013 19:25:17 GMT60QParserGenerator的文法文件介l?/title><link>http://www.shnenglu.com/lwch/archive/2013/10/09/203576.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Wed, 09 Oct 2013 03:17:00 GMT</pubDate><guid>http://www.shnenglu.com/lwch/archive/2013/10/09/203576.html</guid><wfw:comment>http://www.shnenglu.com/lwch/comments/203576.html</wfw:comment><comments>http://www.shnenglu.com/lwch/archive/2013/10/09/203576.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/lwch/comments/commentRss/203576.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/lwch/services/trackbacks/203576.html</trackback:ping><description><![CDATA[在沉默(sh)(jin)数月之后Q博d(j)血来潮想(h)l介lQParserGeneratorQ在q里我们不再(h)l介lQ何有关于LALR(1)的算?那东西只?x)把你的脑子变成一团浆p?Q让我们来看一下QParserGenerator的具体用法?br /> <br /> 说到ParserGenerator不得不提的是BNFQ应此QParserGenerator也有它自qBNFQ这时有Z(x)问BNFI竟是什么呢Q简单的说BNF是用来描述一U语法的东西Q比如在Basic中If后面跟表辑ּ然后是Then中间是语句块末尾必须要有End If{等的一pd描述Q更专业的解释我们可以看一?a target="_blank">l基癄</a>上的解释?br /> <br /> 好了(jin)Q说完了(jin)BNF那让我们来看一下QParserGenerator的BNF到底是长啥样?br /> <div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->%token "%" "token" "start" "|" "-" ">" ";" "[" "]";<br /> <br /> %start start;<br /> <br /> strings             -> strings "{String}"<br />                     |  "{String}"<br />                     ;<br /> <br /> vs                  -> vs "{Letter}"<br />                     |  vs "{String}"<br />                     |  "{Letter}"<br />                     |  "{String}"<br />                     ;<br /> <br /> option              -> "[" vs "]"<br />                     ;<br /> <br /> oneProductionRight  -> oneProductionRight option<br />                     |  oneProductionRight vs<br />                     |  option<br />                     |  vs<br />                     ;<br /> <br /> someProductionRight -> someProductionRight "|" oneProductionRight<br />                     |  oneProductionRight<br />                     ;<br /> <br /> token               -> "%" "token" strings ";"<br />                     ;<br /> <br /> someTokens          -> someTokens token<br />                     |  token<br />                     ;<br /> <br /> production          -> "{Letter}" "-" ">" someProductionRight ";"<br />                     ;<br /> <br /> someProductions     -> someProductions production<br />                     |  production<br />                     ;<br /> <br /> start               -> someTokens "%" "start" "{Letter}" ";" someProductions<br />                     |  "%" "start" "{Letter}" ";" someProductions<br />                     ;</div> 也许有h?x)问Q不对啊Ҏ(gu)<a target="_blank">l基癄</a>上的说明BNF不应该是长这L(fng)Q其实QParserGenerator是一个BNF的生成器Q它可以输入的BNF通过一pd的运最后生成LALR(1)分析表,Z(jin)BNF文g的美观和方便处理我特地把他设计成?jin)这个样子的而已Q好?jin)下面我们就以这个BNF文g来说明应该如何来书写BNF文g?br /> <br /> 首先可以看到最上有一些以%token开头的字符Ԍ在C语言中我们将用双引号括v来的字符序列UCؓ(f)字符Ԍ(j)以及(qing)最后的一个分P其实q里的这些字W串正是BNF中说说的l结W,所以我们规定,所有其他没?token声明的符号都是非l结W。终l符是用来做U进操作的,在某U特定的语言中他表现Z个tokenQ而非l结W可以理解ؓ(f)一个代词,通常一个非l结W都可以展开Z条或多条规则Q?a target="_blank">产生?/a>Q。至于说Z么每条内容后面都?x)有分号呢,只是Z(jin)处理上的方便Q消除语法上的冲H?Q?br /> 好了(jin)Q我们把l结W和非终l符q两个专业术语给解释完了(jin)Q接下来可以看到的是一个以%start开头后跟一个非l结W的语句Q他表明?jin)所有规则(<a target="_blank">产生?/a>Q是从哪里开始的Q有始无l的节奏-_-||杯具啊)(j)?br /> <br /> 最后就是我们的重头?jin),多空一行也不ؓ(f)q吧。这里有一大堆的生式Q那我们如何来阅M呢,其实上面已经介绍?jin)有个表明?jin)所有规则开头的非终l符Q好那让我们来找一下他所对应的生式在哪?br /> <div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->start               -> someTokens "%" "start" "{Letter}" ";" someProductions<br />                     |  "%" "start" "{Letter}" ";" someProductions<br />                     ;</div> 可以看到所有的规则可分为左半部分和叛_部分Q左Ҏ(gu)L一个非l结W来说明他应该被哪一些规则来替代Q而右边则是这些规则的具体内容包含?jin)一些终l符和非l结W序列,中间则用一个箭头符h分割。在所有的规则中非l结W都是不带引L(fng)Q而终l符都是用引号将其括h的,在终l符中有一些内|的变量来表达一些特定的表达式,q个?x)在下文中做(gu)明。当然对于同一个终l符来说我们可以用Q意多个规则来说明他,他们都是<font color="red">?/font>的关p,׃BNF中不可能存在<font color="red">?/font>的关p,应此我们q不需要考虑他?br /> <br /> 下面让我们来看一下预定义的终l符有哪些,?a target="_blank">Parser.cpp</a>的代码中可知预定义的l结W有"{String}"?{Digit}"?{Real}"?{Letter}"?br /> "{String}"Q表C正则表辑ּ\"[^\"]*\"<br /> "{Digit}"Q表C正则表辑ּ[0-9]+<br /> "{Real}"Q表C正则表辑ּ[0-9]*.[0-9]+<br /> "{Letter}"Q表C正则表辑ּ((_[0-9]+)|([_a-zA-Z]+))[_0-9a-zA-Z]*<br /> 从这些正则表辑ּ中可?{String}"表示一个带双引L(fng)字符Ԍ"{Digit}"则表CZ个数字,"{Real}"则表CZ个QҎ(gu)Q?{Letter}"则表CZ个不带双引号的字W串。当然这些正则表辑ּ写的q不完备Q比?{String}"中没有支持{义等{?br /> <br /> 然后让我们来看一下每条规则支持哪些语法,首先从下面几条文法中可知Q可用方括号一些可选项括v来?br /> <div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #008080; ">1</span> vs                  -> vs "{Letter}"<br /> <span style="color: #008080; ">2</span>                     |  vs "{String}"<br /> <span style="color: #008080; ">3</span>                     |  "{Letter}"<br /> <span style="color: #008080; ">4</span>                     |  "{String}"<br /> <span style="color: #008080; ">5</span>                     ;<br /> <span style="color: #008080; ">6</span> <br /> <span style="color: #008080; ">7</span> option              -> "[" vs "]"<br /> <span style="color: #008080; ">8</span>                     ;</div> <br /> 而对于一个规则来说他可以用若q条产生式来说明他,其中每条产生式之间是<font color="red">?/font>的关pR?br /> <div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #008080; ">1</span> oneProductionRight  -> oneProductionRight option<br /> <span style="color: #008080; ">2</span>                     |  oneProductionRight vs<br /> <span style="color: #008080; ">3</span>                     |  option<br /> <span style="color: #008080; ">4</span>                     |  vs<br /> <span style="color: #008080; ">5</span>                     ;<br /> <span style="color: #008080; ">6</span> <br /> <span style="color: #008080; ">7</span> someProductionRight -> someProductionRight "|" oneProductionRight<br /> <span style="color: #008080; ">8</span>                     |  oneProductionRight<br /> <span style="color: #008080; ">9</span>                     ;</div> <br /> 其他一些规则则说明?jin)一些上文提到的规则Q比如开头是一些token的定义等。终于把QParserGenerator的文法文件的l构l介l完?jin),在接下来的一文章中我们介l如何用QParserGenerator来生成一个带括号优先U的四则混合q算计算器,其文法可?a target="_blank">Calculator.txt</a>QQLanguage整个目的代码可?a target="_blank">https://github.com/lwch/QLanguage/</a>?img src ="http://www.shnenglu.com/lwch/aggbug/203576.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/lwch/" target="_blank">lwch</a> 2013-10-09 11:17 <a href="http://www.shnenglu.com/lwch/archive/2013/10/09/203576.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>QParserGenerator代码分析?A fix&An example)http://www.shnenglu.com/lwch/archive/2013/05/30/200608.htmllwchlwchThu, 30 May 2013 15:04:00 GMThttp://www.shnenglu.com/lwch/archive/2013/05/30/200608.htmlhttp://www.shnenglu.com/lwch/comments/200608.htmlhttp://www.shnenglu.com/lwch/archive/2013/05/30/200608.html#Feedback2http://www.shnenglu.com/lwch/comments/commentRss/200608.htmlhttp://www.shnenglu.com/lwch/services/trackbacks/200608.html上一?/a>Q首先需要修正的是在DFA生成法中的传播部分Q应该需要有个@环一直传播到不能传播为止Q在多次实验中表明,有些展望W是通过W?Q?Q?甚至更多ơ传播得来的?br />
应此Q相应的make函数变成?br />
    bool LALR1::make()
    {
        vector<LALR1Production> v;
        v.push_back(inputProductions[begin][0]);
        pStart = closure(v);
        pStart->idx = Item::inc();
        context.states.insert(pStart);
        items.push_back(pStart);

        queue<Item*> q;
        q.push(pStart);

        vector<Item*> changes;

        bool bContinue = false;
        while (!q.empty())
        {
            Item* pItem = q.front();
            vector<Production::Item> s;
            symbols(pItem, s);
            select_into(s, vts, compare_production_item_is_vt, push_back_unique_vector<Production::Item>);
            select_into(s, vns, compare_production_item_is_vn, push_back_unique_vector<Production::Item>);
            for (vector<Production::Item>::const_iterator i = s.begin(), m = s.end(); i != m; ++i)
            {
                Item* pNewItem = NULL;
                if (go(pItem, *i, pNewItem))
                {
                    long n = itemIndex(pNewItem);
                    if (n == -1)
                    {
                        pNewItem->idx = Item::inc();
                        q.push(pNewItem);
                        items.push_back(pNewItem);
                        context.states.insert(pNewItem);
                    }
                    else
                    {
                        items[n]->mergeWildCards(pNewItem, bContinue);
                        changes.push_back_unique(items[n]);
                        destruct(pNewItem, has_destruct(*pNewItem));
                        Item_Alloc::deallocate(pNewItem);
                    }
                    edges[pItem].push_back_unique(Edge(pItem, n == -1 ? pNewItem : items[n], *i));
                }
            }
            q.pop();
        }
        while (bContinue)
        {
            vector<Item*> v;
            v.reserve(changes.size());
            bContinue = false;
            for (vector<Item*>::const_iterator i = changes.begin(), m = changes.end(); i != m; ++i)
            {
                vector<Production::Item> s;
                symbols(*i, s);
                for (vector<Production::Item>::const_iterator j = s.begin(), n = s.end(); j != n; ++j)
                {
                    Item* pNewItem = NULL;
                    if (go(*i, *j, pNewItem))
                    {
                        long n = itemIndex(pNewItem);
                        if (n == -1) throw error<const char*>("unknown item", __FILE__, __LINE__);
                        else
                        {
                            items[n]->mergeWildCards(pNewItem, bContinue);
                            v.push_back_unique(items[n]);
                            destruct(pNewItem, has_destruct(*pNewItem));
                            Item_Alloc::deallocate(pNewItem);
                        }
                    }
                }
            }
            changes = v;
        }
    }
在merge函数中,?x)检有没有新生成的展望W来军_是否l箋(hu)传播下去?br />
一个示?/strong>
下面我们用一个例子来说明LALR1 DFA是如何生成的Q首先它的文法如?br />
S -> L "=" R
  | R "+"
  | R
  ;

L -> "*" R
  |  "id"
  ;

R -> L
  ;
Ҏ(gu)之前的算法,我们先来看自生的部分

首先我们写出q个文法的增q文?br />
begin -> . S (#)
求取它的闭包得到
begin -> . S
wildCards:

S -> . L "=" R
wildCards:

S -> . R "+"
wildCards:

S -> . R
wildCards:

L -> . "*" R
wildCards:
"=" "+" 
L -> . "id"
wildCards:
"=" "+" 
R -> . L
wildCards:
"+" # 
我们观察刎ͼ其中?个可转移的符P分别为S、L、R?*"?id"Q我们分别用go函数对这5个{Uȝh出新的状?br />
首先用符号S求出新状?br />
begin -> S
wildCards:
׃q个状态不在原有列表中Q应此它是一个新生成的状态,我们为它d一条通过W号S转移的边?br />
接下来用W号L求出新状?br />
S -> L . "=" R
wildCards:

R -> L
wildCards:
"+" # 
q个状态也不在原有列表中,应此它也是一个新生成的状态,我们为它d一条通过W号L转移的边?br />
然后用符号R求出新状?br />
S -> R . "+"
wildCards:

S -> R
wildCards:
q个状态也不在原有列表中,应此它也是一个新生成的状态,我们为它d一条通过W号R转移的边?br />
然后用符?求出新的状?br />
L -> "*" . R
wildCards:
"=" "+" 
R -> . L
wildCards:
"+" # "=" 
L -> . "*" R
wildCards:
"=" "+" # 
L -> . "id"
wildCards:
"=" "+" # 
同样的它也不在原有的列表中,我们同样为其d一条通过W号*转移的边?br />
然后是符号id?br />
L -> "id"
wildCards:
"=" "+" 
同样不在列表中,我们为其d一条通过W号id转移的边?br />
q样Q从start状态{Ud来的5条边q成好?jin),下面来看看?个新生成的状态又?x)生成一些什么呢
begin -> S
wildCards:
q一个状态可知,它没有Q何的辏V?br />
S -> L . "=" R
wildCards:

R -> L
wildCards:
"+" # 
W二个状态则有一?的{U,它生成了(jin)一个新状?br />
S -> L "=" . R
wildCards:

R -> . L
wildCards:
"+" # "=" 
L -> . "*" R
wildCards:
"=" "+" # 
L -> . "id"
wildCards:
"=" "+" # 

S -> R . "+"
wildCards:

S -> R
wildCards:
W三个状态有一?的{U,它生成了(jin)一个新状?br />
S -> R "+"
wildCards:

L -> "*" . R
wildCards:
"=" "+" 
R -> . L
wildCards:
"+" # "=" 
L -> . "*" R
wildCards:
"=" "+" # 
L -> . "id"
wildCards:
"=" "+" # 
W四个状态有4个{U,分别为R、L?和id

1.通过W号R转移到新状?br />
L -> "*" R
wildCards:
"=" "+" 

2.通过W号L转移到新状?br />
R -> L
wildCards:
"+" # "=" 

3.通过*则可转移到它自己

4.通过id转移到第5个状?br />
W五个状态则没有M的{UR?br />
S -> L "=" . R
wildCards:

R -> . L
wildCards:
"+" # "=" 
L -> . "*" R
wildCards:
"=" "+" # 
L -> . "id"
wildCards:
"=" "+" # 
W六个状态有4个{U,分别为R、L?和id

1.通过W号R可{Ud新状?br />
S -> L "=" R
wildCards:

2.通过W号L可{Ud状?

3.通过W号*可{Ud状?

4.通过W号id可{Ud状?

W???个状态都没有M转移

然后让我们来看下changes列表里有哪些东西Q根?a href="http://www.shnenglu.com/lwch/archive/2013/05/12/200203.html" target="_blank">上一?/a>的算法可知,所有已存在的状态都在changes列表里,应此它里面应该会(x)???三个状态?br />
x(chng)Q整个自生的部分完成?jin),下面我们其L一张图


下面是传播部?/strong>
在第一ơ传播时changes列表里有3个状态,分别对这3个状态用go函数求出新的展望W,q把它们合ƈ到原有的状态上?br />
首先看状?Q它?个状态{UȝQ分别是R、L?和id

1.通过W号R可{Ud状?Q同时它的展望符如下
L -> "*" R
wildCards:
"=" "+" # 

2.通过W号L可{Ud状?Q同时它的展望符如下
R -> L
wildCards:
"+" # "=" 

3.通过W号*可{Ud它自己,同时它的展望W如?br />
L -> "*" . R
wildCards:
"=" "+" # 
R -> . L
wildCards:
"+" # "=" 
L -> . "*" R
wildCards:
"=" "+" # 
L -> . "id"
wildCards:
"=" "+" # 

4.通过W号id可{Ud状?Q同时它的展望符如下
L -> "id"
wildCards:
"=" "+" # 

然后我们来看一下状??Q它们没有Q何状态{UȝQ应此它们不?x)传播Q何展望符?br />
现在changes列表里有4个状态,分别????Q又׃W?个状态已l生了(jin)新的展望W?应此需要(h)l传?br />
W二ơ传?/strong>

首先先看状??Q它们没有Q何状态{UȝQ应此它们不?x)传播Q何展望符?br />
然后来看状?Q同L(fng)它有4个状态{UȝQ分别ؓ(f)R、L?和id?br />
1.通过W号R可{Ud状?Q同时它的展望符如下
L -> "*" R
wildCards:
"=" "+" # 

2.通过W号L可{Ud状?Q同时它的展望符如下
R -> L
wildCards:
"+" # "=" 

3.通过W号*可{Ud它自己,同时它的展望W如?br />
L -> "*" . R
wildCards:
"=" "+" # 
R -> . L
wildCards:
"+" # "=" 
L -> . "*" R
wildCards:
"=" "+" # 
L -> . "id"
wildCards:
"=" "+" # 

4.通过W号id可{Ud状?Q同时它的展望符如下
L -> "id"
wildCards:
"=" "+" # 

最后我们来看状?Q它没有M状态{UȝQ应此它不会(x)传播M展望W?br />
现在changes列表里同h4个状态,分别????Q由于没有一个状态生了(jin)新的展望W,应此它将不会(x)l箋(hu)传播下去?jin)?br />
现在整个文法的DFAq成完毕了(jin)Q让我们来修改一下原先的那张图来看看最l的DFA是什么样的?br />

整个CZ先介绍到这里,在接下来的一文章中会(x)通过几个CZ来介lclosure和go函数的原理,希望q种q到细的讲解顺序能够被读者所接受。最后完整的代码可到http://code.google.com/p/qlanguage下蝲?img src ="http://www.shnenglu.com/lwch/aggbug/200608.html" width = "1" height = "1" />

lwch 2013-05-30 23:04 发表评论
]]>
QParserGenerator代码分析一(生成LALR1 DFA)http://www.shnenglu.com/lwch/archive/2013/05/12/200203.htmllwchlwchSun, 12 May 2013 14:32:00 GMThttp://www.shnenglu.com/lwch/archive/2013/05/12/200203.htmlhttp://www.shnenglu.com/lwch/comments/200203.htmlhttp://www.shnenglu.com/lwch/archive/2013/05/12/200203.html#Feedback1http://www.shnenglu.com/lwch/comments/commentRss/200203.htmlhttp://www.shnenglu.com/lwch/services/trackbacks/200203.htmlstrings     &n...  阅读全文

lwch 2013-05-12 22:32 发表评论
]]>
词法分析?(&epsilon;-NFA到DFA的{?http://www.shnenglu.com/lwch/archive/2013/02/23/198043.htmllwchlwchSat, 23 Feb 2013 15:30:00 GMThttp://www.shnenglu.com/lwch/archive/2013/02/23/198043.htmlhttp://www.shnenglu.com/lwch/comments/198043.htmlhttp://www.shnenglu.com/lwch/archive/2013/02/23/198043.html#Feedback0http://www.shnenglu.com/lwch/comments/commentRss/198043.htmlhttp://www.shnenglu.com/lwch/services/trackbacks/198043.html?a href="http://www.shnenglu.com/lwch/archive/2013/02/15/197848.html" target="_blank">上一?/a>我们已经得到?jin)一个完整的ε-NFAQ下面来说说如何?#949;-NFA转换为DFAQ确定有限自动机Q?/p>

DFA的状?/h1>

在DFA中,某个状态对应到ε-NFA中的若干状态,应此我们会(x)得到下面q样的一个结构?/p>

 

 

        struct DFA_State
        {
            set<EpsilonNFA_State*> content;
            bool                   bFlag;
#ifdef _DEBUG
            uint                   idx;
#endif

            DFA_State(const set<EpsilonNFA_State*>& x) : content(x), bFlag(false)
            {
#ifdef _DEBUG
                idx = inc();
#endif
            }

            inline const bool operator==(const DFA_State& x)const
            {
                if (&x == this) return true;

                return content == x.content;
            }

#ifdef _DEBUG
            inline uint inc()
            {
                static uint i = 0;
                return i++;
            }
#endif
        };

 

可以看到Qؓ(f)?jin)调试方便我们在l构中定义了(jin)状态的唯一ID以及(qing)对应?#949;-NFA状态的集合和一个标C?/p>

DFA的边

Ҏ(gu)上一?/a>的经验,不难惛_DFA的边应该是什么样的,下面直接l出代码Q不做说明?/p>

 

        struct DFA_Edge
        {
            struct
            {
                Char_Type   char_value;
                String_Type string_value;
            }data;

            enum Edge_Type
            {
                TUnknown = 0,
                TNot     = 1,
                TChar    = 2,
                TString  = 4
            };

            uchar edge_type;

            DFA_State* pFrom;
            DFA_State* pTo;

            DFA_Edge(const Char_Type& x, bool bNot, DFA_State* pFrom, DFA_State* pTo) : pFrom(pFrom), pTo(pTo)
            {
                data.char_value = x;
                edge_type = bNot ? (TChar | TNot) : TChar;
            }

            DFA_Edge(const String_Type& x, bool bNot, DFA_State* pFrom, DFA_State* pTo) : pFrom(pFrom), pTo(pTo)
            {
                data.string_value = x;
                edge_type = bNot ? (TString | TNot) : TString;
            }

            inline const bool isNot()const
            {
                return (edge_type & TNot) == TNot;
            }

            inline const bool isChar()const
            {
                return (edge_type & TChar) == TChar;
            }

            inline const bool isString()const
            {
                return (edge_type & TString) == TString;
            }

            const Edge_Type edgeType()const
            {
                if (isChar()) return TChar;
                else if (isString()) return TString;
                else return TUnknown;
            }

            const bool operator<(const DFA_Edge& x)const
            {
                return (ulong)pFrom + pTo < (ulong)x.pFrom + x.pTo;
            }

            const bool operator==(const DFA_Edge& x)const
            {
                return pFrom == x.pFrom && pTo == x.pTo;
            }
        };

 

 

׃DFA中不存在ε边,应此DFA会(x)存在若干个结束状态,但他只有一个开始状?/p>

 

DFA_State*      pDFAStart;
set<DFA_State*> pDFAEnds;
set<DFA_Edge>   dfa_Edges;

 

 

Z(jin)下一步分析的高效Q以后可能会(x)这里的dfa_Edges同样修改为hashmap?/p>

x(chng)DFA所要用到的两个l构q速的介绍完了(jin)?/p>

子集构造算?/h1>

通过各种资料Q我们不隑֏玎ͼ?#949;-NFA转换到DFA的过E中Q最常用是子集构造算法。子集构造算法的主要思想?strong>让DFA的每个状态对应NFA的一个状态集。这个DFA用它的状态去CNFA在读输入W号后达到的所有状态?/strong>Q引自编译原理)(j)其算法如?/p>

 

输入Q一个NFA N?
输出Q一个接受同栯a的DFA D?
Ҏ(gu)Q?
1.求取ε-NFA初始状态的ε闭包作ؓ(f)DFA的v始状态,q将q个状态加入集合C中,且它是未标记的。同时记录它的向后字W集?
2.从集合C中取Z个未被标记的子集T和其对应的字W集Q标记子集T?
3.使用上一步取出的字符集通过状态{Ud数求?gu){Ud的状态集M?
4.求取上一步得到的状态集M?#949;闭包U
5.如果U不在集合C中则U作ؓ(f)未被标记的子集加入C中,同时记录它的向后字符集。检查状态U中是否存在NFA中的l结状态,若存在则状态U加入到pDFAEnds中?
重复2Q?Q?Q?部直至集合C中不存在未被标记的状态?/pre>

ε闭包

ε闭包是指从某个状态v只经q?#949;边达到的其他状态的集合Q同时这个状态也属于q个集合中。其法如下

 

输入Q状态集k?
输出Q状态集U和其所对应的向后字W集?
Ҏ(gu)Q?
1.遍历状态集k中的每个状态k'?
2.若k'不存在于l果状态集U中,k'插入U中?
3.建立一个(f)旉合tmpQƈk'插入其中?
4.从(f)旉合tmp中取Z个状态p?
5.取出所有从p出发的边Q若q条Ҏ(gu)ε边,且抵辄态不在结果状态集U中,抵辄状态分别插入结果状态集U和(f)旉合tmp中。若q条Ҏ(gu)字符集的边且q条Ҏ(gu)对应的字W不在向后字W集中,则将向后字符插入向后字符集中?
6.状态p从(f)旉合tmp中删除?
循环4Q?Q?部直至tmp中不存在M状态ؓ(f)止?/pre>

 

 

׃在生?#949;-NFA时不存在只有ε边的循环Q应此这里不?x)生死循环。下面给出具体的代码

 

        void epsilonClosure(const set<EpsilonNFA_State*>& k, EpsilonClosureInfo& info)
        {
            for (typename set<EpsilonNFA_State*>::const_iterator i = k.begin(), m = k.end(); i != m; ++i)
            {
                info.states.insert(*i);
                set<EpsilonNFA_State*> tmp;
                tmp.insert(*i);
                while (!tmp.empty())
                {
                    EpsilonNFA_State* pState = *tmp.begin();
                    for (typename vector<EpsilonNFA_Edge>::const_iterator j = epsilonNFA_Edges[pState].begin(), n = epsilonNFA_Edges[pState].end(); j != n; ++j)
                    {
                        if (j->isEpsilon())
                        {
                            if (info.states.insert(j->pTo).second) tmp.insert(j->pTo);
                        }
                        else if (j->isChar()) info.chars.insert(pair<Char_Type, bool>(j->data.char_value, j->isNot()));
                        else if (j->isString()) info.strings.insert(pair<String_Type, bool>(j->data.string_value, j->isNot()));
                    }
                    tmp.erase(pState);
                }
            }
        }

 

 

其中用到的EpsilonClosureInfol构?/p>

 

        struct EpsilonClosureInfo
        {
            set<EpsilonNFA_State*>        states;
            set<pair<Char_Type, bool> >   chars;
            set<pair<String_Type, bool> > strings;

            EpsilonClosureInfo() {}

            EpsilonClosureInfo(const set<EpsilonNFA_State*>& states,
                               const set<pair<Char_Type, bool> >& chars,
                               const set<pair<String_Type, bool> >& strings)
                               : states(states)
                               , chars(chars)
                               , strings(strings) {}

            EpsilonClosureInfo(const EpsilonClosureInfo& x)
            {
                states  = x.states;
                chars   = x.chars;
                strings = x.strings;
            }
        };

 

需要保存的是状态集和向后字W集?/p>

状态{Ud?/h2>

通过状态{Ud敎ͼ输入一个集合T和一个字Wa可得到所有通过T中的每一个状态和aҎ(gu)能达到的状态的集合。应此代码如?/p>

 

        set<EpsilonNFA_State*> move(const DFA_State& t, const Char_Type& c, bool bNot)
        {
            set<EpsilonNFA_State*> result;
            for (typename set<EpsilonNFA_State*>::const_iterator i = t.content.begin(), m = t.content.end(); i != m; ++i)
            {
                for (typename vector<EpsilonNFA_Edge>::const_iterator j = epsilonNFA_Edges[*i].begin(), n = epsilonNFA_Edges[*i].end(); j != n; ++j)
                {
                    if (j->isChar() && j->data.char_value == c && j->isNot() == bNot) result.insert(j->pTo);
                }
            }
            return result;
        }

        set<EpsilonNFA_State*> move(const DFA_State& t, const String_Type& s, bool bNot)
        {
            set<EpsilonNFA_State*> result;
            for (typename set<EpsilonNFA_State*>::const_iterator i = t.content.begin(), m = t.content.end(); i != m; ++i)
            {
                for (typename vector<EpsilonNFA_Edge>::const_iterator j = epsilonNFA_Edges[*i].begin(), n = epsilonNFA_Edges[*i].end(); j != n; ++j)
                {
                    if (j->isString() && j->data.string_value == s && j->isNot() == bNot) result.insert(j->pTo);
                }
            }
            return result;
        }

 

 

Z(jin)分别支持Char_Type和String_Type的字W我们定义了(jin)两个move函数?/p>

最后我们给出子集构造算法的代码

 

        void buildDFA()
        {
            set<EpsilonNFA_State*> start;
            start.insert(pEpsilonStart);

            typedef pair<DFA_State*, EpsilonClosureInfo> c_type;

            map<size_t, list<c_type> > c;
            queue<c_type> c2;

            pDFAStart = DFA_State_Alloc::allocate();
            EpsilonClosureInfo info;
            epsilonClosure(start, info);
            construct(pDFAStart, info.states);

            c_type ct(pDFAStart, info);
            c[info.states.size()].push_back(ct);
            c2.push(ct);

            if (isEndDFAStatus(pDFAStart)) pDFAEnds.insert(pDFAStart);
            context.dfa_States.insert(pDFAStart);

            while (!c2.empty())
            {
                DFA_State* t = c2.front().first;
                set<pair<Char_Type, bool> > chars = c2.front().second.chars;
                set<pair<String_Type, bool> > strings = c2.front().second.strings;
                t->bFlag = true;

                for (typename set<pair<Char_Type, bool> >::const_iterator i = chars.begin(), m = chars.end(); i != m; ++i)
                {
                    EpsilonClosureInfo info;
                    epsilonClosure(move(*t, i->first, i->second), info);

                    DFA_State* p = getDFAState(info.states, c);
                    if (p) // 如果q个状态已存在
                    {
                        dfa_Edges.insert(DFA_Edge(i->first, i->second, t, p));
                    }
                    else
                    {
                        DFA_State* pState = DFA_State_Alloc::allocate();
                        construct(pState, info.states);
                        context.dfa_States.insert(pState);

                        if (isEndDFAStatus(pState)) pDFAEnds.insert(pState);

                        c_type ct(pState, info);
                        c[info.states.size()].push_back(ct);
                        c2.push(ct);

                        dfa_Edges.insert(DFA_Edge(i->first, i->second, t, pState));
                    }
                }

                for (typename set<pair<String_Type, bool> >::const_iterator i = strings.begin(), m = strings.end(); i != m; ++i)
                {
                    EpsilonClosureInfo info;
                    epsilonClosure(move(*t, i->first, i->second), info);

                    DFA_State* p = getDFAState(info.states, c);
                    if (p) // 如果q个状态已存在
                    {
                        dfa_Edges.insert(DFA_Edge(i->first, i->second, t, p));
                    }
                    else
                    {
                        DFA_State* pState = DFA_State_Alloc::allocate();
                        construct(pState, info.states);
                        context.dfa_States.insert(pState);

                        if (isEndDFAStatus(pState)) pDFAEnds.insert(pState);

                        c_type ct(pState, info);
                        c[info.states.size()].push_back(ct);
                        c2.push(ct);

                        dfa_Edges.insert(DFA_Edge(i->first, i->second, t, pState));
                    }
                }
                c2.pop();
            }
        }

 

 

֣

同样我们来编写一个函数来打印出DFA?/p>

 

        void printDFA()
        {
            printf("---------- DFA Start ----------\n");
            set<DFA_State*> tmp;
            for (typename set<DFA_Edge>::const_iterator i = dfa_Edges.begin(), m = dfa_Edges.end(); i != m; ++i)
            {
                printf("%03d -> %03d", i->pFrom->idx, i->pTo->idx);
                switch (i->edgeType())
                {
                case DFA_Edge::TChar:
                    printf("(%c)", i->data.char_value);
                    break;
                case DFA_Edge::TString:
                    printf("(%s)", i->data.string_value.c_str());
                    break;
                default:
                    break;
                }
                if (i->isNot()) printf("(not)");
                printf("\n");
                tmp.insert(i->pFrom);
                tmp.insert(i->pTo);
            }

            printf("start: %03d -> ends: ", pDFAStart->idx);
            for (typename set<DFA_State*>::const_iterator i = pDFAEnds.begin(), m = pDFAEnds.end(); i != m; ++i)
            {
                printf("%03d ", (*i)->idx);
            }
            printf("\n");
#if DEBUG_LEVEL == 3
            printf("-------------------------------\n");

            for (typename set<DFA_State*>::const_iterator i = tmp.begin(), m = tmp.end(); i != m; ++i)
            {
                printf("State: %03d\n", (*i)->idx);
                for (typename set<EpsilonNFA_State*>::const_iterator j = (*i)->content.begin(), n = (*i)->content.end(); j != n; ++j)
                {
                    printf("%03d ", (*j)->idx);
                }
                printf("\n");
            }
#endif
            printf("----------- DFA End -----------\n");
        }

 

 

最后我们加入测试代?/p>

 

Rule_Type::Context context;
Rule_Type a('a', context), b('b', context), d('d', context);
Rule_Type result = (a - d).opt() + (+b | !(a + b));
result.buildDFA();

#ifdef _DEBUG
result.printEpsilonNFA();
result.printDFA();
#endif

 

 

可打印出如下内容

DFA

L囑֦?/p>

DFA? src=

完整的代码可?a target="_blank">http://code.google.com/p/qlanguage下蝲



lwch 2013-02-23 23:30 发表评论
]]>
词法分析?(正则表达式到&epsilon;-NFA的{?http://www.shnenglu.com/lwch/archive/2013/02/15/197848.htmllwchlwchFri, 15 Feb 2013 12:29:00 GMThttp://www.shnenglu.com/lwch/archive/2013/02/15/197848.htmlhttp://www.shnenglu.com/lwch/comments/197848.htmlhttp://www.shnenglu.com/lwch/archive/2013/02/15/197848.html#Feedback3http://www.shnenglu.com/lwch/comments/commentRss/197848.htmlhttp://www.shnenglu.com/lwch/services/trackbacks/197848.html自动?/h1>

关于自动机的说明Q这里不不再复述Q请?a href="http://zh.wikipedia.org/wiki/自动? target="_blank">http://zh.wikipedia.org/wiki/自动?/a>查看?/p>

表达?/h1>

首先Q我们规定表辑ּ中只允许输入Char_Type和String_Typecd的字W?/p>

template <typename Char_Type, typename String_Type>
class Rule
{
};

 

ε-NFA的状?/h1>

对于一个状态来_(d)我们q不需要知道他的Q何信?/p>

在上面的代码中,Z(jin)调试方便Q我为其加入?jin)idx域,qؓ(f)每个状态分配了(jin)一个唯一的ID?/p>

 struct EpsilonNFA_State
{
#ifdef _DEBUG
uint idx;
EpsilonNFA_State()
{
idx = inc();
}
static uint inc()
{
static uint i = 0;
return i++;
}
#else
EpsilonNFA_State() {}
#endif
};

ε-NFA的边

ε-NFA中的辚w是有向的。对于Q意一条边来说Q最重要的是他的两个端点是谁以及(qing)q条Ҏ(gu)对应的字W集Q若q条边不?#949;边)(j)?/p>

 struct EpsilonNFA_Edge
{
struct
{
Char_Type char_value;
String_Type string_value;
}data;
enum Edge_Type
{
TUnknown = 0,
TNot = 1,
TChar = 2,
TString = 4,
TEpsilon = 8
};
uchar edge_type;
EpsilonNFA_State* pFrom;
EpsilonNFA_State* pTo;
EpsilonNFA_Edge(EpsilonNFA_State* pFrom, EpsilonNFA_State* pTo) : edge_type(TEpsilon), pFrom(pFrom), pTo(pTo) {}
EpsilonNFA_Edge(const Char_Type& x, EpsilonNFA_State* pFrom, EpsilonNFA_State* pTo) : edge_type(TChar), pFrom(pFrom), pTo(pTo)
{
data.char_value = x;
}
EpsilonNFA_Edge(const String_Type& x, EpsilonNFA_State* pFrom, EpsilonNFA_State* pTo) : edge_type(TString), pFrom(pFrom), pTo(pTo)
{
data.string_value = x;
}
inline void negate()
{
edge_type ^= TNot;
}
inline const bool isNot()const
{
return (edge_type & TNot) == TNot;
}
inline const bool isEpsilon()const
{
return (edge_type & TEpsilon) == TEpsilon;
}
inline const bool isChar()const
{
return (edge_type & TChar) == TChar;
}
inline const bool isString()const
{
return (edge_type & TString) == TString;
}
const Edge_Type edgeType()const
{
if (isEpsilon()) return TEpsilon;
else if (isChar()) return TChar;
else if (isString()) return TString;
else return TUnknown;
}
};

有了(jin)以上两个l构之后Q我们ؓ(f)Ruled三个成员变量

EpsilonNFA_State *pEpsilonStart, *pEpsilonEnd;
hashmap<EpsilonNFA_State*, vector<EpsilonNFA_Edge>, _hash> epsilonNFA_Edges;

 

pEpsilonStart和pEpsilonEnd分别表示q条表达式所对应状态机的start和end状态,epsilonNFA_Edges则是以某个状态作为keyQ从q个状态到辑֏一个状态所l过的边作ؓ(f)value的hash表?/p>

生成状态机

l于C(jin)正题Q首先,我们把所有的关系分ؓ(f)串联关系、ƈ联关pR可选关pR?ơ及(qing)以上的重复关pR至?ơ以上的重复关系和取反关pR下面分别介l每U关pȝε-NFA如何来生成。(下文中若没有指出q接边的cd则是ε?/strong>Q?/p>

字符?/h2>

正如上文所_(d)字符集包括Char_Type和String_Typecd的字W,应此生成字符集的状态机比较简单了(jin)Q只需创徏Z个状态,然后通过一条经q这个字W集的边这两个状态按照某个方向连接,最后将一个状态标Cؓ(f)start状态,另一个状态标Cؓ(f)end状态即可?/p>

 Rule(const Char_Type& x, Context& context) : pDFAStart(NULL), context(context)
{
pEpsilonStart = EpsilonNFA_State_Alloc::allocate();
construct(pEpsilonStart);
pEpsilonEnd = EpsilonNFA_State_Alloc::allocate();
construct(pEpsilonEnd);
epsilonNFA_Edges[pEpsilonStart].push_back(EpsilonNFA_Edge(x, pEpsilonStart, pEpsilonEnd));
context.epsilonNFA_States.insert(pEpsilonStart);
context.epsilonNFA_States.insert(pEpsilonEnd);
}
Rule(const String_Type& x, Context& context) : pDFAStart(NULL), context(context)
{
pEpsilonStart = EpsilonNFA_State_Alloc::allocate();
construct(pEpsilonStart);
pEpsilonEnd = EpsilonNFA_State_Alloc::allocate();
construct(pEpsilonEnd);
epsilonNFA_Edges[pEpsilonStart].push_back(EpsilonNFA_Edge(x, pEpsilonStart, pEpsilonEnd));
context.epsilonNFA_States.insert(pEpsilonStart);
context.epsilonNFA_States.insert(pEpsilonEnd);
}

串联关系

串联关系中,只需要将前一个状态机的end状态通过ε边连接到另一个状态机的start状态,最后将前一个状态的start状态标Cؓ(f)新状态机的start状态,后一个状态机的end状态标Cؓ(f)新状态机的end状态即可?/p>

 self operator+(const self& x)
{
self a = cloneEpsilonNFA(*this), b = cloneEpsilonNFA(x);
copyEpsilonNFA_Edges(b, a);
a.epsilonNFA_Edges[a.pEpsilonEnd].push_back(EpsilonNFA_Edge(a.pEpsilonEnd, b.pEpsilonStart));
a.pEpsilonEnd = b.pEpsilonEnd;
return a;
}

 

q联关系

q联关系中,需要分别新Z个start和end状态做为新状态机的start和end状态,然后新生成的start状态分别连接到原状态机的start状态,原状态机的end状态连接到新生成的end状态即可?/p>

 self operator|(const self& x)
{
self a = cloneEpsilonNFA(*this), b = cloneEpsilonNFA(x);
copyEpsilonNFA_Edges(b, a);
EpsilonNFA_State* _pStart = EpsilonNFA_State_Alloc::allocate();
construct(_pStart);
EpsilonNFA_State* _pEnd = EpsilonNFA_State_Alloc::allocate();
construct(_pEnd);
context.epsilonNFA_States.insert(_pStart);
context.epsilonNFA_States.insert(_pEnd);
a.epsilonNFA_Edges[_pStart].push_back(EpsilonNFA_Edge(_pStart, a.pEpsilonStart));
a.epsilonNFA_Edges[_pStart].push_back(EpsilonNFA_Edge(_pStart, b.pEpsilonStart));
a.epsilonNFA_Edges[a.pEpsilonEnd].push_back(EpsilonNFA_Edge(a.pEpsilonEnd, _pEnd));
a.epsilonNFA_Edges[b.pEpsilonEnd].push_back(EpsilonNFA_Edge(b.pEpsilonEnd, _pEnd));
a.pEpsilonStart = _pStart;
a.pEpsilonEnd = _pEnd;
return a;
}

重复关系

在正则表辑ּ中存在Ş?a)+?a)*的两U重复关p,对于q两U重复关p,生成的状态机的区别仅在于end状态对于一ơ以上的重复Q只需要给原状态机d一条从end状态到start状态的ε边即可。而对于零ơ以上的重复Q不光需要添?#949;边,同时需要将新状态机的end状态标Cؓ(f)start状态,因ؓ(f)零次重复时不需要经qQ意边既可被接受?/p>

 self operator*()
{
self a = cloneEpsilonNFA(*this);
a.epsilonNFA_Edges.insert(EpsilonNFA_Edge(a.pEpsilonEnd, a.pEpsilonStart));
a.pEpsilonEnd = a.pEpsilonStart;
return a;
}
self operator+()
{
self a = cloneEpsilonNFA(*this);
a.epsilonNFA_Edges[a.pEpsilonEnd].push_back(EpsilonNFA_Edge(a.pEpsilonEnd, a.pEpsilonStart));
return a;
}

上面q三U是最基本的生成方法,通过以上q三U生成方法已_应付多数的表辑ּ?/p>

一些拓?/h1>

下面来看看一些拓展Ş式的状态机是如何生成的?/p>

可选关p?/h2>

在可选关pMQ只需要给原状态机d一条从start状态到end状态的ε边即可。由?#949;-NFA只允许有一个start和end状态的关系Q应此当条g不成立时从start状态就可直接通过ε边到达end状态?/p>

 inline self opt()
{
self a = cloneEpsilonNFA(*this);
a.epsilonNFA_Edges[a.pEpsilonStart].push_back(EpsilonNFA_Edge(a.pEpsilonStart, a.pEpsilonEnd));
return a;
}

 

取反关系

׃我们只处理Char_Type和String_Typecd的字W集Q应此对于取反我们只需要将当前状态机内所有类型ؓ(f)TChar或TStringcd的边取一下反卛_Q?strong>需要注意的是可能存在负负得正的情况Q既取偶数次反等于没取反Q?/p>

 

 self operator!()
{
self a = cloneEpsilonNFA(*this);
for (typename hashmap<EpsilonNFA_State*, vector<EpsilonNFA_Edge>, _hash>::iterator i = a.epsilonNFA_Edges.begin(), m = a.epsilonNFA_Edges.end(); i != m; ++i)
{
for (typename vector<EpsilonNFA_Edge>::iterator j = i->second.begin(), n = i->second.end(); j != n; ++j)
{
if (j->isChar() || j->isString()) j->negate();
}
}
return a;
}

 

 

Char-Char关系

所谓的char-char关系是正则表达式中的[a-z]表达式。其实这是一Uƈ联关pȝ拓展Q由两个原始状态机拓展C(jin)N个,生成Ҏ(gu)也类伹{?/p>

 self operator-(const self& x)
{
self a = cloneEpsilonNFA(*this);
if (epsilonNFA_Edges.size() == 1 && x.epsilonNFA_Edges.size() == 1 &&
epsilonNFA_Edges.begin()->second.size() == 1 && x.epsilonNFA_Edges.begin()->second.size() == 1 &&
epsilonNFA_Edges.begin()->second.begin()->edge_type == EpsilonNFA_Edge::TChar && x.epsilonNFA_Edges.begin()->second.begin()->edge_type == EpsilonNFA_Edge::TChar)
{
EpsilonNFA_State* _pStart = EpsilonNFA_State_Alloc::allocate();
construct(_pStart);
EpsilonNFA_State* _pEnd = EpsilonNFA_State_Alloc::allocate();
construct(_pEnd);
context.epsilonNFA_States.insert(_pStart);
context.epsilonNFA_States.insert(_pEnd);
a.epsilonNFA_Edges[_pStart].push_back(EpsilonNFA_Edge(_pStart, a.pEpsilonStart));
a.epsilonNFA_Edges[a.pEpsilonEnd].push_back(EpsilonNFA_Edge(a.pEpsilonEnd, _pEnd));
const Char_Type chStart = epsilonNFA_Edges.begin()->second.begin()->data.char_value;
const Char_Type chEnd = x.epsilonNFA_Edges.begin()->second.begin()->data.char_value;
for (Char_Type ch = chStart + 1; ch < chEnd; ++ch)
{
self y(ch, context);
copyEpsilonNFA_Edges(y, a);
a.epsilonNFA_Edges[_pStart].push_back(EpsilonNFA_Edge(_pStart, y.pEpsilonStart));
a.epsilonNFA_Edges[y.pEpsilonEnd].push_back(EpsilonNFA_Edge(y.pEpsilonEnd, _pEnd));
}
self b = cloneEpsilonNFA(x);
copyEpsilonNFA_Edges(b, a);
a.epsilonNFA_Edges[_pStart].push_back(EpsilonNFA_Edge(_pStart, b.pEpsilonStart));
a.epsilonNFA_Edges[b.pEpsilonEnd].push_back(EpsilonNFA_Edge(b.pEpsilonEnd, _pEnd));
a.pEpsilonStart = _pStart;
a.pEpsilonEnd = _pEnd;
}
else
{
throw error<string>("doesn't support", __FILE__, __LINE__);
}
return a;
}

֣

让我们来~写一个函数来打印出整个生成后的状态机?/p>

 void printEpsilonNFA()
{
printf("-------- ε- NFA Start --------\n");
for (typename hashmap<EpsilonNFA_State*, vector<EpsilonNFA_Edge>, _hash>::const_iterator i = epsilonNFA_Edges.begin(), m = epsilonNFA_Edges.end(); i != m; ++i)
{
for (typename vector<EpsilonNFA_Edge>::const_iterator j = i->second.begin(), n = i->second.end(); j != n; ++j)
{
printf("%03d -> %03d", j->pFrom->idx, j->pTo->idx);
switch (j->edgeType())
{
case EpsilonNFA_Edge::TEpsilon:
printf("(ε)");
break;
case EpsilonNFA_Edge::TChar:
printf("(%c)", j->data.char_value);
break;
case EpsilonNFA_Edge::TString:
printf("(%s)", j->data.string_value.c_str());
break;
default:
break;
}
if (j->isNot()) printf("(not)");
printf("\n");
}
}
printf("start: %03d -> end: %03d\n", pEpsilonStart->idx, pEpsilonEnd->idx);
printf("--------- ε- NFA End ---------\n");
}

 

最后我们来~写一些测试代码来试试生成效果如何

Rule_Type::Context context;
Rule_Type a('a', context), b('b', context), d('d', context);
Rule_Type result = (a - d).opt() + (+b | !(a + b));
#ifdef _DEBUG
result.printEpsilonNFA();
#endif

可打印出如下内容

状态机

最后Ş成Ş如下囄状态机

状态机? src=

完整的代码可?a target="_blank">http://code.google.com/p/qlanguage下蝲?/p>

lwch 2013-02-15 20:29 发表评论
]]>
修复?jin)一个关于CParser_Input的Bughttp://www.shnenglu.com/lwch/archive/2011/07/10/150615.htmllwchlwchSun, 10 Jul 2011 14:13:00 GMThttp://www.shnenglu.com/lwch/archive/2011/07/10/150615.htmlhttp://www.shnenglu.com/lwch/comments/150615.htmlhttp://www.shnenglu.com/lwch/archive/2011/07/10/150615.html#Feedback0http://www.shnenglu.com/lwch/comments/commentRss/150615.htmlhttp://www.shnenglu.com/lwch/services/trackbacks/150615.html我们先了(jin)看下Altl合子的分析代码
 1     virtual O Parser(I& input)
 2     {
 3         I temp = input;
 4         if(O Result = left.Parser(input)) return Result;
 5         input = temp;
 6         if(O Result = right.Parser(input)) return Result;
 7         input = temp;
 8         O Result(GetMM());
 9         return Result;
10     }
当left分析p|时会(x)原先的input值重新赋值给input,但此时ƈ没有改变SymbolStack和StringStack,应此当第一ơ分析失败时SymbolStack和StringStack中会(x)包含一些重复的?当然其他l合子同样存在这个问?
应此我ؓ(f)CParser_Input增加?jin)两个成员变量保存此时的SymbolStack和StringStack的Size,当SymbolStack和StringStack Push的时候同时增加input相应的?
最后重载CParser_Input的operator=赋值操作符,在其中根据原先的SymbolStack和StringStack的Size来弹出相应数量的重复?br />
 1     CParser_Input& operator=(CParser_Input& _value)
 2     {
 3         LexerTokenList = _value.LexerTokenList;
 4         index = _value.index;
 5 
 6         if(_value.symbolCount < symbolCount && _value.symbolCount)
 7         {
 8             int Count = symbolCount - _value.symbolCount;
 9             for(int i=0;i<Count;i++) SymbolStack.Pop();
10         }
11 
12         if(_value.stringCount < stringCount && _value.stringCount)
13         {
14             int Count = stringCount - _value.stringCount;
15             for(int i=0;i<Count;i++) StringStack.Pop();
16         }
17 
18         symbolCount = SymbolStack.Size();
19         stringCount = StringStack.Size();
20         return *this;
21     }
以此来解决SymbolStack和StringStack的同步问?

lwch 2011-07-10 22:13 发表评论
]]>
QLanguage的ASThttp://www.shnenglu.com/lwch/archive/2011/07/01/149941.htmllwchlwchFri, 01 Jul 2011 13:51:00 GMThttp://www.shnenglu.com/lwch/archive/2011/07/01/149941.htmlhttp://www.shnenglu.com/lwch/comments/149941.htmlhttp://www.shnenglu.com/lwch/archive/2011/07/01/149941.html#Feedback2http://www.shnenglu.com/lwch/comments/commentRss/149941.htmlhttp://www.shnenglu.com/lwch/services/trackbacks/149941.htmlhttp://qlanguage.codeplex.com

1.AST的每个节点由2个域l成,q?个域分别表示当前节点的类型和附加信息?br />2.AST的每个节点包含一个指向其子节点的序表?br />3.AST的每个节点包含指向下一个节点的指针?br />lg所q我们得到AST节点的代码:(x)
 1     class CSyntaxTreeNode
 2     {
 3     public:
 4         CSyntaxTreeNode(int _type,int _value) : type(_type),value(_value){}
 5 
 6         inline List<NAutoPtr<CSyntaxTreeNode>>& Child()
 7         {
 8             return child;
 9         }
10 
11         inline NAutoPtr<CSyntaxTreeNode> Next()
12         {
13             return next;
14         }
15 
16         inline int& Type()
17         {
18             return type;
19         }
20 
21         inline int& Value()
22         {
23             return value;
24         }
25     protected:
26         int type;
27         int value;
28         List<NAutoPtr<CSyntaxTreeNode>> child;
29         NAutoPtr<CSyntaxTreeNode> next;
30     };
然后我们l出?jin)部分枚举来标识节点的类型?x)
 1         // for type
 2         enum TYPE
 3         {
 4             stNull,
 5             stDeclare,
 6             stFunction,
 7             stParamterList,
 8             stIf,
 9             stDo,
10             stExp,
11         };
最后是一A(ch)ST的整体结构:(x)
 1 class CParserAnalyze
 2 {
 3 public:
 4     inline void Push(NAutoPtr<CSyntaxTreeNode>& Node)
 5     {
 6         SyntaxTreeStack.Push(Node);
 7     }
 8 
 9     inline NAutoPtr<CSyntaxTreeNode> Pop()
10     {
11         return SyntaxTreeStack.Pop();
12     }
13 
14     inline NAutoPtr<CSyntaxTreeNode> Top()
15     {
16         return SyntaxTreeStack.Top();
17     }
18 
19     inline NAutoPtr<CSyntaxTreeNode> Root()
20     {
21         return SyntaxTreeRoot;
22     }
23 protected:
24     NAutoPtr<CSyntaxTreeNode> SyntaxTreeRoot;            // 语法?wi)根节?/span>
25     Stack<NAutoPtr<CSyntaxTreeNode>> SyntaxTreeStack;    // 语法?wi)?/span>
26 };

q里我们单的分析一下分析过E:(x)
以if语句ZQ其l合子代码ؓ(f)Q?br />
1     if_desc = (str_if + exp_desc)[if_desc_first] +
2             (str_then + stmt_list)[if_desc_second] +
3             Parser_Combinator_Node::opt((str_else + stmt_list)[if_desc_third]) +
4             (str_end + str_if)[if_desc_fourth];
我们输入代码Q?br />
1     if a then
2         declare b as integer
3     end if
在做语法分析Q?br />1.dif aQa被归Uؓ(f)一条exp生成一个类型ؓ(f)exp的节点ƈ压入AST的语法树(wi)栈?br />2.if a被归U生成一个类型ؓ(f)stIf的节点ƈ弹出栈顶的exp节点填充到新生成的stIf节点的第一个子节点?br />3.dthen declare b as integerQinteger被归U生成一个生cd为stDeclare的节点ƈ压入语法?wi)栈?br />4.declare b as integer被归Uؓ(f)栈顶的stDeclare节点填充一个b标识W的子节炏V?br />5.then declare b as integer被归U,首先弹出栈顶的stmt_list因ؓ(f)q里是stDeclare说明stmt_list有内容应此将栈顶的stIf的值域的最低位|ؓ(f)1?br />6.else子句不存在?br />7.整体被归U?br />此时栈顶为stIf节点Q其不包含next节点Q有两个子节点分别ؓ(f)stExp和stDeclare?br />
分析q程如下图:(x)
1.
2.
3.
4.
5.
6.
7.

lwch 2011-07-01 21:51 发表评论
]]>
QLanguage基本语法http://www.shnenglu.com/lwch/archive/2011/06/27/149572.htmllwchlwchMon, 27 Jun 2011 08:36:00 GMThttp://www.shnenglu.com/lwch/archive/2011/06/27/149572.htmlhttp://www.shnenglu.com/lwch/comments/149572.htmlhttp://www.shnenglu.com/lwch/archive/2011/06/27/149572.html#Feedback0http://www.shnenglu.com/lwch/comments/commentRss/149572.htmlhttp://www.shnenglu.com/lwch/services/trackbacks/149572.html1.cȝ定义
1 class a [inherit Object]
2 end class

2.cM可以包含(声明Q函敎ͼ新类。其中除?jin)class都含有public、private、protected和static属?
1 class a
2     [public] declare a as string // 声明
3 
4     [private] [static] function main() // 函数
5     end function
6 
7     class b // 新类
8     end class
9 end class
3.变量声明
1 declare a as integer[,b as integer]
4.函数
1 function main([a as integer[,b as integer]])[as integer]
2 end function
5.stmt_list包含声明语句、if语句、do语句、while语句、for语句、switch语句和experience表达?br />6.if语句
1 if experience then
2 stmt_list
3 [else stmt_list]
4 end if
7.do语句
1 do
2 stmt_list
3 while experience end
8.while语句
1 while experience do
2 stmt_list
3 end while
9.for语句
1 for stmt_list to experience by stmt_list do
2 stmt_list
3 next
10.switch语句
1 switch experience do
2 case experience:
3 [stmt_list]
4 [case experience:
5 [stmt_list]]
6 [default:
7 [stmt_list]]
8 end switch
11.experience表达?br />
 1 函数调用语句
 2 赋D?br /> 3 symbol
 4 string
 5 number
 6 true
 7 false
 8 (+|-)experience
 9 not experience
10 experience (&|||^|%) experience
11 experience (>|<|>=|<=|==|!=) experience
12 experience (+|-|*|/) experience
13 ++symbol
14 --symbol
15 symbol++
16 symbol--
12.函数调用语句
1 函数?参数?
13.赋D?br />
1 变量=experience

l合子代?br />
 1     program = *item;
 2     item = declare_desc |
 3             class_desc |
 4             function_desc;
 5     property_desc = str_public |
 6                     str_private |
 7                     str_protected;
 8     declare_type = str_integer |
 9                     str_string |
10                     str_bool |
11                     str_real |
12                     type_symbol;
13     paramter_desc_list = (type_symbol + str_as + declare_type) +
14                         *(str_comma + type_symbol + str_as + declare_type);
15     paramter_value_list = exp_desc + *(str_comma + exp_desc);
16     declare_desc = str_declare + type_symbol + str_as + declare_type +
17         *(str_comma + type_symbol + str_as + declare_type);
18     class_desc = str_class + type_symbol +
19                 Parser_Combinator_Node::opt(str_inherit + type_symbol +
20                 *(str_comma + (type_symbol & Parser_Combinator_Node::not(str_class | str_function | property_desc | str_static)))
21                 ) + *class_content_desc + str_end + str_class;
22     class_content_desc = (Parser_Combinator_Node::opt(property_desc) + Parser_Combinator_Node::opt(str_static) +
23                         (declare_desc | function_desc)) |
24                         class_desc;
25     function_desc = (str_function + type_symbol) +
26                     (str_leftbracket + Parser_Combinator_Node::opt(paramter_desc_list) + str_rightbracket) +
27                     Parser_Combinator_Node::opt(str_as + declare_type) +
28                     stmt_list +
29                     (str_end + str_function);
30     stmt_list = *(stmt & Parser_Combinator_Node::not(str_end));
31     stmt = declare_desc |
32             if_desc |
33             do_desc |
34             while_desc |
35             for_desc |
36             switch_desc |
37             exp_desc;
38     if_desc = (str_if + exp_desc) +
39             (str_then + stmt_list) +
40             Parser_Combinator_Node::opt(str_else + stmt_list) +
41             (str_end + str_if);
42     do_desc = (str_do + stmt_list) +
43                 (str_while + exp_desc + str_end);
44     while_desc = str_while + exp_desc + str_do + stmt_list + str_end + str_while;
45     for_desc = str_for + stmt_list + str_to + exp_desc + str_by + stmt_list + str_do + stmt_list + str_next;
46     switch_desc = str_switch + exp_desc + str_do + case_list + str_end + str_switch;
47     case_list = *case_desc;
48     case_desc = (str_case + exp_desc + str_colon + stmt_list) |
49                 (str_default + str_colon + stmt_list);
50     assign_desc = type_symbol + str_equal + exp_desc;
51     call_desc = type_symbol + str_leftbracket + Parser_Combinator_Node::opt(paramter_value_list) + str_rightbracket;
52     logic_desc = (str_not + compare_desc) |
53                 (compare_desc + *((str_operator_and | str_operator_or | str_xor | str_mod) + compare_desc));
54     compare_desc = term_desc + *((str_bigger | str_smaller |
55                                 str_bigger_equal | str_smaller_equal |
56                                 str_equal_equal | str_not_equal) + term_desc);
57     term_desc = factor_desc + *((str_add | str_sub) + factor_desc);
58     factor_desc = self_desc + *((str_mul | str_div) + self_desc);
59     self_desc = (str_add_add + type_symbol) |
60                 (str_sub_sub + type_symbol) |
61                 (type_symbol + str_add_add) |
62                 (type_symbol + str_sub_sub) |
63                 value_desc;
64     value_desc = call_desc |
65                 assign_desc |
66                 type_symbol |
67                 type_string |
68                 type_number |
69                 str_true |
70                 str_false |
71                 ((str_add | str_sub) + logic_desc) |
72                 (str_leftbracket + logic_desc + str_rightbracket);
73     exp_desc = logic_desc;

如有M补充会(x)在此文档更新?br />

lwch 2011-06-27 16:36 发表评论
]]>
ESEngine_Demo5http://www.shnenglu.com/lwch/archive/2011/03/02/140979.htmllwchlwchWed, 02 Mar 2011 05:20:00 GMThttp://www.shnenglu.com/lwch/archive/2011/03/02/140979.htmlhttp://www.shnenglu.com/lwch/comments/140979.htmlhttp://www.shnenglu.com/lwch/archive/2011/03/02/140979.html#Feedback3http://www.shnenglu.com/lwch/comments/commentRss/140979.htmlhttp://www.shnenglu.com/lwch/services/trackbacks/140979.html修正?jin)词法分析器的一些Bug.
修正?jin)一些运行时的Bug.
支持?jin)单行注?/和多行注?* */
支持?jin)所有的函数声明形式.

ESEngine_Demo5.rar



lwch 2011-03-02 13:20 发表评论
]]>
ESEngine_Demo4http://www.shnenglu.com/lwch/archive/2011/02/13/139989.htmllwchlwchSun, 13 Feb 2011 11:20:00 GMThttp://www.shnenglu.com/lwch/archive/2011/02/13/139989.htmlhttp://www.shnenglu.com/lwch/comments/139989.htmlhttp://www.shnenglu.com/lwch/archive/2011/02/13/139989.html#Feedback1http://www.shnenglu.com/lwch/comments/commentRss/139989.htmlhttp://www.shnenglu.com/lwch/services/trackbacks/139989.html
ESEngine_Demo4.rar

lwch 2011-02-13 19:20 发表评论
]]>
QLanguagehttp://www.shnenglu.com/lwch/archive/2011/02/13/139956.htmllwchlwchSat, 12 Feb 2011 16:09:00 GMThttp://www.shnenglu.com/lwch/archive/2011/02/13/139956.htmlhttp://www.shnenglu.com/lwch/comments/139956.htmlhttp://www.shnenglu.com/lwch/archive/2011/02/13/139956.html#Feedback2http://www.shnenglu.com/lwch/comments/commentRss/139956.htmlhttp://www.shnenglu.com/lwch/services/trackbacks/139956.html可能q有大量的Bug,请反馈给QQ:510134884.
QLanguage的发展需要?zhn)的支?img border="0" align="absMiddle" src="http://www.shnenglu.com/CuteSoft_Client/CuteEditor/images/emsmile.gif" alt="" />

开源项目地址:http://qlanguage.codeplex.com/

Demo5:
修正?jin)词法分析器的一些Bug.
修正?jin)一些运行时的Bug.
支持?jin)单行注?/和多行注?* */
支持?jin)所有的函数声明形式.
http://www.shnenglu.com/lwch/archive/2011/03/02/140979.html

Demo4:
d?jin)DLL的支?见Samples下的TestDLL.dll)
http://www.shnenglu.com/lwch/archive/2011/02/13/139989.html

Demo3:
修正?jin)return语句的一些Bug
d?jin)COMlg的支?见Samples目录下的factorial.txt)
http://www.shnenglu.com/lwch/archive/2011/02/07/139787.html

Demo2:
1.修正?jin)函数调用时的一些Bug
2.CZ中增加了(jin)一个递归求阶乘的例子
http://www.shnenglu.com/lwch/archive/2011/01/30/139624.html

Demo1:
q行Ҏ(gu):
1.打开命o(h)行提C符
2.cd ESEngine.exe所在\?br /> 3.ESEngine xxx.txt 1.Samples文g夹下有几个例?br /> 2.函数目前只写?br />   "function" "{Symbol}" "{LQ}" "{RQ}" stmt_list "end" "function"
  "function" "{Symbol}" "{LQ}" "{RQ}" "end" "function"
  "function" "{Symbol}" "{LQ}" paramter_list "{RQ}" "as" var_type stmt_list "end" "function"
  q三c?所以对?br />   function mn(integer s)
 stmts
  end function
  在生成语法树(wi)时会(x)产生错误
http://www.shnenglu.com/lwch/archive/2011/01/28/139546.html


lwch 2011-02-13 00:09 发表评论
]]>
ESEngine_Demo3http://www.shnenglu.com/lwch/archive/2011/02/07/139787.htmllwchlwchMon, 07 Feb 2011 09:27:00 GMThttp://www.shnenglu.com/lwch/archive/2011/02/07/139787.htmlhttp://www.shnenglu.com/lwch/comments/139787.htmlhttp://www.shnenglu.com/lwch/archive/2011/02/07/139787.html#Feedback0http://www.shnenglu.com/lwch/comments/commentRss/139787.htmlhttp://www.shnenglu.com/lwch/services/trackbacks/139787.htmld?jin)COMlg的支?见Samples目录下的factorial.txt)

ESEngine_Demo3.rar

lwch 2011-02-07 17:27 发表评论
]]>
ESEngine_Demo2http://www.shnenglu.com/lwch/archive/2011/01/30/139624.htmllwchlwchSun, 30 Jan 2011 13:19:00 GMThttp://www.shnenglu.com/lwch/archive/2011/01/30/139624.htmlhttp://www.shnenglu.com/lwch/comments/139624.htmlhttp://www.shnenglu.com/lwch/archive/2011/01/30/139624.html#Feedback0http://www.shnenglu.com/lwch/comments/commentRss/139624.htmlhttp://www.shnenglu.com/lwch/services/trackbacks/139624.html1.修正?jin)函数调用时的一些Bug
2.CZ中增加了(jin)一个递归求阶乘的例子

ESEngine_Demo2.rar

lwch 2011-01-30 21:19 发表评论
]]>
ESEngine_Demo1http://www.shnenglu.com/lwch/archive/2011/01/28/139546.htmllwchlwchFri, 28 Jan 2011 13:03:00 GMThttp://www.shnenglu.com/lwch/archive/2011/01/28/139546.htmlhttp://www.shnenglu.com/lwch/comments/139546.htmlhttp://www.shnenglu.com/lwch/archive/2011/01/28/139546.html#Feedback0http://www.shnenglu.com/lwch/comments/commentRss/139546.htmlhttp://www.shnenglu.com/lwch/services/trackbacks/139546.htmlq行Ҏ(gu):
1.打开命o(h)行提C符
2.cd ESEngine.exe所在\?br>3.ESEngine xxx.txt

1.Samples文g夹下有几个例?br>2.函数目前只写?br>  "function" "{Symbol}" "{LQ}" "{RQ}" stmt_list "end" "function"
  "function" "{Symbol}" "{LQ}" "{RQ}" "end" "function"
  "function" "{Symbol}" "{LQ}" paramter_list "{RQ}" "as" var_type stmt_list "end" "function"
  q三c?所以对?br>  function mn(integer s)
 stmts
  end function
  在生成语法树(wi)时会(x)产生错误

ESEngine_Demo1_0.rar



lwch 2011-01-28 21:03 发表评论
]]>
ESLanguage对于非常Bug的表辑ּ的翻?/title><link>http://www.shnenglu.com/lwch/archive/2011/01/27/139497.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Thu, 27 Jan 2011 13:39:00 GMT</pubDate><guid>http://www.shnenglu.com/lwch/archive/2011/01/27/139497.html</guid><wfw:comment>http://www.shnenglu.com/lwch/comments/139497.html</wfw:comment><comments>http://www.shnenglu.com/lwch/archive/2011/01/27/139497.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.shnenglu.com/lwch/comments/commentRss/139497.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/lwch/services/trackbacks/139497.html</trackback:ping><description><![CDATA[表达?<br> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">1</span> <span style="COLOR: #000000">function main()<br></span><span style="COLOR: #008080">2</span> <span style="COLOR: #000000">    integer a<br></span><span style="COLOR: #008080">3</span> <span style="COLOR: #000000">    a </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">a </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">123</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">a)<br></span><span style="COLOR: #008080">4</span> <span style="COLOR: #000000">end function</span></div> <br>译l果:<br><img height=431 alt="" src="http://www.shnenglu.com/images/cppblog_com/lwch/ESLanguage006.PNG" width=668 border=0><br><br>表达?<br> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">1</span> <span style="COLOR: #000000">function main()<br></span><span style="COLOR: #008080">2</span> <span style="COLOR: #000000">    integer a<br></span><span style="COLOR: #008080">3</span> <span style="COLOR: #000000">    a </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">a </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">4</span> <span style="COLOR: #000000">end function</span></div> <br>译l果:<br><img height=431 alt="" src="http://www.shnenglu.com/images/cppblog_com/lwch/ESLanguage007.PNG" width=668 border=0><img src ="http://www.shnenglu.com/lwch/aggbug/139497.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/lwch/" target="_blank">lwch</a> 2011-01-27 21:39 <a href="http://www.shnenglu.com/lwch/archive/2011/01/27/139497.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ATL调用COMcȝ装http://www.shnenglu.com/lwch/archive/2010/11/20/134179.htmllwchlwchSat, 20 Nov 2010 14:40:00 GMThttp://www.shnenglu.com/lwch/archive/2010/11/20/134179.htmlhttp://www.shnenglu.com/lwch/comments/134179.htmlhttp://www.shnenglu.com/lwch/archive/2010/11/20/134179.html#Feedback0http://www.shnenglu.com/lwch/comments/commentRss/134179.htmlhttp://www.shnenglu.com/lwch/services/trackbacks/134179.html
 1 #pragma once
 2 #include <atlcomcli.h>
 3 
 4 class COMMacro
 5 {
 6 public:
 7     COMMacro(LPTSTR Object);
 8     ~COMMacro();
 9     BOOL Invoke(LPTSTR strFunction,VARIANT* pVarParams,int nParamterCount,VARIANT* pResult);
10     VARIANT ToVARIANT(BSTR str);
11     VARIANT ToVARIANT(int nVal);
12     VARIANT ToVARIANT(bool bVal);
13     VARIANT ToVARIANT(double dVal);
14     VARIANT ToVARIANT_ByRef(BSTR* pStr);
15     VARIANT ToVARIANT_ByRef(int* pnVal);
16     VARIANT ToVARIANT_ByRef(bool* pbVal);
17     VARIANT ToVARIANT_ByRef(double* pdVal);
18     BSTR ToBSTR(VARIANT Val);
19     int ToInt(VARIANT Val);
20     bool ToBool(VARIANT Val);
21     double ToDouble(VARIANT Val);
22 
23     BOOL ToBSTR(LPTSTR src,BSTR& dest);
24 protected:
25     CLSID m_clsID;
26     CComPtr<IUnknown> m_Unknown;
27     CComDispatchDriver* m_pDispatchDriver;
28 };
COM.cpp:
  1 #include "stdafx.h"
  2 #include "COM.h"
  3 #include <comdef.h>
  4 
  5 COMMacro::COMMacro(LPTSTR Object)
  6 {
  7     HRESULT hr = CLSIDFromProgID(Object,&m_clsID);
  8     if(FAILED(hr))
  9     {
 10         throw _com_error(hr);
 11         return;
 12     }
 13     hr = CoCreateInstance(m_clsID,NULL,CLSCTX_ALL,IID_IUnknown,(LPVOID*)&m_Unknown);
 14     if(FAILED(hr))
 15     {
 16         throw _com_error(hr);
 17         return;
 18     }
 19     m_pDispatchDriver = new CComDispatchDriver(m_Unknown);
 20 }
 21 
 22 COMMacro::~COMMacro()
 23 {
 24     delete m_pDispatchDriver;
 25 }
 26 
 27 BOOL COMMacro::Invoke(LPTSTR strFunction,VARIANT* pVarParams,int nParamterCount,VARIANT* pResult)
 28 {
 29     DISPID DispID;
 30     HRESULT hr = m_pDispatchDriver->GetIDOfName(strFunction,&DispID);
 31     if(FAILED(hr))
 32     {
 33         throw _com_error(hr);
 34         return FALSE;
 35     }
 36     hr = m_pDispatchDriver->InvokeN(DispID,pVarParams,nParamterCount,pResult);
 37     if(FAILED(hr))
 38     {
 39         throw _com_error(hr);
 40         return FALSE;
 41     }
 42     return TRUE;
 43 }
 44 
 45 VARIANT COMMacro::ToVARIANT(BSTR str)
 46 {
 47     VARIANT vResult;
 48     vResult.vt = VT_BSTR;
 49     vResult.bstrVal = SysAllocString(str);
 50     return vResult;
 51 }
 52 
 53 VARIANT COMMacro::ToVARIANT(int nVal)
 54 {
 55     VARIANT vResult;
 56     vResult.vt = VT_I4;
 57     vResult.intVal = nVal;
 58     return vResult;
 59 }
 60 
 61 VARIANT COMMacro::ToVARIANT(bool bVal)
 62 {
 63     VARIANT vResult;
 64     vResult.vt = VT_BOOL;
 65     vResult.boolVal = bVal;
 66     return vResult;
 67 }
 68 
 69 VARIANT COMMacro::ToVARIANT(double dVal)
 70 {
 71     VARIANT vResult;
 72     vResult.vt = VT_R8;
 73     vResult.dblVal = dVal;
 74     return vResult;
 75 }
 76 
 77 VARIANT COMMacro::ToVARIANT_ByRef(BSTR* pStr)
 78 {
 79     VARIANT vResult;
 80     vResult.vt = VT_BSTR | VT_BYREF;
 81     vResult.byref = pStr;
 82     return vResult;
 83 }
 84 
 85 VARIANT COMMacro::ToVARIANT_ByRef(int* pnVal)
 86 {
 87     VARIANT vResult;
 88     vResult.vt = VT_I4 | VT_BYREF;
 89     vResult.byref = pnVal;
 90     return vResult;
 91 }
 92 
 93 VARIANT COMMacro::ToVARIANT_ByRef(bool* pbVal)
 94 {
 95     VARIANT vResult;
 96     vResult.vt = VT_BOOL | VT_BYREF;
 97     vResult.byref = pbVal;
 98     return vResult;
 99 }
100 
101 VARIANT COMMacro::ToVARIANT_ByRef(double* pdVal)
102 {
103     VARIANT vResult;
104     vResult.vt = VT_BOOL | VT_BYREF;
105     vResult.byref = pdVal;
106     return vResult;
107 }
108 
109 BSTR COMMacro::ToBSTR(VARIANT Val)
110 {
111     return *(BSTR*)Val.byref;
112 }
113 
114 int COMMacro::ToInt(VARIANT Val)
115 {
116     return *(int*)Val.byref;
117 }
118 
119 bool COMMacro::ToBool(VARIANT Val)
120 {
121     return *(bool*)Val.byref;
122 }
123 
124 double COMMacro::ToDouble(VARIANT Val)
125 {
126     return *(double*)Val.byref;
127 }
128 
129 BOOL COMMacro::ToBSTR(LPTSTR src,BSTR& dest)
130 {
131     dest = SysAllocString(src);
132     return TRUE;
133 }

使用说明:
1.构造函?
参数(字符串常?:工程?cd
2.Invoke:
参数1(字符串常?:函数?br>参数2(VARIANT数组):调用参数,从右臛_
参数3(数值常?:调用参数个数
参数4(VARIANT指针):q回?br>3.ToVARIANT:给定参数{换ؓ(f)VARIANTcd
4.ToVARIANT_ByRef:给定参数{换ؓ(f)ByRef的VARIANTcd
5.ToBSTR:给定ByRef的VARIANT转换为BSTR
6.ToInt:给定ByRef的VARIANT转换为int
7.ToBool:给定ByRef的VARIANT转换为bool
8.ToDouble:给定ByRef的VARIANT转换为double
9.ToBSTR:给定字W串帔R转换为BSTRcd

CZ:
 1     CoInitialize(0); // 初始化ATL
 2     try
 3     {
 4         COMMacro m(L"aaa.bbb");
 5         VARIANT vResult,vParams[3];
 6         int i = 100;
 7         BSTR str;
 8         m.ToBSTR(L"abc",str);
 9         vParams[2= m.ToVARIANT(123.456);
10         vParams[1= m.ToVARIANT(i);
11         vParams[0= m.ToVARIANT_ByRef(&str);
12         m.Invoke(L"aaa",vParams,3,&vResult);
13         wprintf(L"%s\n",m.ToBSTR(vParams[0]));
14     }
15     catch(_com_error& e)
16     {
17         wprintf(L"%s\n",e.ErrorMessage());
18     }


lwch 2010-11-20 22:40 发表评论
]]>
递归阶乘函数的语法制导翻?/title><link>http://www.shnenglu.com/lwch/archive/2010/10/02/128293.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Sat, 02 Oct 2010 03:56:00 GMT</pubDate><guid>http://www.shnenglu.com/lwch/archive/2010/10/02/128293.html</guid><wfw:comment>http://www.shnenglu.com/lwch/comments/128293.html</wfw:comment><comments>http://www.shnenglu.com/lwch/archive/2010/10/02/128293.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/lwch/comments/commentRss/128293.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/lwch/services/trackbacks/128293.html</trackback:ping><description><![CDATA[代码: <br> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080"> 1</span> <span style="COLOR: #0000ff">function</span><span style="COLOR: #000000"> fact(</span><span style="COLOR: #0000ff">integer</span><span style="COLOR: #000000"> n) </span><span style="COLOR: #0000ff">as</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">integer</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 2</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> n </span><span style="COLOR: #000000">></span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">then</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 3</span> <span style="COLOR: #000000">        return fact(n </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">) </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> n<br></span><span style="COLOR: #008080"> 4</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 5</span> <span style="COLOR: #000000">        return n<br></span><span style="COLOR: #008080"> 6</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 7</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">end function</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 8</span> <span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 9</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000"> main()<br></span><span style="COLOR: #008080">10</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">integer</span><span style="COLOR: #000000"> Result<br></span><span style="COLOR: #008080">11</span> <span style="COLOR: #000000">    Result </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> fact(</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">12</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">end function</span></div> W号?<br> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">    n<br> </span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">    </span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"><br> </span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">    fact<br> </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">    Result<br> </span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">    </span><span style="COLOR: #000000">5</span><span style="COLOR: #000000"><br> </span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">    main</span></div> 译l果:<br> <img height=575 alt="" src="http://www.shnenglu.com/images/cppblog_com/lwch/ESLanguage005.PNG" width=668 border=0> <img src ="http://www.shnenglu.com/lwch/aggbug/128293.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/lwch/" target="_blank">lwch</a> 2010-10-02 11:56 <a href="http://www.shnenglu.com/lwch/archive/2010/10/02/128293.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Switch语句的语法制导翻?/title><link>http://www.shnenglu.com/lwch/archive/2010/09/29/128060.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Wed, 29 Sep 2010 07:55:00 GMT</pubDate><guid>http://www.shnenglu.com/lwch/archive/2010/09/29/128060.html</guid><wfw:comment>http://www.shnenglu.com/lwch/comments/128060.html</wfw:comment><comments>http://www.shnenglu.com/lwch/archive/2010/09/29/128060.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/lwch/comments/commentRss/128060.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/lwch/services/trackbacks/128060.html</trackback:ping><description><![CDATA[首先生成抽象语法?Ҏ(gu)如下:<br>1.根节点ؓ(f)0时表C没有default标签,?时表C有default标签<br>2.W?个根节点表示switch里的条g<br>3.若有default标签,则最后一个根节点为default子树(wi)<br>4.每个根节点ؓ(f)0时表C在此标{下没有stmt_list语句?q个节点的唯一孩子匚w的表辑ּ;?时表C有语句?根节点的左孩子表C匚w的表辑ּ,叛_子ؓ(f)要执行的语句?br>注意:Equal指o(h)?x)弹Z操作?应此在Equal指o(h)执行之前必须先保留switch里exp的副?即Push一?,最后弹出副?br>试代码:<br> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080"> 1</span> <span style="COLOR: #0000ff">integer</span><span style="COLOR: #000000"> aaa,bbb<br></span><span style="COLOR: #008080"> 2</span> <span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 3</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000"> ccc()<br></span><span style="COLOR: #008080"> 4</span> <span style="COLOR: #000000">    switch aaa </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 5</span> <span style="COLOR: #000000">        default:<br></span><span style="COLOR: #008080"> 6</span> <span style="COLOR: #000000">            aaa </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">123</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 7</span> <span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">case</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">123</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080"> 8</span> <span style="COLOR: #000000">            </span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 9</span> <span style="COLOR: #000000">                aaa </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> aaa </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">10</span> <span style="COLOR: #000000">            </span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000"> aaa </span><span style="COLOR: #000000"><</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">789</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">11</span> <span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">case</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">456</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">12</span> <span style="COLOR: #000000">            aaa </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">123</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">13</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000"> switch<br></span><span style="COLOR: #008080">14</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">end function</span></div> 生成虚拟Z?<br><img height=607 alt="" src="http://www.shnenglu.com/images/cppblog_com/lwch/ESLanguage003.PNG" width=668 border=0> <img src ="http://www.shnenglu.com/lwch/aggbug/128060.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/lwch/" target="_blank">lwch</a> 2010-09-29 15:55 <a href="http://www.shnenglu.com/lwch/archive/2010/09/29/128060.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>For语句的语法制导翻?/title><link>http://www.shnenglu.com/lwch/archive/2010/09/22/127329.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Wed, 22 Sep 2010 04:20:00 GMT</pubDate><guid>http://www.shnenglu.com/lwch/archive/2010/09/22/127329.html</guid><wfw:comment>http://www.shnenglu.com/lwch/comments/127329.html</wfw:comment><comments>http://www.shnenglu.com/lwch/archive/2010/09/22/127329.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/lwch/comments/commentRss/127329.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/lwch/services/trackbacks/127329.html</trackback:ping><description><![CDATA[For语句的翻译比较复??个前|条件和q行代码,1个语句块,也就?*3*2*1=24U情?应此在生成抽象语法树(wi)的时候我采用的是2q制位来表示当前块是否存?其中最底位表示stmt_list语句?倒数W?位表Cby之后的语句是否存?倒数W?位表Cto之后的表辑ּ是否存在,倒数W?位表Cfor之后的语句是否存?<br>代码: <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080"> 1</span> <span style="COLOR: #0000ff">integer</span><span style="COLOR: #000000"> aaa,bbb<br></span><span style="COLOR: #008080"> 2</span> <span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 3</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000"> ccc()<br></span><span style="COLOR: #008080"> 4</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 5</span> <span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> aaa </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">456</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">to</span><span style="COLOR: #000000"> by </span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 6</span> <span style="COLOR: #000000">            </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> aaa </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">456</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">then</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 7</span> <span style="COLOR: #000000">                aaa </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">789</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 8</span> <span style="COLOR: #000000">            </span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 9</span> <span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">next</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">10</span> <span style="COLOR: #000000">        aaa </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">123</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">11</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000"> aaa </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">123</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">12</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">end function</span></div> 译l果:<br><img height=431 alt="" src="http://www.shnenglu.com/images/cppblog_com/lwch/ESLanguage002.PNG" width=668 border=0> <img src ="http://www.shnenglu.com/lwch/aggbug/127329.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/lwch/" target="_blank">lwch</a> 2010-09-22 12:20 <a href="http://www.shnenglu.com/lwch/archive/2010/09/22/127329.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>复合语句的嵌套语法制导翻?/title><link>http://www.shnenglu.com/lwch/archive/2010/09/20/127188.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Mon, 20 Sep 2010 14:29:00 GMT</pubDate><guid>http://www.shnenglu.com/lwch/archive/2010/09/20/127188.html</guid><wfw:comment>http://www.shnenglu.com/lwch/comments/127188.html</wfw:comment><comments>http://www.shnenglu.com/lwch/archive/2010/09/20/127188.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.shnenglu.com/lwch/comments/commentRss/127188.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/lwch/services/trackbacks/127188.html</trackback:ping><description><![CDATA[已实现do,while,if和赋D句的语法制导译,q次他们逐层嵌套h看看译l果是否正确.<br>代码:<br> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080"> 1</span> <span style="COLOR: #0000ff">integer</span><span style="COLOR: #000000"> aaa<br></span><span style="COLOR: #008080"> 2</span> <span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 3</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000"> ccc()<br></span><span style="COLOR: #008080"> 4</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000"> aaa </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">123</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 5</span> <span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 6</span> <span style="COLOR: #000000">            </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> aaa </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">123</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">then</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 7</span> <span style="COLOR: #000000">                </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> aaa </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">456</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">then</span><span style="COLOR: #000000"> aaa </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">123</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 8</span> <span style="COLOR: #000000">                </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> aaa </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">456</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 9</span> <span style="COLOR: #000000">                </span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">10</span> <span style="COLOR: #000000">            </span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">11</span> <span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000"> aaa </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">123</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">12</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">13</span> <span style="COLOR: #000000">    aaa </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">456</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">14</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">end function</span></div> 译l果:<br><img height=687 alt="" src="http://www.shnenglu.com/images/cppblog_com/lwch/ESLanguage_001.PNG" width=668 border=0> <img src ="http://www.shnenglu.com/lwch/aggbug/127188.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/lwch/" target="_blank">lwch</a> 2010-09-20 22:29 <a href="http://www.shnenglu.com/lwch/archive/2010/09/20/127188.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>If语句的语法制导翻?/title><link>http://www.shnenglu.com/lwch/archive/2010/09/19/127034.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Sat, 18 Sep 2010 23:27:00 GMT</pubDate><guid>http://www.shnenglu.com/lwch/archive/2010/09/19/127034.html</guid><wfw:comment>http://www.shnenglu.com/lwch/comments/127034.html</wfw:comment><comments>http://www.shnenglu.com/lwch/archive/2010/09/19/127034.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/lwch/comments/commentRss/127034.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/lwch/services/trackbacks/127034.html</trackback:ping><description><![CDATA[<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">1</span> <span style="COLOR: #0000ff">integer</span><span style="COLOR: #000000"> aaa<br></span><span style="COLOR: #008080">2</span> <span style="COLOR: #000000"><br></span><span style="COLOR: #008080">3</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000"> ccc()<br></span><span style="COLOR: #008080">4</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> aaa </span><span style="COLOR: #0000ff">and</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">then</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">5</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">6</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">end function</span></div> <br><img border=0 alt="" src="http://www.shnenglu.com/images/cppblog_com/lwch/If_001.png" width=677 height=442><br><br> <div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">1</span> <span style="COLOR: #0000ff">integer</span><span style="COLOR: #000000"> aaa<br></span><span style="COLOR: #008080">2</span> <span style="COLOR: #000000"><br></span><span style="COLOR: #008080">3</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000"> ccc()<br></span><span style="COLOR: #008080">4</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> aaa </span><span style="COLOR: #0000ff">and</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">then</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">5</span> <span style="COLOR: #000000">        aaa </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">123</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">6</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">7</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">end function</span></div> <br><img border=0 alt="" src="http://www.shnenglu.com/images/cppblog_com/lwch/If_002.png" width=677 height=442><br><br> <div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">1</span> <span style="COLOR: #0000ff">integer</span><span style="COLOR: #000000"> aaa<br></span><span style="COLOR: #008080">2</span> <span style="COLOR: #000000"><br></span><span style="COLOR: #008080">3</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000"> ccc()<br></span><span style="COLOR: #008080">4</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> aaa </span><span style="COLOR: #0000ff">and</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">then</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">5</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">6</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">7</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">end function</span></div> <br><img border=0 alt="" src="http://www.shnenglu.com/images/cppblog_com/lwch/If_003.png" width=677 height=442><br><br> <div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">1</span> <span style="COLOR: #0000ff">integer</span><span style="COLOR: #000000"> aaa<br></span><span style="COLOR: #008080">2</span> <span style="COLOR: #000000"><br></span><span style="COLOR: #008080">3</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000"> ccc()<br></span><span style="COLOR: #008080">4</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> aaa </span><span style="COLOR: #0000ff">and</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">then</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">5</span> <span style="COLOR: #000000">        aaa </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">123</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">6</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">7</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">8</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">end function</span></div> <br><img border=0 alt="" src="http://www.shnenglu.com/images/cppblog_com/lwch/If_004.png" width=677 height=442><br><br> <div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">1</span> <span style="COLOR: #0000ff">integer</span><span style="COLOR: #000000"> aaa<br></span><span style="COLOR: #008080">2</span> <span style="COLOR: #000000"><br></span><span style="COLOR: #008080">3</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000"> ccc()<br></span><span style="COLOR: #008080">4</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> aaa </span><span style="COLOR: #0000ff">and</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">then</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">5</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">6</span> <span style="COLOR: #000000">        aaa </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">123</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">7</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">8</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">end function</span></div> <br><img border=0 alt="" src="http://www.shnenglu.com/images/cppblog_com/lwch/If_005.png" width=677 height=442><br><br> <div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">1</span> <span style="COLOR: #0000ff">integer</span><span style="COLOR: #000000"> aaa<br></span><span style="COLOR: #008080">2</span> <span style="COLOR: #000000"><br></span><span style="COLOR: #008080">3</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000"> ccc()<br></span><span style="COLOR: #008080">4</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> aaa </span><span style="COLOR: #0000ff">and</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">then</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">5</span> <span style="COLOR: #000000">        aaa </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">123</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">6</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">7</span> <span style="COLOR: #000000">        aaa </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">456</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">8</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">9</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">end function</span></div> <br><img border=0 alt="" src="http://www.shnenglu.com/images/cppblog_com/lwch/If_006.png" width=677 height=442> <img src ="http://www.shnenglu.com/lwch/aggbug/127034.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/lwch/" target="_blank">lwch</a> 2010-09-19 07:27 <a href="http://www.shnenglu.com/lwch/archive/2010/09/19/127034.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ESLanguage部分语法制导译http://www.shnenglu.com/lwch/archive/2010/09/17/126918.htmllwchlwchFri, 17 Sep 2010 14:21:00 GMThttp://www.shnenglu.com/lwch/archive/2010/09/17/126918.htmlhttp://www.shnenglu.com/lwch/comments/126918.htmlhttp://www.shnenglu.com/lwch/archive/2010/09/17/126918.html#Feedback0http://www.shnenglu.com/lwch/comments/commentRss/126918.htmlhttp://www.shnenglu.com/lwch/services/trackbacks/126918.html生成Ҏ(gu):
1.U进时将Number,String或Symbol分别加入对应集合
2.归约时从集合中取出对应的成员,q删除这条生式里的所有终l符
3.生的语法?wi)节点压入栈?br>4.当遇C生式item_list->item_list item或stmt_list->stmt_list stmt时从栈中弹出两颗语法?wi)ƈ按顺序连接v?br>5.当遇到非l结W时弹出相应数量的语法树(wi)节点,生成新的根节点ƈ把弹出的语法?wi)节炚wq接到这个新的根节点?br>6.当归U到W?条生式时检查栈的元素数?1为正常?然后Ҏ(gu)象语法树(wi)q行前序遍历q生成虚拟机代码



lwch 2010-09-17 22:21 发表评论
]]>
ESLanguage部分语法http://www.shnenglu.com/lwch/archive/2010/09/17/126912.htmllwchlwchFri, 17 Sep 2010 14:04:00 GMThttp://www.shnenglu.com/lwch/archive/2010/09/17/126912.htmlhttp://www.shnenglu.com/lwch/comments/126912.htmlhttp://www.shnenglu.com/lwch/archive/2010/09/17/126912.html#Feedback0http://www.shnenglu.com/lwch/comments/commentRss/126912.htmlhttp://www.shnenglu.com/lwch/services/trackbacks/126912.html阅读全文

lwch 2010-09-17 22:04 发表评论
]]>
ƷѾþþþþþ| ƷëٸAVѾþ| ݺɫۺþö | vavavaþ| ˹ھƷþþþӰԺ| þù| vaĻþ | Ʒһþ㽶߿| þþƷ99þ˿| պƷþþþþ| Ʒ۲ӰԺþ| ˾þô߽| Ʒ˿þþþþò| ݺɫþþۺƵպ| þerƷѹۿ8| ɫۺϾþþþ| þݺҹҹ2014| þۺĻ| ɫۺϾþ| ܻƺ۵վþmimiɫ| þˬˬƬav | þþþþƷAV| þ99Ʒ99þ| ƷþþþóѶ | Ļþ| þþƵ| ޹Ʒľþþ| 㽶99þùۺϾƷլ | ҹþþþþþþõӰ | ޹Ʒþþþþ| þþþѾƷ| ݺɫþۺ_| ˾þþþƷ| ˾ƷѾþþþ| þþƵ| AVӰƬþþþþ| þþþһƷ | ŷҹƷþþþ| þ99þ99Ʒӿ| 91ƷۺϾþþƷ| ˾þˬ|