在没有全局或静态变量的情况下配置Bison和Flex
Configuring Bison and Flex without global or static variable
我使用的是一种小型语言/IDE。我需要知道如何配置flex和bison以在不使用任何全局或静态变量的情况下协同工作。我需要把我的AST指针传给野牛。我也需要野牛通过我的AST来弯曲。这是一个线程环境,但我不需要任何线程同步。对于每个yyprse()调用,我都需要一个separete yylineno变量。我读过关于%define api.pure、%parse param和%option recentrant的文章。但我不知道如何让他们一起工作。。。提前thx。。。
我试过这个:
扫描仪.l:
%{
#include <iostream>
#include <sstream>
#include "parser.tab.h"
#define YY_DECL extern "C" int yylex(YYSTYPE * lvalp, yyscan_t scanner)
extern void yyerror(yyscan_t scanner, NBloco * bloco, const char *s);
%}
%option noyywrap
%option yylineno
%option reentrant
%option bison-bridge
%%
//...scanner code
语法分析器.y:
%{
#include <iostream>
#include "AST.h"
#ifndef YY_TYPEDEF_YY_SCANNER_T
#define YY_TYPEDEF_YY_SCANNER_T
typedef void* yyscan_t;
#endif
extern "C" int yylex(YYSTYPE * lvalp, yyscan_t scanner);
extern "C" FILE *yyin;
extern int yylineno;
void yyerror(yyscan_t scanner, NBloco * bloco, const char *s);
%}
%union{
//union code
}
%define api.pure full
%lex-param { yyscan_t scanner }
%parse-param { yyscan_t scanner }
%parse-param { NBlock* block}
//tokens...
//types...
%%
//parser code...
我得到了这个:
parser.y:13:22: warning: 'yylex' initialized and declared 'extern' [enabled by default] extern "C" int yylex(YYSTYPE * lvalp, yyscan_t scanner);
parser.y:13:22: error: 'YYSTYPE' was not declared in this scope
parser.y:13:32: error: 'lvalp' was not declared in this scope extern "C" int yylex(YYSTYPE * lvalp, yyscan_t scanner);
parser.y:13:48: error: expected primary-expression before 'scanner'
extern "C" int yylex(YYSTYPE * lvalp, yyscan_t scanner);
^
parser.y:13:55: error: expression list treated as compound expression in initializer [-fpermissive]
extern "C" int yylex(YYSTYPE * lvalp, yyscan_t scanner);
^
parser.tab.c: In function 'int yyparse(yyscan_t, NBloco*)':
parser.tab.c:932:39: error: 'yylex' cannot be used as a function
# define YYLEX yylex (&yylval, scanner)
parser.tab.c:1618:16: note: in expansion of macro 'YYLEX'
yychar = YYLEX;
//更多错误。。。
我还将yylineno修复为每个文件。。。我是基于http://benlynn.blogspot.com.br/2013/12/reentrant-parsers-with-flex-and-bison.html和http://www.lemoda.net/c/reentrant-parser/index.html
首先,这里有一个C可重入flex解析器和纯bison示例,它解析与以下内容匹配的语法:
()
(())
(()())
()()(())()()
lexer.l
%option bison-bridge
%option bison-locations
%option ecs
%option nodefault
%option noyywrap
%option reentrant
%option stack
%option warn
%option yylineno
%{
#include "parser.h"
%}
%%
"(" { return (LPAREN); }
")" { return (RPAREN); }
[ frtvn]+ /* eat whitespace */
%%
/* don't use lexer.l for code, organize it logically elsewhere */
语法分析器.y
%define parse.error verbose
%define api.pure true
%locations
%token-table
%glr-parser
%lex-param {void *scanner}
%parse-param {void *scanner}
%{
/* your top code here */
%}
%union {
int value; // or whatever else here
}
%token LPAREN
%token RPAREN
%%
document
: exprs
exprs
: %empty
| expr exprs
expr
: parens
parens
: LPAREN exprs RPAREN
%%
int
yyerror(YYLTYPE *locp, char *msg) {
if (locp) {
fprintf(stderr, "parse error: %s (:%d.%d -> :%d.%d)n",
msg,
locp->first_line, locp->first_column,
locp->last_line, locp->last_column
);
/* todo: add some fancy ^^^^^ error handling here */
} else {
fprintf(stderr, "parse error: %sn", msg);
}
return (0);
}
main.c
#include "parser.h"
#include "lexer.h"
int
main(int argc, char **argv) {
int result;
yyscan_t scanner;
yylex_init(&scanner);
result = (yyparse(scanner));
yylex_destroy(scanner);
return (result);
}
建筑物
flex --header-file=lexer.h --outfile=lexer.c lexer.l
bison --output-file=parser.c --defines=parser.h --warnings=all --feature=all parser.y
cc lexer.c parser.c main.c -o parser
./parser
注意:OSX的内置bison已经过时,所以请安装3.x:
brew install bison
然后像/usr/local/opt/bison/bin/bison ....
一样运行
现在,要迁移到C++
- 将.l复制到.lxx,将.y复制到.xxx
- 将输出文件的名称分别更改为*.cxx和*.hxx
lexer.lxx
- 添加
%option c++
- 删除
reentrant
、bison-bridge
和bison-locations
- 更改所有令牌,如下所示:
LPAREN
到yy::parser::token::LPAREN
parser.yxx
- 添加
%skeleton "lalr1.cc"
- 删除
api.pure
- 删除
yyerror
main.cxx
- 为C重写++
连接lexer和解析器对象是读者的一项练习。
另请参阅:https://github.com/bingmann/flex-bison-cpp-example但要注意,它使用的是旧的bison2.x接口。
GNU Bison 3.x C++示例文档
相关文章:
- 在没有太多条件句的情况下,我如何避免被零除
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 在未初始化映射的情况下,将值插入到映射的映射中
- 是默认情况下分配给char数组常量的值
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- 如何在不产生任何垃圾的情况下获得C中的像素
- 在已经使用Git的情况下减少编译时间
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- 如何在没有信号的情况下从C++执行QML插槽
- 如何在不知道向量大小的情况下输入向量内部的向量?
- 为什么在某些情况下不写入此文件?
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 在没有Xcode的情况下在Mac捆绑包中嵌入框架
- UE4-如何在给定4个屏幕坐标的情况下缩放纹理或材质
- 为什么需要复制构造函数,在哪些情况下它们非常有用
- 如何在不创建新配置的情况下对两个不同解决方案使用的一个项目使用不同的 #defines
- 在没有全局或静态变量的情况下配置Bison和Flex
- 如何在没有VAO的情况下使用OpenGL Core配置文件
- 如何在没有调试符号和优化的情况下创建 cmake 构建配置
- 如何在没有 Xlib 的情况下配置 QT5