??xml version="1.0" encoding="utf-8" standalone="yes"?>
最?span lang="EN-US">,只好选择再装一?span lang="EN-US">VC6, ?span lang="EN-US">, 两个VC, 不错.
先介l一?span lang="EN-US">Parser Generator,主页下蝲:http://www.bumblebeesoftware.com/downloads.htm
Parser Generator is a YACC and Lex programming tool for Windows. As well as including a Graphical User Interace, the software also includes two versions of YACC and Lex, called AYACC and ALex. Parser Generator is able to generate C, C++ and Java parsers and lexical analysers. This includes both Unicode and Multibyte Character Set (MBCS) variants. In your applications you can create multiple, thread safe, instances of these parsers and lexical analysers.
下面说一?span lang="EN-US">windows环境?span lang="EN-US">parser generator?span lang="EN-US">vc++的各w|?span lang="EN-US">
Q一Q?span lang="EN-US">parser generator的环境设|?span lang="EN-US">
安装?span lang="EN-US">parser generatorQ打开集成开发环境,炚w?span lang="EN-US">Project菜单Q在下拉菜单中?span lang="EN-US">LibBuilderQ弹?span lang="EN-US">LibBuilder对话框选择属性按钮,弹出compiler properties 对话框:
Name 选择Visual C++ (32-bit)
Directory :msvc32
options:
依次?vc++版本(Versoin 6)
是否支持unicode码?span lang="EN-US">(选择默认)
是否?span lang="EN-US">w_char_t作ؓ内徏cd?span lang="EN-US">(选择默认)
下边?span lang="EN-US">VC的各U目录:
依次?span lang="EN-US">
Compiler Bin Directory (C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\VC98\BIN
Compiler Bin Directory(C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\COMMON\MSDEV98\BIN
Compiler Include Directory(C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\VC98\INCLUDE
Compiler Include Directory(C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\VC98\MFC\INCLUDE
Compiler Library Directory(C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\VC98\LIB
Compiler Library Directory(C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\VC98\MFC\LIB
注意Q编译器安装目录Ҏ个h安装目录需要做相应的调整。所有的q些讄完成之后?span lang="EN-US">ok?span lang="EN-US">
最后一?span lang="EN-US">,配置parser generator?span lang="EN-US">properties,如图卛_:
q回LibBuilder。点Build可以编?span lang="EN-US">vc++使用?span lang="EN-US">lex?span lang="EN-US">yacc?span lang="EN-US">lib库?span lang="EN-US">
?span lang="EN-US">:我参?span lang="EN-US">Vs 2003.net的设|?span lang="EN-US">,?span lang="EN-US">VC 2005下进行相应设|?span lang="EN-US">, l果lex?span lang="EN-US">yacc?span lang="EN-US">lib库没能编译通过, 可能是我讄错误, 不应该是不兼容的问题吧.
生成库文件在软g安装目录下的D:\Parser Generator 2\Cpp\Lib\msvc32目录下?span lang="EN-US">
Q二Q?span lang="EN-US">vc++环境的设|?span lang="EN-US">
1.目录讄
Z?span lang="EN-US">VC++中可以找到包含文?span lang="EN-US">yacc.h?span lang="EN-US">lex.h以及YACC?span lang="EN-US">Lex的库文gQ需要对VC++q行相关的目录设|?span lang="EN-US">
Q?span lang="EN-US">1Q?span lang="EN-US"> 选择Tools菜单中的Options命oQ打开Options对话框?span lang="EN-US">
Q?span lang="EN-US">2Q?span lang="EN-US"> 选择Directories选项卡?span lang="EN-US">
Q?span lang="EN-US">3Q?span lang="EN-US"> ?span lang="EN-US">Show Directories for下拉列表框中选择Include Files?span lang="EN-US">
?span lang="EN-US">Directories框中Q点L后的I目录,q填?span lang="EN-US"> F:\PARGEN\CPP\INCLUDE(Ҏ个h安装目录需要做相应的调?span lang="EN-US">)
Q?span lang="EN-US">4Q?span lang="EN-US"> ?span lang="EN-US">Show Directories for下拉列表框中选择Library Files?span lang="EN-US">
?span lang="EN-US">Directories框中Q点L后的I目录,q填?span lang="EN-US">F:\PARGEN\CPP\LIB\MSVC32
Q?span lang="EN-US">5Q?span lang="EN-US"> ?span lang="EN-US">Show Directories for下拉列表框中选择Source Files?span lang="EN-US">
?span lang="EN-US">Directories框中Q点L后的I目录,q填?span lang="EN-US">F:\PARGEN\CPP\SOURCE
Q?span lang="EN-US">6Q?span lang="EN-US"> 点击OK按钮,Options对话框将接受讄q关闭?span lang="EN-US">
2Q项目设|?span lang="EN-US">
对于每个VC++目Q都需?span lang="EN-US">VC++中进行以下设|?/span>Q以?span lang="EN-US">VC++可以从特定的库中接受LEX?span lang="EN-US">YACC所需要的函数和变?span lang="EN-US">
Q?span lang="EN-US">1Q?span lang="EN-US"> 选择Project菜单中的Settings命oQ打开Project Settings对话框?span lang="EN-US">
Q?span lang="EN-US">2Q?span lang="EN-US"> ?span lang="EN-US">Settings for下拉列表框中选择Win32 Debug?span lang="EN-US">
Q?span lang="EN-US">3Q?span lang="EN-US"> 选择C/C++选项卡, ?span lang="EN-US">Category下拉列表框中选择General?span lang="EN-US">
?span lang="EN-US">Preprocessor Definitions框中Q在当前文本的最后,输入
Q?span lang="EN-US" style="color: red">YYDEBUG
?span lang="EN-US">:对应?span lang="EN-US">VC 2005?span lang="EN-US">C/C++->Preprocessor->Preprocessor Definitions.
Q?span lang="EN-US">4Q?span lang="EN-US"> 选择Link选项卡,?span lang="EN-US">Category下拉列表框中选择General?span lang="EN-US">
?span lang="EN-US">Object/Library Modules框中Q在当前文本的后面,输入yld.lib
?span lang="EN-US">:VC 6中的Object/Library Modules对应?span lang="EN-US">VC 2005?span lang="EN-US">Propert->Configuration Properties->Linker->Input->Additional Dependencies ,找了好久.
Q?span lang="EN-US">5Q?span lang="EN-US"> ?span lang="EN-US">Settings for下拉列表框中选择Win32 Release?span lang="EN-US">
Q?span lang="EN-US">6Q?span lang="EN-US"> 重复W?span lang="EN-US">4步的工作?span lang="EN-US">
Q?span lang="EN-US">7Q?span lang="EN-US"> 点击OK按钮Q?span lang="EN-US">Project Settings对话框设|完毕?span lang="EN-US">
q样讄之后我们可以用vc++~译Parser Generator 生成?span lang="EN-US">c文g了。具体ؓQ?span lang="EN-US">
先打开Parser Generator 集成开发环境。点?span lang="EN-US">Project菜单Q点M拉菜单中?span lang="EN-US">ParseWizard菜单Q一路下d立一个工E。然后点?span lang="EN-US">project菜单下的?span lang="EN-US">Rebuild All。在目文g夹下q成了相应c文g?span lang="EN-US">h文g?span lang="EN-US">
再用VC++建立一个空控制台工E,然后把用?span lang="EN-US">Parser Generator
生成?span lang="EN-US">c文g和头文g加入工程中。接着?span lang="EN-US">VC++q行上面所说的目讄Q然后就可以~译q行了。新手可以?span lang="EN-US">parser generator 自带的范例,q样方便验环境的配置是否正确.
Lex ?Yacc ?Unix 和Linux 下词法和语法的分析,解析工具Q有了这两个工具Q你可以自己制作惌的编译器Q也可以重新制作已有E序语言的解析器。需要注意的是linux下的q两个工L成的E序源码只能是C和C++语言Q当然现在早已有cM可以生成Java源码的语法分析器Q如较常用的JavaCC(Java Compiler Compiler)Q相兛_容可以去|上搜烦。Lex和Yacc已被UL到windows下,现在常用的工hParser Generator。本文只介绍Linux 下Lex和Yacc的用方法?br>
Lex介绍
Lex 通过?lex?l文g定义的格式生成一个C语言源码文gQ通过~译q个源码Q就生成?lex文g?l文g定义的编译器?lex?l文g的格式分三段:
1.全局变量声明部分
2.词法规则部分
3.函数定义部分
以下是一个简单的例子Qlex_example.l文g
%{ //全局声明部分
/*林木100 linux
www.linmu100.com
*/
#include <stdio.h>
extern char *yytext;
extern FILE *yyin;
int sem_count = 0;
%}
//规则定义部分Q?br>%%
[a-zA-Z][a-zA-Z0-9]* {printf("WORD[%s] ", yytext);}
[a-zA-Z0-9\/.-]+ printf("FILENAME ");
\" printf("QUOTE ");
\{ printf("OBRACE ");
\} printf("EBRACE ");
; {sem_count++; printf("SEMICOLON ");}
\n printf("\n");
[ \t]+ /* ignore whitespace */;
%%
//以下为函数定义部?br>int main(int avgs, char *avgr[])
{
yyin = fopen(avgr[1], "r");
if (!yyin)
{
return 0;
}
yylex();
printf("sem_count : %d\n", sem_count);
fclose(yyin);
return 1;
}
Lex 常用格式如下表,常规表达式:
字符 |
含义 |
A-Z, 0-9, a-z |
构成了部分模式的字符和数字?o:p> |
. |
匚wL字符Q除?\n?o:p> |
- |
用来指定范围。例如:A-Z 指从 A ?Z 之间的所有字W?o:p> |
[ ] |
一个字W集合。匹配括号内的Q?nbsp;字符。如果第一个字W是 ^ 那么它表C否定模式。例? [abC] 匚w a, b, ?C中的M一个?o:p> |
* |
匚w0个或者多个上q的模式?o:p> |
+ |
匚w1个或者多个上q模式?o:p> |
? |
匚w0个或1个上q模式?o:p> |
$ |
作ؓ模式的最后一个字W匹配一行的l尾?o:p> |
{ } |
指出一个模式可能出现的ơ数?例如: A{1,3} 表示 A 可能出现1ơ或3ơ?o:p> |
\ |
用来转义元字W。同L来覆盖字W在此表中定义的Ҏ意义Q只取字W的本意?o:p> |
^ |
否定?o:p> |
| |
表达式间的逻辑或?o:p> |
"<一些符?gt;" |
字符的字面含义。元字符h?o:p> |
/ |
向前匚w。如果在匚w的模版中?#8220;/”后跟有后l表辑ּQ只匚w模版?#8220;/”前面的部分。如Q如果输?A01Q那么在模版 A0/1 中的 A0 是匹配的?o:p> |
( ) |
一pd常规表达式分l?o:p> |
常规表达式D?o:p>
常规表达?o:p> |
含义 |
joke[rs] |
匚w jokes ?joker?o:p> |
A{1,2}shis+ |
匚w AAshis, Ashis, AAshi, Ashi?o:p> |
(A[b-e])+ |
匚w?A 出现位置后跟随的?b ?e 的所有字W中?0 个或 1个?o:p> |
使用lex扫描上述举例文g lex_example.lQ?br>lex lex_example.l
~省会生成lex.yy.c文gQ然后用gcc~译q个文gQ注意要?ll选项:
gcc lex.yy.c -o analyse -ll
q样q成了一个简单的词法分析器analyseQ假设有文gdemoQ其内容如下所C?
firstword;
secondword;
thirdword
fourthword{
fifthword
}
输入命o:
./analyse demo
会有如下昄Q?br>WORD[firstword] SEMICOLON
WORD[secondword] SEMICOLON
WORD[thirdword]
WORD[fourthword] OBRACE
WORD[fifthword]
EBRACE
sem_count : 2
实际上,对于上述lex_example.l文gQ函数定义部分可以完全省略,因ؓlex会自动ؓ你生成main函数。这时仍然按上述Ҏ生成analyseQ输入命?
./analse < demo
l果如下Q?br>WORD[firstword] SEMICOLON
WORD[secondword] SEMICOLON
WORD[thirdword]
WORD[fourthword] OBRACE
WORD[fifthword]
EBRACE
在上qlex_example.l文g中我们还使用了两个变量:
extern char *yytext;
extern FILE *yyin;
q两个变量是lex提供的外部借口Q用户可以根据自己需要自己更改,lex提供了以下接口:
Lex 变量
yyin |
FILE* cd?它指?lexer 正在解析的当前文件?o:p> |
yyout |
FILE* cd?它指向记?lexer 输出的位|?~省情况下,yyin ?yyout 都指向标准输入和输出?o:p> |
yytext |
匚w模式的文本存储在q一变量中(char*Q?o:p> |
yyleng |
l出匚w模式的长度?o:p> |
yylineno |
提供当前的行C息。(lexer不一定支持。) |
Lex 函数
yylex() |
q一函数开始分析?它由 Lex 自动生成?o:p> |
yywrap() |
q?一函数在文Ӟ或输入)的末调用。如果函数的q回值是1Q就停止解析?因此它可以用来解析多个文件。代码可以写在第三段Q这p够解析多个文件?Ҏ是?yyin 文g指针Q见上表Q指向不同的文gQ直到所有的文g都被解析。最后,yywrap() 可以q回 1 来表C析的l束?o:p> |
yyless(int n) |
q一函数可以用来送回除了前憂? 个字W外的所有读出标记?o:p> |
yymore() |
q一函数告诉 Lexer 下一个标记附加到当前标记后?o:p> |
以下是一个计字W个数的.l文g内容Q有兴趣的朋友可以编译试?br>%{
/*
林木100 linux
www.linmu100.com
*/
int wc = 0; /* word count */
%}
%%
[a-zA-Z]+ { wc++; }
\n|. { /* gobble up */ }
%%
int main(void)
{
int n = yylex();
return n;
}
int yywrap(void)
{
printf("word count: %d\n", wc);
return 1;
}
yacc介绍
Yacc ?Yet Another Compiler Compiler的羃写?Yacc ?GNU 版叫?Bison。它是一U语法解析工兗它用巴U斯范式(BNF, Backus Naur Form)来书写。按照惯例,Yacc 文g?.y 后缀?br>实际上,yacc才是真正分析语法的核心,.y文g格式?l文g一样分三段Q但每一D늚意义有所不同Q?br>1.全局变量声明Q终l符?l端W号)声明
2.语法定义
3.函数定义
以下是一个简单的yacc_example.y文gQ定义了一个简单的计算器:
%{
//全局变量声明
#include <ctype.h>
#include <stdio.h>
#define YYSTYPE double /*double type for YACC stack; for yylval*/
/*林木100 www.linmu100.com */
void yyerror(const char *str)
{
fprintf(stderr, "error:%s\n", str );
}
%}
//l结W声?nbsp;
%token NUMBER
%%
lines : lines expr
| lines
| /* e */
| error
;
expr : expr
| expr
| term
;
term : term
| term
| factor
;
factor :
|
|
| NUMBER
;
%%
//以上部分法定义,以下部分为函数定?nbsp;
int main(void)
{
return yyparse();
}
int yylex(void)
{
int c;
while ((c = getchar()) ==
if (c ==
ungetc(c, stdin);
scanf("%lf", &yylval);
return NUMBER;
}
return c;
}
使用yacc扫描q个文gQ?br>yacc yacc_example.y
~省会生成一个y.tab.c文gQ然后用gcc~译q个文gQ注意要有选项 -ll ?nbsp;-lyQ?br>gcc y.tab.c -o analyse -ll
q行./analyseQ结果如下图所C?
现在对照yacc_example.y文g讲解一?y文g的规则:
1.在全局变量声明部分Q声明了一个接口函数yyerrorQ这个函数是用来在出错时调用的。这一D主要是声明一些变量,数据l构Q函数用?br>2.%token NUMBER则声明了一个终端符(l结W?Q这个符h由Lexq回的,会在yacc语法规则中用到?br>3.语法规则部分则声明了语法Q?br> 3.1语法规则对外只有一个接口,q一点要注意Q初学者常怼犯语法对外有多个接口的错误?br> 3.2无论是lex文gq是yacc文g都要注意最大可能性的词法和语法规则要攑֜冲突规则的前面,q样保证了最大可能规则会被最先匹配,比如lex文g中:
temperator return T1;
temp return T2;
在yacc文g中,例子如下
command:
NUMBER CHAR
| NUMBER
;
对于.y文gq要注意全局语法Q以及递归的调用?br>
初学者对于yacc文g规则可能会较为生疏,关键q要多做一些练习?br>
Lex ?Yacc 的结?br>
lex和yaccl合旉要注意的?br>lex文g头要引用yacc生成的头文g:"y.tab.h"
以下是一个lex和yaccl合的实例:
lex_yacc_exp.l文gQ?br>%{
/*林木100
www.linmu100.com
*/
#include <stdio.h>
#include <string.h>
#include "y.tab.h"
extern char *yytext;
%}
%%
[0-9]+ yylval.number=atoi(yytext); return NUMBER;
heater return TOKHEATER;
heat return TOKHEAT;
on|off yylval.number=!strcmp(yytext,"on"); return STATE;
target return TOKTARGET;
temperature return TOKTEMPERATURE;
[a-z0-9]+ yylval.string=strdup(yytext);return WORD;
\n /* ignore end of line */;
[ \t]+ /* ignore whitespace */;
%%
lex_yacc_exp.y文g:
%{
/*林木100
www.linmu100.com
*/
#include <stdio.h>
#include <string.h>
void yyerror(const char *str)
{
fprintf(stderr,"error: %s\n",str);
}
int yywrap()
{
return 1;
}
main()
{
yyparse();
}
char *heater="xl
%}
%token TOKHEATER TOKHEAT TOKTARGET TOKTEMPERATURE
%union
{
int number;
char *string;
}
%token <number> STATE
%token <number> NUMBER
%token <string> WORD
%%
commands:
| commands command
;
command:
heat_switch | target_set | heater_select
heat_switch:
TOKHEAT STATE
{
if($2)
printf("\tHeater
else
printf("\tHeat
}
;
target_set:
TOKTARGET TOKTEMPERATURE NUMBER
{
printf("\tHeater
}
;
heater_select:
TOKHEATER WORD
{
printf("\tSelected heater
heater=$2;
}
;
输入以下命oQ分别生成lex.yy.cQy.tab.cQy.tab.h三个文gQ?br>lex lex_yacc_exp.l
yacc -d lex_yacc_exp.y
gcc lex.yy.c y.tab.c -o analyse -ll
创徏一个语法用例demoQ内容如?
heat on
target temperature 99
heater asdfsieiwef99adsf
输入./analyse <demo分析demo文gQ会得到以下l果:
l语Q?br>Lex ?Yacc 是很强大的工Pq里只简单介l了一些入门知识?br>The Lex & Yacc Page 中有很多有趣的历史参考,以及 非常好的 lex ?yacc 文档?nbsp;
参考文档:
http://www.ibm.com/developerworks/cn/linux/l-lexyac.html
http://blog.csdn.net/ThinkinginLinux/archive/
关于yacc ?lex 和在下面链接的文章里已经有所介绍?br>/html/linuxshijie/20070909/80.html
链接中的文章q介l了在linux下如何用yacc和lex工具Q下面主要是介绍yacc和lex在windows下的用法?/p>
yacc和lex在windows已经UL成功Q其中常用的一个工具就是Parser Generator。这个工具用yacc和lex能够生成Visual C++QBorland C++QOther C/C++以及相关Java代码。下面介l一下这个工h如何生成代码q用Visual C++~译的?br>注:关于Parser Generator的用和配置Q其实在Parser Generator Help中已l有很详l的介绍Q感兴趣的朋友可以去那里查到更多有用的信息?br>首先要去http://www.bumblebeesoftware.com/downloads.htm下蝲Parser Generator?br>安装完毕后,我们可以在它的安装目录下扑ֈ一些例子以及编译程序所需的库文g和源文gQ这些文件在~译是很重要?br>单独yacc文g的编译?br>
以下是一个单独的yacc文gQ实C个简单的计算器功能?/strong>
%{
/************************************************************
www.linmu100.com
************************************************************/
#include <ctype.h>
#include <stdio.h>
#define YYSTYPE double /* double type for YACC stack */
%}
%token NUMBER
%%
lines : lines expr '\n' { printf("%g\n", $2); }
| lines '\n'
| /* e */
| error '\n' { yyerror("reenter last line:"); yyerrok(); }
;
expr : expr '+' term { $$ = $1 + $3; }
| expr '-' term { $$ = $1 - $3; }
| term
;
term : term '*' factor { $$ = $1 * $3; }
| term '/' factor { $$ = $1 / $3; }
| factor
;
factor : '(' expr ')' { $$ = $2; }
| '(' expr error { $$ = $2; yyerror("missing ')'"); yyerrok(); }
| '-' factor { $$ = -$2; }
| NUMBER
;
%%
int main(void)
{
return yyparse();
}
int yylex(void)
{
int c;
while ((c = getchar()) == ' ');
if (c == '.' || isdigit(c)) {
ungetc(c, stdin);
scanf("%lf", &yylval);
return NUMBER;
}
return c;
}
我们用Parser Generator的Project --> Parser Wizard创徏一个工E,如下图所C,注意U圈部分的设|:
q时Q我们可以看到Parser Generator帮我们自动生成了一个myparser.y文gQ语法规则就可以在这里加了?br>
现在我们把开头展C的yacc源码完全覆盖myparser.y文gQ然后编译,成功后会生成三个文gQmyparser.cQmyparser.hQmyparser.v
好,现在我们要做的就是用vc来编译myparser.cQmyparser.hq两个文件了?/p>
打开Microsoft Visual C++ 6.0Q新Z个工E?br>
然后Parser Generator生成的两个文件myparser.cQmyparser.h导入工程。(q里׃多说了^-^Q?br>现在要设|环境变量了Q首先要导入Parser Generator的库文g和源文g。在工具->选项里要讄q些环境变量?br>
好,一切设|完毕,开始编译,~译通过后,׃生成yacc_vc.exe文g?br>假设有文件demo.txtQ此文g和yacc_vc.exe在同一个目录,其内容如下:
1+3*5
3*4-23
7- 9 *30 - 999
在此目录的命令行下运行如下命令:yacc_vc.exe <demo.txtQ即可得到计结果:
单独lex文g的编译?/strong>
以下是一个单独的lex文gQ实C个简单的计算单词个数功能?br>%{
/************************************************************
www.linmu100.com
************************************************************/
int wc = 0; /* word count */
%}
%%
[a-zA-Z]+ { wc++; }
\n|. { /* gobble up */ }
%%
int main(void)
{
int n = yylex();
return n;
}
int yywrap(void)
{
printf("word count: %d\n", wc);
return 1;
}
下一步默认完成即可。这ӞParser Generator帮我们自动生成了一个mylexer.l文gQ词法规则可以在q里加?br>同样的,我们用上面展C的lex文g内容完全覆盖mylexer.l文gQ编译后同样生成三个文gQ然后用VC~译其中的myparser.cQmyparser.hq两个文件?br>VC的设|方法和上面~译单独yacc文g时的步骤完全一P最l会生成一个可以计文件单词数目的.exe文g?br>
yacc ?lex整合文g的编译?/strong>
以下分别是yacc文g和lex文g的内容,q两个文件共同实C自定义的一个简单语法规则?br>yacc文g内容Q?br>%{
/*
www.linmu100.com
*/
#include <stdio.h>
#include <string.h>
void yyerror(const char *str)
{
fprintf(stderr,"error: %s\n",str);
}
int yywrap()
{
return 1;
}
main()
{
yyparse();
}
char *heater="xl's test";
%}
%token TOKHEATER TOKHEAT TOKTARGET TOKTEMPERATURE
%union
{
int number;
char *string;
}
%token <number> STATE
%token <number> NUMBER
%token <string> WORD
%%
commands:
| commands command
;
command:
heat_switch | target_set | heater_select
;
heat_switch:
TOKHEAT STATE
{
if($2)
printf("\tHeater '%s' turned on\n", heater);
else
printf("\tHeat '%s' turned off\n", heater);
}
;
target_set:
TOKTARGET TOKTEMPERATURE NUMBER
{
printf("\tHeater '%s' temperature set to %d\n",heater, $3);
}
;
heater_select:
TOKHEATER WORD
{
printf("\tSelected heater '%s'\n",$2);
heater=$2;
}
;
lex文g内容Q?br>%{
/*
www.linmu100.com
*/
#include <stdio.h>
#include <string.h>
#include "myparser.h" //注意Q这里的头文件要和Parser Generator生成的头文g名一栗?br>extern char *yytext;
%}
%%
[0-9]+ {yylval.number=atoi(yytext); return NUMBER;}
heater return TOKHEATER;
heat return TOKHEAT;
on|off {yylval.number=!strcmp(yytext,"on"); return STATE;}
target return TOKTARGET;
temperature return TOKTEMPERATURE;
[a-z0-9]+ {yylval.string=strdup(yytext);return WORD;}
\n /* ignore end of line */;
[ \t]+ /* ignore whitespace */;
%%
现在用Parser Generator创徏新的工程Q?br>
其余的步骤和上面~译yacc时的步骤相同Q最l可以生成both_y_l.exe文gQ放一个demo.txt和both_y_l.exe在同一个目录下Qdemo.txt内容如下Q?br>heat on
target temperature 99
heater asdfsieiwef99adsf
然后在此目录的命令行下执行both_y_l.exe <demo.txt得到Q?br>
以上即ؓParser Generator的用以及如何用VC~译?br>/
/*-----Lex & Yacc ----www.linmu100.com ----*/
/
/*-----linux工具,Lex & Yacc,windows下操?---*/
/
/*-----linux配置,UNIX,开源Y?linux技?makefile----*/
/
/*----------------------@xiaolin--------------------*/
在安装了Parser Generator后,执行以下步骤Q即可VC++~译和连接由Parser Generator产生的文件?
1Q目录设|?
在VC++中执行以下步骤,每个步骤只执行一ơ?
Q?Q?选择Tools菜单中的Options命oQ在屏幕上即会出现Options对话框?
Q?Q?选择Directories选项卡?
Q?Q?在Show Directories for下拉列表框中选择Include Files?
Q?Q?在Directories框中Q点L后的I目录,q填入Parser Generator的include子目录的路径?
Q?Q?在Show Directories for下拉列表框中选择Library Files?
Q?Q?在Directories框中Q点L后的I目录,q填入Parser Generator的lib\msdev子目录的路径?
Q?Q?在Show Directories for下拉列表框中选择Source Files?
Q?Q?在Directories框中Q点L后的I目录,q填入Parser Generator的Source子目录的路径?
Q?Q?点击OK按钮,Options对话框将接受讄q关闭?
VC++在就可以扑ֈ包含文gyacc.h和lex.h以及YACC和Lex的库文g?
2Q项目设|?
对于每个VC++目Q都需在VC++中执行以下步骤:
Q?Q?选择Project菜单中的Settings命oQ在屏幕上即会出现Project Settings对话框?
Q?Q?在Settings for下拉列表框中选择Win32 Debug?
Q?Q?选择C/C++标签?
Q?Q?在Category下拉列表框中选择General?
Q?Q?在Preprocessor Definitions框中Q在当前文本的最后,输入YYDEBUG?
Q?Q?选择Link标签?
Q?Q?在Category下拉列表框中选择General?
Q?Q?在Object/Library Modules框中Q在当前文本的后面,输入yld.lib ylmtd.lib ylmtdlld.lib?
Q?Q?在Settings for下拉列表框中选择Win32 Release?
Q?0Q?重复W?步的工作?
Q?1Q?点击OK按钮QProject Settings对话框将接受讄q关闭?
VC++现在可以从特定的库中接受YACC和Lex所需的函数和变量?
3Q应?
Q?Q在Parser Generator下的~辑H口输入YACC源程序(扩展名必Mؓ.yQ?
Q?Q用Parser Generator下的Project菜单的Compile file命o~译源程序,生成相应的C语言源程序(.cppQ?
Q?Q用VC++~译Q连接C语言源程序,生成可执行程序(.exeQ后卛_执行?
用的VC 2005, 和原来VC 6的设|项对应不上, 很多半天都找不到.好不Ҏ扑օ? 却还是编译出?
最?只好选择再装一个VC6, ? 两个VC, 不错.
先介l一下Parser Generator,主页下蝲:http://www.bumblebeesoftware.com/downloads.htm
Parser Generator is a YACC and Lex programming tool for Windows. As well as including a Graphical User Interace, the software also includes two versions of YACC and Lex, called AYACC and ALex. Parser Generator is able to generate C, C++ and Java parsers and lexical analysers. This includes both Unicode and Multibyte Character Set (MBCS) variants. In your applications you can create multiple, thread safe, instances of these parsers and lexical analysers.
下面说一下windows环境下parser generator和vc++的各w|?
Q一Qparser generator的环境设|?
安装好parser generatorQ打开集成开发环境,炚w目Project菜单Q在下拉菜单中选LibBuilderQ弹出LibBuilder对话框选择属性按钮,弹出compiler properties 对话框:
Name 选择Visual C++ (32-bit)
Directory :msvc32
options:
依次?vc++版本(Versoin 6)
是否支持unicode码?选择默认)
是否把w_char_t作ؓ内徏cd?选择默认)
下边是VC的各U目录:
依次?br>Compiler Bin Directory (C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\VC98\BIN
Compiler Bin Directory(C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\COMMON\MSDEV98\BIN
Compiler Include Directory(C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\VC98\INCLUDE
Compiler Include Directory(C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\VC98\MFC\INCLUDE
Compiler Library Directory(C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\VC98\LIB
Compiler Library Directory(C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\VC98\MFC\LIB
注意Q编译器安装目录Ҏ个h安装目录需要做相应的调整。所有的q些讄完成之后点ok?br> 最后一?配置parser generator的properties,如图卛_:
q回LibBuilder。点Build可以编译vc++使用的lex与yacc的lib库?
?我参考Vs 2003.net的设|?在VC 2005下进行相应设|? l果lex与yacc的lib库没能编译通过, 可能是我讄错误, 不应该是不兼容的问题吧.
生成库文件在软g安装目录下的D:\Parser Generator 2\Cpp\Lib\msvc32目录下?
Q二Qvc++环境的设|?
1.目录讄
Z在VC++中可以找到包含文件yacc.h和lex.h以及YACC和Lex的库文gQ需要对VC++q行相关的目录设|?br>Q?Q?nbsp; 选择Tools菜单中的Options命oQ打开Options对话框?br>Q?Q?nbsp; 选择Directories选项卡?br>Q?Q?nbsp; 在Show Directories for下拉列表框中选择Include Files?br> 在Directories框中Q点L后的I目录,q填?F:\PARGEN\CPP\INCLUDE(Ҏ个h安装目录需要做相应的调?
Q?Q?nbsp; 在Show Directories for下拉列表框中选择Library Files?br> 在Directories框中Q点L后的I目录,q填入F:\PARGEN\CPP\LIB\MSVC32
Q?Q?nbsp; 在Show Directories for下拉列表框中选择Source Files?br> 在Directories框中Q点L后的I目录,q填入F:\PARGEN\CPP\SOURCE
Q?Q?nbsp; 点击OK按钮,Options对话框将接受讄q关闭?
2Q项目设|?br>对于每个VC++目Q都需在VC++中进行以下设|?/strong>Q以使VC++可以从特定的库中接受LEX和YACC所需要的函数和变?br>Q?Q?nbsp; 选择Project菜单中的Settings命oQ打开Project Settings对话框?br>Q?Q?nbsp; 在Settings for下拉列表框中选择Win32 Debug?br>Q?Q?nbsp; 选择C/C++选项卡, 在Category下拉列表框中选择General?br> 在Preprocessor Definitions框中Q在当前文本的最后,输入 q样讄之后我们可以用vc++~译Parser Generator 生成的c文g了。具体ؓQ?br>先打开Parser Generator 集成开发环境。点击Project菜单Q点M拉菜单中的ParseWizard菜单Q一路下d立一个工E。然后点击project菜单下的的Rebuild All。在目文g夹下q成了相应c文g与h文g?br>再用VC++建立一个空控制台工E,然后把用用Parser Generator
QYYDEBUG
?对应到VC 2005为C/C++->Preprocessor->Preprocessor Definitions.
Q?Q?nbsp; 选择Link选项卡,在Category下拉列表框中选择General?br> 在Object/Library Modules框中Q在当前文本的后面,输入yld.lib
?VC 6中的Object/Library Modules对应到VC 2005为Propert->Configuration Properties->Linker->Input->Additional Dependencies ,找了好久.
Q?Q?nbsp; 在Settings for下拉列表框中选择Win32 Release?br>Q?Q?nbsp; 重复W?步的工作?br>Q?Q?nbsp; 点击OK按钮QProject Settings对话框设|完毕?
生成的c文g和头文g加入工程中。接着对VC++q行上面所说的目讄Q然后就可以~译q行了。新手可以用parser generator 自带的范例,q样方便验环境的配置是否正确.
]]>
yacc(Yet Another Compiler Compiler)Q是Unix/Linux上一个用来生成编译器的编译器Q编译器代码生成器)。yacc生成的编译器主要是用C语言写成的语法解析器QParserQ,需要与词法解析器Lex一起用,再把两部份生出来的CE序一q编译。yacc本来只在Unixpȝ上才有,但现时已普遍UL往Windows及其他^台?br>分析E序生成?parser generator)是一个指定某个格式中的一U语a的语法作为它的输入,qؓ该种语言产生分析q程以作为它的输出的E序。在历史上,分析E序生成器被UC~译-~译E序( compiler- compiler )Q这是由于按照规律可所有的~译步骤作ؓ包含在分析程序中的动作来执行。现在的观点是将分析E序仅考虑为编译处理的一个部分,所以这个术语也有些过时了。合q?LALR(1) 分析法是一U常用的分析生成器,它被UC Yacc( yet another compiler- compiler )。给?Yacc 的概貌来Q将使用Yacc?TINY 语言开发一个分析程序?br>作ؓ Yacc 对说明文件中?%token NUMBER 声明的对应。Yacc 坚持定义所有的W号记号本nQ而不是从别的地方引入一个定义。但是却有可能通过在记号声明中的记号名之后书写一个值来指定赋l记L数字倹{?br>yacc的输入是巴科斯范式(BNFQ表辄语法规则以及语法规约的处理代码,Yacc输出的是Z表驱动的~译器,包含输入的语法规U的处理代码部分?br>yacc是开发编译器的一个有用的工具,采用LALR(1)语法分析Ҏ?br>Yacc最初由AT&T的Steven C. Johnson为Unix操作pȝ开发,后来一些兼容的E序如Berkeley YaccQGNU bisonQMKS yacc和Abraxas yacc陆箋出现。它们都在原先基上做了少许改q或者增加,但是基本概念是相同的?br>׃所产生的解析器需要词法分析器配合Q因此Yaccl常和词法分析器的生器——一般就是Lex——联合用。IEEE POSIX P1003.2 标准定义了Lex和Yacc的功能和需求?br>http://dickey.his.com/byacc/byacc.html Berkeley Yacc 一般认为是目前最好的yacc变种。与bison相比Q避免了对特定编译器的依赖?br>http://www.informatik.uni-freiburg.de/proglang/software/essence/ EssenceQScheme的LR(1)语法解析器的生成?br>http://download.plt-scheme.org/scheme/plt/collects/parser-tools/ 用于DrScheme的语法解析工?br>http://www.ssw.uni-linz.ac.at/Research/Projects/Coco/ Coco/R Java和C#的扫描和解析?br>http://mhss.nease.net/unix/yacc.html Yacc: 另一个编译器的编译器,Stephen C. Johnson
IBM的快速入?/font>
http://www.ibm.com/developerworks/cn/linux/sdk/lex/
windows下的lex与yacc工具
只所以推荐它是因为它生成的c文g可以在vc++下通过~译?br> 下蝲地址 http://www.bumblebeesoftware.com/downloads.htm
下蝲之后Q解压羃Q然后安装。打开集成开发环境,炚w目Project菜单Q在下拉菜单中选LibBuilderQ弹出LibBuilder对话框选择属性按?br>弹出compiler properties 对话框,
Name 选择Visual C++ (32-bit)
Directory :msvc32
options:
依次?br>vc++版本(Versoin 7(.net))?br>是否支持unicode码?br>是否把w_char_t作ؓ内徏cd?br>下边是VC的各U目录:
依次?br>Compiler Bin Directory (C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO .NET 2003\VC7\BIN)
Compiler Bin Directory(C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO .NET 2003\COMMON7\IDE)
Compiler Include Directory(C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO .NET 2003\VC7\INCLUDE)
Compiler Include Directory(C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO .NET 2003\VC7\PLATFORMSDK\INCLUDE)
Compiler Library Directory(C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO .NET 2003\VC7\LIB)
Compiler Library Directory(C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO .NET 2003\VC7\PLATFORMSDK\LIB)
注意Q括号里边的是我自己~译器安装目录,也许你的和我的不一P需要做相应的调整?br>所有的q些讄完成之后点ok。返回LibBuilder。点Build可以编译vc++使用的lex与yacc的lib库。生成库文g在Y件安装目录下的D:\Parser Generator 2\Cpp\Lib\msvc32目录下?br>然后我们我们在vc++环境讄中增加包含文件目录D:\Parser Generator 2\Cpp\Include
lib库目录D:\Parser Generator 2\Cpp\Lib\msvc32
具体讄
打开VC++.net集成开发环境?br>点工兯?br>下拉菜单中点选项菜单?br>弹出框中点左边列表框中的projectsQ然后点击vc++目录
在显CZ下内容目录标{下的列表框?#8220;选包含目?#8221;q行讄Q?#8220;库文?#8221;q行讄?br>具体讄是点击列表框下边五个按钮中的第二个按钮Q就加入一行,当选择“包含目录”的时候填入D:\Parser Generator 2\Cpp\IncludeQ当选择“库文?#8221;的时候填入D:\Parser Generator 2\Cpp\Lib\msvc32Q也可以点右边的览按钮q行选择?br>q样讄之后我们可以用vc++~译用Parser Generator 2生成的c文g。具体ؓ
打开Parser Generator 2集成开发环境?br>点击Project菜单Q点M拉菜单中的ParseWizard菜单Q一路下d立一个工E。然后点击project菜单下的的Rebuild All。在目文g夹下q成了相应c文g与h文g?br>用VC++建立一个空控制台工E,然后把用用Parser Generator 2生成的c文g加入工程中。最后引入响应的库文Ӟ是我们在D:\Parser Generator 2\Cpp\Lib\msvc32目录下生成的lex与yacc库文件。接着~译Q如果成功,那么万事大吉?