gpt4 book ai didi

c - 如何通过 "win_flex bison"编写纯解析器和可重入扫描器?

转载 作者:行者123 更新时间:2023-12-04 17:35:04 24 4
gpt4 key购买 nike

我编写了一个解析器来评估逻辑表达式。我知道 flex 和 bison 使用全局变量(如 yylval)。我想要一个纯解析器和一个用于线程编程的可重入扫描器。我的“.y”文件在这里:

%{
#include <stdio.h>
#include <string>
#define YYSTYPE bool

void yyerror(char *);

//int yylex (YYSTYPE* lvalp);

int yylex(void);
bool parseExpression(const std::string& inp);
%}

%token INTEGER
%left '&' '|'

%%

program:
program statement '\n'
| /* NULL */
;

statement:
expression { printf("%d\n", $1); return $1; }
;

expression:
INTEGER
| expression '|' expression { $$ = $1 | $3; }
| expression '&' expression { $$ = $1 & $3; }
| '(' expression ')' { $$ = $2; }
| '!' expression { $$ = !$2; }
;

%%

void yyerror(char *s) {
fprintf(stderr, "%s\n", s);
}


void main(void) {

std::string inp = "0|0\n";

bool nasi = parseExpression(inp);
printf("%s%d\n", "nasi ", nasi);
printf("Press ENTER to close. ");
getchar();
}

我的“.y”文件在这里:

    /* Lexer */
%{
#include "parser.tab.h"
#include <stdlib.h>
#include <string>
#define YYSTYPE bool
void yyerror(char *);
%}


%%

[0-1] {
if (strcmp(yytext, "0")==0)
{
yylval = false;
//*lvalp = false;
}
else
{
yylval = true;
//*lvalp = true;
}

return INTEGER;
}

[&|!()\n] { return *yytext; }

[ \t] ; /* skip whitespace */

. yyerror("Unknown character");

%%

int yywrap(void) {
return 1;
}

bool parseExpression(const std::string& inp)
{
yy_delete_buffer(YY_CURRENT_BUFFER);

/*Copy string into new buffer and Switch buffers*/
yy_scan_string(inp.c_str());
bool nasi = yyparse();

return nasi;


}

我已将 %pure_parser 添加到两个文件中,将 yylex 声明更改为 int yylex (YYSTYPE*​​ lvalp); 并将 yylval 替换为*lvalp,但我看到一个错误:'lvalp' is undeclared identifier.。有很多关于“可重入”和“纯”的例子,但我找不到最好的指南。

有人可以指导我吗?

提前致谢。

最佳答案

幸运的是,我做到了。这是我的代码。我认为对于想要编写纯解析器的人来说,这可能是一个很好的指南。ä

我的可重入扫描仪:

    /* Lexer */
%{
#include "parser.tab.h"
#include <stdlib.h>
#include <string>
#define YYSTYPE bool
void yyerror (yyscan_t yyscanner, char const *msg);
%}

%option reentrant bison-bridge

%%

[0-1] {
if (strcmp(yytext, "0")==0)
{
*yylval = false;
}
else
{
*yylval = true;
}

//yylval = atoi(yytext);
return INTEGER;
}

[&|!()\n] { return *yytext; }

[ \t] ; /* skip whitespace */

. yyerror (yyscanner, "Unknown character");

%%

int yywrap(yyscan_t yyscanner)
{
return 1;
}

bool parseExpression(const std::string& inp)
{
yyscan_t myscanner;
yylex_init(&myscanner);
struct yyguts_t * yyg = (struct yyguts_t*)myscanner;

yy_delete_buffer(YY_CURRENT_BUFFER,myscanner);

/*Copy string into new buffer and Switch buffers*/
yy_scan_string(inp.c_str(), myscanner);

bool nasi = yyparse(myscanner);
yylex_destroy(myscanner);
return nasi;
}

我的纯解析器:

%{
#include <stdio.h>
#include <string>

#define YYSTYPE bool
typedef void* yyscan_t;
void yyerror (yyscan_t yyscanner, char const *msg);
int yylex(YYSTYPE *yylval_param, yyscan_t yyscanner);
bool parseExpression(const std::string& inp);
%}


%define api.pure full
%lex-param {yyscan_t scanner}
%parse-param {yyscan_t scanner}

%token INTEGER
%left '&' '|'

%%

program:
program statement '\n'
| /* NULL */
;

statement:
expression { printf("%d\n", $1); return $1; }
;

expression:
INTEGER
| expression '|' expression { $$ = $1 | $3; }
| expression '&' expression { $$ = $1 & $3; }
| '(' expression ')' { $$ = $2; }
| '!' expression { $$ = !$2; }
;

%%

void yyerror (yyscan_t yyscanner, char const *msg){
fprintf(stderr, "%s\n", msg);
}


void main(void) {

std::string inp = "1|0\n";

bool nasi = parseExpression(inp);
printf("%s%d\n", "nasi ", nasi);
printf("Press ENTER to close. ");
getchar();
}

请注意,我作弊并将 yyg 定义为

struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;

我没有找到另一种获取 YY_CURRENT_BUFFER 的方法。所以,如果有人知道获取 YY_CURRENT_BUFFER 的最佳方法,请告诉我。

关于c - 如何通过 "win_flex bison"编写纯解析器和可重入扫描器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26483735/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com