我在 Debian Squeeze 上运行,并使用 apt-get install flex 安装了 flex/flex++。
不过我注意到 flex++ 只是一个指向 flex 的符号链接。那么,真的存在一个生成 C++ 扫描仪的“程序”flex++,还是只是一个我应该切换的 Flex 标志?
另外,常见的问题是:互联网上的许多示例无法在flex或flex++下“编译”。Flex 出现以下错误:
test.lex:1: invalid character: %
...
Run Code Online (Sandbox Code Playgroud)
当仅使用以下命令处理输入时:
%name Test
Run Code Online (Sandbox Code Playgroud)
这里出了什么问题?
Flex/Flex++ 版本为 2.5.35
我正在用 bison 构建语法,并且我已将最后一个 reduce/reduce 错误缩小到以下测试用例:
%{
#include <stdio.h>
#include <string.h>
extern yydebug;
void yyerror(const char *str)
{
fprintf(stderr, "Error: %s\n", str);
}
main()
{
yydebug = 1;
yyparse();
}
%}
%right '='
%precedence CAST
%left '('
%token AUTO BOOL BYTE DOUBLE FLOAT INT LONG SHORT SIGNED STRING UNSIGNED VOID
%token IDENTIFIER
%start file
%debug
%%
file
: %empty
| statement file
;
statement
: expression ';'
;
expression
: expression '=' expression
| '(' type ')' expression %prec CAST
| …Run Code Online (Sandbox Code Playgroud) 我正在编写一个解析器,我希望它尽可能便携。
现在我正在使用GNU bison来生成我的解析器,但我不确定我的代码是否依赖于不完全可移植的yacc扩展。
所以我想知道GNU bison具有的原始yacc缺失的功能。
我担心的原因是我注意到我的解析器无法使用bison端口在 Windows 上编译。如果它能让我的解析器更容易在不同平台之间移植,我会牺牲GNU bison功能并坚持使用原始的标准化yacc。
那么GNU bison和原始标准yacc之间有什么区别呢?如果我希望我的程序尽可能便携,在使用GNU bison时应该避免哪些功能?
为了使我的问题易于理解,我想使用以下示例:
以下代码在fortran语言中称为非块do-loop
DO 20 I=1, N ! line 1
DO 20 J=1, N ! line 2
! more codes
20 CONTINUE ! line 4
Run Code Online (Sandbox Code Playgroud)
要注意的是,标签204个装置的末端都内做环和外DO循环。
我希望我的 flex 程序正确解析该功能:当 flex 读取 label 时20,它将返回ENDDO终端两次。
首先,因为我也用bison,所以每次bison 打电话yylex()都拿到一个终端。如果我可以yylex()在某些情况下要求 bison 获取终端,在其他情况下从另一个函数获取终端,也许我可以解决这个问题,但是,我当时不知道。
当然有一些解决方法,例如,我可以使用 flex 的启动条件,但我认为这不是一个好的解决方案。所以我问是否有任何方法可以在没有解决方法的情况下解决我的问题?
我在 Mac 上使用 Bison,但似乎出现以下错误。我似乎无法解决这个问题。知道为什么我从下面显示的代码中收到语法错误吗?
运行时的终端输出:
语法错误、意外标识符、需要字符串
bison -d parser.y
解析器.y
%{
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define YYDEBUG 1
extern FILE * yyin;
FILE * outputFile;
int yyerror(const char* s);
int yylex(void);
%}
%define parse.error verbose
%token PROGRAM BEGIN_WORD END VAR PRINT INTEGER STRING NUM ID
%%
start : PROGRAM pname ';' VAR decList ';' BEGIN_WORD statList END { YYACCEPT; }
;
pname : ID { fprintf(outputFile, "#include <iostream>\nUsing namespace std;\nint main()\n{\n"); }
;
decList : dec ':' type …Run Code Online (Sandbox Code Playgroud) 我想做解析器,它将把表达式输出到它们的计算步骤中。而且,当我编译代码时,我无法解决这些问题。我总是会出错
code.l:13:1: error: expected expression before '=' token
yylval.name = strdup(yytext);
^
code.l:18:1: error: expected expression before '=' token
yylval.name = strdup(yytext);
^
Run Code Online (Sandbox Code Playgroud)
我尝试了很多不同的事情,我认为这是一个问题,但是没有成功。
代码
code.l:13:1: error: expected expression before '=' token
yylval.name = strdup(yytext);
^
code.l:18:1: error: expected expression before '=' token
yylval.name = strdup(yytext);
^
Run Code Online (Sandbox Code Playgroud)
代码
%{
#include <stdio.h>
#include <string.h>
#include "Assignment.tab.h"
%}
%%
" " ;
"\t" ;
[a-zA-Z]+
{
yylval.name = strdup(yytext);
return(ID);
}
[0-9]+
{
yylval.name = strdup(yytext);
return(NUM);
}
[-+=()*/\n]
{
return yytext[0]; …Run Code Online (Sandbox Code Playgroud) 我看到很多例子,其中一些将 yytext 传递给 yylval,而另一些则没有。这是 lex 和 yacc 中简单加法器的代码
/* add.l */
digit [0-9]
%%
{digit}+ {sscanf(yytext, "%d", &yylval);
return(INT);
}
\+ return(PLUS);
\n return(NL);
. ;
%%
int yywrap() { return 1; }
Run Code Online (Sandbox Code Playgroud)
和
/* add.y */
/* L = {INT PLUS INT NL} */
%token INT PLUS NL
%%
add: INT PLUS INT NL { printf("%d\n", $1 + $3);}
%%
#include "lex.yy.c"
yyerror(char *s) { printf("%s\n", s); }
main() {
return yyparse();
}
Run Code Online (Sandbox Code Playgroud)
我没有看到像 printf(yylval) 等代码。为什么代码sscanf(yytext, "%d", &yylval) …
我的文件结构是,
`pragma TOKEN1_NAME TOKEN1_VALUE
`pragma TOKEN2_NAME TOKEN2_VALUE
`pragma TOKEN3_NAME TOKEN3_VALUE
`pragma TOKEN4_NAME TOKEN4_VALUE
TEXT{
// A valid VHDL or verilog
}
`pragma TOKEN2_NAME TOKEN2_VALUE
TEXT{
// VHDL or verilog
}
Run Code Online (Sandbox Code Playgroud)
因为我正在处理Verilog和VHDL.我需要重新构建我的令牌名称,记住VHDL不区分大小写.我想对这两种情况使用单一解析器.同样的最有效方法是什么?flex是否支持某种功能以允许不区分大小写的模式匹配,如果文件的格式是Verilog,我们以后可以检查是否清除了令牌名称(包含所有小写字母)?
我正在尝试从BNF Grammar编写一个Flex/Bison文件.但是,当我尝试编译时出现错误,我不确定如何调试它们.
BNF Grammer:
<exp>::=<list> | head(<list>)
<list>::=<num1>::<list> | <list>@<list> | tail(<list>) | [<numlist>]
<numlist>::=<empty> | <num1><num2>
<num2>::=<empty> | ,<num1><num2>
<num1>::=<D1><N> | <N> | head(<list>)
<D1>::=<D1><N> | <D2>
<D2>::=[1-9]
<N>::=[0-9]
Run Code Online (Sandbox Code Playgroud)
我的Flex文件
%option noyywrap
%{
#include <stdlib.h>
#include <list>
using namespace std;
#define YYSTYPE list<int>
#include "listop.tab.h"
%}
hd head
tl tail
ap [@()\[\]]
con ::
n [0-9]
d2 [1-9]
d1 ({d2}{n}+)|{d2}
ws[ \t\n]+
%%
{d1} yylval.clear(); yylval.push_front(atoi(yytext)); return D1;
{n} yylval.clear(); yylval.push_front(atoi(yytext)); return N;
{hd} return HEAD;
{tl} return TAIL; …Run Code Online (Sandbox Code Playgroud) 这是我的html.l:
DOC_START "<html>"|"<HTML>"
DOC_END "</html>"|"</HTML>"
SPACE " "
TEXT .
%%
%%
Run Code Online (Sandbox Code Playgroud)
这是我的html.y:
%{
#include "lex.yy.c"
%}
%%
Doc : DOC_START Other DOC_END
Other : TEXT
| SPACE
%%
Run Code Online (Sandbox Code Playgroud)
这是我的html文件:
<HTML>
foo bar
</HTML>
Run Code Online (Sandbox Code Playgroud)
我正在编译第一个flex文件,在bison文件之后.它给出了has no rules错误.我想检查一下,如果这个文件是一个正确的html文件,如Doc声明中所述.并且预计会给出错误或消息stdout.我们需要做什么?