﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-lwch-随笔分类-QLanguage</title><link>http://www.cppblog.com/lwch/category/14952.html</link><description>【QQ:510134884】【Email:&lt;a href="mailto:lwch748@gmail.com"&gt;lwch748@gmail.com&lt;/a&gt;】</description><language>zh-cn</language><lastBuildDate>Wed, 16 Oct 2013 19:25:17 GMT</lastBuildDate><pubDate>Wed, 16 Oct 2013 19:25:17 GMT</pubDate><ttl>60</ttl><item><title>QParserGenerator的文法文件介绍</title><link>http://www.cppblog.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.cppblog.com/lwch/archive/2013/10/09/203576.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/203576.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2013/10/09/203576.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/203576.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lwch/services/trackbacks/203576.html</trackback:ping><description><![CDATA[在沉默了数月之后，博主心血来潮想继续介绍QParserGenerator，在这里我们将不再继续介绍任何有关于LALR(1)的算法(那东西只会把你的脑子变成一团浆糊)，让我们来看一下QParserGenerator的具体用法。<br />
<br />
说到ParserGenerator不得不提的是BNF，应此QParserGenerator也有它自己的BNF，这时有人会问BNF究竟是什么呢？简单的说BNF就是用来描述一种语法的东西，比如在Basic中If后面跟表达式然后是Then中间是语句块末尾必须要有End If等等的一系列描述，更专业的解释我们可以看一下<a href="http://zh.wikipedia.org/zh/%E5%B7%B4%E7%A7%91%E6%96%AF%E8%8C%83%E5%BC%8F" target="_blank">维基百科</a>上的解释。<br />
<br />
好了，说完了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&nbsp;"%"&nbsp;"token"&nbsp;"start"&nbsp;"|"&nbsp;"-"&nbsp;"&gt;"&nbsp;";"&nbsp;"["&nbsp;"]";<br />
<br />
%start&nbsp;start;<br />
<br />
strings&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&gt;&nbsp;strings&nbsp;"{String}"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;"{String}"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;<br />
<br />
vs&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&gt;&nbsp;vs&nbsp;"{Letter}"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;vs&nbsp;"{String}"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;"{Letter}"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;"{String}"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;<br />
<br />
option&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&gt;&nbsp;"["&nbsp;vs&nbsp;"]"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;<br />
<br />
oneProductionRight&nbsp;&nbsp;-&gt;&nbsp;oneProductionRight&nbsp;option<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;oneProductionRight&nbsp;vs<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;option<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;vs<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;<br />
<br />
someProductionRight&nbsp;-&gt;&nbsp;someProductionRight&nbsp;"|"&nbsp;oneProductionRight<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;oneProductionRight<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;<br />
<br />
token&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&gt;&nbsp;"%"&nbsp;"token"&nbsp;strings&nbsp;";"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;<br />
<br />
someTokens&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&gt;&nbsp;someTokens&nbsp;token<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;token<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;<br />
<br />
production&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&gt;&nbsp;"{Letter}"&nbsp;"-"&nbsp;"&gt;"&nbsp;someProductionRight&nbsp;";"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;<br />
<br />
someProductions&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&gt;&nbsp;someProductions&nbsp;production<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;production<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;<br />
<br />
start&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&gt;&nbsp;someTokens&nbsp;"%"&nbsp;"start"&nbsp;"{Letter}"&nbsp;";"&nbsp;someProductions<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;"%"&nbsp;"start"&nbsp;"{Letter}"&nbsp;";"&nbsp;someProductions<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;</div>
也许有人会问，不对啊根据<a href="http://zh.wikipedia.org/wiki/%E5%B7%B4%E7%A7%91%E6%96%AF%E8%8C%83%E5%BC%8F" target="_blank">维基百科</a>上的说明BNF不应该是长这样的，其实QParserGenerator是一个BNF的生成器，它可以将输入的BNF通过一系列的运算最后生成LALR(1)分析表，为了BNF文件的美观和方便处理我特地把他设计成了这个样子的而已，好了下面我们就以这个BNF文件来说明应该如何来书写BNF文件。<br />
<br />
首先可以看到最顶上有一些以%token开头的字符串（在C语言中我们将用双引号括起来的字符序列称为字符串）以及最后的一个分号，其实这里的这些字符串正是BNF中说说的终结符，所以我们规定，所有其他没用%token声明的符号都是非终结符。终结符是用来做移进操作的，在某种特定的语言中他表现为一个token，而非终结符可以理解为一个代词，通常一个非终结符都可以展开为一条或多条规则（<a href="http://zh.wikipedia.org/wiki/%E5%BD%A2%E5%BC%8F%E6%96%87%E6%B3%95" target="_blank">产生式</a>）。至于说为什么每条内容后面都会有分号呢，只是为了处理上的方便（消除语法上的冲突？）。<br />
好了，我们把终结符和非终结符这两个专业术语给解释完了，接下来可以看到的是一个以%start开头后跟一个非终结符的语句，他表明了所有规则（<a href="http://zh.wikipedia.org/wiki/%E5%BD%A2%E5%BC%8F%E6%96%87%E6%B3%95" target="_blank">产生式</a>）是从哪里开始的（有始无终的节奏-_-||杯具啊）。<br />
<br />
最后就是我们的重头了，多空一行也不为过吧。这里有一大堆的产生式，那我们如何来阅读他呢，其实上面已经介绍了有个表明了所有规则开头的非终结符，好那让我们来找一下他所对应的产生式在哪里<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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&gt;&nbsp;someTokens&nbsp;"%"&nbsp;"start"&nbsp;"{Letter}"&nbsp;";"&nbsp;someProductions<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;"%"&nbsp;"start"&nbsp;"{Letter}"&nbsp;";"&nbsp;someProductions<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;</div>
可以看到所有的规则可分为左半部分和右半部分，左边总是一个非终结符来说明他应该被哪一些规则来替代，而右边则是这些规则的具体内容包含了一些终结符和非终结符序列，中间则用一个箭头符号来分割。在所有的规则中非终结符都是不带引号的，而终结符都是用引号将其括起来的，在终结符中有一些内置的变量来表达一些特定的表达式，这个会在下文中做出说明。当然对于同一个终结符来说我们可以用任意多个规则来说明他，他们都是<font color="red">或</font>的关系，由于BNF中不可能存在<font color="red">且</font>的关系，应此我们并不需要考虑他。<br />
<br />
下面让我们来看一下预定义的终结符有哪些，从<a href="https://github.com/lwch/QLanguage/blob/dev/Source/QParserGenerator/Parser/Parser.cpp" target="_blank">Parser.cpp</a>的代码中可知预定义的终结符有"{String}"、"{Digit}"、"{Real}"、"{Letter}"。<br />
"{String}"：表示正则表达式\"[^\"]*\"<br />
"{Digit}"：表示正则表达式[0-9]+<br />
"{Real}"：表示正则表达式[0-9]*.[0-9]+<br />
"{Letter}"：表示正则表达式((_[0-9]+)|([_a-zA-Z]+))[_0-9a-zA-Z]*<br />
从这些正则表达式中可见"{String}"表示一个带双引号的字符串，"{Digit}"则表示一个数字，"{Real}"则表示一个浮点数，"{Letter}"则表示一个不带双引号的字符串。当然这些正则表达式写的并不完备，比如"{String}"中没有支持转义等等。<br />
<br />
然后让我们来看一下每条规则支持哪些语法，首先从下面几条文法中可知，可用方括号将一些可选项括起来。<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>&nbsp;vs&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&gt;&nbsp;vs&nbsp;"{Letter}"<br />
<span style="color: #008080; ">2</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;vs&nbsp;"{String}"<br />
<span style="color: #008080; ">3</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;"{Letter}"<br />
<span style="color: #008080; ">4</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;"{String}"<br />
<span style="color: #008080; ">5</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;<br />
<span style="color: #008080; ">6</span>&nbsp;<br />
<span style="color: #008080; ">7</span>&nbsp;option&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&gt;&nbsp;"["&nbsp;vs&nbsp;"]"<br />
<span style="color: #008080; ">8</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;</div>
<br />
而对于一个规则来说他可以用若干条产生式来说明他，其中每条产生式之间是<font color="red">或</font>的关系。<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>&nbsp;oneProductionRight&nbsp;&nbsp;-&gt;&nbsp;oneProductionRight&nbsp;option<br />
<span style="color: #008080; ">2</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;oneProductionRight&nbsp;vs<br />
<span style="color: #008080; ">3</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;option<br />
<span style="color: #008080; ">4</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;vs<br />
<span style="color: #008080; ">5</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;<br />
<span style="color: #008080; ">6</span>&nbsp;<br />
<span style="color: #008080; ">7</span>&nbsp;someProductionRight&nbsp;-&gt;&nbsp;someProductionRight&nbsp;"|"&nbsp;oneProductionRight<br />
<span style="color: #008080; ">8</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;oneProductionRight<br />
<span style="color: #008080; ">9</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;</div>
<br />
其他一些规则则说明了一些上文提到的规则，比如开头是一些token的定义等。终于把QParserGenerator的文法文件的结构给介绍完了，在接下来的一篇文章中我们将介绍如何用QParserGenerator来生成一个带括号优先级的四则混合运算计算器，其文法可见<a href="https://github.com/lwch/QLanguage/blob/dev/GeneratorFiles/Calculator.txt" target="_blank">Calculator.txt</a>，QLanguage整个项目的代码可见<a href="https://github.com/lwch/QLanguage/" target="_blank">https://github.com/lwch/QLanguage/</a>。<img src ="http://www.cppblog.com/lwch/aggbug/203576.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2013-10-09 11:17 <a href="http://www.cppblog.com/lwch/archive/2013/10/09/203576.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>QParserGenerator代码分析二(A fix&amp;An example)</title><link>http://www.cppblog.com/lwch/archive/2013/05/30/200608.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Thu, 30 May 2013 15:04:00 GMT</pubDate><guid>http://www.cppblog.com/lwch/archive/2013/05/30/200608.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/200608.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2013/05/30/200608.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/200608.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lwch/services/trackbacks/200608.html</trackback:ping><description><![CDATA[接<a href="http://www.cppblog.com/lwch/archive/2013/05/12/200203.html" target="_blank">上一篇</a>，首先需要修正的是在DFA生成算法中的传播部分，应该需要有个循环一直传播到不能传播为止，在多次实验中表明，有些展望符是通过第2，3，4甚至更多次传播得来的。<br />
<br />
应此，相应的make函数变成了<br />
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp;&nbsp;<span style="color: #0000ff">bool</span>&nbsp;LALR1::make()<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vector&lt;LALR1Production&gt;&nbsp;v;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;v.push_back(inputProductions[begin][0]);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pStart&nbsp;=&nbsp;closure(v);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pStart-&gt;idx&nbsp;=&nbsp;Item::inc();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context.states.insert(pStart);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;items.push_back(pStart);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;queue&lt;Item*&gt;&nbsp;q;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;q.push(pStart);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vector&lt;Item*&gt;&nbsp;changes;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">bool</span>&nbsp;bContinue&nbsp;=&nbsp;<span style="color: #0000ff">false</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">while</span>&nbsp;(!q.empty())<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Item*&nbsp;pItem&nbsp;=&nbsp;q.front();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vector&lt;Production::Item&gt;&nbsp;s;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;symbols(pItem,&nbsp;s);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select_into(s,&nbsp;vts,&nbsp;compare_production_item_is_vt,&nbsp;push_back_unique_vector&lt;Production::Item&gt;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select_into(s,&nbsp;vns,&nbsp;compare_production_item_is_vn,&nbsp;push_back_unique_vector&lt;Production::Item&gt;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">for</span>&nbsp;(vector&lt;Production::Item&gt;::const_iterator&nbsp;i&nbsp;=&nbsp;s.begin(),&nbsp;m&nbsp;=&nbsp;s.end();&nbsp;i&nbsp;!=&nbsp;m;&nbsp;++i)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Item*&nbsp;pNewItem&nbsp;=&nbsp;NULL;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">if</span>&nbsp;(go(pItem,&nbsp;*i,&nbsp;pNewItem))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">long</span>&nbsp;n&nbsp;=&nbsp;itemIndex(pNewItem);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">if</span>&nbsp;(n&nbsp;==&nbsp;-1)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pNewItem-&gt;idx&nbsp;=&nbsp;Item::inc();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;q.push(pNewItem);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;items.push_back(pNewItem);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context.states.insert(pNewItem);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">else</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;items[n]-&gt;mergeWildCards(pNewItem,&nbsp;bContinue);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;changes.push_back_unique(items[n]);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;destruct(pNewItem,&nbsp;has_destruct(*pNewItem));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Item_Alloc::deallocate(pNewItem);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;edges[pItem].push_back_unique(Edge(pItem,&nbsp;n&nbsp;==&nbsp;-1&nbsp;?&nbsp;pNewItem&nbsp;:&nbsp;items[n],&nbsp;*i));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;q.pop();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">while</span>&nbsp;(bContinue)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vector&lt;Item*&gt;&nbsp;v;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;v.reserve(changes.size());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bContinue&nbsp;=&nbsp;<span style="color: #0000ff">false</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">for</span>&nbsp;(vector&lt;Item*&gt;::const_iterator&nbsp;i&nbsp;=&nbsp;changes.begin(),&nbsp;m&nbsp;=&nbsp;changes.end();&nbsp;i&nbsp;!=&nbsp;m;&nbsp;++i)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vector&lt;Production::Item&gt;&nbsp;s;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;symbols(*i,&nbsp;s);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">for</span>&nbsp;(vector&lt;Production::Item&gt;::const_iterator&nbsp;j&nbsp;=&nbsp;s.begin(),&nbsp;n&nbsp;=&nbsp;s.end();&nbsp;j&nbsp;!=&nbsp;n;&nbsp;++j)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Item*&nbsp;pNewItem&nbsp;=&nbsp;NULL;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">if</span>&nbsp;(go(*i,&nbsp;*j,&nbsp;pNewItem))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">long</span>&nbsp;n&nbsp;=&nbsp;itemIndex(pNewItem);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">if</span>&nbsp;(n&nbsp;==&nbsp;-1)&nbsp;<span style="color: #0000ff">throw</span>&nbsp;error&lt;<span style="color: #0000ff">const</span>&nbsp;<span style="color: #0000ff">char</span>*&gt;("unknown&nbsp;item",&nbsp;__FILE__,&nbsp;__LINE__);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">else</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;items[n]-&gt;mergeWildCards(pNewItem,&nbsp;bContinue);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;v.push_back_unique(items[n]);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;destruct(pNewItem,&nbsp;has_destruct(*pNewItem));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Item_Alloc::deallocate(pNewItem);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;changes&nbsp;=&nbsp;v;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}</div>
在merge函数中，会检测有没有新生成的展望符来决定是否继续传播下去。<br />
<br />
<strong style="font-size: 14pt">一个示例</strong><br />
下面我们用一个例子来说明LALR1 DFA是如何生成的，首先它的文法如下<br />
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->S&nbsp;-&gt;&nbsp;L&nbsp;"="&nbsp;R<br />
&nbsp;&nbsp;|&nbsp;R&nbsp;"+"<br />
&nbsp;&nbsp;|&nbsp;R<br />
&nbsp;&nbsp;;<br />
<br />
L&nbsp;-&gt;&nbsp;"*"&nbsp;R<br />
&nbsp;&nbsp;|&nbsp;&nbsp;"id"<br />
&nbsp;&nbsp;;<br />
<br />
R&nbsp;-&gt;&nbsp;L<br />
&nbsp;&nbsp;;</div>
根据之前的算法，我们先来看自生的部分<br />
<br />
首先我们写出这个文法的增广文法<br />
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee; border-image: initial"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->begin&nbsp;-&gt;&nbsp;.&nbsp;S&nbsp;(#)</div>
求取它的闭包得到<br />
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee; border-image: initial"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->begin&nbsp;-&gt;&nbsp;.&nbsp;S<br />
wildCards:<br />
#&nbsp;<br />
S&nbsp;-&gt;&nbsp;.&nbsp;L&nbsp;"="&nbsp;R<br />
wildCards:<br />
#&nbsp;<br />
S&nbsp;-&gt;&nbsp;.&nbsp;R&nbsp;"+"<br />
wildCards:<br />
#&nbsp;<br />
S&nbsp;-&gt;&nbsp;.&nbsp;R<br />
wildCards:<br />
#&nbsp;<br />
L&nbsp;-&gt;&nbsp;.&nbsp;"*"&nbsp;R<br />
wildCards:<br />
"="&nbsp;"+"&nbsp;<br />
L&nbsp;-&gt;&nbsp;.&nbsp;"id"<br />
wildCards:<br />
"="&nbsp;"+"&nbsp;<br />
R&nbsp;-&gt;&nbsp;.&nbsp;L<br />
wildCards:<br />
"+"&nbsp;#&nbsp;</div>
我们观察到，其中有5个可转移的符号，分别为S、L、R、"*"和"id"，我们分别用go函数对这5个转移符号求出新的状态<br />
<br />
首先用符号S求出新状态<br />
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee; border-image: initial">begin&nbsp;-&gt;&nbsp;S<br />
wildCards:<br />
#&nbsp;</div>
由于这个状态不在原有列表中，应此它是一个新生成的状态，我们为它添加一条通过符号S转移的边。<br />
<br />
接下来用符号L求出新状态<br />
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->S&nbsp;-&gt;&nbsp;L&nbsp;.&nbsp;"="&nbsp;R<br />
wildCards:<br />
#&nbsp;<br />
R&nbsp;-&gt;&nbsp;L<br />
wildCards:<br />
"+"&nbsp;#&nbsp;</div>
这个状态也不在原有列表中，应此它也是一个新生成的状态，我们为它添加一条通过符号L转移的边。<br />
<br />
然后用符号R求出新状态<br />
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->S&nbsp;-&gt;&nbsp;R&nbsp;.&nbsp;"+"<br />
wildCards:<br />
#&nbsp;<br />
S&nbsp;-&gt;&nbsp;R<br />
wildCards:<br />
#&nbsp;</div>
这个状态也不在原有列表中，应此它也是一个新生成的状态，我们为它添加一条通过符号R转移的边。<br />
<br />
然后用符号*求出新的状态<br />
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->L&nbsp;-&gt;&nbsp;"*"&nbsp;.&nbsp;R<br />
wildCards:<br />
"="&nbsp;"+"&nbsp;<br />
R&nbsp;-&gt;&nbsp;.&nbsp;L<br />
wildCards:<br />
"+"&nbsp;#&nbsp;"="&nbsp;<br />
L&nbsp;-&gt;&nbsp;.&nbsp;"*"&nbsp;R<br />
wildCards:<br />
"="&nbsp;"+"&nbsp;#&nbsp;<br />
L&nbsp;-&gt;&nbsp;.&nbsp;"id"<br />
wildCards:<br />
"="&nbsp;"+"&nbsp;#&nbsp;</div>
同样的它也不在原有的列表中，我们同样为其添加一条通过符号*转移的边。<br />
<br />
然后是符号id的<br />
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->L&nbsp;-&gt;&nbsp;"id"<br />
wildCards:<br />
"="&nbsp;"+"&nbsp;</div>
同样不在列表中，我们为其添加一条通过符号id转移的边。<br />
<br />
这样，从start状态转移出来的5条边就生成好了，下面来看看这5个新生成的状态又会生成一些什么呢<br />
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee; border-image: initial"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->begin&nbsp;-&gt;&nbsp;S<br />
wildCards:<br />
#&nbsp;</div>
由第一个状态可知，它没有任何的边。<br />
<br />
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee; border-image: initial"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->S&nbsp;-&gt;&nbsp;L&nbsp;.&nbsp;"="&nbsp;R<br />
wildCards:<br />
#&nbsp;<br />
R&nbsp;-&gt;&nbsp;L<br />
wildCards:<br />
"+"&nbsp;#&nbsp;</div>
第二个状态则有一个=的转移，它生成了一个新状态<br />
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee; border-image: initial"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->S&nbsp;-&gt;&nbsp;L&nbsp;"="&nbsp;.&nbsp;R<br />
wildCards:<br />
#&nbsp;<br />
R&nbsp;-&gt;&nbsp;.&nbsp;L<br />
wildCards:<br />
"+"&nbsp;#&nbsp;"="&nbsp;<br />
L&nbsp;-&gt;&nbsp;.&nbsp;"*"&nbsp;R<br />
wildCards:<br />
"="&nbsp;"+"&nbsp;#&nbsp;<br />
L&nbsp;-&gt;&nbsp;.&nbsp;"id"<br />
wildCards:<br />
"="&nbsp;"+"&nbsp;#&nbsp;</div>
<br />
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->S&nbsp;-&gt;&nbsp;R&nbsp;.&nbsp;"+"<br />
wildCards:<br />
#&nbsp;<br />
S&nbsp;-&gt;&nbsp;R<br />
wildCards:<br />
#&nbsp;</div>
第三个状态有一个+的转移，它生成了一个新状态<br />
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->S&nbsp;-&gt;&nbsp;R&nbsp;"+"<br />
wildCards:<br />
#&nbsp;</div>
<br />
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->L&nbsp;-&gt;&nbsp;"*"&nbsp;.&nbsp;R<br />
wildCards:<br />
"="&nbsp;"+"&nbsp;<br />
R&nbsp;-&gt;&nbsp;.&nbsp;L<br />
wildCards:<br />
"+"&nbsp;#&nbsp;"="&nbsp;<br />
L&nbsp;-&gt;&nbsp;.&nbsp;"*"&nbsp;R<br />
wildCards:<br />
"="&nbsp;"+"&nbsp;#&nbsp;<br />
L&nbsp;-&gt;&nbsp;.&nbsp;"id"<br />
wildCards:<br />
"="&nbsp;"+"&nbsp;#&nbsp;</div>
第四个状态有4个转移，分别为R、L、*和id<br />
<br />
1.通过符号R转移到新状态<br />
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->L&nbsp;-&gt;&nbsp;"*"&nbsp;R<br />
wildCards:<br />
"="&nbsp;"+"&nbsp;</div>
<br />
2.通过符号L转移到新状态<br />
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee; border-image: initial"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->R&nbsp;-&gt;&nbsp;L<br />
wildCards:<br />
"+"&nbsp;#&nbsp;"="&nbsp;</div>
<br />
3.通过*则可转移到它自己<br />
<br />
4.通过id转移到第5个状态<br />
<br />
第五个状态则没有任何的转移。<br />
<br />
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee; border-image: initial"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->S&nbsp;-&gt;&nbsp;L&nbsp;"="&nbsp;.&nbsp;R<br />
wildCards:<br />
#&nbsp;<br />
R&nbsp;-&gt;&nbsp;.&nbsp;L<br />
wildCards:<br />
"+"&nbsp;#&nbsp;"="&nbsp;<br />
L&nbsp;-&gt;&nbsp;.&nbsp;"*"&nbsp;R<br />
wildCards:<br />
"="&nbsp;"+"&nbsp;#&nbsp;<br />
L&nbsp;-&gt;&nbsp;.&nbsp;"id"<br />
wildCards:<br />
"="&nbsp;"+"&nbsp;#&nbsp;</div>
第六个状态有4个转移，分别为R、L、*和id<br />
<br />
1.通过符号R可转移到新状态<br />
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee; border-image: initial"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->S&nbsp;-&gt;&nbsp;L&nbsp;"="&nbsp;R<br />
wildCards:<br />
#&nbsp;</div>
<br />
2.通过符号L可转移到状态9<br />
<br />
3.通过符号*可转移到状态4<br />
<br />
4.通过符号id可转移到状态5<br />
<br />
第6、7、8个状态都没有任何转移<br />
<br />
然后让我们来看下changes列表里有哪些东西，根据<a href="http://www.cppblog.com/lwch/archive/2013/05/12/200203.html" target="_blank">上一篇</a>的算法可知，所有已存在的状态都在changes列表里，应此它里面应该会有4、5和9三个状态。<br />
<br />
至此，整个自生的部分完成了，下面我们将其画成一张图<br />
<img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/lwch/LALR1DFA1.png" width="522" height="599" /><br />
<br />
<strong style="font-size: 14pt">下面是传播部分</strong><br />
在第一次传播时changes列表里有3个状态，分别对这3个状态用go函数求出新的展望符，并把它们合并到原有的状态上。<br />
<br />
首先看状态4，它有4个状态转移符，分别是R、L、*和id<br />
<br />
1.通过符号R可转移到状态8，同时它的展望符如下<br />
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->L&nbsp;-&gt;&nbsp;"*"&nbsp;R<br />
wildCards:<br />
"="&nbsp;"+"&nbsp;#&nbsp;</div>
<br />
2.通过符号L可转移到状态9，同时它的展望符如下<br />
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->R&nbsp;-&gt;&nbsp;L<br />
wildCards:<br />
"+"&nbsp;#&nbsp;"="&nbsp;</div>
<br />
3.通过符号*可转移到它自己，同时它的展望符如下<br />
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->L&nbsp;-&gt;&nbsp;"*"&nbsp;.&nbsp;R<br />
wildCards:<br />
"="&nbsp;"+"&nbsp;#&nbsp;<br />
R&nbsp;-&gt;&nbsp;.&nbsp;L<br />
wildCards:<br />
"+"&nbsp;#&nbsp;"="&nbsp;<br />
L&nbsp;-&gt;&nbsp;.&nbsp;"*"&nbsp;R<br />
wildCards:<br />
"="&nbsp;"+"&nbsp;#&nbsp;<br />
L&nbsp;-&gt;&nbsp;.&nbsp;"id"<br />
wildCards:<br />
"="&nbsp;"+"&nbsp;#&nbsp;</div>
<br />
4.通过符号id可转移到状态5，同时它的展望符如下<br />
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->L&nbsp;-&gt;&nbsp;"id"<br />
wildCards:<br />
"="&nbsp;"+"&nbsp;#&nbsp;</div>
<br />
然后我们来看一下状态5和9，它们没有任何状态转移符，应此它们不会传播任何展望符。<br />
<br />
现在changes列表里有4个状态，分别为8、9、4和5，又由于第8个状态已经产生了新的展望符#应此需要继续传播<br />
<br />
<strong style="font-size: 14pt">第二次传播</strong><br />
<br />
首先先看状态8和9，它们没有任何状态转移符，应此它们不会传播任何展望符。<br />
<br />
然后来看状态4，同样的它有4个状态转移符，分别为R、L、*和id。<br />
<br />
1.通过符号R可转移到状态8，同时它的展望符如下<br />
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->L&nbsp;-&gt;&nbsp;"*"&nbsp;R<br />
wildCards:<br />
"="&nbsp;"+"&nbsp;#&nbsp;</div>
<br />
2.通过符号L可转移到状态9，同时它的展望符如下<br />
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->R&nbsp;-&gt;&nbsp;L<br />
wildCards:<br />
"+"&nbsp;#&nbsp;"="&nbsp;</div>
<br />
3.通过符号*可转移到它自己，同时它的展望符如下<br />
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->L&nbsp;-&gt;&nbsp;"*"&nbsp;.&nbsp;R<br />
wildCards:<br />
"="&nbsp;"+"&nbsp;#&nbsp;<br />
R&nbsp;-&gt;&nbsp;.&nbsp;L<br />
wildCards:<br />
"+"&nbsp;#&nbsp;"="&nbsp;<br />
L&nbsp;-&gt;&nbsp;.&nbsp;"*"&nbsp;R<br />
wildCards:<br />
"="&nbsp;"+"&nbsp;#&nbsp;<br />
L&nbsp;-&gt;&nbsp;.&nbsp;"id"<br />
wildCards:<br />
"="&nbsp;"+"&nbsp;#&nbsp;</div>
<br />
4.通过符号id可转移到状态5，同时它的展望符如下<br />
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee; border-image: initial"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->L&nbsp;-&gt;&nbsp;"id"<br />
wildCards:<br />
"="&nbsp;"+"&nbsp;#&nbsp;</div>
<br />
最后我们来看状态5，它没有任何状态转移符，应此它不会传播任何展望符。<br />
<br />
现在changes列表里同样有4个状态，分别为8、9、4和5，由于没有一个状态产生了新的展望符，应此它将不会继续传播下去了。<br />
<br />
现在整个文法的DFA就生成完毕了，让我们来修改一下原先的那张图来看看最终的DFA是什么样的。<br />
<img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/lwch/LALR1DFA2.png" width="522" height="599" /><br />
<br />
整个示例就先介绍到这里，在接下来的一篇文章中将会通过几个示例来介绍closure和go函数的原理，希望这种由粗到细的讲解顺序能够被读者所接受。最后完整的代码可到<a href="http://code.google.com/p/qlanguage/" target="_blank">http://code.google.com/p/qlanguage</a>下载。<img src ="http://www.cppblog.com/lwch/aggbug/200608.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2013-05-30 23:04 <a href="http://www.cppblog.com/lwch/archive/2013/05/30/200608.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>QParserGenerator代码分析一(生成LALR1 DFA)</title><link>http://www.cppblog.com/lwch/archive/2013/05/12/200203.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Sun, 12 May 2013 14:32:00 GMT</pubDate><guid>http://www.cppblog.com/lwch/archive/2013/05/12/200203.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/200203.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2013/05/12/200203.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/200203.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lwch/services/trackbacks/200203.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 以下所说的文法文件均为QParserGenerator的文法文件产生式我们将文法文件中形如Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->strings&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n...&nbsp;&nbsp;<a href='http://www.cppblog.com/lwch/archive/2013/05/12/200203.html'>阅读全文</a><img src ="http://www.cppblog.com/lwch/aggbug/200203.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2013-05-12 22:32 <a href="http://www.cppblog.com/lwch/archive/2013/05/12/200203.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>词法分析器2(&amp;epsilon;-NFA到DFA的转换)</title><link>http://www.cppblog.com/lwch/archive/2013/02/23/198043.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Sat, 23 Feb 2013 15:30:00 GMT</pubDate><guid>http://www.cppblog.com/lwch/archive/2013/02/23/198043.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/198043.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2013/02/23/198043.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/198043.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lwch/services/trackbacks/198043.html</trackback:ping><description><![CDATA[<p>接<a href="http://www.cppblog.com/lwch/archive/2013/02/15/197848.html" target="_blank">上一篇</a>我们已经得到了一个完整的&#949;-NFA，下面来说说如何将&#949;-NFA转换为DFA（确定有限自动机）。</p>  <h1></h1>  <h1>DFA的状态</h1>  <p>在DFA中，某个状态对应到&#949;-NFA中的若干状态，应此我们将会得到下面这样的一个结构。</p> <span style="display: none" id="Code_Open_Text_449308">   <p>&nbsp;</p> </span>  <p>&nbsp;</p>  <div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px" class="cnblogs_code">   <pre>        <span style="color: #0000ff">struct</span> DFA_State
        {
            set&lt;EpsilonNFA_State*&gt; content;
            <span style="color: #0000ff">bool</span>                   bFlag;
#ifdef _DEBUG
            uint                   idx;
#endif

            DFA_State(<span style="color: #0000ff">const</span> set&lt;EpsilonNFA_State*&gt;&amp; x) : content(x), bFlag(<span style="color: #0000ff">false</span>)
            {
#ifdef _DEBUG
                idx = inc();
#endif
            }

            <span style="color: #0000ff">inline</span> <span style="color: #0000ff">const</span> <span style="color: #0000ff">bool</span> <span style="color: #0000ff">operator</span>==(<span style="color: #0000ff">const</span> DFA_State&amp; x)<span style="color: #0000ff">const</span>
            {
                <span style="color: #0000ff">if</span> (&amp;x == <span style="color: #0000ff">this</span>) <span style="color: #0000ff">return</span> <span style="color: #0000ff">true</span>;

                <span style="color: #0000ff">return</span> content == x.content;
            }

#ifdef _DEBUG
            <span style="color: #0000ff">inline</span> uint inc()
            {
                <span style="color: #0000ff">static</span> uint i = 0;
                <span style="color: #0000ff">return</span> i++;
            }
#endif
        };</pre>
</div>

<p>&nbsp;</p>

<p>可以看到，为了调试方便我们在结构中定义了状态的唯一ID以及对应到&#949;-NFA状态的集合和一个标记位。</p>

<h1>DFA的边</h1>

<p>根据<a href="http://www.cppblog.com/lwch/archive/2013/02/15/197848.html" target="_blank">上一篇</a>的经验，不难想到DFA的边应该是什么样的，下面直接给出代码，不做说明。</p>

<p>&nbsp;</p>

<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px" class="cnblogs_code">
  <pre>        <span style="color: #0000ff">struct</span> DFA_Edge
        {
            <span style="color: #0000ff">struct</span>
            {
                Char_Type   char_value;
                String_Type string_value;
            }data;

            <span style="color: #0000ff">enum</span> Edge_Type
            {
                TUnknown = 0,
                TNot     = 1,
                TChar    = 2,
                TString  = 4
            };

            uchar edge_type;

            DFA_State* pFrom;
            DFA_State* pTo;

            DFA_Edge(<span style="color: #0000ff">const</span> Char_Type&amp; x, <span style="color: #0000ff">bool</span> bNot, DFA_State* pFrom, DFA_State* pTo) : pFrom(pFrom), pTo(pTo)
            {
                data.char_value = x;
                edge_type = bNot ? (TChar | TNot) : TChar;
            }

            DFA_Edge(<span style="color: #0000ff">const</span> String_Type&amp; x, <span style="color: #0000ff">bool</span> bNot, DFA_State* pFrom, DFA_State* pTo) : pFrom(pFrom), pTo(pTo)
            {
                data.string_value = x;
                edge_type = bNot ? (TString | TNot) : TString;
            }

            <span style="color: #0000ff">inline</span> <span style="color: #0000ff">const</span> <span style="color: #0000ff">bool</span> isNot()<span style="color: #0000ff">const</span>
            {
                <span style="color: #0000ff">return</span> (edge_type &amp; TNot) == TNot;
            }

            <span style="color: #0000ff">inline</span> <span style="color: #0000ff">const</span> <span style="color: #0000ff">bool</span> isChar()<span style="color: #0000ff">const</span>
            {
                <span style="color: #0000ff">return</span> (edge_type &amp; TChar) == TChar;
            }

            <span style="color: #0000ff">inline</span> <span style="color: #0000ff">const</span> <span style="color: #0000ff">bool</span> isString()<span style="color: #0000ff">const</span>
            {
                <span style="color: #0000ff">return</span> (edge_type &amp; TString) == TString;
            }

            <span style="color: #0000ff">const</span> Edge_Type edgeType()<span style="color: #0000ff">const</span>
            {
                <span style="color: #0000ff">if</span> (isChar()) <span style="color: #0000ff">return</span> TChar;
                <span style="color: #0000ff">else</span> <span style="color: #0000ff">if</span> (isString()) <span style="color: #0000ff">return</span> TString;
                <span style="color: #0000ff">else</span> <span style="color: #0000ff">return</span> TUnknown;
            }

            <span style="color: #0000ff">const</span> <span style="color: #0000ff">bool</span> <span style="color: #0000ff">operator</span>&lt;(<span style="color: #0000ff">const</span> DFA_Edge&amp; x)<span style="color: #0000ff">const</span>
            {
                <span style="color: #0000ff">return</span> (ulong)pFrom + pTo &lt; (ulong)x.pFrom + x.pTo;
            }

            <span style="color: #0000ff">const</span> <span style="color: #0000ff">bool</span> <span style="color: #0000ff">operator</span>==(<span style="color: #0000ff">const</span> DFA_Edge&amp; x)<span style="color: #0000ff">const</span>
            {
                <span style="color: #0000ff">return</span> pFrom == x.pFrom &amp;&amp; pTo == x.pTo;
            }
        };</pre>
</div>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>由于DFA中不存在&#949;边，应此DFA将会存在若干个结束状态，但他只有一个开始状态</p>

<p>&nbsp;</p>

<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px" class="cnblogs_code">
  <pre>DFA_State*      pDFAStart;
set&lt;DFA_State*&gt; pDFAEnds;
set&lt;DFA_Edge&gt;   dfa_Edges;</pre>
</div>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>为了下一步分析的高效，以后可能会将这里的dfa_Edges同样修改为hashmap。</p>

<p>至此DFA所要用到的两个结构迅速的介绍完了。</p>

<h1>子集构造算法</h1>

<p>通过各种资料，我们不难发现，从&#949;-NFA转换到DFA的过程中，最常用就是子集构造算法。子集构造算法的主要思想是<strong>让DFA的每个状态对应NFA的一个状态集。这个DFA用它的状态去记住NFA在读输入符号后达到的所有状态。</strong>（引自编译原理）其算法如下</p>

<p>&nbsp;</p>

<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px" class="cnblogs_code">
  <pre>输入：一个NFA N。
输出：一个接受同样语言的DFA D。
方法：
1.求取&#949;-NFA初始状态的&#949;闭包作为DFA的起始状态，并将这个状态加入集合C中，且它是未标记的。同时记录它的向后字符集。
2.从集合C中取出一个未被标记的子集T和其对应的字符集，标记子集T。
3.使用上一步取出的字符集通过状态转移函数求出转移后的状态集M。
4.求取上一步得到的状态集M的&#949;闭包U
5.如果U不在集合C中则将U作为未被标记的子集加入C中，同时记录它的向后字符集。检查状态U中是否存在NFA中的终结状态，若存在则将状态U加入到pDFAEnds中。
重复2，3，4，5部直至集合C中不存在未被标记的状态。</pre>
</div>

<h2>&#949;闭包</h2>

<p>&#949;闭包是指从某个状态起只经过&#949;边达到的其他状态的集合，同时这个状态也属于这个集合中。其算法如下</p>

<p>&nbsp;</p>

<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px" class="cnblogs_code">
  <pre>输入：状态集k。
输出：状态集U和其所对应的向后字符集。
方法：
1.遍历状态集k中的每个状态k'。
2.若k'不存在于结果状态集U中，将k'插入U中。
3.建立一个临时集合tmp，并将k'插入其中。
4.从临时集合tmp中取出一个状态p。
5.取出所有从p出发的边，若这条边是&#949;边，且抵达状态不在结果状态集U中，将抵达的状态分别插入结果状态集U和临时集合tmp中。若这条边是字符集的边且这条边所对应的字符不在向后字符集中，则将向后字符插入向后字符集中。
6.将状态p从临时集合tmp中删除。
循环4，5，6部直至tmp中不存在任何状态为止。</pre>
</div>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>由于在生成&#949;-NFA时不存在只有&#949;边的循环，应此这里不会产生死循环。下面给出具体的代码</p>

<p>&nbsp;</p>

<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px" class="cnblogs_code">
  <pre>        <span style="color: #0000ff">void</span> epsilonClosure(<span style="color: #0000ff">const</span> set&lt;EpsilonNFA_State*&gt;&amp; k, EpsilonClosureInfo&amp; info)
        {
            <span style="color: #0000ff">for</span> (<span style="color: #0000ff">typename</span> set&lt;EpsilonNFA_State*&gt;::const_iterator i = k.begin(), m = k.end(); i != m; ++i)
            {
                info.states.insert(*i);
                set&lt;EpsilonNFA_State*&gt; tmp;
                tmp.insert(*i);
                <span style="color: #0000ff">while</span> (!tmp.empty())
                {
                    EpsilonNFA_State* pState = *tmp.begin();
                    <span style="color: #0000ff">for</span> (<span style="color: #0000ff">typename</span> vector&lt;EpsilonNFA_Edge&gt;::const_iterator j = epsilonNFA_Edges[pState].begin(), n = epsilonNFA_Edges[pState].end(); j != n; ++j)
                    {
                        <span style="color: #0000ff">if</span> (j-&gt;isEpsilon())
                        {
                            <span style="color: #0000ff">if</span> (info.states.insert(j-&gt;pTo).second) tmp.insert(j-&gt;pTo);
                        }
                        <span style="color: #0000ff">else</span> <span style="color: #0000ff">if</span> (j-&gt;isChar()) info.chars.insert(pair&lt;Char_Type, <span style="color: #0000ff">bool</span>&gt;(j-&gt;data.char_value, j-&gt;isNot()));
                        <span style="color: #0000ff">else</span> <span style="color: #0000ff">if</span> (j-&gt;isString()) info.strings.insert(pair&lt;String_Type, <span style="color: #0000ff">bool</span>&gt;(j-&gt;data.string_value, j-&gt;isNot()));
                    }
                    tmp.erase(pState);
                }
            }
        }</pre>
</div>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>其中用到的EpsilonClosureInfo结构为</p>

<p>&nbsp;</p>

<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px" class="cnblogs_code">
  <pre>        <span style="color: #0000ff">struct</span> EpsilonClosureInfo
        {
            set&lt;EpsilonNFA_State*&gt;        states;
            set&lt;pair&lt;Char_Type, <span style="color: #0000ff">bool</span>&gt; &gt;   chars;
            set&lt;pair&lt;String_Type, <span style="color: #0000ff">bool</span>&gt; &gt; strings;

            EpsilonClosureInfo() {}

            EpsilonClosureInfo(<span style="color: #0000ff">const</span> set&lt;EpsilonNFA_State*&gt;&amp; states,
                               <span style="color: #0000ff">const</span> set&lt;pair&lt;Char_Type, <span style="color: #0000ff">bool</span>&gt; &gt;&amp; chars,
                               <span style="color: #0000ff">const</span> set&lt;pair&lt;String_Type, <span style="color: #0000ff">bool</span>&gt; &gt;&amp; strings)
                               : states(states)
                               , chars(chars)
                               , strings(strings) {}

            EpsilonClosureInfo(<span style="color: #0000ff">const</span> EpsilonClosureInfo&amp; x)
            {
                states  = x.states;
                chars   = x.chars;
                strings = x.strings;
            }
        };</pre>
</div>

<p>&nbsp;</p>

<p>需要保存的是状态集和向后字符集。</p>

<h2>状态转移函数</h2>

<p>通过状态转移函数，输入一个集合T和一个字符a将可得到所有通过T中的每一个状态和a边所能达到的状态的集合。应此代码如下</p>

<p>&nbsp;</p>

<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px" class="cnblogs_code">
  <pre>        set&lt;EpsilonNFA_State*&gt; move(<span style="color: #0000ff">const</span> DFA_State&amp; t, <span style="color: #0000ff">const</span> Char_Type&amp; c, <span style="color: #0000ff">bool</span> bNot)
        {
            set&lt;EpsilonNFA_State*&gt; result;
            <span style="color: #0000ff">for</span> (<span style="color: #0000ff">typename</span> set&lt;EpsilonNFA_State*&gt;::const_iterator i = t.content.begin(), m = t.content.end(); i != m; ++i)
            {
                <span style="color: #0000ff">for</span> (<span style="color: #0000ff">typename</span> vector&lt;EpsilonNFA_Edge&gt;::const_iterator j = epsilonNFA_Edges[*i].begin(), n = epsilonNFA_Edges[*i].end(); j != n; ++j)
                {
                    <span style="color: #0000ff">if</span> (j-&gt;isChar() &amp;&amp; j-&gt;data.char_value == c &amp;&amp; j-&gt;isNot() == bNot) result.insert(j-&gt;pTo);
                }
            }
            <span style="color: #0000ff">return</span> result;
        }

        set&lt;EpsilonNFA_State*&gt; move(<span style="color: #0000ff">const</span> DFA_State&amp; t, <span style="color: #0000ff">const</span> String_Type&amp; s, <span style="color: #0000ff">bool</span> bNot)
        {
            set&lt;EpsilonNFA_State*&gt; result;
            <span style="color: #0000ff">for</span> (<span style="color: #0000ff">typename</span> set&lt;EpsilonNFA_State*&gt;::const_iterator i = t.content.begin(), m = t.content.end(); i != m; ++i)
            {
                <span style="color: #0000ff">for</span> (<span style="color: #0000ff">typename</span> vector&lt;EpsilonNFA_Edge&gt;::const_iterator j = epsilonNFA_Edges[*i].begin(), n = epsilonNFA_Edges[*i].end(); j != n; ++j)
                {
                    <span style="color: #0000ff">if</span> (j-&gt;isString() &amp;&amp; j-&gt;data.string_value == s &amp;&amp; j-&gt;isNot() == bNot) result.insert(j-&gt;pTo);
                }
            }
            <span style="color: #0000ff">return</span> result;
        }</pre>
</div>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>为了分别支持Char_Type和String_Type的字符我们定义了两个move函数。</p>

<p>最后我们给出子集构造算法的代码</p>

<p>&nbsp;</p>

<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px" class="cnblogs_code">
  <pre>        <span style="color: #0000ff">void</span> buildDFA()
        {
            set&lt;EpsilonNFA_State*&gt; start;
            start.insert(pEpsilonStart);

            <span style="color: #0000ff">typedef</span> pair&lt;DFA_State*, EpsilonClosureInfo&gt; c_type;

            map&lt;size_t, list&lt;c_type&gt; &gt; c;
            queue&lt;c_type&gt; 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);

            <span style="color: #0000ff">if</span> (isEndDFAStatus(pDFAStart)) pDFAEnds.insert(pDFAStart);
            context.dfa_States.insert(pDFAStart);

            <span style="color: #0000ff">while</span> (!c2.empty())
            {
                DFA_State* t = c2.front().first;
                set&lt;pair&lt;Char_Type, <span style="color: #0000ff">bool</span>&gt; &gt; chars = c2.front().second.chars;
                set&lt;pair&lt;String_Type, <span style="color: #0000ff">bool</span>&gt; &gt; strings = c2.front().second.strings;
                t-&gt;bFlag = <span style="color: #0000ff">true</span>;

                <span style="color: #0000ff">for</span> (<span style="color: #0000ff">typename</span> set&lt;pair&lt;Char_Type, <span style="color: #0000ff">bool</span>&gt; &gt;::const_iterator i = chars.begin(), m = chars.end(); i != m; ++i)
                {
                    EpsilonClosureInfo info;
                    epsilonClosure(move(*t, i-&gt;first, i-&gt;second), info);

                    DFA_State* p = getDFAState(info.states, c);
                    <span style="color: #0000ff">if</span> (p) <span style="color: #008000">// 如果这个状态已存在</span>
                    {
                        dfa_Edges.insert(DFA_Edge(i-&gt;first, i-&gt;second, t, p));
                    }
                    <span style="color: #0000ff">else</span>
                    {
                        DFA_State* pState = DFA_State_Alloc::allocate();
                        construct(pState, info.states);
                        context.dfa_States.insert(pState);

                        <span style="color: #0000ff">if</span> (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-&gt;first, i-&gt;second, t, pState));
                    }
                }

                <span style="color: #0000ff">for</span> (<span style="color: #0000ff">typename</span> set&lt;pair&lt;String_Type, <span style="color: #0000ff">bool</span>&gt; &gt;::const_iterator i = strings.begin(), m = strings.end(); i != m; ++i)
                {
                    EpsilonClosureInfo info;
                    epsilonClosure(move(*t, i-&gt;first, i-&gt;second), info);

                    DFA_State* p = getDFAState(info.states, c);
                    <span style="color: #0000ff">if</span> (p) <span style="color: #008000">// 如果这个状态已存在</span>
                    {
                        dfa_Edges.insert(DFA_Edge(i-&gt;first, i-&gt;second, t, p));
                    }
                    <span style="color: #0000ff">else</span>
                    {
                        DFA_State* pState = DFA_State_Alloc::allocate();
                        construct(pState, info.states);
                        context.dfa_States.insert(pState);

                        <span style="color: #0000ff">if</span> (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-&gt;first, i-&gt;second, t, pState));
                    }
                }
                c2.pop();
            }
        }</pre>
</div>

<p>&nbsp;</p>

<p>&nbsp;</p>

<h1>尾声</h1>

<p>同样我们来编写一个函数来打印出DFA。</p>

<p>&nbsp;</p>

<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px" class="cnblogs_code">
  <pre>        <span style="color: #0000ff">void</span> printDFA()
        {
            printf("<span style="color: #8b0000">---------- DFA Start ----------\n</span>");
            set&lt;DFA_State*&gt; tmp;
            <span style="color: #0000ff">for</span> (<span style="color: #0000ff">typename</span> set&lt;DFA_Edge&gt;::const_iterator i = dfa_Edges.begin(), m = dfa_Edges.end(); i != m; ++i)
            {
                printf("<span style="color: #8b0000">%03d -&gt; %03d</span>", i-&gt;pFrom-&gt;idx, i-&gt;pTo-&gt;idx);
                <span style="color: #0000ff">switch</span> (i-&gt;edgeType())
                {
                <span style="color: #0000ff">case</span> DFA_Edge::TChar:
                    printf("<span style="color: #8b0000">(%c)</span>", i-&gt;data.char_value);
                    <span style="color: #0000ff">break</span>;
                <span style="color: #0000ff">case</span> DFA_Edge::TString:
                    printf("<span style="color: #8b0000">(%s)</span>", i-&gt;data.string_value.c_str());
                    <span style="color: #0000ff">break</span>;
                <span style="color: #0000ff">default</span>:
                    <span style="color: #0000ff">break</span>;
                }
                <span style="color: #0000ff">if</span> (i-&gt;isNot()) printf("<span style="color: #8b0000">(not)</span>");
                printf("<span style="color: #8b0000">\n</span>");
                tmp.insert(i-&gt;pFrom);
                tmp.insert(i-&gt;pTo);
            }

            printf("<span style="color: #8b0000">start: %03d -&gt; ends: </span>", pDFAStart-&gt;idx);
            <span style="color: #0000ff">for</span> (<span style="color: #0000ff">typename</span> set&lt;DFA_State*&gt;::const_iterator i = pDFAEnds.begin(), m = pDFAEnds.end(); i != m; ++i)
            {
                printf("<span style="color: #8b0000">%03d </span>", (*i)-&gt;idx);
            }
            printf("<span style="color: #8b0000">\n</span>");
#<span style="color: #0000ff">if</span> DEBUG_LEVEL == 3
            printf("<span style="color: #8b0000">-------------------------------\n</span>");

            <span style="color: #0000ff">for</span> (<span style="color: #0000ff">typename</span> set&lt;DFA_State*&gt;::const_iterator i = tmp.begin(), m = tmp.end(); i != m; ++i)
            {
                printf("<span style="color: #8b0000">State: %03d\n</span>", (*i)-&gt;idx);
                <span style="color: #0000ff">for</span> (<span style="color: #0000ff">typename</span> set&lt;EpsilonNFA_State*&gt;::const_iterator j = (*i)-&gt;content.begin(), n = (*i)-&gt;content.end(); j != n; ++j)
                {
                    printf("<span style="color: #8b0000">%03d </span>", (*j)-&gt;idx);
                }
                printf("<span style="color: #8b0000">\n</span>");
            }
#endif
            printf("<span style="color: #8b0000">----------- DFA End -----------\n</span>");
        }</pre>
</div>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>最后我们加入测试代码</p>

<p>&nbsp;</p>

<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px" class="cnblogs_code">
  <pre>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</pre>
</div>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>可打印出如下内容</p>

<p><a href="http://www.cppblog.com/images/cppblog_com/lwch/WindowsLiveWriter/2NFADFA_14AC0/DFA_2.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="DFA" border="0" alt="DFA" src="http://www.cppblog.com/images/cppblog_com/lwch/WindowsLiveWriter/2NFADFA_14AC0/DFA_thumb.png" width="504" height="484" /></a> </p>

<p>画成图如下</p>

<p><a href="http://www.cppblog.com/images/cppblog_com/lwch/WindowsLiveWriter/2NFADFA_14AC0/DFA%E5%9B%BE_2.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="DFA图" border="0" alt="DFA图" src="http://www.cppblog.com/images/cppblog_com/lwch/WindowsLiveWriter/2NFADFA_14AC0/DFA%E5%9B%BE_thumb.png" width="366" height="484" /></a> </p>

<p>完整的代码可到<a href="http://code.google.com/p/qlanguage" target="_blank">http://code.google.com/p/qlanguage</a>下载</p><img src ="http://www.cppblog.com/lwch/aggbug/198043.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2013-02-23 23:30 <a href="http://www.cppblog.com/lwch/archive/2013/02/23/198043.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>词法分析器1(正则表达式到&amp;epsilon;-NFA的转换)</title><link>http://www.cppblog.com/lwch/archive/2013/02/15/197848.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Fri, 15 Feb 2013 12:29:00 GMT</pubDate><guid>http://www.cppblog.com/lwch/archive/2013/02/15/197848.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/197848.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2013/02/15/197848.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/197848.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lwch/services/trackbacks/197848.html</trackback:ping><description><![CDATA[<h1>自动机</h1>
<p>关于自动机的说明，这里不不再复述，请到<a href="http://zh.wikipedia.org/wiki/自动机" target="_blank">http://zh.wikipedia.org/wiki/自动机</a>查看。</p>
<h1>表达式</h1>
<p>首先，我们规定表达式中只允许输入Char_Type和String_Type类型的字符。</p>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px" class="cnblogs_code">
<pre>template &lt;typename Char_Type, typename String_Type&gt;
<span style="color: #0000ff">class</span><span style="color: #000000"> Rule
{
};</span></pre>
</div>
<p>&nbsp;</p>
<h1>&#949;-NFA的状态</h1>
<p>对于一个状态来说，我们并不需要知道他的任何信息</p>
<p>在上面的代码中，为了调试方便，我为其加入了idx域，并为每个状态分配了一个唯一的ID。</p>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px" class="cnblogs_code">
<pre> <span style="color: #0000ff">struct</span><span style="color: #000000"> EpsilonNFA_State
{
#ifdef _DEBUG
</span><span style="color: #0000ff">uint</span><span style="color: #000000"> idx;
EpsilonNFA_State()
{
idx </span>=<span style="color: #000000"> inc();
}
</span><span style="color: #0000ff">static</span> <span style="color: #0000ff">uint</span><span style="color: #000000"> inc()
{
</span><span style="color: #0000ff">static</span> <span style="color: #0000ff">uint</span> i = <span style="color: #800080">0</span><span style="color: #000000">;
</span><span style="color: #0000ff">return</span> i++<span style="color: #000000">;
}
</span><span style="color: #0000ff">#else</span><span style="color: #000000">
EpsilonNFA_State() {}
</span><span style="color: #0000ff">#endif</span><span style="color: #000000">
};</span></pre>
</div>
<h1>&#949;-NFA的边</h1>
<p>&#949;-NFA中的边都是有向的。对于任意一条边来说，最重要的是他的两个端点是谁以及这条边所对应的字符集（若这条边不是&#949;边）。</p>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px" class="cnblogs_code">
<pre> <span style="color: #0000ff">struct</span><span style="color: #000000"> EpsilonNFA_Edge
{
</span><span style="color: #0000ff">struct</span><span style="color: #000000">
{
Char_Type char_value;
String_Type string_value;
}data;
</span><span style="color: #0000ff">enum</span><span style="color: #000000"> Edge_Type
{
TUnknown </span>= <span style="color: #800080">0</span><span style="color: #000000">,
TNot </span>= <span style="color: #800080">1</span><span style="color: #000000">,
TChar </span>= <span style="color: #800080">2</span><span style="color: #000000">,
TString </span>= <span style="color: #800080">4</span><span style="color: #000000">,
TEpsilon </span>= <span style="color: #800080">8</span><span style="color: #000000">
};
uchar edge_type;
EpsilonNFA_State</span>*<span style="color: #000000"> pFrom;
EpsilonNFA_State</span>*<span style="color: #000000"> pTo;
EpsilonNFA_Edge(EpsilonNFA_State</span>* pFrom, EpsilonNFA_State*<span style="color: #000000"> pTo) : edge_type(TEpsilon), pFrom(pFrom), pTo(pTo) {}
EpsilonNFA_Edge(</span><span style="color: #0000ff">const</span> Char_Type&amp; x, EpsilonNFA_State* pFrom, EpsilonNFA_State*<span style="color: #000000"> pTo) : edge_type(TChar), pFrom(pFrom), pTo(pTo)
{
data.char_value </span>=<span style="color: #000000"> x;
}
EpsilonNFA_Edge(</span><span style="color: #0000ff">const</span> String_Type&amp; x, EpsilonNFA_State* pFrom, EpsilonNFA_State*<span style="color: #000000"> pTo) : edge_type(TString), pFrom(pFrom), pTo(pTo)
{
data.string_value </span>=<span style="color: #000000"> x;
}
inline </span><span style="color: #0000ff">void</span><span style="color: #000000"> negate()
{
edge_type </span>^=<span style="color: #000000"> TNot;
}
inline </span><span style="color: #0000ff">const</span> <span style="color: #0000ff">bool</span> isNot()<span style="color: #0000ff">const</span><span style="color: #000000">
{
</span><span style="color: #0000ff">return</span> (edge_type &amp; TNot) ==<span style="color: #000000"> TNot;
}
inline </span><span style="color: #0000ff">const</span> <span style="color: #0000ff">bool</span> isEpsilon()<span style="color: #0000ff">const</span><span style="color: #000000">
{
</span><span style="color: #0000ff">return</span> (edge_type &amp; TEpsilon) ==<span style="color: #000000"> TEpsilon;
}
inline </span><span style="color: #0000ff">const</span> <span style="color: #0000ff">bool</span> isChar()<span style="color: #0000ff">const</span><span style="color: #000000">
{
</span><span style="color: #0000ff">return</span> (edge_type &amp; TChar) ==<span style="color: #000000"> TChar;
}
inline </span><span style="color: #0000ff">const</span> <span style="color: #0000ff">bool</span> isString()<span style="color: #0000ff">const</span><span style="color: #000000">
{
</span><span style="color: #0000ff">return</span> (edge_type &amp; TString) ==<span style="color: #000000"> TString;
}
</span><span style="color: #0000ff">const</span> Edge_Type edgeType()<span style="color: #0000ff">const</span><span style="color: #000000">
{
</span><span style="color: #0000ff">if</span> (isEpsilon()) <span style="color: #0000ff">return</span><span style="color: #000000"> TEpsilon;
</span><span style="color: #0000ff">else</span> <span style="color: #0000ff">if</span> (isChar()) <span style="color: #0000ff">return</span><span style="color: #000000"> TChar;
</span><span style="color: #0000ff">else</span> <span style="color: #0000ff">if</span> (isString()) <span style="color: #0000ff">return</span><span style="color: #000000"> TString;
</span><span style="color: #0000ff">else</span> <span style="color: #0000ff">return</span><span style="color: #000000"> TUnknown;
}
};</span></pre>
</div>
<p>有了以上两个结构之后，我们为Rule添加三个成员变量</p>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px" class="cnblogs_code">
<pre>EpsilonNFA_State *pEpsilonStart, *<span style="color: #000000">pEpsilonEnd;
hashmap</span>&lt;EpsilonNFA_State*, vector&lt;EpsilonNFA_Edge&gt;, _hash&gt; epsilonNFA_Edges;</pre>
</div>
<p>&nbsp;</p>
<p>pEpsilonStart和pEpsilonEnd分别表示这条表达式所对应状态机的start和end状态，epsilonNFA_Edges则是以某个状态作为key，从这个状态到达另一个状态所经过的边作为value的hash表。</p>
<h1>生成状态机</h1>
<p>终于到了正题，首先，我们把所有的关系分为串联关系、并联关系、可选关系、0次及以上的重复关系、至少1次以上的重复关系和取反关系。下面分别介绍每种关系的&#949;-NFA如何来生成。（<strong>下文中若没有指出连接边的类型则是&#949;边</strong>）</p>
<h2>字符集</h2>
<p>正如上文所说，字符集包括Char_Type和String_Type类型的字符，应此生成字符集的状态机就比较简单了，只需创建出两个状态，然后通过一条经过这个字符集的边将这两个状态按照某个方向连接，最后将一个状态标记为start状态，另一个状态标记为end状态即可。</p>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px" class="cnblogs_code">
<pre> Rule(<span style="color: #0000ff">const</span> Char_Type&amp; x, Context&amp;<span style="color: #000000"> context) : pDFAStart(NULL), context(context)
{
pEpsilonStart </span>=<span style="color: #000000"> EpsilonNFA_State_Alloc::allocate();
construct(pEpsilonStart);
pEpsilonEnd </span>=<span style="color: #000000"> 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(</span><span style="color: #0000ff">const</span> String_Type&amp; x, Context&amp;<span style="color: #000000"> context) : pDFAStart(NULL), context(context)
{
pEpsilonStart </span>=<span style="color: #000000"> EpsilonNFA_State_Alloc::allocate();
construct(pEpsilonStart);
pEpsilonEnd </span>=<span style="color: #000000"> 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);
}</span></pre>
</div>
<h2>串联关系</h2>
<p>串联关系中，只需要将前一个状态机的end状态通过&#949;边连接到另一个状态机的start状态，最后将前一个状态的start状态标记为新状态机的start状态，后一个状态机的end状态标记为新状态机的end状态即可。</p>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px" class="cnblogs_code">
<pre> self <span style="color: #0000ff">operator</span>+(<span style="color: #0000ff">const</span> self&amp;<span style="color: #000000"> x)
{
self a </span>= cloneEpsilonNFA(*<span style="color: #0000ff">this</span>), b =<span style="color: #000000"> cloneEpsilonNFA(x);
copyEpsilonNFA_Edges(b, a);
a.epsilonNFA_Edges[a.pEpsilonEnd].push_back(EpsilonNFA_Edge(a.pEpsilonEnd, b.pEpsilonStart));
a.pEpsilonEnd </span>=<span style="color: #000000"> b.pEpsilonEnd;
</span><span style="color: #0000ff">return</span><span style="color: #000000"> a;
}</span></pre>
</div>
<p>&nbsp;</p>
<h2>并联关系</h2>
<p>并联关系中，需要分别新建一个start和end状态做为新状态机的start和end状态，然后将新生成的start状态分别连接到原状态机的start状态，原状态机的end状态连接到新生成的end状态即可。</p>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px" class="cnblogs_code">
<pre> self <span style="color: #0000ff">operator</span>|(<span style="color: #0000ff">const</span> self&amp;<span style="color: #000000"> x)
{
self a </span>= cloneEpsilonNFA(*<span style="color: #0000ff">this</span>), b =<span style="color: #000000"> cloneEpsilonNFA(x);
copyEpsilonNFA_Edges(b, a);
EpsilonNFA_State</span>* _pStart =<span style="color: #000000"> EpsilonNFA_State_Alloc::allocate();
construct(_pStart);
EpsilonNFA_State</span>* _pEnd =<span style="color: #000000"> 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 </span>=<span style="color: #000000"> _pStart;
a.pEpsilonEnd </span>=<span style="color: #000000"> _pEnd;
</span><span style="color: #0000ff">return</span><span style="color: #000000"> a;
}</span></pre>
</div>
<h2>重复关系</h2>
<p>在正则表达式中存在形如(a)+和(a)*的两种重复关系，对于这两种重复关系，生成的状态机的区别仅在于end状态对于一次以上的重复，只需要给原状态机添加一条从end状态到start状态的&#949;边即可。而对于零次以上的重复，不光需要添加&#949;边，同时需要将新状态机的end状态标记为start状态，因为零次重复时不需要经过任意边既可被接受。</p>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px" class="cnblogs_code">
<pre> self <span style="color: #0000ff">operator</span>*<span style="color: #000000">()
{
self a </span>= cloneEpsilonNFA(*<span style="color: #0000ff">this</span><span style="color: #000000">);
a.epsilonNFA_Edges.insert(EpsilonNFA_Edge(a.pEpsilonEnd, a.pEpsilonStart));
a.pEpsilonEnd </span>=<span style="color: #000000"> a.pEpsilonStart;
</span><span style="color: #0000ff">return</span><span style="color: #000000"> a;
}
self </span><span style="color: #0000ff">operator</span>+<span style="color: #000000">()
{
self a </span>= cloneEpsilonNFA(*<span style="color: #0000ff">this</span><span style="color: #000000">);
a.epsilonNFA_Edges[a.pEpsilonEnd].push_back(EpsilonNFA_Edge(a.pEpsilonEnd, a.pEpsilonStart));
</span><span style="color: #0000ff">return</span><span style="color: #000000"> a;
}</span></pre>
</div>
<p>上面这三种是最基本的生成方法，通过以上这三种生成方法已足够应付多数的表达式。</p>
<h1>一些拓展</h1>
<p>下面来看看一些拓展形式的状态机是如何生成的。</p>
<h2>可选关系</h2>
<p>在可选关系中，只需要给原状态机添加一条从start状态到end状态的&#949;边即可。由于&#949;-NFA只允许有一个start和end状态的关系，应此当条件不成立时从start状态就可直接通过&#949;边到达end状态。</p>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px" class="cnblogs_code">
<pre> <span style="color: #000000">inline self opt()
{
self a </span>= cloneEpsilonNFA(*<span style="color: #0000ff">this</span><span style="color: #000000">);
a.epsilonNFA_Edges[a.pEpsilonStart].push_back(EpsilonNFA_Edge(a.pEpsilonStart, a.pEpsilonEnd));
</span><span style="color: #0000ff">return</span><span style="color: #000000"> a;
}</span></pre>
</div>
<p>&nbsp;</p>
<h2>取反关系</h2>
<p>由于我们只处理Char_Type和String_Type类型的字符集，应此对于取反我们只需要将当前状态机内所有类型为TChar或TString类型的边取一下反即可（<strong>需要注意的是可能存在负负得正的情况，既取偶数次反等于没取反</strong>）</p>
<p>&nbsp;</p>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px" class="cnblogs_code">
<pre> self <span style="color: #0000ff">operator</span>!<span style="color: #000000">()
{
self a </span>= cloneEpsilonNFA(*<span style="color: #0000ff">this</span><span style="color: #000000">);
</span><span style="color: #0000ff">for</span> (typename hashmap&lt;EpsilonNFA_State*, vector&lt;EpsilonNFA_Edge&gt;, _hash&gt;::iterator i = a.epsilonNFA_Edges.begin(), m = a.epsilonNFA_Edges.end(); i != m; ++<span style="color: #000000">i)
{
</span><span style="color: #0000ff">for</span> (typename vector&lt;EpsilonNFA_Edge&gt;::iterator j = i-&gt;second.begin(), n = i-&gt;second.end(); j != n; ++<span style="color: #000000">j)
{
</span><span style="color: #0000ff">if</span> (j-&gt;isChar() || j-&gt;isString()) j-&gt;<span style="color: #000000">negate();
}
}
</span><span style="color: #0000ff">return</span><span style="color: #000000"> a;
}</span></pre>
</div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h2></h2>
<h2>Char-Char关系</h2>
<p>所谓的char-char关系就是正则表达式中的[a-z]表达式。其实这是一种并联关系的拓展，由两个原始状态机拓展到了N个，生成方法也类似。</p>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px" class="cnblogs_code">
<pre> self <span style="color: #0000ff">operator</span>-(<span style="color: #0000ff">const</span> self&amp;<span style="color: #000000"> x)
{
self a </span>= cloneEpsilonNFA(*<span style="color: #0000ff">this</span><span style="color: #000000">);
</span><span style="color: #0000ff">if</span> (epsilonNFA_Edges.size() == <span style="color: #800080">1</span> &amp;&amp; x.epsilonNFA_Edges.size() == <span style="color: #800080">1</span> &amp;&amp;<span style="color: #000000">
epsilonNFA_Edges.begin()</span>-&gt;second.size() == <span style="color: #800080">1</span> &amp;&amp; x.epsilonNFA_Edges.begin()-&gt;second.size() == <span style="color: #800080">1</span> &amp;&amp;<span style="color: #000000">
epsilonNFA_Edges.begin()</span>-&gt;second.begin()-&gt;edge_type == EpsilonNFA_Edge::TChar &amp;&amp; x.epsilonNFA_Edges.begin()-&gt;second.begin()-&gt;edge_type ==<span style="color: #000000"> EpsilonNFA_Edge::TChar)
{
EpsilonNFA_State</span>* _pStart =<span style="color: #000000"> EpsilonNFA_State_Alloc::allocate();
construct(_pStart);
EpsilonNFA_State</span>* _pEnd =<span style="color: #000000"> 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));
</span><span style="color: #0000ff">const</span> Char_Type chStart = epsilonNFA_Edges.begin()-&gt;second.begin()-&gt;<span style="color: #000000">data.char_value;
</span><span style="color: #0000ff">const</span> Char_Type chEnd = x.epsilonNFA_Edges.begin()-&gt;second.begin()-&gt;<span style="color: #000000">data.char_value;
</span><span style="color: #0000ff">for</span> (Char_Type ch = chStart + <span style="color: #800080">1</span>; ch &lt; chEnd; ++<span style="color: #000000">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 </span>=<span style="color: #000000"> 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 </span>=<span style="color: #000000"> _pStart;
a.pEpsilonEnd </span>=<span style="color: #000000"> _pEnd;
}
</span><span style="color: #0000ff">else</span><span style="color: #000000">
{
</span><span style="color: #0000ff">throw</span> error&lt;<span style="color: #0000ff">string</span>&gt;(<span style="color: #800000">"</span><span style="color: #800000">doesn't support</span><span style="color: #800000">"</span><span style="color: #000000">, __FILE__, __LINE__);
}
</span><span style="color: #0000ff">return</span><span style="color: #000000"> a;
}</span></pre>
</div>
<h1>尾声</h1>
<p>让我们来编写一个函数来打印出整个生成后的状态机。</p>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px" class="cnblogs_code">
<pre> <span style="color: #0000ff">void</span><span style="color: #000000"> printEpsilonNFA()
{
printf(</span><span style="color: #800000">"</span><span style="color: #800000">-------- &#949;- NFA Start --------\n</span><span style="color: #800000">"</span><span style="color: #000000">);
</span><span style="color: #0000ff">for</span> (typename hashmap&lt;EpsilonNFA_State*, vector&lt;EpsilonNFA_Edge&gt;, _hash&gt;::const_iterator i = epsilonNFA_Edges.begin(), m = epsilonNFA_Edges.end(); i != m; ++<span style="color: #000000">i)
{
</span><span style="color: #0000ff">for</span> (typename vector&lt;EpsilonNFA_Edge&gt;::const_iterator j = i-&gt;second.begin(), n = i-&gt;second.end(); j != n; ++<span style="color: #000000">j)
{
printf(</span><span style="color: #800000">"</span><span style="color: #800000">%03d -&gt; %03d</span><span style="color: #800000">"</span>, j-&gt;pFrom-&gt;idx, j-&gt;pTo-&gt;<span style="color: #000000">idx);
</span><span style="color: #0000ff">switch</span> (j-&gt;<span style="color: #000000">edgeType())
{
</span><span style="color: #0000ff">case</span><span style="color: #000000"> EpsilonNFA_Edge::TEpsilon:
printf(</span><span style="color: #800000">"</span><span style="color: #800000">(&#949;)</span><span style="color: #800000">"</span><span style="color: #000000">);
</span><span style="color: #0000ff">break</span><span style="color: #000000">;
</span><span style="color: #0000ff">case</span><span style="color: #000000"> EpsilonNFA_Edge::TChar:
printf(</span><span style="color: #800000">"</span><span style="color: #800000">(%c)</span><span style="color: #800000">"</span>, j-&gt;<span style="color: #000000">data.char_value);
</span><span style="color: #0000ff">break</span><span style="color: #000000">;
</span><span style="color: #0000ff">case</span><span style="color: #000000"> EpsilonNFA_Edge::TString:
printf(</span><span style="color: #800000">"</span><span style="color: #800000">(%s)</span><span style="color: #800000">"</span>, j-&gt;<span style="color: #000000">data.string_value.c_str());
</span><span style="color: #0000ff">break</span><span style="color: #000000">;
</span><span style="color: #0000ff">default</span><span style="color: #000000">:
</span><span style="color: #0000ff">break</span><span style="color: #000000">;
}
</span><span style="color: #0000ff">if</span> (j-&gt;isNot()) printf(<span style="color: #800000">"</span><span style="color: #800000">(not)</span><span style="color: #800000">"</span><span style="color: #000000">);
printf(</span><span style="color: #800000">"</span><span style="color: #800000">\n</span><span style="color: #800000">"</span><span style="color: #000000">);
}
}
printf(</span><span style="color: #800000">"</span><span style="color: #800000">start: %03d -&gt; end: %03d\n</span><span style="color: #800000">"</span>, pEpsilonStart-&gt;idx, pEpsilonEnd-&gt;<span style="color: #000000">idx);
printf(</span><span style="color: #800000">"</span><span style="color: #800000">--------- &#949;- NFA End ---------\n</span><span style="color: #800000">"</span><span style="color: #000000">);
}</span></pre>
</div>
<p>&nbsp;</p>
<p>最后我们来编写一些测试代码来试试生成效果如何</p>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px" class="cnblogs_code">
<pre><span style="color: #000000">Rule_Type::Context context;
Rule_Type a(</span><span style="color: #800000">'</span><span style="color: #800000">a</span><span style="color: #800000">'</span>, context), b(<span style="color: #800000">'</span><span style="color: #800000">b</span><span style="color: #800000">'</span>, context), d(<span style="color: #800000">'</span><span style="color: #800000">d</span><span style="color: #800000">'</span><span style="color: #000000">, context);
Rule_Type result </span>= (a - d).opt() + (+b | !(a +<span style="color: #000000"> b));
#ifdef _DEBUG
result.printEpsilonNFA();
</span><span style="color: #0000ff">#endif</span></pre>
</div>
<p>可打印出如下内容</p>
<p><a href="http://www.cppblog.com/images/cppblog_com/lwch/WindowsLiveWriter/1NFA_12DF6/%E7%8A%B6%E6%80%81%E6%9C%BA_2.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="状态机" border="0" alt="状态机" src="http://www.cppblog.com/images/cppblog_com/lwch/WindowsLiveWriter/1NFA_12DF6/%E7%8A%B6%E6%80%81%E6%9C%BA_thumb.png" width="681" height="510" /></a> </p>
<p>最后形成形如下图的状态机</p>
<p><a href="http://www.cppblog.com/images/cppblog_com/lwch/WindowsLiveWriter/1NFA_12DF6/%E7%8A%B6%E6%80%81%E6%9C%BA%E5%9B%BE_2.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="状态机图" border="0" alt="状态机图" src="http://www.cppblog.com/images/cppblog_com/lwch/WindowsLiveWriter/1NFA_12DF6/%E7%8A%B6%E6%80%81%E6%9C%BA%E5%9B%BE_thumb.png" width="644" height="336" /></a> </p>
<p>完整的代码可到<a href="http://code.google.com/p/qlanguage" target="_blank">http://code.google.com/p/qlanguage</a>下载。</p><img src ="http://www.cppblog.com/lwch/aggbug/197848.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2013-02-15 20:29 <a href="http://www.cppblog.com/lwch/archive/2013/02/15/197848.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>修复了一个关于CParser_Input的Bug</title><link>http://www.cppblog.com/lwch/archive/2011/07/10/150615.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Sun, 10 Jul 2011 14:13:00 GMT</pubDate><guid>http://www.cppblog.com/lwch/archive/2011/07/10/150615.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/150615.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2011/07/10/150615.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/150615.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lwch/services/trackbacks/150615.html</trackback:ping><description><![CDATA[<div>我们先了看下Alt组合子的分析代码 
<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"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">&nbsp;1</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">virtual</span><span style="color: #000000">&nbsp;O&nbsp;Parser(I</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;input)<br /></span><span style="color: #008080">&nbsp;2</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080">&nbsp;3</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;I&nbsp;temp&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;input;<br /></span><span style="color: #008080">&nbsp;4</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(O&nbsp;Result&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;left.Parser(input))&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;Result;<br /></span><span style="color: #008080">&nbsp;5</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;input&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;temp;<br /></span><span style="color: #008080">&nbsp;6</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(O&nbsp;Result&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;right.Parser(input))&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;Result;<br /></span><span style="color: #008080">&nbsp;7</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;input&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;temp;<br /></span><span style="color: #008080">&nbsp;8</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;O&nbsp;Result(GetMM());<br /></span><span style="color: #008080">&nbsp;9</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;Result;<br /></span><span style="color: #008080">10</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>当left分析失败时会将原先的input值重新赋值给input,但此时并没有改变SymbolStack和StringStack,应此当第一次分析失败时SymbolStack和StringStack中会包含一些重复的值.当然其他组合子同样存在这个问题.<br />应此我为CParser_Input增加了两个成员变量保存此时的SymbolStack和StringStack的Size,当SymbolStack和StringStack Push的时候同时增加input相应的值.<br />最后重载CParser_Input的operator=赋值操作符,在其中根据原先的SymbolStack和StringStack的Size来弹出相应数量的重复值<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"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">&nbsp;1</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;CParser_Input</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">operator</span><span style="color: #000000">=</span><span style="color: #000000">(CParser_Input</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;_value)<br /></span><span style="color: #008080">&nbsp;2</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080">&nbsp;3</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LexerTokenList&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;_value.LexerTokenList;<br /></span><span style="color: #008080">&nbsp;4</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;index&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;_value.index;<br /></span><span style="color: #008080">&nbsp;5</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080">&nbsp;6</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(_value.symbolCount&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;symbolCount&nbsp;</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">&nbsp;_value.symbolCount)<br /></span><span style="color: #008080">&nbsp;7</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080">&nbsp;8</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;Count&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;symbolCount&nbsp;</span><span style="color: #000000">-</span><span style="color: #000000">&nbsp;_value.symbolCount;<br /></span><span style="color: #008080">&nbsp;9</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;i</span><span style="color: #000000">=</span><span style="color: #000000">0</span><span style="color: #000000">;i</span><span style="color: #000000">&lt;</span><span style="color: #000000">Count;i</span><span style="color: #000000">++</span><span style="color: #000000">)&nbsp;SymbolStack.Pop();<br /></span><span style="color: #008080">10</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080">11</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080">12</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(_value.stringCount&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;stringCount&nbsp;</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">&nbsp;_value.stringCount)<br /></span><span style="color: #008080">13</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080">14</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;Count&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;stringCount&nbsp;</span><span style="color: #000000">-</span><span style="color: #000000">&nbsp;_value.stringCount;<br /></span><span style="color: #008080">15</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;i</span><span style="color: #000000">=</span><span style="color: #000000">0</span><span style="color: #000000">;i</span><span style="color: #000000">&lt;</span><span style="color: #000000">Count;i</span><span style="color: #000000">++</span><span style="color: #000000">)&nbsp;StringStack.Pop();<br /></span><span style="color: #008080">16</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080">17</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080">18</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;symbolCount&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;SymbolStack.Size();<br /></span><span style="color: #008080">19</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stringCount&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;StringStack.Size();<br /></span><span style="color: #008080">20</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #0000ff">this</span><span style="color: #000000">;<br /></span><span style="color: #008080">21</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}</span></div></div>以此来解决SymbolStack和StringStack的同步问题.<img src ="http://www.cppblog.com/lwch/aggbug/150615.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2011-07-10 22:13 <a href="http://www.cppblog.com/lwch/archive/2011/07/10/150615.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>QLanguage的AST</title><link>http://www.cppblog.com/lwch/archive/2011/07/01/149941.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Fri, 01 Jul 2011 13:51:00 GMT</pubDate><guid>http://www.cppblog.com/lwch/archive/2011/07/01/149941.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/149941.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2011/07/01/149941.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/149941.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lwch/services/trackbacks/149941.html</trackback:ping><description><![CDATA[QLanguage开源项目地址：<a href="http://qlanguage.codeplex.com" target="_blank">http://qlanguage.codeplex.com</a><br /><br />1.AST的每个节点由2个域组成,这2个域分别表示当前节点的类型和附加信息。<br />2.AST的每个节点包含一个指向其子节点的顺序表。<br />3.AST的每个节点包含指向下一个节点的指针。<br />综上所述我们得到AST节点的代码： 
<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"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">&nbsp;1</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;CSyntaxTreeNode<br /></span><span style="color: #008080">&nbsp;2</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080">&nbsp;3</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">:<br /></span><span style="color: #008080">&nbsp;4</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CSyntaxTreeNode(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;_type,</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;_value)&nbsp;:&nbsp;type(_type),value(_value){}<br /></span><span style="color: #008080">&nbsp;5</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080">&nbsp;6</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;List</span><span style="color: #000000">&lt;</span><span style="color: #000000">NAutoPtr</span><span style="color: #000000">&lt;</span><span style="color: #000000">CSyntaxTreeNode</span><span style="color: #000000">&gt;&gt;&amp;</span><span style="color: #000000">&nbsp;Child()<br /></span><span style="color: #008080">&nbsp;7</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080">&nbsp;8</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;child;<br /></span><span style="color: #008080">&nbsp;9</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080">10</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080">11</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;NAutoPtr</span><span style="color: #000000">&lt;</span><span style="color: #000000">CSyntaxTreeNode</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;Next()<br /></span><span style="color: #008080">12</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080">13</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;next;<br /></span><span style="color: #008080">14</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080">15</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080">16</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;Type()<br /></span><span style="color: #008080">17</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080">18</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;type;<br /></span><span style="color: #008080">19</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080">20</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080">21</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;Value()<br /></span><span style="color: #008080">22</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080">23</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;value;<br /></span><span style="color: #008080">24</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080">25</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">protected</span><span style="color: #000000">:<br /></span><span style="color: #008080">26</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;type;<br /></span><span style="color: #008080">27</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;value;<br /></span><span style="color: #008080">28</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List</span><span style="color: #000000">&lt;</span><span style="color: #000000">NAutoPtr</span><span style="color: #000000">&lt;</span><span style="color: #000000">CSyntaxTreeNode</span><span style="color: #000000">&gt;&gt;</span><span style="color: #000000">&nbsp;child;<br /></span><span style="color: #008080">29</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NAutoPtr</span><span style="color: #000000">&lt;</span><span style="color: #000000">CSyntaxTreeNode</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;next;<br /></span><span style="color: #008080">30</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;};</span></div>然后我们给出了部分枚举来标识节点的类型：<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"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">&nbsp;1</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;for&nbsp;type</span><span style="color: #008000"><br /></span><span style="color: #008080">&nbsp;2</span>&nbsp;<span style="color: #008000"></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">enum</span><span style="color: #000000">&nbsp;TYPE<br /></span><span style="color: #008080">&nbsp;3</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080">&nbsp;4</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stNull,<br /></span><span style="color: #008080">&nbsp;5</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stDeclare,<br /></span><span style="color: #008080">&nbsp;6</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stFunction,<br /></span><span style="color: #008080">&nbsp;7</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stParamterList,<br /></span><span style="color: #008080">&nbsp;8</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stIf,<br /></span><span style="color: #008080">&nbsp;9</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stDo,<br /></span><span style="color: #008080">10</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stExp,<br /></span><span style="color: #008080">11</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};</span></div>最后是一棵AST的整体结构：<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"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">&nbsp;1</span>&nbsp;<span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;CParserAnalyze<br /></span><span style="color: #008080">&nbsp;2</span>&nbsp;<span style="color: #000000">{<br /></span><span style="color: #008080">&nbsp;3</span>&nbsp;<span style="color: #000000"></span><span style="color: #0000ff">public</span><span style="color: #000000">:<br /></span><span style="color: #008080">&nbsp;4</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;Push(NAutoPtr</span><span style="color: #000000">&lt;</span><span style="color: #000000">CSyntaxTreeNode</span><span style="color: #000000">&gt;&amp;</span><span style="color: #000000">&nbsp;Node)<br /></span><span style="color: #008080">&nbsp;5</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080">&nbsp;6</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SyntaxTreeStack.Push(Node);<br /></span><span style="color: #008080">&nbsp;7</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080">&nbsp;8</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080">&nbsp;9</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;NAutoPtr</span><span style="color: #000000">&lt;</span><span style="color: #000000">CSyntaxTreeNode</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;Pop()<br /></span><span style="color: #008080">10</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080">11</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;SyntaxTreeStack.Pop();<br /></span><span style="color: #008080">12</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080">13</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080">14</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;NAutoPtr</span><span style="color: #000000">&lt;</span><span style="color: #000000">CSyntaxTreeNode</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;Top()<br /></span><span style="color: #008080">15</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080">16</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;SyntaxTreeStack.Top();<br /></span><span style="color: #008080">17</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080">18</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080">19</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;NAutoPtr</span><span style="color: #000000">&lt;</span><span style="color: #000000">CSyntaxTreeNode</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;Root()<br /></span><span style="color: #008080">20</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080">21</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;SyntaxTreeRoot;<br /></span><span style="color: #008080">22</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080">23</span>&nbsp;<span style="color: #000000"></span><span style="color: #0000ff">protected</span><span style="color: #000000">:<br /></span><span style="color: #008080">24</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;NAutoPtr</span><span style="color: #000000">&lt;</span><span style="color: #000000">CSyntaxTreeNode</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;SyntaxTreeRoot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;语法树根节点</span><span style="color: #008000"><br /></span><span style="color: #008080">25</span>&nbsp;<span style="color: #008000"></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;Stack</span><span style="color: #000000">&lt;</span><span style="color: #000000">NAutoPtr</span><span style="color: #000000">&lt;</span><span style="color: #000000">CSyntaxTreeNode</span><span style="color: #000000">&gt;&gt;</span><span style="color: #000000">&nbsp;SyntaxTreeStack;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;语法树栈</span><span style="color: #008000"><br /></span><span style="color: #008080">26</span>&nbsp;<span style="color: #008000"></span><span style="color: #000000">};</span></div><br />这里我们简单的分析一下分析过程：<br />以if语句为例，其组合子代码为：<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"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">1</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;if_desc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(str_if&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;exp_desc)[if_desc_first]&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000"><br /></span><span style="color: #008080">2</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str_then&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;stmt_list)[if_desc_second]&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000"><br /></span><span style="color: #008080">3</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Parser_Combinator_Node::opt((str_else&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;stmt_list)[if_desc_third])&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000"><br /></span><span style="color: #008080">4</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str_end&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;str_if)[if_desc_fourth];</span></div>我们输入代码：<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"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">1</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;a&nbsp;then<br /></span><span style="color: #008080">2</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;declare&nbsp;b&nbsp;</span><span style="color: #0000ff">as</span><span style="color: #000000">&nbsp;integer<br /></span><span style="color: #008080">3</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;end&nbsp;</span><span style="color: #0000ff">if</span></div>在做语法分析：<br />1.读入if a，a被归约为一条exp生成一个类型为exp的节点并压入AST的语法树栈。<br />2.if a被归约生成一个类型为stIf的节点并弹出栈顶的exp节点填充到新生成的stIf节点的第一个子节点。<br />3.读入then declare b as integer，integer被归约生成一个生类型为stDeclare的节点并压入语法树栈。<br />4.declare b as integer被归约为栈顶的stDeclare节点填充一个b标识符的子节点。<br />5.then declare b as integer被归约，首先弹出栈顶的stmt_list因为这里是stDeclare说明stmt_list有内容应此将栈顶的stIf的值域的最低位置为1。<br />6.else子句不存在。<br />7.整体被归约。<br />此时栈顶为stIf节点，其不包含next节点，有两个子节点分别为stExp和stDeclare。<br /><br />分析过程如下图：<br />1.<img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/lwch/Analyze_001.png" width="125" longdesc="" height="230" /><br />2.<img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/lwch/Analyze_002.png" width="150" longdesc="" height="230" /><br />3.<img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/lwch/Analyze_003.png" width="240" longdesc="" height="250" /><br />4.<img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/lwch/Analyze_004.png" width="240" longdesc="" height="250" /><br />5.<img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/lwch/Analyze_005.png" width="240" longdesc="" height="250" /><br />6.<img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/lwch/Analyze_006.png" width="240" longdesc="" height="250" /><br />7. <img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/lwch/Analyze_007.png" width="360" longdesc="" height="250" /><img src ="http://www.cppblog.com/lwch/aggbug/149941.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2011-07-01 21:51 <a href="http://www.cppblog.com/lwch/archive/2011/07/01/149941.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>QLanguage基本语法</title><link>http://www.cppblog.com/lwch/archive/2011/06/27/149572.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Mon, 27 Jun 2011 08:36:00 GMT</pubDate><guid>http://www.cppblog.com/lwch/archive/2011/06/27/149572.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/149572.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2011/06/27/149572.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/149572.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lwch/services/trackbacks/149572.html</trackback:ping><description><![CDATA[<div>1.类的定义 
<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"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">1</span>&nbsp;<span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;a&nbsp;[inherit&nbsp;Object]<br /></span><span style="color: #008080">2</span>&nbsp;<span style="color: #000000">end&nbsp;</span><span style="color: #0000ff">class</span></div><br />2.类中可以包含(声明，函数，新类。其中除了class都含有public、private、protected和static属性)<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"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">1</span>&nbsp;<span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;a<br /></span><span style="color: #008080">2</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;[</span><span style="color: #0000ff">public</span><span style="color: #000000">]&nbsp;declare&nbsp;a&nbsp;</span><span style="color: #0000ff">as</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;声明</span><span style="color: #008000"><br /></span><span style="color: #008080">3</span>&nbsp;<span style="color: #008000"></span><span style="color: #000000"><br /></span><span style="color: #008080">4</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;[</span><span style="color: #0000ff">private</span><span style="color: #000000">]&nbsp;[</span><span style="color: #0000ff">static</span><span style="color: #000000">]&nbsp;function&nbsp;main()&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;函数</span><span style="color: #008000"><br /></span><span style="color: #008080">5</span>&nbsp;<span style="color: #008000"></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;end&nbsp;function<br /></span><span style="color: #008080">6</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080">7</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;b&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;新类</span><span style="color: #008000"><br /></span><span style="color: #008080">8</span>&nbsp;<span style="color: #008000"></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;end&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000"><br /></span><span style="color: #008080">9</span>&nbsp;<span style="color: #000000">end&nbsp;</span><span style="color: #0000ff">class</span></div></div>3.变量声明<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"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">1</span>&nbsp;<span style="color: #000000">declare&nbsp;a&nbsp;</span><span style="color: #0000ff">as</span><span style="color: #000000">&nbsp;integer[,b&nbsp;</span><span style="color: #0000ff">as</span><span style="color: #000000">&nbsp;integer]</span></div>4.函数<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"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">1</span>&nbsp;<span style="color: #000000">function&nbsp;main([a&nbsp;</span><span style="color: #0000ff">as</span><span style="color: #000000">&nbsp;integer[,b&nbsp;</span><span style="color: #0000ff">as</span><span style="color: #000000">&nbsp;integer]])[</span><span style="color: #0000ff">as</span><span style="color: #000000">&nbsp;integer]<br /></span><span style="color: #008080">2</span>&nbsp;<span style="color: #000000">end&nbsp;function</span></div>5.stmt_list包含声明语句、if语句、do语句、while语句、for语句、switch语句和experience表达式<br />6.if语句<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"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">1</span>&nbsp;<span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;experience&nbsp;then<br /></span><span style="color: #008080">2</span>&nbsp;<span style="color: #000000">stmt_list<br /></span><span style="color: #008080">3</span>&nbsp;<span style="color: #000000">[</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;stmt_list]<br /></span><span style="color: #008080">4</span>&nbsp;<span style="color: #000000">end&nbsp;</span><span style="color: #0000ff">if</span></div>7.do语句<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"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">1</span>&nbsp;<span style="color: #0000ff">do</span><span style="color: #000000"><br /></span><span style="color: #008080">2</span>&nbsp;<span style="color: #000000">stmt_list<br /></span><span style="color: #008080">3</span>&nbsp;<span style="color: #000000"></span><span style="color: #0000ff">while</span><span style="color: #000000">&nbsp;experience&nbsp;end</span></div>8.while语句<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"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">1</span>&nbsp;<span style="color: #0000ff">while</span><span style="color: #000000">&nbsp;experience&nbsp;</span><span style="color: #0000ff">do</span><span style="color: #000000"><br /></span><span style="color: #008080">2</span>&nbsp;<span style="color: #000000">stmt_list<br /></span><span style="color: #008080">3</span>&nbsp;<span style="color: #000000">end&nbsp;</span><span style="color: #0000ff">while</span></div>9.for语句<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"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">1</span>&nbsp;<span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;stmt_list&nbsp;to&nbsp;experience&nbsp;by&nbsp;stmt_list&nbsp;</span><span style="color: #0000ff">do</span><span style="color: #000000"><br /></span><span style="color: #008080">2</span>&nbsp;<span style="color: #000000">stmt_list<br /></span><span style="color: #008080">3</span>&nbsp;<span style="color: #000000">next</span></div>10.switch语句 
<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"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">1</span>&nbsp;<span style="color: #0000ff">switch</span><span style="color: #000000">&nbsp;experience&nbsp;</span><span style="color: #0000ff">do</span><span style="color: #000000"><br /></span><span style="color: #008080">2</span>&nbsp;<span style="color: #000000"></span><span style="color: #0000ff">case</span><span style="color: #000000">&nbsp;experience:<br /></span><span style="color: #008080">3</span>&nbsp;<span style="color: #000000">[stmt_list]<br /></span><span style="color: #008080">4</span>&nbsp;<span style="color: #000000">[</span><span style="color: #0000ff">case</span><span style="color: #000000">&nbsp;experience:<br /></span><span style="color: #008080">5</span>&nbsp;<span style="color: #000000">[stmt_list]]<br /></span><span style="color: #008080">6</span>&nbsp;<span style="color: #000000">[</span><span style="color: #0000ff">default</span><span style="color: #000000">:<br /></span><span style="color: #008080">7</span>&nbsp;<span style="color: #000000">[stmt_list]]<br /></span><span style="color: #008080">8</span>&nbsp;<span style="color: #000000">end&nbsp;</span><span style="color: #0000ff">switch</span></div>11.experience表达式<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"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">&nbsp;1</span>&nbsp;<span style="color: #000000">函数调用语句<br /></span><span style="color: #008080">&nbsp;2</span>&nbsp;<span style="color: #000000">赋值语句<br /></span><span style="color: #008080">&nbsp;3</span>&nbsp;<span style="color: #000000">symbol<br /></span><span style="color: #008080">&nbsp;4</span>&nbsp;<span style="color: #000000"></span><span style="color: #0000ff">string</span><span style="color: #000000"><br /></span><span style="color: #008080">&nbsp;5</span>&nbsp;<span style="color: #000000">number<br /></span><span style="color: #008080">&nbsp;6</span>&nbsp;<span style="color: #000000"></span><span style="color: #0000ff">true</span><span style="color: #000000"><br /></span><span style="color: #008080">&nbsp;7</span>&nbsp;<span style="color: #000000"></span><span style="color: #0000ff">false</span><span style="color: #000000"><br /></span><span style="color: #008080">&nbsp;8</span>&nbsp;<span style="color: #000000">(</span><span style="color: #000000">+|-</span><span style="color: #000000">)experience<br /></span><span style="color: #008080">&nbsp;9</span>&nbsp;<span style="color: #000000">not&nbsp;experience<br /></span><span style="color: #008080">10</span>&nbsp;<span style="color: #000000">experience&nbsp;(</span><span style="color: #000000">&amp;|||^|%</span><span style="color: #000000">)&nbsp;experience<br /></span><span style="color: #008080">11</span>&nbsp;<span style="color: #000000">experience&nbsp;(</span><span style="color: #000000">&gt;|&lt;|&gt;=|&lt;=|==|!=</span><span style="color: #000000">)&nbsp;experience<br /></span><span style="color: #008080">12</span>&nbsp;<span style="color: #000000">experience&nbsp;(</span><span style="color: #000000">+|-|*|/</span><span style="color: #000000">)&nbsp;experience<br /></span><span style="color: #008080">13</span>&nbsp;<span style="color: #000000"></span><span style="color: #000000">++</span><span style="color: #000000">symbol<br /></span><span style="color: #008080">14</span>&nbsp;<span style="color: #000000"></span><span style="color: #000000">--</span><span style="color: #000000">symbol<br /></span><span style="color: #008080">15</span>&nbsp;<span style="color: #000000">symbol</span><span style="color: #000000">++</span><span style="color: #000000"><br /></span><span style="color: #008080">16</span>&nbsp;<span style="color: #000000">symbol</span><span style="color: #000000">--</span></div>12.函数调用语句<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"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">1</span>&nbsp;<span style="color: #000000">函数名(参数表)</span></div>13.赋值语句<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"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">1</span>&nbsp;<span style="color: #000000">变量</span><span style="color: #000000">=</span><span style="color: #000000">experience</span></div><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"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">&nbsp;1</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;program&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">item;<br /></span><span style="color: #008080">&nbsp;2</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;item&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;declare_desc&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000"><br /></span><span style="color: #008080">&nbsp;3</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class_desc&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000"><br /></span><span style="color: #008080">&nbsp;4</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;function_desc;<br /></span><span style="color: #008080">&nbsp;5</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;property_desc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;str_public&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000"><br /></span><span style="color: #008080">&nbsp;6</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str_private&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000"><br /></span><span style="color: #008080">&nbsp;7</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str_protected;<br /></span><span style="color: #008080">&nbsp;8</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;declare_type&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;str_integer&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000"><br /></span><span style="color: #008080">&nbsp;9</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str_string&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000"><br /></span><span style="color: #008080">10</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str_bool&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000"><br /></span><span style="color: #008080">11</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str_real&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000"><br /></span><span style="color: #008080">12</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type_symbol;<br /></span><span style="color: #008080">13</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;paramter_desc_list&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(type_symbol&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;str_as&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;declare_type)&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000"><br /></span><span style="color: #008080">14</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">(str_comma&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;type_symbol&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;str_as&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;declare_type);<br /></span><span style="color: #008080">15</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;paramter_value_list&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;exp_desc&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">(str_comma&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;exp_desc);<br /></span><span style="color: #008080">16</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;declare_desc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;str_declare&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;type_symbol&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;str_as&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;declare_type&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000"><br /></span><span style="color: #008080">17</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">(str_comma&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;type_symbol&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;str_as&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;declare_type);<br /></span><span style="color: #008080">18</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;class_desc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;str_class&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;type_symbol&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000"><br /></span><span style="color: #008080">19</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Parser_Combinator_Node::opt(str_inherit&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;type_symbol&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000"><br /></span><span style="color: #008080">20</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">(str_comma&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;(type_symbol&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;Parser_Combinator_Node::not(str_class&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000">&nbsp;str_function&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000">&nbsp;property_desc&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000">&nbsp;str_static)))<br /></span><span style="color: #008080">21</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">class_content_desc&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;str_end&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;str_class;<br /></span><span style="color: #008080">22</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;class_content_desc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(Parser_Combinator_Node::opt(property_desc)&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;Parser_Combinator_Node::opt(str_static)&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000"><br /></span><span style="color: #008080">23</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(declare_desc&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000">&nbsp;function_desc))&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000"><br /></span><span style="color: #008080">24</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class_desc;<br /></span><span style="color: #008080">25</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;function_desc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(str_function&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;type_symbol)&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000"><br /></span><span style="color: #008080">26</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str_leftbracket&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;Parser_Combinator_Node::opt(paramter_desc_list)&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;str_rightbracket)&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000"><br /></span><span style="color: #008080">27</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Parser_Combinator_Node::opt(str_as&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;declare_type)&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000"><br /></span><span style="color: #008080">28</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stmt_list&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000"><br /></span><span style="color: #008080">29</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str_end&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;str_function);<br /></span><span style="color: #008080">30</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;stmt_list&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">(stmt&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;Parser_Combinator_Node::not(str_end));<br /></span><span style="color: #008080">31</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;stmt&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;declare_desc&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000"><br /></span><span style="color: #008080">32</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if_desc&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000"><br /></span><span style="color: #008080">33</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do_desc&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000"><br /></span><span style="color: #008080">34</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while_desc&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000"><br /></span><span style="color: #008080">35</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for_desc&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000"><br /></span><span style="color: #008080">36</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch_desc&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000"><br /></span><span style="color: #008080">37</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exp_desc;<br /></span><span style="color: #008080">38</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;if_desc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(str_if&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;exp_desc)&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000"><br /></span><span style="color: #008080">39</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str_then&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;stmt_list)&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000"><br /></span><span style="color: #008080">40</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Parser_Combinator_Node::opt(str_else&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;stmt_list)&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000"><br /></span><span style="color: #008080">41</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str_end&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;str_if);<br /></span><span style="color: #008080">42</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;do_desc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(str_do&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;stmt_list)&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000"><br /></span><span style="color: #008080">43</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str_while&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;exp_desc&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;str_end);<br /></span><span style="color: #008080">44</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;while_desc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;str_while&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;exp_desc&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;str_do&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;stmt_list&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;str_end&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;str_while;<br /></span><span style="color: #008080">45</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;for_desc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;str_for&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;stmt_list&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;str_to&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;exp_desc&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;str_by&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;stmt_list&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;str_do&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;stmt_list&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;str_next;<br /></span><span style="color: #008080">46</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;switch_desc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;str_switch&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;exp_desc&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;str_do&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;case_list&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;str_end&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;str_switch;<br /></span><span style="color: #008080">47</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;case_list&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">case_desc;<br /></span><span style="color: #008080">48</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;case_desc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(str_case&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;exp_desc&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;str_colon&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;stmt_list)&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000"><br /></span><span style="color: #008080">49</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str_default&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;str_colon&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;stmt_list);<br /></span><span style="color: #008080">50</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;assign_desc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;type_symbol&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;str_equal&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;exp_desc;<br /></span><span style="color: #008080">51</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;call_desc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;type_symbol&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;str_leftbracket&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;Parser_Combinator_Node::opt(paramter_value_list)&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;str_rightbracket;<br /></span><span style="color: #008080">52</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;logic_desc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(str_not&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;compare_desc)&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000"><br /></span><span style="color: #008080">53</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(compare_desc&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">((str_operator_and&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000">&nbsp;str_operator_or&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000">&nbsp;str_xor&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000">&nbsp;str_mod)&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;compare_desc));<br /></span><span style="color: #008080">54</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;compare_desc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;term_desc&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">((str_bigger&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000">&nbsp;str_smaller&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000"><br /></span><span style="color: #008080">55</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str_bigger_equal&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000">&nbsp;str_smaller_equal&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000"><br /></span><span style="color: #008080">56</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str_equal_equal&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000">&nbsp;str_not_equal)&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;term_desc);<br /></span><span style="color: #008080">57</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;term_desc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;factor_desc&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">((str_add&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000">&nbsp;str_sub)&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;factor_desc);<br /></span><span style="color: #008080">58</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;factor_desc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;self_desc&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">((str_mul&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000">&nbsp;str_div)&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;self_desc);<br /></span><span style="color: #008080">59</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;self_desc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(str_add_add&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;type_symbol)&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000"><br /></span><span style="color: #008080">60</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str_sub_sub&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;type_symbol)&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000"><br /></span><span style="color: #008080">61</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(type_symbol&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;str_add_add)&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000"><br /></span><span style="color: #008080">62</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(type_symbol&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;str_sub_sub)&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000"><br /></span><span style="color: #008080">63</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value_desc;<br /></span><span style="color: #008080">64</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;value_desc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;call_desc&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000"><br /></span><span style="color: #008080">65</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assign_desc&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000"><br /></span><span style="color: #008080">66</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type_symbol&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000"><br /></span><span style="color: #008080">67</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type_string&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000"><br /></span><span style="color: #008080">68</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type_number&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000"><br /></span><span style="color: #008080">69</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str_true&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000"><br /></span><span style="color: #008080">70</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str_false&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000"><br /></span><span style="color: #008080">71</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;((str_add&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000">&nbsp;str_sub)&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;logic_desc)&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000"><br /></span><span style="color: #008080">72</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str_leftbracket&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;logic_desc&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;str_rightbracket);<br /></span><span style="color: #008080">73</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;exp_desc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;logic_desc;</span></div><br />如有任何补充将会在此文档更新。<br /><img src ="http://www.cppblog.com/lwch/aggbug/149572.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2011-06-27 16:36 <a href="http://www.cppblog.com/lwch/archive/2011/06/27/149572.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ESEngine_Demo5</title><link>http://www.cppblog.com/lwch/archive/2011/03/02/140979.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Wed, 02 Mar 2011 05:20:00 GMT</pubDate><guid>http://www.cppblog.com/lwch/archive/2011/03/02/140979.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/140979.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2011/03/02/140979.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/140979.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lwch/services/trackbacks/140979.html</trackback:ping><description><![CDATA[<p>修正了词法分析器的一些Bug.<br>修正了一些运行时的Bug.<br>支持了单行注释//和多行注释/* */<br>支持了所有的函数声明形式.<br><a href="http://www.cppblog.com/Files/lwch/ESEngine_Demo5.rar"><br>ESEngine_Demo5.rar</a></p><img src ="http://www.cppblog.com/lwch/aggbug/140979.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2011-03-02 13:20 <a href="http://www.cppblog.com/lwch/archive/2011/03/02/140979.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ESEngine_Demo4</title><link>http://www.cppblog.com/lwch/archive/2011/02/13/139989.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Sun, 13 Feb 2011 11:20:00 GMT</pubDate><guid>http://www.cppblog.com/lwch/archive/2011/02/13/139989.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/139989.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2011/02/13/139989.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/139989.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lwch/services/trackbacks/139989.html</trackback:ping><description><![CDATA[添加了DLL的支持(见Samples下的TestDLL.dll)<br><br><a href="http://www.cppblog.com/Files/lwch/ESEngine_Demo4.rar">ESEngine_Demo4.rar</a><img src ="http://www.cppblog.com/lwch/aggbug/139989.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2011-02-13 19:20 <a href="http://www.cppblog.com/lwch/archive/2011/02/13/139989.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>QLanguage</title><link>http://www.cppblog.com/lwch/archive/2011/02/13/139956.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Sat, 12 Feb 2011 16:09:00 GMT</pubDate><guid>http://www.cppblog.com/lwch/archive/2011/02/13/139956.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/139956.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2011/02/13/139956.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/139956.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lwch/services/trackbacks/139956.html</trackback:ping><description><![CDATA[<span style="widows: 2; text-transform: none; text-indent: 0px; border-collapse: separate; font: medium Simsun; white-space: normal; orphans: 2; letter-spacing: normal; color: #000000; word-spacing: 0px; webkit-border-horizontal-spacing: 0px; webkit-border-vertical-spacing: 0px; webkit-text-decorations-in-effect: none; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px" class="Apple-style-span"><span style="line-height: 18px; font-family: verdana, Arial, helvetica, sans-seriff; color: #7b7d62; font-size: 12px" class="Apple-style-span">可能还有大量的Bug,请反馈给QQ:510134884.<br />
QLanguage的发展需要您的支持<img border="0" align="absMiddle" src="http://www.cppblog.com/CuteSoft_Client/CuteEditor/images/emsmile.gif" alt="" /><br />
<br />
开源项目地址:<a href="http://qlanguage.codeplex.com/" target="_blank">http://qlanguage.codeplex.com/</a><br />
<br />
Demo5:<br />
修正了词法分析器的一些Bug.<br />
修正了一些运行时的Bug.<br />
支持了单行注释//和多行注释/* */<br />
支持了所有的函数声明形式.<br />
<a href="http://www.cppblog.com/lwch/archive/2011/03/02/140979.html" target="_blank">http://www.cppblog.com/lwch/archive/2011/03/02/140979.html</a><br />
<br />
Demo4:<br />
添加了DLL的支持(见Samples下的TestDLL.dll)<br />
<a href="http://www.cppblog.com/lwch/archive/2011/02/13/139989.html">http://www.cppblog.com/lwch/archive/2011/02/13/139989.html</a><br />
<br />
Demo3:<br />
修正了return语句的一些Bug<br />
添加了COM组件的支持(见Samples目录下的factorial.txt)<br />
<a href="http://www.cppblog.com/lwch/archive/2011/02/07/139787.html">http://www.cppblog.com/lwch/archive/2011/02/07/139787.html</a><br />
<br />
Demo2:<br />
1.修正了函数调用时的一些Bug<br />
2.示例中增加了一个递归求阶乘的例子<br />
<a href="http://www.cppblog.com/lwch/archive/2011/01/30/139624.html">http://www.cppblog.com/lwch/archive/2011/01/30/139624.html</a><br />
<br />
Demo1:<br />
运行方法:<br />
1.打开命令行提示符<br />
2.cd ESEngine.exe所在路径<br />
3.ESEngine xxx.txt 1.Samples文件夹下有几个例子<br />
2.函数目前只写了<br />
&nbsp; "function" "{Symbol}" "{LQ}" "{RQ}" stmt_list "end" "function"<br />
&nbsp; "function" "{Symbol}" "{LQ}" "{RQ}" "end" "function"<br />
&nbsp; "function" "{Symbol}" "{LQ}" paramter_list "{RQ}" "as" var_type stmt_list "end" "function"<br />
&nbsp; 这三类,所以对于<br />
&nbsp; function mn(integer s)<br />
&nbsp;stmts<br />
&nbsp; end function<br />
&nbsp; 在生成语法树时会产生错误<br />
<a href="http://www.cppblog.com/lwch/archive/2011/01/28/139546.html">http://www.cppblog.com/lwch/archive/2011/01/28/139546.html</a></span></span><img src ="http://www.cppblog.com/lwch/aggbug/139956.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2011-02-13 00:09 <a href="http://www.cppblog.com/lwch/archive/2011/02/13/139956.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ESEngine_Demo3</title><link>http://www.cppblog.com/lwch/archive/2011/02/07/139787.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Mon, 07 Feb 2011 09:27:00 GMT</pubDate><guid>http://www.cppblog.com/lwch/archive/2011/02/07/139787.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/139787.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2011/02/07/139787.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/139787.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lwch/services/trackbacks/139787.html</trackback:ping><description><![CDATA[修正了return语句的一些Bug<br>添加了COM组件的支持(见Samples目录下的factorial.txt)<br><br><a href="http://www.cppblog.com/Files/lwch/ESEngine_Demo3.rar">ESEngine_Demo3.rar</a><img src ="http://www.cppblog.com/lwch/aggbug/139787.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2011-02-07 17:27 <a href="http://www.cppblog.com/lwch/archive/2011/02/07/139787.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ESEngine_Demo2</title><link>http://www.cppblog.com/lwch/archive/2011/01/30/139624.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Sun, 30 Jan 2011 13:19:00 GMT</pubDate><guid>http://www.cppblog.com/lwch/archive/2011/01/30/139624.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/139624.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2011/01/30/139624.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/139624.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lwch/services/trackbacks/139624.html</trackback:ping><description><![CDATA[<span class=Apple-style-span style="WORD-SPACING: 0px; FONT: medium Simsun; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate; orphans: 2; widows: 2; webkit-border-horizontal-spacing: 0px; webkit-border-vertical-spacing: 0px; webkit-text-decorations-in-effect: none; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px">1.修正了函数调用时的一些Bug<br>2.示例中增加了一个递归求阶乘的例子<br><br><a href="http://www.cppblog.com/Files/lwch/ESEngine_Demo2.rar">ESEngine_Demo2.rar</a></span><img src ="http://www.cppblog.com/lwch/aggbug/139624.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2011-01-30 21:19 <a href="http://www.cppblog.com/lwch/archive/2011/01/30/139624.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ESEngine_Demo1</title><link>http://www.cppblog.com/lwch/archive/2011/01/28/139546.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Fri, 28 Jan 2011 13:03:00 GMT</pubDate><guid>http://www.cppblog.com/lwch/archive/2011/01/28/139546.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/139546.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2011/01/28/139546.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/139546.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lwch/services/trackbacks/139546.html</trackback:ping><description><![CDATA[<p>运行方法:<br>1.打开命令行提示符<br>2.cd ESEngine.exe所在路径<br>3.ESEngine xxx.txt</p>
<p>1.Samples文件夹下有几个例子<br>2.函数目前只写了<br>&nbsp; "function" "{Symbol}" "{LQ}" "{RQ}" stmt_list "end" "function"<br>&nbsp; "function" "{Symbol}" "{LQ}" "{RQ}" "end" "function"<br>&nbsp; "function" "{Symbol}" "{LQ}" paramter_list "{RQ}" "as" var_type stmt_list "end" "function"<br>&nbsp; 这三类,所以对于<br>&nbsp; function mn(integer s)<br>&nbsp;stmts<br>&nbsp; end function<br>&nbsp; 在生成语法树时会产生错误<br><a href="http://www.cppblog.com/Files/lwch/ESEngine_Demo1.rar"><br></a><a href="http://www.cppblog.com/Files/lwch/ESEngine_Demo1_0.rar">ESEngine_Demo1_0.rar</a></p><img src ="http://www.cppblog.com/lwch/aggbug/139546.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2011-01-28 21:03 <a href="http://www.cppblog.com/lwch/archive/2011/01/28/139546.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ESLanguage对于非常Bug的表达式的翻译</title><link>http://www.cppblog.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.cppblog.com/lwch/archive/2011/01/27/139497.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/139497.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2011/01/27/139497.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/139497.html</wfw:commentRss><trackback:ping>http://www.cppblog.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>&nbsp;<span style="COLOR: #000000">function&nbsp;main()<br></span><span style="COLOR: #008080">2</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;integer&nbsp;a<br></span><span style="COLOR: #008080">3</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">a&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">123</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">a)<br></span><span style="COLOR: #008080">4</span>&nbsp;<span style="COLOR: #000000">end&nbsp;function</span></div>
<br>翻译结果:<br><img height=431 alt="" src="http://www.cppblog.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>&nbsp;<span style="COLOR: #000000">function&nbsp;main()<br></span><span style="COLOR: #008080">2</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;integer&nbsp;a<br></span><span style="COLOR: #008080">3</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">a&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">4</span>&nbsp;<span style="COLOR: #000000">end&nbsp;function</span></div>
<br>翻译结果:<br><img height=431 alt="" src="http://www.cppblog.com/images/cppblog_com/lwch/ESLanguage007.PNG" width=668 border=0><img src ="http://www.cppblog.com/lwch/aggbug/139497.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2011-01-27 21:39 <a href="http://www.cppblog.com/lwch/archive/2011/01/27/139497.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ATL调用COM类的封装</title><link>http://www.cppblog.com/lwch/archive/2010/11/20/134179.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Sat, 20 Nov 2010 14:40:00 GMT</pubDate><guid>http://www.cppblog.com/lwch/archive/2010/11/20/134179.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/134179.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2010/11/20/134179.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/134179.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lwch/services/trackbacks/134179.html</trackback:ping><description><![CDATA[COM.h:<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">&nbsp;1</span>&nbsp;<span style="COLOR: #000000">#pragma&nbsp;once<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">atlcomcli.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;COMMacro<br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;COMMacro(LPTSTR&nbsp;Object);<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">COMMacro();<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;BOOL&nbsp;Invoke(LPTSTR&nbsp;strFunction,VARIANT</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;pVarParams,</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;nParamterCount,VARIANT</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;pResult);<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;VARIANT&nbsp;ToVARIANT(BSTR&nbsp;str);<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;VARIANT&nbsp;ToVARIANT(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;nVal);<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;VARIANT&nbsp;ToVARIANT(</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;bVal);<br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;VARIANT&nbsp;ToVARIANT(</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">&nbsp;dVal);<br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;VARIANT&nbsp;ToVARIANT_ByRef(BSTR</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;pStr);<br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;VARIANT&nbsp;ToVARIANT_ByRef(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;pnVal);<br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;VARIANT&nbsp;ToVARIANT_ByRef(</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;pbVal);<br></span><span style="COLOR: #008080">17</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;VARIANT&nbsp;ToVARIANT_ByRef(</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;pdVal);<br></span><span style="COLOR: #008080">18</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;BSTR&nbsp;ToBSTR(VARIANT&nbsp;Val);<br></span><span style="COLOR: #008080">19</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;ToInt(VARIANT&nbsp;Val);<br></span><span style="COLOR: #008080">20</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;ToBool(VARIANT&nbsp;Val);<br></span><span style="COLOR: #008080">21</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">&nbsp;ToDouble(VARIANT&nbsp;Val);<br></span><span style="COLOR: #008080">22</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">23</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;BOOL&nbsp;ToBSTR(LPTSTR&nbsp;src,BSTR</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;dest);<br></span><span style="COLOR: #008080">24</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">protected</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">25</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;CLSID&nbsp;m_clsID;<br></span><span style="COLOR: #008080">26</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;CComPtr</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">IUnknown</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;m_Unknown;<br></span><span style="COLOR: #008080">27</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;CComDispatchDriver</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;m_pDispatchDriver;<br></span><span style="COLOR: #008080">28</span>&nbsp;<span style="COLOR: #000000">};</span></div>
COM.cpp:<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">&nbsp;&nbsp;1</span>&nbsp;<span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">stdafx.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;&nbsp;2</span>&nbsp;<span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">COM.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;&nbsp;3</span>&nbsp;<span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">comdef.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;&nbsp;4</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;&nbsp;5</span>&nbsp;<span style="COLOR: #000000">COMMacro::COMMacro(LPTSTR&nbsp;Object)<br></span><span style="COLOR: #008080">&nbsp;&nbsp;6</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;HRESULT&nbsp;hr&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;CLSIDFromProgID(Object,</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">m_clsID);<br></span><span style="COLOR: #008080">&nbsp;&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(FAILED(hr))<br></span><span style="COLOR: #008080">&nbsp;&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">throw</span><span style="COLOR: #000000">&nbsp;_com_error(hr);<br></span><span style="COLOR: #008080">&nbsp;11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">&nbsp;12</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">&nbsp;13</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;hr&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;CoCreateInstance(m_clsID,NULL,CLSCTX_ALL,IID_IUnknown,(LPVOID</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">m_Unknown);<br></span><span style="COLOR: #008080">&nbsp;14</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(FAILED(hr))<br></span><span style="COLOR: #008080">&nbsp;15</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;16</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">throw</span><span style="COLOR: #000000">&nbsp;_com_error(hr);<br></span><span style="COLOR: #008080">&nbsp;17</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">&nbsp;18</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">&nbsp;19</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;m_pDispatchDriver&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;CComDispatchDriver(m_Unknown);<br></span><span style="COLOR: #008080">&nbsp;20</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">&nbsp;21</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;22</span>&nbsp;<span style="COLOR: #000000">COMMacro::</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">COMMacro()<br></span><span style="COLOR: #008080">&nbsp;23</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;24</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;m_pDispatchDriver;<br></span><span style="COLOR: #008080">&nbsp;25</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">&nbsp;26</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;27</span>&nbsp;<span style="COLOR: #000000">BOOL&nbsp;COMMacro::Invoke(LPTSTR&nbsp;strFunction,VARIANT</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;pVarParams,</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;nParamterCount,VARIANT</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;pResult)<br></span><span style="COLOR: #008080">&nbsp;28</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;29</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;DISPID&nbsp;DispID;<br></span><span style="COLOR: #008080">&nbsp;30</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;HRESULT&nbsp;hr&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;m_pDispatchDriver</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">GetIDOfName(strFunction,</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">DispID);<br></span><span style="COLOR: #008080">&nbsp;31</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(FAILED(hr))<br></span><span style="COLOR: #008080">&nbsp;32</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;33</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">throw</span><span style="COLOR: #000000">&nbsp;_com_error(hr);<br></span><span style="COLOR: #008080">&nbsp;34</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;FALSE;<br></span><span style="COLOR: #008080">&nbsp;35</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">&nbsp;36</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;hr&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;m_pDispatchDriver</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">InvokeN(DispID,pVarParams,nParamterCount,pResult);<br></span><span style="COLOR: #008080">&nbsp;37</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(FAILED(hr))<br></span><span style="COLOR: #008080">&nbsp;38</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;39</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">throw</span><span style="COLOR: #000000">&nbsp;_com_error(hr);<br></span><span style="COLOR: #008080">&nbsp;40</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;FALSE;<br></span><span style="COLOR: #008080">&nbsp;41</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">&nbsp;42</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;TRUE;<br></span><span style="COLOR: #008080">&nbsp;43</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">&nbsp;44</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;45</span>&nbsp;<span style="COLOR: #000000">VARIANT&nbsp;COMMacro::ToVARIANT(BSTR&nbsp;str)<br></span><span style="COLOR: #008080">&nbsp;46</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;47</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;VARIANT&nbsp;vResult;<br></span><span style="COLOR: #008080">&nbsp;48</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;vResult.vt&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;VT_BSTR;<br></span><span style="COLOR: #008080">&nbsp;49</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;vResult.bstrVal&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;SysAllocString(str);<br></span><span style="COLOR: #008080">&nbsp;50</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;vResult;<br></span><span style="COLOR: #008080">&nbsp;51</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">&nbsp;52</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;53</span>&nbsp;<span style="COLOR: #000000">VARIANT&nbsp;COMMacro::ToVARIANT(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;nVal)<br></span><span style="COLOR: #008080">&nbsp;54</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;55</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;VARIANT&nbsp;vResult;<br></span><span style="COLOR: #008080">&nbsp;56</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;vResult.vt&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;VT_I4;<br></span><span style="COLOR: #008080">&nbsp;57</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;vResult.intVal&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;nVal;<br></span><span style="COLOR: #008080">&nbsp;58</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;vResult;<br></span><span style="COLOR: #008080">&nbsp;59</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">&nbsp;60</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;61</span>&nbsp;<span style="COLOR: #000000">VARIANT&nbsp;COMMacro::ToVARIANT(</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;bVal)<br></span><span style="COLOR: #008080">&nbsp;62</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;63</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;VARIANT&nbsp;vResult;<br></span><span style="COLOR: #008080">&nbsp;64</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;vResult.vt&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;VT_BOOL;<br></span><span style="COLOR: #008080">&nbsp;65</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;vResult.boolVal&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;bVal;<br></span><span style="COLOR: #008080">&nbsp;66</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;vResult;<br></span><span style="COLOR: #008080">&nbsp;67</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">&nbsp;68</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;69</span>&nbsp;<span style="COLOR: #000000">VARIANT&nbsp;COMMacro::ToVARIANT(</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">&nbsp;dVal)<br></span><span style="COLOR: #008080">&nbsp;70</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;71</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;VARIANT&nbsp;vResult;<br></span><span style="COLOR: #008080">&nbsp;72</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;vResult.vt&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;VT_R8;<br></span><span style="COLOR: #008080">&nbsp;73</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;vResult.dblVal&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;dVal;<br></span><span style="COLOR: #008080">&nbsp;74</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;vResult;<br></span><span style="COLOR: #008080">&nbsp;75</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">&nbsp;76</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;77</span>&nbsp;<span style="COLOR: #000000">VARIANT&nbsp;COMMacro::ToVARIANT_ByRef(BSTR</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;pStr)<br></span><span style="COLOR: #008080">&nbsp;78</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;79</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;VARIANT&nbsp;vResult;<br></span><span style="COLOR: #008080">&nbsp;80</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;vResult.vt&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;VT_BSTR&nbsp;</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">&nbsp;VT_BYREF;<br></span><span style="COLOR: #008080">&nbsp;81</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;vResult.byref&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;pStr;<br></span><span style="COLOR: #008080">&nbsp;82</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;vResult;<br></span><span style="COLOR: #008080">&nbsp;83</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">&nbsp;84</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;85</span>&nbsp;<span style="COLOR: #000000">VARIANT&nbsp;COMMacro::ToVARIANT_ByRef(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;pnVal)<br></span><span style="COLOR: #008080">&nbsp;86</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;87</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;VARIANT&nbsp;vResult;<br></span><span style="COLOR: #008080">&nbsp;88</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;vResult.vt&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;VT_I4&nbsp;</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">&nbsp;VT_BYREF;<br></span><span style="COLOR: #008080">&nbsp;89</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;vResult.byref&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;pnVal;<br></span><span style="COLOR: #008080">&nbsp;90</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;vResult;<br></span><span style="COLOR: #008080">&nbsp;91</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">&nbsp;92</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;93</span>&nbsp;<span style="COLOR: #000000">VARIANT&nbsp;COMMacro::ToVARIANT_ByRef(</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;pbVal)<br></span><span style="COLOR: #008080">&nbsp;94</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;95</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;VARIANT&nbsp;vResult;<br></span><span style="COLOR: #008080">&nbsp;96</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;vResult.vt&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;VT_BOOL&nbsp;</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">&nbsp;VT_BYREF;<br></span><span style="COLOR: #008080">&nbsp;97</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;vResult.byref&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;pbVal;<br></span><span style="COLOR: #008080">&nbsp;98</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;vResult;<br></span><span style="COLOR: #008080">&nbsp;99</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">100</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">101</span>&nbsp;<span style="COLOR: #000000">VARIANT&nbsp;COMMacro::ToVARIANT_ByRef(</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;pdVal)<br></span><span style="COLOR: #008080">102</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">103</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;VARIANT&nbsp;vResult;<br></span><span style="COLOR: #008080">104</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;vResult.vt&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;VT_BOOL&nbsp;</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">&nbsp;VT_BYREF;<br></span><span style="COLOR: #008080">105</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;vResult.byref&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;pdVal;<br></span><span style="COLOR: #008080">106</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;vResult;<br></span><span style="COLOR: #008080">107</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">108</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">109</span>&nbsp;<span style="COLOR: #000000">BSTR&nbsp;COMMacro::ToBSTR(VARIANT&nbsp;Val)<br></span><span style="COLOR: #008080">110</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">111</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">(BSTR</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">)Val.byref;<br></span><span style="COLOR: #008080">112</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">113</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">114</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;COMMacro::ToInt(VARIANT&nbsp;Val)<br></span><span style="COLOR: #008080">115</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">116</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">)Val.byref;<br></span><span style="COLOR: #008080">117</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">118</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">119</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;COMMacro::ToBool(VARIANT&nbsp;Val)<br></span><span style="COLOR: #008080">120</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">121</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">)Val.byref;<br></span><span style="COLOR: #008080">122</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">123</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">124</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">&nbsp;COMMacro::ToDouble(VARIANT&nbsp;Val)<br></span><span style="COLOR: #008080">125</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">126</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">)Val.byref;<br></span><span style="COLOR: #008080">127</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">128</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">129</span>&nbsp;<span style="COLOR: #000000">BOOL&nbsp;COMMacro::ToBSTR(LPTSTR&nbsp;src,BSTR</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;dest)<br></span><span style="COLOR: #008080">130</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">131</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;dest&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;SysAllocString(src);<br></span><span style="COLOR: #008080">132</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;TRUE;<br></span><span style="COLOR: #008080">133</span>&nbsp;<span style="COLOR: #000000">}</span></div>
<br>使用说明:<br>1.构造函数:<br>参数(字符串常量):工程名.类名<br>2.Invoke:<br>参数1(字符串常量):函数名<br>参数2(VARIANT数组):调用参数,从右至左<br>参数3(数值常量):调用参数个数<br>参数4(VARIANT指针):返回值<br>3.ToVARIANT:将给定参数转换为VARIANT类型<br>4.ToVARIANT_ByRef:将给定参数转换为ByRef的VARIANT类型<br>5.ToBSTR:将给定ByRef的VARIANT转换为BSTR<br>6.ToInt:将给定ByRef的VARIANT转换为int<br>7.ToBool:将给定ByRef的VARIANT转换为bool<br>8.ToDouble:将给定ByRef的VARIANT转换为double<br>9.ToBSTR:将给定字符串常量转换为BSTR类型<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">&nbsp;1</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;CoInitialize(</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;初始化ATL</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">try</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;COMMacro&nbsp;m(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">aaa.bbb</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VARIANT&nbsp;vResult,vParams[</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">];<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">100</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BSTR&nbsp;str;<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m.ToBSTR(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">abc</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,str);<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vParams[</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;m.ToVARIANT(</span><span style="COLOR: #000000">123.456</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vParams[</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;m.ToVARIANT(i);<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vParams[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;m.ToVARIANT_ByRef(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">str);<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m.Invoke(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">aaa</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,vParams,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">vResult);<br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wprintf(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%s\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,m.ToBSTR(vParams[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">]));<br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #000000">(_com_error</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;e)<br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">17</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wprintf(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%s\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,e.ErrorMessage());<br></span><span style="COLOR: #008080">18</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
<img src ="http://www.cppblog.com/lwch/aggbug/134179.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2010-11-20 22:40 <a href="http://www.cppblog.com/lwch/archive/2010/11/20/134179.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>递归阶乘函数的语法制导翻译</title><link>http://www.cppblog.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.cppblog.com/lwch/archive/2010/10/02/128293.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/128293.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2010/10/02/128293.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/128293.html</wfw:commentRss><trackback:ping>http://www.cppblog.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">&nbsp;1</span>&nbsp;<span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">&nbsp;fact(</span><span style="COLOR: #0000ff">integer</span><span style="COLOR: #000000">&nbsp;n)&nbsp;</span><span style="COLOR: #0000ff">as</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">integer</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;n&nbsp;</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">then</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;fact(n&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;n<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;n<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">end&nbsp;function</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">&nbsp;main()<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">integer</span><span style="COLOR: #000000">&nbsp;Result<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;Result&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;fact(</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">end&nbsp;function</span></div>
符号表:<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">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;n<br>&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"><br>&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;fact<br>&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;Result<br>&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000"><br>&nbsp;</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;main</span></div>
翻译结果:<br>&nbsp;<img height=575 alt="" src="http://www.cppblog.com/images/cppblog_com/lwch/ESLanguage005.PNG" width=668 border=0>
<img src ="http://www.cppblog.com/lwch/aggbug/128293.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2010-10-02 11:56 <a href="http://www.cppblog.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.cppblog.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.cppblog.com/lwch/archive/2010/09/29/128060.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/128060.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2010/09/29/128060.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/128060.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lwch/services/trackbacks/128060.html</trackback:ping><description><![CDATA[首先生成抽象语法树,方法如下:<br>1.根节点为0时表示没有default标签,为1时表示有default标签<br>2.第0个根节点表示switch里的条件<br>3.若有default标签,则最后一个根节点为default子树<br>4.每个根节点为0时表示在此标签下没有stmt_list语句块,这个节点的唯一孩子为要匹配的表达式;为1时表示有语句块,根节点的左孩子表示要匹配的表达式,右孩子为要执行的语句块<br>注意:Equal指令会弹出两操作数,应此在Equal指令执行之前必须先保留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">&nbsp;1</span>&nbsp;<span style="COLOR: #0000ff">integer</span><span style="COLOR: #000000">&nbsp;aaa,bbb<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">&nbsp;ccc()<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;switch&nbsp;aaa&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;aaa&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">123</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">case</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">123</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;aaa&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;aaa&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">&nbsp;aaa&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">789</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">case</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">456</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;aaa&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">123</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000">&nbsp;switch<br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">end&nbsp;function</span></div>
生成虚拟机代码:<br><img height=607 alt="" src="http://www.cppblog.com/images/cppblog_com/lwch/ESLanguage003.PNG" width=668 border=0> 
<img src ="http://www.cppblog.com/lwch/aggbug/128060.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2010-09-29 15:55 <a href="http://www.cppblog.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.cppblog.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.cppblog.com/lwch/archive/2010/09/22/127329.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/127329.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2010/09/22/127329.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/127329.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lwch/services/trackbacks/127329.html</trackback:ping><description><![CDATA[For语句的翻译比较复杂,有3个前置条件和运行代码,1个语句块,也就有4*3*2*1=24种情况.应此在生成抽象语法树的时候我采用的是2进制位来表示当前块是否存在,其中最底位表示stmt_list语句块,倒数第2位表示by之后的语句是否存在,倒数第3位表示to之后的表达式是否存在,倒数第4位表示for之后的语句是否存在.<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">&nbsp;1</span>&nbsp;<span style="COLOR: #0000ff">integer</span><span style="COLOR: #000000">&nbsp;aaa,bbb<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">&nbsp;ccc()<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;aaa&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">456</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">to</span><span style="COLOR: #000000">&nbsp;by&nbsp;</span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;aaa&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">456</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">then</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;aaa&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">789</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">next</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;aaa&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">123</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">&nbsp;aaa&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">123</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">end&nbsp;function</span></div>
翻译结果:<br><img height=431 alt="" src="http://www.cppblog.com/images/cppblog_com/lwch/ESLanguage002.PNG" width=668 border=0>
<img src ="http://www.cppblog.com/lwch/aggbug/127329.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2010-09-22 12:20 <a href="http://www.cppblog.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.cppblog.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.cppblog.com/lwch/archive/2010/09/20/127188.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/127188.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2010/09/20/127188.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/127188.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lwch/services/trackbacks/127188.html</trackback:ping><description><![CDATA[已实现do,while,if和赋值语句的语法制导翻译,这次将他们逐层嵌套起来看看翻译结果是否正确.<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">&nbsp;1</span>&nbsp;<span style="COLOR: #0000ff">integer</span><span style="COLOR: #000000">&nbsp;aaa<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">&nbsp;ccc()<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">&nbsp;aaa&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">123</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;aaa&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">123</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">then</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;aaa&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">456</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">then</span><span style="COLOR: #000000">&nbsp;aaa&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">123</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000">&nbsp;aaa&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">456</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">&nbsp;aaa&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">123</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;aaa&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">456</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">end&nbsp;function</span></div>
翻译结果:<br><img height=687 alt="" src="http://www.cppblog.com/images/cppblog_com/lwch/ESLanguage_001.PNG" width=668 border=0>
<img src ="http://www.cppblog.com/lwch/aggbug/127188.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2010-09-20 22:29 <a href="http://www.cppblog.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.cppblog.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.cppblog.com/lwch/archive/2010/09/19/127034.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/127034.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2010/09/19/127034.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/127034.html</wfw:commentRss><trackback:ping>http://www.cppblog.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>&nbsp;<span style="COLOR: #0000ff">integer</span><span style="COLOR: #000000">&nbsp;aaa<br></span><span style="COLOR: #008080">2</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">3</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">&nbsp;ccc()<br></span><span style="COLOR: #008080">4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;aaa&nbsp;</span><span style="COLOR: #0000ff">and</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">then</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">6</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">end&nbsp;function</span></div>
<br><img border=0 alt="" src="http://www.cppblog.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>&nbsp;<span style="COLOR: #0000ff">integer</span><span style="COLOR: #000000">&nbsp;aaa<br></span><span style="COLOR: #008080">2</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">3</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">&nbsp;ccc()<br></span><span style="COLOR: #008080">4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;aaa&nbsp;</span><span style="COLOR: #0000ff">and</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">then</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;aaa&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">123</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">7</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">end&nbsp;function</span></div>
<br><img border=0 alt="" src="http://www.cppblog.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>&nbsp;<span style="COLOR: #0000ff">integer</span><span style="COLOR: #000000">&nbsp;aaa<br></span><span style="COLOR: #008080">2</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">3</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">&nbsp;ccc()<br></span><span style="COLOR: #008080">4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;aaa&nbsp;</span><span style="COLOR: #0000ff">and</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">then</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">7</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">end&nbsp;function</span></div>
<br><img border=0 alt="" src="http://www.cppblog.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>&nbsp;<span style="COLOR: #0000ff">integer</span><span style="COLOR: #000000">&nbsp;aaa<br></span><span style="COLOR: #008080">2</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">3</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">&nbsp;ccc()<br></span><span style="COLOR: #008080">4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;aaa&nbsp;</span><span style="COLOR: #0000ff">and</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">then</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;aaa&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">123</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">8</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">end&nbsp;function</span></div>
<br><img border=0 alt="" src="http://www.cppblog.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>&nbsp;<span style="COLOR: #0000ff">integer</span><span style="COLOR: #000000">&nbsp;aaa<br></span><span style="COLOR: #008080">2</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">3</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">&nbsp;ccc()<br></span><span style="COLOR: #008080">4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;aaa&nbsp;</span><span style="COLOR: #0000ff">and</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">then</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;aaa&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">123</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">8</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">end&nbsp;function</span></div>
<br><img border=0 alt="" src="http://www.cppblog.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>&nbsp;<span style="COLOR: #0000ff">integer</span><span style="COLOR: #000000">&nbsp;aaa<br></span><span style="COLOR: #008080">2</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">3</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">&nbsp;ccc()<br></span><span style="COLOR: #008080">4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;aaa&nbsp;</span><span style="COLOR: #0000ff">and</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">then</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;aaa&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">123</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;aaa&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">456</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">9</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">end&nbsp;function</span></div>
<br><img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/lwch/If_006.png" width=677 height=442> 
<img src ="http://www.cppblog.com/lwch/aggbug/127034.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2010-09-19 07:27 <a href="http://www.cppblog.com/lwch/archive/2010/09/19/127034.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ESLanguage部分语法制导翻译</title><link>http://www.cppblog.com/lwch/archive/2010/09/17/126918.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Fri, 17 Sep 2010 14:21:00 GMT</pubDate><guid>http://www.cppblog.com/lwch/archive/2010/09/17/126918.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/126918.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2010/09/17/126918.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/126918.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lwch/services/trackbacks/126918.html</trackback:ping><description><![CDATA[首先生成抽象语法树(AST)<br>生成方法:<br>1.移进时将Number,String或Symbol分别加入对应集合<br>2.归约时从集合中取出对应的成员,并删除这条产生式里的所有终结符<br>3.将产生的语法树节点压入栈中<br>4.当遇到产生式item_list-&gt;item_list item或stmt_list-&gt;stmt_list stmt时从栈中弹出两颗语法树并按顺序连接起来<br>5.当遇到非终结符时弹出相应数量的语法树节点,生成新的根节点并把弹出的语法树节点都连接到这个新的根节点上<br>6.当归约到第0条产生式时检查栈的元素数量,1为正常值,然后对抽象语法树进行前序遍历并生成虚拟机代码<br><br><img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/lwch/ESLanguage001.png" width=677 height=442>
<img src ="http://www.cppblog.com/lwch/aggbug/126918.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2010-09-17 22:21 <a href="http://www.cppblog.com/lwch/archive/2010/09/17/126918.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ESLanguage部分语法</title><link>http://www.cppblog.com/lwch/archive/2010/09/17/126912.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Fri, 17 Sep 2010 14:04:00 GMT</pubDate><guid>http://www.cppblog.com/lwch/archive/2010/09/17/126912.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/126912.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2010/09/17/126912.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/126912.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lwch/services/trackbacks/126912.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;1&nbsp;%token&nbsp;"function"&nbsp;"as"&nbsp;"end";&nbsp;&nbsp;2&nbsp;%token&nbsp;"integer"&nbsp;"string"&nbsp;"bool"&nbsp;"pointer";&nbsp;&nbsp;3&nbsp;%token&nbsp;"if"&nbsp;"then"&nbsp;"e...&nbsp;&nbsp;<a href='http://www.cppblog.com/lwch/archive/2010/09/17/126912.html'>阅读全文</a><img src ="http://www.cppblog.com/lwch/aggbug/126912.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2010-09-17 22:04 <a href="http://www.cppblog.com/lwch/archive/2010/09/17/126912.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>