返回首页

{A}{S0}简介
在计算机科学中的更为艰巨的任务之一是建立分析器和编译器。有很多工具可用,在繁琐的任务援助,最特别的是,Flex和Yacc的,无论是在Linux / UNIX平台上。该计划,我目前在这篇文章中这里被称为TokenIcer。这是一个类似的Flex,但TokenIcer提供了一个很好的易于使用的测试您的规则的图形用户界面,可作为您的规则编辑器,以及一个测试床。此外,一旦你的解析规则已被定义,TokenIcer可以创建一个解析器类,根据你的规则,在C#或VB.NET背景
为了能够使用好TokenIcer,你应该有一个不错的正则表达式是如何工作的理解。你进入到TokenIcer每个规则将基于一个正则表达式。任何正则表达式。NET正则表达式库可以解析,也将在TokenIcer有效。
解析器的工作方式,也TokenIcer将工作的方式,就是你到分析器饲料某种输入字符串。例如,如果我们送入解析器以下行:

3+2 * (6 + 1)  

我们应该期待我们的解析器为我们提供这样的输出:{C}
我们这个解析器输出取决于正是我们所试图完成的任务。也许你正在建设一个语言的编译器,或者一个数学解析器。这是什么TokenIcer。它需要输入像"3 2 *(1)quot;,并转换成一系列枚举值。 使用代码
当你运行TokenIcer时,您将与3个文本框的屏幕和一个TreeView的。第一个文本框,是我们进入我们的规则。规则简单地包裹引号之间的正则表达式。紧随规则是空间(或多个空格,如果你愿意)。以下的空间,是该规则的标识符。至于上面的例子中,一个标识符可以像整数,空白或任何你想用的东西。可以使用任何有效的VB.NET或C#标识符。继续前进,在文本框中输入以下规则:
"[0-9]+" INTEGER 

此规则将正确地确定一个整数。在中间的文本框,是我们的测试床。根据你在它上面的文本框中的规则,任何你在这里输入将被解析。来吧,你希望在测试中,输入任何整数。一旦你进入你的电话号码,请按一下quot;测试Grammarquot;在窗口的左侧底部的按钮。一旦你做,你会看到第三个文本框,输出的文本框,确实,正确识别作为一个{INTEGER的}我们的电话号码。输出树也显示整数,但如果展开树,你会看到解析器解析的实际价值。现在继续,并输入以下两条规则中的第一个文本框,紧随第一条规则:
"[0-9]+\.+[0-9]+" FLOAT

"[ \t]+" WHITESPACE

在您的测试中,尝试下面的测试:
3.2 15 4.932 

继续并单击quot;测试Grammarquot;你可能会惊讶地看到一堆的quot; UNDEFINEDquot;标签并没有浮法标签。 (疑难杂症#1)的原因是因为解析器会解析投入使用的第一条规则匹配。使你的规则时,你必须把quot; priorityquot较高;规则第一。分析器来的quot; 3quot;,说quot;确定3 integerquot;它连看都不看过去的3,看看是否有一个小数点。为了解决这个问题,只需把以上INTEGER行的浮法线。这样,解析器将尝试相匹配的浮动规则,如果没有小数点,移动INTEGER规则。更改您的规则,在规则文本框中周围,所以它看起来像这样:
"[0-9]+\.+[0-9]+" FLOAT

"[0-9]+" INTEGER

"[ \t]+" WHITESPACE 

现在,如果您按一下",测试Grammarquot,输出中和输出树看起来不如预期。这是现在可以正确地解析你所期望的。
结束本节,我现在将显示您如何TokenIcer可以创建C#或VB.NET类,可以包括在自己的项目。既然我们现在有三个规则,他们没有输入测试,去按一下按钮,上面写着quot;生成类... ... quot;当你这样做,弹出一个窗口与一个降下来询问你喜欢的语言列表。您可以选择C#或VB.NET。也有一种意见,包括复选框。如果选中此复选框,也会产生一些简单的评论,以帮助您了解的代码。一旦你选择你的语言,点击quot;生成Classquot;和另一个窗口会弹出生成的C#或VB.NET代码。你可以打LT; Ctrlgt;一个选择这一切,LT; Ctrlgt,C的代码复制到自己的项目。它的一切就是这么简单!
TokenParser类公开下列财产:InputString - 实例的TokenParser副本后,你必须设置此字符串属性,你要解析的字符串值。
TokenParser类公开下列方法: GetToken() - 从输入字符串调用此方法来检索下一个标记。 GetToken()方法返回一个记号对象。令牌对象包含TokenName(这是你在你的规则前面定义的标记枚举,如整数,空白,持股量),它包含了TokenValue。 TokenValue将会从解析器中检索值。例如,一个整数可能返回"53quot;例如。PEEK() - 此方法将返回下一个标记,GetToken()将返回。它可以让你看看在未来的令牌缓冲区没有脱下任何队列。 PEEK()的返回值是一个PeekToken。一个PeekToken是一个特殊的的对象,它包含一个记号对象和索引。 PEEK()通过调用和PEEK的参数(),聚醚醚酮()传递一个PeekToken将返回最后PEEK()调用后返回的令牌。这样,你可以偷看未来几个令牌深。ResetParser() - 此方法重置解析器。调用此之后,您必须设置字符串InputString财产,那么你可以调用GetToken()或PeekToken(),你通常会解析一个新的字符串。评论
TokenIcer支持两种类型的评论。内嵌的意见和全行注释。这两种意见都是通过前面加上一个hash符号(#符号)您的评论。评论第一种类型,内联的意见,评论枚举的方式。看看这个例子:
"[a-zA-Z_][a-zA-Z0-9_]*" IDENTIFIER #This is an Identifier 

当您创建您的C#或VB.NET类,您可以选择评论规则。如果此选项是打开的,那么您有任何意见与您的规则中的内联将增加一条,作为一个生成枚举的注释。
第二种类型的注释是一个完整的行注释,像这样:
# This line is completely ignored.  

任何规则的一个hash符号开头的行是完全忽略。反正你认为合适的,你可以使用你自己的目的。语法规则范例
这里是一个非常简单的基本分析器的例子:
"[Ll][Ee][Tt]" LET

"[Pp][Rr][Ii][Nn][Tt]" PRINT

"[Cc][Ll][Ss]" CLS

"[Rr][Ee][Mm][^\r\n]*" REM

"[Ee][Nn][Dd]" END

"[Gg][Oo][Tt][Oo]" GOTO

"[Ff][Oo][Rr]" FOR

"[Ss][Tt][Ee][Pp]" STEP

"[Nn][Ee][Xx][Tt]" NEXT

"[Tt][Oo]" TO

"\:" COLON

"=" EQUALS

"\".*?\"" STRING

"[a-zA-Z_][a-zA-Z0-9_]*"     IDENTIFIER

"[ \t]+" WHITESPACE

"[\r\n]+" NEWLINE

"[0-9]?\.+[0-9]+" FLOAT

"[0-9]+" INTEGER

"'.*" APOSTROPHE

"\(" LPAREN

"\)" RPAREN

"\*" ASTERISK

"\/" SLASH

"\+" PLUS

"\-" MINUS 

这些规则可以正确地解析下列程序:
10 CLS

20 PRINT "Hello" : PRINT " World!"

30 X = 5

40 Y = X * 2 + 3.5

50 PRINT Y

60 FOR Z = 50 TO 1 STEP -1

70 PRINT "Z = " + Z

80 NEXT Z

90 END

随意扩大语法规则和尝试,使自己的BASIC编译器!历史2011年7月3日 - 版本1.0发布2011年7月5日 - 版本1.1发布。 TokenIcer现在可以保存语法和测试输入文件!2011年7月7日 - 版本1.2发布。 TokenIcer现在可以正常使用时保留VB.NET或C#关键字作为标识符。此外,做了一些代码重构,清理一些东西。2011年7月8日 - 版本1.3发布。 GetToken()发动机现在快95%左右(感谢您的帮助T_uRRiCA_N)。此外,规则编辑器"文本框中,现在更容易阅读的行号。2011年7月9日 - 版本1.4发布。之前,我到新的功能,我只是想在这样短的时间内有这么多的更新道歉。我答应慢下来一点,至少在一个星期左右,你不会看到新的更新,(在此版本中,除非有一些重要的错误)。这个版本好了新的功能包括语法高亮显示,以及一个新的选项菜单中禁用或改变颜色,以及禁用行号的能力。此外,这个版本现在支持的意见,内联和全行注释。还增加了选项来创建XML风格的注释,这样就可以创建文档使用沙塔或其他一些方案。

回答

评论会员:lovegq 时间:2012/02/04
规则:

"="等于
"\"加上#
"\ ="plus_equal#
"\ D"INT
"\ W"ID
"\ *"空白

公告称,规则"plus_equal"是"加"后的规则。

输入文本:

A = 2

输出文本:

{ID} {空白} {加} {平等} {空白} {INT}
 0; -----------{ BR}它的{加}和{平等},{plus_equal}

开关的位置规则A和规则B

u得到这样的输出:
{ID} {空白} {plus_equal} {空白} {INT}

它的{plus_equal},{加}和{相等}

贪婪或没有? ü不能仅仅的foreach的字典,需要超前,以决定应该选择哪条规则。
或者,你可以重写的规则A与规则B,将它们合并到一个规则

"\ (=)?" #plus_or_plus_equal

但我不喜欢这些,它很丑陋的。

所以,"贪婪"点,u能修复它
?icemanind
评论会员:游客 时间:2012/02/04
你必须把"优先"的规则,提前"非优先"的规则。因此你需要做你的规则如何的是这样的:"\="plus_equal#"="等于"\"加上#"\D"INT"\W"ID"\*"空白如果您正在创建2个或更多字符的规则,他们需要提前单的单个字符,这样的规则相匹配的第一。这个意义上,我需要更清晰?读我的文章,解析整数和浮点数时,我指出这一点^^^
T_uRRiCA_N
评论会员:游客 时间:2012/02/04
在当前阶段,你劈裂成标记您的输入什么记号,正确的顺序规则-语法我知道,这是不是真的很容易。我也看过有关ANTLR(ANTLRworks)...{BR}也许你有想法吗?问候,T_uRRiCA_N我不知道的事情,我可以补库
icemanind
评论会员:游客 时间:2012/02/04
我使用一个开源的工具包,词法分析和语法分析,并有很好的效果您可以在imgsrc=http://www.orcode.com/img/ico/smiley_wink.gifLiron
T_uRRiCA_N
评论会员:游客 时间:2012/02/04
评论。虽然花园点的词典应用程序是不错的,我认为我仍然有一定的优势,以及在竞争中的一些缺点。原因之一,我有一个漂亮的图形编辑您的规则,那里的花园点词法仅仅是一个命令行程序的后端。第二,我的应用程序可以创建不仅C#的,但也VB.NET和未来可能的其他语言。此外,生成的代码,我的工具是自给自足,这意味着你只需要添加一个源文件到您的项目。不需要额外的库需要链接。我不知道,如果这是真的花园或不点,但很多第三方词典需要额外的库。无论如何,我不是要敲花园点。我只是想找到一个在我的程序和竞争的之间的分离
。icemanind
评论会员:游客 时间:2012/02/04
您好,我觉得我做了很大的改善。我的代码是现在快13倍。2486记号,我减少了识别时间从1250ms到96ms。imgsrc=http://www.orcode.com/img/ico/smiley_biggrin.gif我实现了预正则表达式的整个事情,并存储在字典中产生的matchcollections。然后,我分析这本字典的方式。在类TokenParser我补充道:codeprePrivate_REGexAsNewDictionary(OfTokens,MatchCollection)/pre/code然后,我添加了一个小组(C#中:void函数)codeprePublicSubPrepare_REGex()ForEachpairAsKeyValuePair(OfTokens,spanclass="code-SDKkeyword"String/span)In_tokens_REGex.Add(pair.Key,Regex.Matches(_inputString,pair.Value))NextEndSub/pre/code我在GetToken功能改变检测例程:codeprePublicFunctionGetToken()AsTokenIf_index=_inputString.LengthThenReturnNothingEndIf ForEachpairAsKeyValuePair(OfTokens,MatchCollection)In_REGexForEach_MatchAsMatchInpair.ValueIf_Match.Index=_indexThen_index+=_Match.LengthReturnNewToken(pair.Key,_Match.Value)ElseIf_Match.Index_indexThenExitForEndIfNextNext _index+=spanclass="code-digit"1/spanReturnNewToken(Tokens.[UNDEFINED],spanclass="code-SDKkeyword"String/span.Empty)EndFunction/pre/code不要忘记ResetParser,地址:现在你只需要调用Prepare_REGex()之前运行所有GetToken调用。,我仍然舒尔,还有更重要的。你只需要翻译到C#和测试,如果我这样做是正确的......问候,T_uRRiCA_N我不知道的事情,我可以填补库
T_uRRiCA_N
评论会员:游客 时间:2012/02/04
感谢您的帮助。我做了一些小的修改您提交像现在快95%的变化。我刚刚上传修订GetToken()函数的新版本,现在随着行号上的规则编辑器"窗口
。icemanind
评论会员:游客 时间:2012/02/04
您好icemanind,我喜欢你的词法分析,很好的工具。但有一个改善点在VB角它的类生成工具当您创建所有的枚举,你有问题,当您使用保留字,如让,REM,GOTO等请使用括号中的所有一般枚举-[的LET],[REM]...因此,改变枚举的声明和新的常规。其他最小的改善是:更换这样的行:_index=_indexm.Length与_index=m.Length此外,我相信必须有一个更快的方法来分析。采取的最长时间是在GetToken这个"新的Regex"目前,它需要我1227ms找到2486令牌。来吧,这是一个好方法问候,T_uRRiCA_N我不知道的事情,我可以补库
T_uRRiCA_N
评论会员:游客 时间:2012/02/04
好吧,我固定的错误,让你可以使用VB.NET或C#关键字作为标识符保留。你枚举不应该打破了。我也换成了指数=mLength建议。我会找到一个方式来优化TokenIcer更好一点。感谢您的建议
icemanind
评论会员:游客 时间:2012/02/04
嘿,魅力也_index=_index1-_index=1{S2}我不知道的事情,我可以补库
icemanind
评论会员:游客 时间:2012/02/04
对不起!我不能看到一个语法的任何地方。工具的名称是正确的,因为它仅用于指定如何标记化输入。"测试语法"是有点误导虽然文法产生式规则的分析输入令牌。断词是做词法分析的解析过程中的一部分。干杯
!Rhuros
评论会员:游客 时间:2012/02/04
我知道对某些人来说,这个词的语法可能会产生误导,因为语法规则,分析如何分析输入流中的令牌。但在本文中,我根本没有一个更好的词,浮现在脑海中的"语法"。这是我的意图,有一天,以扩大根据这项计划,也许有一天,它会做一个真正的"语法分析"。但在任何情况下,我道歉的混乱,我希望你享受这个方案
!理查德安德鲁64
评论会员:游客 时间:2012/02/04
其实这只是标题设置我偏离了轨道。而不是调用解析器,你可以说:"轻松创建自己的TokenIcer"我会不喜欢您的帐户名称的文字游戏。{S2}干杯!mdash;MRB:"我的最新一个被称为"在我所有的项目名称
| icemanind哈哈我"一直以来作为冰人永远所以我尽量纳入"冰IceSQL"(发音冰柱)无论如何,重新表决的感谢
评论会员:。杰里米哈钦森 时间:2012/02/04

不错的工作
评论会员:icemanind 时间:2012/02/04
,这是一个词法分析器,但它不是一个解析器
的困难,我们马上去做...
... ...不可能的时间稍长