好的,我理解这个问题可能听起来很基于意见,但是由于我有几个特定的选择标准,我认为它会很适合SO.所以,我在这里......
我过去曾经使用编译器/解释器构建很多(显然主要是作为一种业余爱好)并且出于某种原因我坚持使用Lex/Yacc(或Flex/Bison,我对他们现在如何称呼它们感到困惑... 大声笑).
然而,由于我发现自己目前正在玩另一个业余爱好者翻译项目,我认为我应该尝试一些不同的东西,以避免我不喜欢Lex/Yacc.
所以,即:
Syntax Error
...... Yuhuu!),很少有人帮助诊断问题.(好吧,除非你是开发翻译的人......哈哈).那么,有没有比Lex/Yacc更好的错误报告?好的,我希望这不是太冗长.我全都耳朵!:-)
我一直在尝试按照http://gnuu.org/2009/09/18/writing-your-own-toy-compiler/5/(使用flex,bison和llvm)的教程,但在键入行时
g ++ -o parser parser.cpp tokens.cpp main.cpp
我收到以下错误:
In file included from /usr/local/include/llvm/Support/PointerLikeTypeTraits.h:18:0,
from /usr/local/include/llvm/ADT/PointerIntPair.h:17,
from /usr/local/include/llvm/IR/Use.h:28,
from /usr/local/include/llvm/IR/Value.h:17,
from node.h:3,
from parser.y:2:
/usr/local/include/llvm/Support/DataTypes.h:48:3: erreur: #error "Must #define __STDC_LIMIT_MACROS before #including Support/DataTypes.h"
/usr/local/include/llvm/Support/DataTypes.h:52:3: erreur: #error "Must #define __STDC_CONSTANT_MACROS before " "#including Support/DataTypes.h"
parser.y: In function ‘void yyerror(const char*)’:
parser.y:6:58: erreur: ‘printf’ was not declared in this scope
In file included from /usr/local/include/llvm/Support/PointerLikeTypeTraits.h:18:0,
from /usr/local/include/llvm/ADT/PointerIntPair.h:17,
from /usr/local/include/llvm/IR/Use.h:28,
from /usr/local/include/llvm/IR/Value.h:17,
from node.h:3,
from tokens.l:3:
/usr/local/include/llvm/Support/DataTypes.h:48:3: erreur: #error "Must #define …
Run Code Online (Sandbox Code Playgroud) 我正在尝试在我的flex(.l)文件中解析C风格的多行注释:
%s ML_COMMENT
%%
...
<INITIAL>"/*" BEGIN(ML_COMMENT);
<ML_COMMENT>"*/" BEGIN(INITIAL);
<ML_COMMENT>[.\n]+ { }
Run Code Online (Sandbox Code Playgroud)
我没有返回任何令牌,我的语法(.y)也没有以任何方式处理评论.
当我运行我的可执行文件时,我得到一个解析错误:
$ ./a.out
/*
abc
def
Parse error: parse error
$ echo "/* foo */" | ./a.out
Parse error: parse error
Run Code Online (Sandbox Code Playgroud)
(我的yyerror函数执行printf("解析错误:%s \n"),这是冗余错误消息的前半部分来自).
我可以看到为什么第二个示例失败,因为整个输入是注释,并且由于语法忽略了注释,因此没有语句.因此输入不是有效的程序.但是在我完成评论之前,第一部分抛出了一个解析错误.
同样令人困惑:
$ ./a.out
/* foo */
a = b;
Parse error: parse error
Run Code Online (Sandbox Code Playgroud)
在这种情况下,注释在实际有效输入之前关闭(没有注释,解析就好了).解析"a"后实际发生失败,而不是在尝试解析赋值"a = b;"之后.如果我在自己的行上输入"a",它仍然会抛出错误.
鉴于错误消息是解析器错误而不是扫描程序错误,我的.y文件中是否存在一些至关重要的内容?或者我在扫描器规则中做错了什么传播到解析器端?
编辑: Per @ Rudi的建议,我打开调试,发现:
$ ./a.out
Starting parse
Entering state 0
Reading a token: /*
foo
Next token is 44 (IDENTIFER)
Shifting token 44 (IDENTIFER), Entering …
Run Code Online (Sandbox Code Playgroud) 我正在寻找一个良好的开发环境,可以在flex或bison或两者上工作.
是否有任何IDE具有这些功能和/或适用于此?
(如果不是,那么下一个最常见的问题是是否有带IDE的词法分析器/解析器生成器?)
谢谢〜亚历克斯
我有以下代码,它给出错误""hello.l",第31行:过早的EOF"当我运行以下命令时flex hello.l
%{
#include <stdlib.h>
#include "y.tab.h"
%}
%%
("hi"|"oi")"\n" {return HI; }
("tchau"|"bye")"\n" {return BYE;}
. {yyerror(); }
%%
int main(void)
{
yyparse();
return 0;
}
int yywrap(void)
{
return 0;
}
int yyerror(void)
{
printf("Error\n");
exit(1);
}
Run Code Online (Sandbox Code Playgroud) 我已经找到了答案,但我没有得到任何快速回复的简单例子.
我想使用g ++编译flex/bison扫描器+解析器,因为我想使用C++类来创建AST和类似的东西.
通过互联网搜索我发现了一些漏洞,所有人都说只需要在lex文件中使用extern"C"来声明一些函数原型.
所以我的shady.y文件是
%{
#include <stdio.h>
#include "opcodes.h"
#include "utils.h"
void yyerror(const char *s)
{
fprintf(stderr, "error: %s\n", s);
}
int counter = 0;
extern "C"
{
int yyparse(void);
int yylex(void);
int yywrap()
{
return 1;
}
}
%}
%token INTEGER FLOAT
%token T_SEMICOL T_COMMA T_LPAR T_RPAR T_GRID T_LSPAR T_RSPAR
%token EOL
%token T_MOV T_NOP
%%
... GRAMMAR OMITTED ...
%%
main(int argc, char **argv)
{
yyparse();
}
Run Code Online (Sandbox Code Playgroud)
而shady.l文件是
%{
#include "shady.tab.h"
%}
%%
"MOV"|"mov" { return T_MOV; …
Run Code Online (Sandbox Code Playgroud) 我正在使用GNU Bison 2.4.2为我正在研究的新语言编写语法,我有一个问题.当我指定规则时,让我们说:
statement : T_CLASS T_IDENT '{' T_CLASS_MEMBERS '}' {
// create a node for the statement ...
}
Run Code Online (Sandbox Code Playgroud)
例如,如果我对规则有变化
statement : T_CLASS T_IDENT T_EXTENDS T_IDENT_LIST '{' T_CLASS_MEMBERS '}' {
// create a node for the statement ...
}
Run Code Online (Sandbox Code Playgroud)
其中(来自flex扫描器规则):
"class" return T_CLASS;
"extends" return T_EXTENDS;
[a-zA-Z\_][a-zA-Z0-9\_]* return T_IDENT;
Run Code Online (Sandbox Code Playgroud)
(和T_IDENT_LIST是逗号分隔标识符的规则).
有没有办法只在一个规则中指定所有这些,将"T_EXTENDS T_IDENT_LIST"设置为可选?我已经尝试过了
T_CLASS T_IDENT (T_EXTENDS T_IDENT_LIST)? '{' T_CLASS_MEMBERS '}' {
// create a node for the statement ...
}
Run Code Online (Sandbox Code Playgroud)
但是Bison给了我一个错误.
谢谢
我已经阅读了http://msdn.microsoft.com/en-us/library/aa730877%28vs.80%29.aspx但这篇文档是针对VS 2005的.我坚持使用"在Visual中导入.rules文件"部分C++'在文档中.似乎VS 2010不支持.rules文件,相反,它似乎使用.targets文件来定制构建规则.
有谁知道如何在VS 2010中使用flex&bison?谢谢.
在gcc 4.1.2(linux 5)中运行makefile时,出现以下错误
make: yacc: Command not found
Run Code Online (Sandbox Code Playgroud)
通过谷歌搜索,我发现安装Bison-GNU解析器生成器可以纠正这个错误.但即使在安装Bison之后,我也会遇到同样的错误.
如何解决这个错误?
我正在寻找Sublime Text中的语法,以一种使它们可读的方式突出我的Flex和Bison文件(或lex/yacc)... Sublime Text自动选择Lisp for Flex文件,但这并不能解决问题一切都很好.尝试其他语法的任何建议?或者是否有一个有用的插件(到目前为止还没找到任何东西)?
bison ×10
flex-lexer ×6
lex ×3
yacc ×3
c ×2
c++ ×2
comments ×1
gcc ×1
grammar ×1
ide ×1
llvm ×1
multiline ×1
parsing ×1
sublimetext2 ×1
sublimetext3 ×1
visual-c++ ×1