lex和yacc环境配置

lex和yacc的使用很简单,但环境配置却是各种问题,本章说明lex和yacc在windows下的环境配置。

软件需求:
系统 win7-64位(win7-32, win8, win10全部通过)
c++编译器: vs2010(2008,2013,2015也全部通过)
lex和yacc编译器: ParGen.exe

基本流程:
安装Pargen.exe,采用的默认目录安装在C:\Program Files (x86)\Parser Generator 2\
安装vs2010,这个各种教程,不再赘述

启动Pargen程序,并选择Project->ParserWizard…
这里写图片描述

选中ParserWizard,开始工程的创建,此处我创建功能,命名为Test,目录位置可自己选择,目标语言为C++,编译器为vc++(32-bit)
这里写图片描述

下一步,选择是创建lex,还是yacc,还是两者兼有。此处我选择是lex和yacc都有,准备实现一个不支持变量的计算器,使用lex识别token,使用yacc识别语法。
这里写图片描述

下一步,设置yacc的文件名字以及使用的解析器,此处我使用的默认选项,不进行修改,文件名默认为myparser.y
这里写图片描述

下一步,设置lex的文件名以及使用的分析器的名字,此处我使用的默认选项,文件名默认为mylexer.l
这里写图片描述

点击完成按钮,创建工程完毕,同时有两个文件mylexer.l 和myparser.y
这里写图片描述

工程的管理,可使用window->project菜单,查看工程下的所有文件
这里写图片描述
这里写图片描述

当你点击文件编辑窗口的放大按钮,会将其他的文件编辑覆盖,此时可以使用window->project菜单查看,也可以使用window->Tile vertically查看全部文件的平铺
这里写图片描述

编辑mylexer.l文件,粘贴入以下内容:

%{
//this code will be added into the header of generated .cpp file
#include <iostream>
#include "myparser.h"
using namespace std;//already defined in yacc.y, use %token...
//enum{LT,  EQ, GT, IF, ELSE, ID, NUMBER, PLUS, MINUS, TIMES, OVER, INT, DOUBLE,CHAR, LP,RP};const char* tokenStr[] = {"LT",  "EQ", "GT", "IF", "ELSE", "ID", "NUMBER", "PLUS", "MINUS", "TIMES", "OVER", "INT", "DOUBLE","CHAR"};
static void print_token(int token, char* lex);%}%name mylexerdelim [ \t]
ws    {delim}+
letter [a-zA-Z]
digit [0-9]
id    {letter}({letter}|{digit})*
/* can support 12.34 */
number {digit}+(\.{digit}+)?%%
%{
//this code will be added into yyaction functionYYSTYPE YYFAR& yylval = *(YYSTYPE YYFAR*)yyparserptr->yylvalptr;//double yylval;
%}{ws} {/* do nothing */}
"int"  {print_token(INT, yytext); return INT;}
"double"  {print_token(DOUBLE, yytext);}
"char"  {print_token(CHAR, yytext);}"+"         {print_token(PLUS, yytext); return PLUS;}
"-"         {print_token(MINUS, yytext); return MINUS;}
"*"         {print_token(TIMES, yytext); return TIMES;}
"/"         {print_token(OVER, yytext); return OVER;}
"("         {return LP;}
")"         {return RP;}
"\n"        {return EOL;}
{id}        { return ID;}
{number}    { yylval = atof(yytext);return NUMBER;}
"//".*      {return COMMENT;}
"."          {printf("Mystery character %s\n", yytext); }
%%static void print_token(int token, char* lex)
{
#ifdef LEX_DEUBcout<<"token:" << token<<" "<<"lex:"<<lex<<endl;
#endif
}

编译myparser.y文件,粘贴入以下内容

%{
#include "mylexer.h"
%}%name myparser
// class definition
{// place any extra class members here
}
// constructor
{// place any extra initialisation code here
}// destructor
{// place any extra cleanup code here
}// place any declarations here
%include {
#ifndef YYSTYPE
#define YYSTYPE double
#endif
}%token NUMBER ID
%token PLUS MINUS TIMES OVER
%token LP RP EOL COMMENT
%TOKEN INT DOUBLE CHAR%left PLUS MINUS
%left TIMES OVER
%right UMINUS%%lines   :   lines expr EOL  { printf("%g\n", $2); }|   lines EOL|  lines COMMENT|;expr    :   expr PLUS expr  { $$ = $1 + $3; }|	expr MINUS expr	{ $$ = $1 - $3; }|	expr TIMES expr	{ $$ = $1 * $3; }|	expr OVER expr	{ $$ = $1 / $3; }|	LP expr RP	{ $$ = $2; }|	'-' expr %prec UMINUS	{ $$ = -$2; }|	NUMBER {$$=$1;} //$$=$1 can be ignored|   ID //should be complemented;  
%%int main(int argc, char *argv[])
{printf("a cacluator which support +,-,*,/ and (): \n");printf("    e.g.  12.2+3*(2+5)\n");int n = 1;mylexer lexer;myparser parser;if (parser.yycreate(&lexer)) {if (lexer.yycreate(&parser)) {//lexer.yyin = new ifstream(argv[1]);//lexer.yyout = new ofstream(argv[2]);n = parser.yyparse();//parse_tree.get_label();//parse_tree.gen_code(*lexer.yyout);}}getchar();return n;
}

点击Pargen右上角的编译build按钮,会生成相应的.h和.cpp代码
这里写图片描述
这里写图片描述

新建vs2010工程,并将生成的.h和.cpp代码加入到工程中。简单起见,在comple\Test目录下创建vs工程vsTest
这里写图片描述

选择控制台工程, 工程的目录,以及工程名称vsTest,点击确定按钮后
这里写图片描述

继续下一步配置
这里写图片描述

此处附件选项选择空项目,然后点击完成按钮,即完成vsTest工程创建
这里写图片描述

工程右键添加现有项,即添加已经生成.h和.cpp文件
这里写图片描述
这里写图片描述
这里写图片描述

在vs界面,点击编译按钮,查看当前的编译情况,会显示编译错误,找不到yy的头文件,这是因为并没有将Pargen安装后的头文件加入到工程的包含目录中
这里写图片描述

下面将Pargen安装后的头文件加入到工程include配置
这里写图片描述
这里写图片描述
这里写图片描述

在vs界面,点击编译按钮,查看编译情况。 当前头文件可以正常找到,会出现大量的链接错误-link error。这是因为对应的lib文件还没有加载进来。
这里写图片描述

下面加入库文件,加入库所在目录
这里写图片描述

加入要使用的库的名字:ylmtri.lib, 注意使用分号隔开
这里写图片描述

再次点击编译按钮,会发现可以编译,但是运行的时候,会出现ylmtri.dll的错误。这是因为我们使用动态dll库,需要将对应的dll文件从Pargen目录复制到工程目录的exe文件同级目录下
这里写图片描述

下面开始将ylmtri.dll从Pargen目录复制到vsTest.exe同级目录
这里写图片描述
这里写图片描述

再次点击编译运行按钮,可以正常运行,效果如下
这里写图片描述
这里写图片描述



出处:http://blog.csdn.net/lpstudy/article/details/51330063


在最后一步的过程中,遇到了添加完ylmtri.dll仍然报错的情况,也是比较尴尬,在解决之后再修改。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/508605.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java集合之Vector源码分析

概述 Vector与ArrayLIst类似, 内部同样维护一个数组, Vector是线程安全的. 方法与ArrayList大体一致, 只是加上 synchronized 关键字, 保证线程安全, 下面就不具体分析源码了, 具体可以查看ArrayList中的源码分析. Vector源码分析 1.主要字段 2.构造函数 3.增删改查 其他方法…

Gossip协议的P2P会员管理

阅读此论文主要目的在于理解gossip协议及其背后的原理&#xff0c;此部分详细翻译&#xff0c;其余部分看时间 文章标题&#xff1a;Gossip协议的P2P会员管理 作者&#xff1a;Ayalvadi J. Ganesh, Anne-Marie Kermarrec, and Laurent Massoulie Abstract&#xff1a;基于…

Java集合之LinkedHashSet源码分析

概述 LinkedHashSet与HashSet类似, 不同的是LinkedHashSet底层使用LinkedHashMap维护元素插入的顺序. LinkedHashSet继承自HashSet, 只是重写了HashSet的构造方法, 初始化一个LinkedHashMap, 其他均与HashSet相同. LinkedHashSet构造方法 HashSet的构造方法: 以上几乎就是Li…

2016-2017NBU期末考试记录

又是一年期末考 这个学期考的少&#xff0c;就两门 还是来记录一下都考了什么东西吧 首先编译&#xff1a;编译的题目是开始十道判断题&#xff0c;后面全都是大题。大题内容有&#xff1a;画出第二次递归过程中&#xff0c;活动记录中静态链和动态链的情况&#xff1b;给出一…

Java集合之ArrayList源码分析

概述 ArrayList可以理解为动态数组, 根据MSDN的说法, 就是Array的复杂版本. 与数组相比, 它的容量能动态增长. ArrayList是List接口的可变数组的实现. 实现了所有可选列表操作, 允许包括null在内的所有元素. 数组的特点, 查询快增删慢. 每个ArrayList实例都有一个容量, 该容…

视频业务原理

最近要学习如何进行视频的用户体验测量&#xff0c;首先学习最基础的知识&#xff0c;视频业务的原理是什么。 研究的视频的应用层协议是HTTP&#xff0c;使用的传输层协议是TCP。 工作过程如下&#xff1a;客户端向服务器请求相应的视频信息&#xff1b;服务器响应请求发回视…

Java集合之Hashtable源码分析

概述 Hashtable也是基于哈希表实现的, 与map相似, 不过Hashtable是线程安全的, Hashtable不允许 key或value为null. 成员变量 Hashtable的数据结构和HashMap一样, 采用 数组加链表的方式实现. 几个成员变量与HashMap一样: 方法 Hashtable的方法与HashMap基本一样, 只是 Ha…

视频质量检测中的TP、FP、Reacll、Precision

在看论文《Measuring Vedio QoE from Encrypted Traffic》的时候看到TP&#xff08;True Positives&#xff09;、FP&#xff08;False Positives&#xff09;、Precison、Recall的概念&#xff0c;这属于数据挖掘方面的内容&#xff0c;学习之后特来记录。 首先&#xff0c;下…

Java集合之LinkedHashMap源码分析

概述 HashMap是无序的, 即put的顺序与遍历顺序不保证一样. LinkedHashMap是HashMap的一个子类, 它通过重写父类的相关方法, 实现自己的功能. 它保留插入的顺序. 如果需要输出和输入顺序相同时, 就选用此类. LinkedHashMap原理 LinkedHashMap是如何保证输入输出顺序的呢? L…

视频流传输协议RTP/RTCP/RTSP/HTTP的区别

在转载之前&#xff1a;我研究主要是基于HTTP的视频流&#xff0c;正在研读的论文名&#xff1a;“Modeling and Analyzing the Influence of Chunk Size Variation on Bitrate Adaptation in DASH”&#xff0c;里面有一句话&#xff0c;“Compared with early connection-ori…

Java集合之HashSet源码分析

概述 HashSet是基于HashMap来实现的, 底层采用HashMap的key来保存数据, 借此实现元素不重复, 因此HashSet的实现比较简单, 基本上的都是直接调用底层HashMap的相关方法来完成. HashSet的构造方法就是创建HashMap: 基本操作 1.添加操作 2.删除操作 3.迭代器 其他方法基本也是调…

三次握手wireshark抓包分析,成功握手和失败握手

转载之前&#xff1a;基于HTTP的视频流中&#xff0c;客户端有时会打开使用多条TCP与服务器连接&#xff0c;为了验证每一对话的sessionID是否相同&#xff0c;使用wireshark进行了抓包分析&#xff08;抓到的都是加密的包&#xff0c;无卵用orz....&#xff09;&#xff0c;这…

Java 内部类及其原理

Java中实现内部类 内部类相信大家都用过很多次了&#xff0c;就不说它是怎么用的了。 内部类 1.成员内部类 需要注意的是&#xff0c; 当成员内部类拥有和外部类同名的成员变量或这方法时&#xff0c; 默认情况下访问的是内部类的成员&#xff0c; 如要访问外部类的同名成员&…

西游日记7/27

已经到第四天了&#xff0c;觉得需要写一些进展来督促一下自己。 早上8点钟左右到的实验室&#xff0c;将昨天没有回顾完的论文再次回顾一遍&#xff0c;又重新发现了一些点&#xff0c;确实&#xff0c;在完全明白之前&#xff0c;一篇好的论文是常读常新的。在吃午饭之前&am…

JVM 垃圾回收机制

首先JVM的内存结构包括五大区域: 程序计数器、虚拟机栈、本地方法栈、方法区、堆区。其中程序计数器、虚拟机栈和本地方法栈3个区域随线程启动与销毁&#xff0c; 因此这几个区域的内存分配和回收都具有确定性&#xff0c;不需要过多考虑回收的问题。而Java堆区和方法区则不一样…

Modeling and Analyzing the Influence of Chunk Size Variation on Bitrate Adaptation in DASH 名字解释0728

在看“Modeling and Analyzing the Influence of Chunk Size Variation on Bitrate Adaptation in DASH”的时候遇到挺多的名词不是很明白&#xff0c;在这里做一下学习笔记&#xff08;按照论文顺序&#xff09;。 1、CDN server&#xff1a;“CDN将源站内容分发至最接近用户的…

Java8 Lambda表达式

概述 lambda表达式&#xff0c; 是Java8中的一个新特性。可以理解为一个匿名函数。 lambda表达式可以理解为将一个函数浓缩为一行代码&#xff0c;使代码更加简洁紧凑。 lambda表达式语法&#xff1a; (parameters) -> statement; 或 (parameters) -> {statements;} 参…

西游日记0728

今天要早点翘班儿&#xff0c;请表妹儿吃饭&#xff0c;现在来总结一下我今天的干活吧。 早上8点钟到的实验室&#xff0c;私以为还可以提早一点&#xff0c;确实是一个人的时候比较容易狂欢&#xff0c;早上的工作效率有点低啊。早上嘛&#xff0c;就是看论文诺&#xff0c;看…

Java8 方法引用

概述 方法引用是用来直接访问类或实例阴茎存在的方法或者构造方法.它需要由兼容的函数式接口(lambda表达式中用到的接口)构成的目标类型上下文. 有时候, 当我们想要实现一个函数式接口的方法, 但是已经由类实现了我们想要的功能, 这时可以使用方法引用来直接使用现有的功能实现…

配置过程中的一些问题

一、 Tomcat相关问题 1、百度经验有设置用户名密码&#xff0c;但是按照步骤进行&#xff0c;到测试的时候发现还是错误的。 解决&#xff1a;在设置的时候应该stop Tomcat&#xff0c;在设置好之后再重新开启Tomcat&#xff0c;发现可以。 2、把web项目加入Tomcat&#xff0…