【发布时间】:2015-01-12 00:17:14
【问题描述】:
我想在 C++ 中获取 if 语句的所有条件。如果我输入(foo&&bar&&(one&&two)),那么我想打印foo - bar - one - two。
我已经编译了scanner.l 和parser.y 文件,并单独测试:my yy.lex.c 有效:如果我输入(a&&b),那么我得到5 个令牌:(、a、&& , b 和 ) 我想要的。但是当我使用 .y 文件时,如果我输入相同的输入,则会得到 a&&b 和 b)。请注意,在这种情况下,我得到 2 个令牌,因为令牌 a&&b 应该分为 3 个令牌 a、&& 和 b。我尝试引入一个更简单的条件:(a) 然后我得到:( 和 a) 但我想得到 (、a、)。
我不知道我做错了什么还是一个错误;希望是我的错。
parser.y
%{
#include <iostream>
#include <list>
#include <stdio.h>
#include <sstream>
#include <string>
using namespace std;
int yylex(void);
void yyerror(char *);
list<string> tokenList;
#define YYSTYPE char *
%}
%token PAR_IZQ
PAR_DER
SIMBOLO
FIN
NADA
AND
OR
%start input
%%
input:
| input terminos
;
terminos:
PAR_IZQ terminos PAR_DER { }
| PAR_IZQ condicion PAR_DER { }
;
condicion:
terminos AND terminos { }
| SIMBOLO AND terminos { cout << " 1) CONDITION FOUND: " << $1 << endl; }
| terminos AND SIMBOLO { cout << " 2) CONDITION FOUND: " << $3 << endl; }
| SIMBOLO AND SIMBOLO { cout << " 3) CONDITION FOUND: " << $3 << " AND " << $1 << endl; }
| SIMBOLO { cout << " 4) CONDITION FOUND: " << $1 << endl; }
;
%%
void yyerror(char *s) {
fprintf(stderr, "%s\n", s);
}
int main(void) {
yyparse();
return 0;
}
scanner.l
%option noyywrap
%{
#include <iostream>
#include "parser.tab.c"
using namespace std;
%}
%%
[a-zA-Z0-9]+ {
yylval = yytext;
return SIMBOLO;
}
"&&" {
return AND;
}
"||" {
return OR;
}
[ \0\0] {
return FIN;
}
"(" {
yylval = yytext;
return PAR_IZQ;
}
")" {
yylval = yytext;
return PAR_DER;
}
. {
cout << "Entrada no permitida.";
cout << endl << yytext << endl;
exit(1);
}
%%
main.cpp
#include "mainwindow.h"
#include <QApplication>
#include "lex.yy.c"
#include <iostream>
#include <vector>
#include <string>
using namespace std;
typedef yy_buffer_state *YY_BUFFER_STATE;
extern int yyparse();
extern YY_BUFFER_STATE yy_scan_buffer(char *, size_t);
int main(int argc, char** argv) {
char condition[] = "(a) \0\0";
// note yy_scan_buffer is looking for a double null string
yy_scan_buffer(condition, sizeof(condition));
yyparse();
return 0;
}
请注意,解析器的输入是一个字符串,所以我必须将它作为yy_scan_buffer 函数的参数传递。 \0\0 是必要的,否则程序将永远不会结束其执行。控制台显示红色“语法错误”,但我不知道为什么!
你知道如何修复它并获得我想要的令牌吗?
谢谢!
PS:我正在使用 Windows 8.1、Qt creator 2.8.1、win_bison 2.7 和 win_flex 2.5.37。
【问题讨论】:
-
离题但仍然:我真的可以推荐使用 Flexc++ 和 Bisonc++(不要与 bison++ 和 flex++ 混淆)。这些将生成适当的 C++ 代码供您使用,而不是
yy_的东西 ;-) -
我怀疑你需要增加解析器的前瞻。
-
如果你想认真做这件事,你将需要一个匹配正在使用的 C++ 语法,以及所有 C++ 前端机制(宏扩展、名称解析、模板实例化,......处理 C++14 特性的方法,因为它实际上是目前的标准)。滚动一个非常简单的语法将无济于事。如果您这样做是为了获得教育体验,那么请继续并忽略我。
标签: c++ bison flex-lexer parser-generator