Parser Generator 2 过往资料

背景

我这里讲的Parser Generator 2是Bumble-Bee Software制作的一款解析器开发工具。它的优点就是可以在Windows上通过编写传统的lex和yacc文件来生成解析器源代码。支持生成C/C++和Java两种语言的代码。

以前由于工作的原因接触到这个工具。当时,项目中设计了一种表示版图布局规则的简单语言,需要有对应的解释器。于是我找到了Parser Generator 2,通过几天的学习,发现用这个工具来写是最方便的,而且运行效率高。使用这个工具解决了工作中的这个问题。所以这个工具,在我的心里一直有着重要的地位。

但是,不知道是不是这个工具出得太早了,那时候的IDE开发支持较差、网络环境没有现在便利,再加之主创人员对这个软件使用的便利性和运营的模式都没有正确的认识。导致国内使用这款软件的人好像并不多。如果在本网站上查找,有用的文章不超过10篇。最有影响力的一篇竟然是以Visual Studio 6.0作为工具的。这20几年,IT业迅猛发展,光Visual Studio就发布了十几个版本,但是用户却要为每一个版本重新编译库,编译过程非常不方便。整个工具好像处于无人维护状态,也不为每一个VS发布新的编译脚本,也不增加任何新功能。

虽然Parser Generator的现状令人失望,但是我依然想用现在可得到的工具和代码,对这个工具进行一个完整的介绍。你将看到这款软件在中小型语言或者是具有格式的文本解析方面的强大能力。

下载安装

可以到以下网站下载:http://www.bumblebeesoftware.com/downloads.htm

下载得到一个2M的安装文件,安装一下。我们大致浏览一下安装后的目录:

可以看到有一个Bin,一个Cpp和一个Java目录。Bin下面有个ParGen.exe,这个点开是一个集成开发环境。用来创建解析器项目、编写编译lex和yacc文件用的。另外Cpp目录就是提供C/C++头文件和库的,Java目录是提供Java类和库的。

注册

打开ParGen.exe,发现它是需要注册的。

点开选择第三项

那怎么获得注册码呢?

笔者曾经在刚使用这款工具的时候在网上搜索过,有一个反编译大神闲得无聊随手破解过:

以下为转载内容------------------------------------------------

tankaihaDec 14 2005, 11:19 AM

这几天一直在玩Parser Generator 2(http://www.bumblebeesoftware.com/),顺便看了一下他的注册。这个东东提供一个教学版,如果选择这个版就没有任何限制。如果选择商业版要求输入注册码。看来作者没指望他赚钱,或者老外都比较自觉的注册。废话不多说,来看他的注册码。

跟踪出错的MessageBox,来到这里

00401CE0 8B4424 08 mov eax,dword ptr ss:[esp+8]

00401CE4 85C0 test eax,eax

00401CE6 74 06 je short PGReg.00401CEE

00401CE8 C700 0000>mov dword ptr ds:[eax],0

00401CEE 53 push ebx

00401CEF 55 push ebp

00401CF0 56 push esi

00401CF1 8B7424 10 mov esi,dword ptr ss:[esp+10]

00401CF5 57 push edi

00401CF6 803E 20 cmp byte ptr ds:[esi],20

00401CF9 75 08 jnz short PGReg.00401D03

00401CFB 8A46 01 mov al,byte ptr ds:[esi+1]

00401CFE 46 inc esi

00401CFF 3C 20 cmp al,20

00401D01 ^ 74 F8 je short PGReg.00401CFB

00401D03 8A06 mov al,byte ptr ds:[esi]

00401D05 8BFE mov edi,esi

00401D07 3C 50 cmp al,50 第一位是'P'

00401D09 74 07 je short PGReg.00401D12

00401D0B 5F pop edi

00401D0C 5E pop esi

00401D0D 5D pop ebp

00401D0E 33C0 xor eax,eax

00401D10 5B pop ebx

00401D11 C3 retn

00401D12 8A46 01 mov al,byte ptr ds:[esi+1]

00401D15 46 inc esi

00401D16 3C 47 cmp al,47;第二位是G

00401D18 74 07 je short PGReg.00401D21

00401D1A 5F pop edi

00401D1B 5E pop esi

00401D1C 5D pop ebp

00401D1D 33C0 xor eax,eax

00401D1F 5B pop ebx

00401D20 C3 retn

00401D21 8A46 01 mov al,byte ptr ds:[esi+1]

00401D24 46 inc esi

00401D25 3C 53 cmp al,53

00401D27 74 0B je short PGReg.00401D34

00401D29 3C 4D cmp al,4D

00401D2B 74 07 je short PGReg.00401D34 第三位是'S'或'M'

00401D2D 5F pop edi

00401D2E 5E pop esi

00401D2F 5D pop ebp

00401D30 33C0 xor eax,eax

00401D32 5B pop ebx

00401D33 C3 retn

00401D34 8B2D 4432>mov ebp,dword ptr ds:[<&MSVCRT._ismbcdigit>] ; msvcrt._ismbcdigit没查到是做什么的,可能就是判断是否是数字吧

00401D3A 46 inc esi

00401D3B 33DB xor ebx,ebx

00401D3D 8A06 mov al,byte ptr ds:[esi]

00401D3F 3C 80 cmp al,80

00401D41 73 4E jnb short PGReg.00401D91

00401D43 0FBEC0 movsx eax,al

00401D46 50 push eax

00401D47 FFD5 call ebp

00401D49 83C4 04 add esp,4

00401D4C 85C0 test eax,eax

00401D4E 74 41 je short PGReg.00401D91

00401D50 46 inc esi

00401D51 43 inc ebx

00401D52 83FB 05 cmp ebx,5 ;后面再跟5个数字

00401D55 ^ 7C E6 jl short PGReg.00401D3D

00401D57 8A0E mov cl,byte ptr ds:[esi]

00401D59 8BC6 mov eax,esi

00401D5B 80F9 20 cmp cl,20

00401D5E 75 09 jnz short PGReg.00401D69

00401D60 8A4E 01 mov cl,byte ptr ds:[esi+1]

00401D63 46 inc esi

00401D64 80F9 20 cmp cl,20

00401D67 ^ 74 F7 je short PGReg.00401D60

00401D69 803E 00 cmp byte ptr ds:[esi],0

00401D6C 74 07 je short PGReg.00401D75

00401D6E 5F pop edi

00401D6F 5E pop esi

00401D70 5D pop ebp

00401D71 33C0 xor eax,eax

00401D73 5B pop ebx

00401D74 C3 retn

00401D75 8B7424 18 mov esi,dword ptr ss:[esp+18]

00401D79 85F6 test esi,esi

00401D7B 74 38 je short PGReg.00401DB5

00401D7D 2BC7 sub eax,edi

00401D7F 40 inc eax

00401D80 50 push eax

00401D81 E8 B20700>call <jmp.&MFC42.#823_operator new>

00401D86 8BD0 mov edx,eax

00401D88 83C4 04 add esp,4

00401D8B 85D2 test edx,edx

00401D8D 8916 mov dword ptr ds:[esi],edx

00401D8F 75 07 jnz short PGReg.00401D98

00401D91 5F pop edi

00401D92 5E pop esi

00401D93 5D pop ebp

00401D94 33C0 xor eax,eax

00401D96 5B pop ebx

00401D97 C3 retn

00401D98 83C9 FF or ecx,FFFFFFFF到这里已经注册成功了,准备把注册码写进注册表

00401D9B 33C0 xor eax,eax

00401D9D F2:AE repne scas byte ptr es:[edi]

00401D9F F7D1 not ecx

00401DA1 2BF9 sub edi,ecx

00401DA3 8BC1 mov eax,ecx

00401DA5 8BF7 mov esi,edi

00401DA7 8BFA mov edi,edx

00401DA9 C1E9 02 shr ecx,2

00401DAC F3:A5 rep movs dword ptr es:[edi],dword ptr ds:[esi]

00401DAE 8BC8 mov ecx,eax

00401DB0 83E1 03 and ecx,3

00401DB3 F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]

00401DB5 5F pop edi

00401DB6 5E pop esi

00401DB7 5D pop ebp

00401DB8 B8 010000>mov eax,1

00401DBD 5B pop ebx

00401DBE C3 retn

总结:注册码为PGSxxxxx或PGMxxxxx,xxxxx为任意五位数字。没什么技术含量,纯粹闲着没事灌水了。

以上为转载内容------------------------------------------------

其实我也看不懂,最后的结论就是,Parser Generator 2的注册码就是PGSxxxxx或PGMxxxxx,xxxxx为任意五位数字。就这么简单,比如PGS12345, PGM67890都可以。

编译库

这里讲的是编译C/C++库,网上可以找到不少。但是从Visual Studio 2005开始编译选项发生了变化。当时我找到了一篇有关的文章,转载如下:

以下为转载内容------------------------------------------------

作者:YENI (yeni@yueds.com)

版本:1.0 (2006-10-14)

软件环境

我进行配置的软件环境如下:

  • Windows XP SP2

  • Microsoft Visual Studio 2005 Professional (Version 8.0.50727.42)

  • Parser Generator 2.07

问题原因

经过多次实验,由ParserGenerator生成的.h/.cpp文件确实无法直接在Visual Studio 2005中编译。编译器返回的错误主要为LINK错误,包括符号不存在、运行时间库冲突等问题。我们知道,VS2005的C++编译器与运行库较前版本有重大改动(例如去除了单线程版本库、对DLL版本库做了修改)由这些错误可判断,问题大致在Parser Generator提供的库文件中。我们需要利用Parser Generator中的LibBuilder重新编译这些库文件。

对源代码进行必要的修改

Parser Generator库的源文件全部位于“\Parser Generator2\Cpp\Source”文件夹中,其中共有300多个.c或.cpp文件。其中一部分需要经过修改才可以通过VS2005的编译。

  • 关于全局变量初始化。
    由于C编译器只允许用常量初始化全局变量,但PG库中多处用其他全局对象(如stdout)来初始化变量,因此我们需要把这些文件改名。具体方法是将“*var.c”重命名为“*var.cpp”。

  • 关于“swprintf”及其它已被废除函数的使用。
    在此版本的C++编译器中,一些不符合ISO C++标准的函数已被废除或修正,其中包括“sprintf”、“swprintf”等。特别是“swprintf”函数,其行为也发生了变化。为保证其仍可按照原来的方式工作,我们应该通过设置标识来告诉编译器。具体方法是在“..\Include\yyglobal.h”中添加“#define _CRT_NON_CONFORMING_SWPRINTFS”一行。

修改编译脚本

Parser Generator的LibBuilder通过运行一个编译脚本来完成库编译。该编译脚本位于“\ParserGenerator 2\Cpp\Script\msvc32.lbs”。

由于新C++编译器及链接器参数的变化,我们需要对该脚本做以下修改。

  • 通过“查找功能”将第一个“/GZ”参数改为“/EHsc”(这将用于编译器)。

  • 将第二个“/GZ”参数改为“/RTC1”(这将用于链接器)。

编译库

完成了上述准备工作,我们就可以开始编译Parser Generator库了。

  1. 在Parser Generator中从菜单选择“Project”、“LibBuilder”。

  1. 只勾选“Visual C++ (32-bit)”一项,并选中该项,按“Properties…”按钮打开属性框。

  1. 由于没有直接提供 8.0的选项,我们进行如下配置:

  1. Compiler Version: Versoin7(.NET)

  1. Unicode: True

  1. Treat w_char_t as Build-inType: True

  1. Compiler Bin Directory: C:\PROGRAMFILES\MICROSOFT VISUAL STUDIO 8\VC\BIN

  1. Compiler Bin Directory(2): C:\PROGRAMFILES\MICROSOFT VISUAL STUDIO 8\COMMON7\IDE

  1. Compiler Include Directory: C:\PROGRAMFILES\MICROSOFT VISUAL STUDIO 8\VC\INCLUDE

  1. Compiler Include Directory(2): C:\PROGRAMFILES\MICROSOFT VISUAL STUDIO 8\VC\PLATFORMSDK\INCLUDE

  1. Compiler Library Directory: C:\PROGRAMFILES\MICROSOFT VISUAL STUDIO 8\VC\LIB

  1. Compiler Library Directory(2): C:\PROGRAMFILES\MICROSOFT VISUAL 8\VC\PLATFORMSDK\LIB

  1. 按“OK”保存属性。

  1. 按“Build”开始编译所有库文件。整个编译过程会接到数个Warning,主要是提示部分函数已过时。编译过程大约会持续10分钟。

  1. 若编译成功,既可按照本文前面“快速向导”一节内容设置并使用VS2005和ParserGenerator共同开发了。

已知问题

以上的解决方案还不甚完善,已知的问题和需要完善的地方如下:

  • 在编译库的过程中仍会接到数个关于函数过时的Warning。因此有必要修改库的源代码,使其符合新版C++的相应规则。

  • 在Debug配置下运行程序会产生与iostream相关的错误导致程序无法运行。我认为此问题也与上一条所述有关,需要通过修改源代码来完善。

  • 编译脚本文件“msvc32.lbs”本身已经提供了可扩展性,我们可以很容易地将新版本的配置添加到该.lbs文件中,而不应该直接修改.lbs文件内容。

以上问题将在此解决方案的新版本中得到解决。

以上为转载内容------------------------------------------------

这篇文章的链接已经失效,所以先贴在这里,这是文章的后半部分。当时,我参考这个内容,在Visual Studio 2005和后来的Visual Studio 2010上进行了正确编译。(在VS2010上编译还要提供Windows SDK的相关目录)。我在这里转发这个内容,不是要大家按这个去编库。只是为了记录一下过往的资料。其实以现在软件开发的发展情况,大可不必再使用这个工具本身提供的LibBuilder去编这些库。后面可以单独讨论编库的问题。

项目配置与使用

其实配置与使用的文章蛮多的,基本上只要搜索就能找到。比如这篇就非常好:

https://blog.youkuaiyun.com/jianxia_wzx/article/details/7782052

我在这里就不赘述了。

总结

到这里Parser Generator 2的基本背景、使用方法等,过去的资料都做了汇总。读者大可不必按本文的内容编译库,现在的编译工具已今非昔比。我们要找到一些新的做法,突破限制。关于库的问题和其他使用技巧我将提供后续内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值