我已经找到了答案,但我没有得到任何快速回复的简单例子.
我想使用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) 我正在寻找一种在PHP中获得Flex/Bison(或Lex/Yacc等人)支持的方法.具体来说,我正在Web UI中实现一个布尔查询解析器,而宁愿将所有操作保留在PHP中(而不是调用C解析器,或者将事物传递给Python等).
我以前从未做过Bison或Wisent.
我该如何开始?
我的真正目标是为C#生成一个有效的Wisent/Semantic语法,允许在带有代码完成的emacs中编辑C#,以及所有其他CEDET好东西.(对于那些不知道是谁,野牛之是一个与Emacs口齿不清端口GNU野牛,这是纳入CEDET. 野牛之显然是欧洲野牛.野牛,我把它,是一出戏,对词的派生YACC.而CEDET是Emacs开发工具的集合.所有人都赶上了?我不打算尝试定义emacs.)
Microsoft在语言参考文档中为C#提供了BNF语法,包括所有LINQ扩展.我能够将其转换为成功编译的.wy文件semantic-grammar-create-package.
但编译后的语法并没有"起作用".在某些情况下,语法"查找" enum声明,但不是class声明.为什么?我不知道.我无法识别属性.我发现语法的"调试"并不容易.
我想我会退后一步,尝试为一种简单易懂的语言制作一个明智的语法,这种语言只有几个关键词.只是为了获得一些经验.即便如此,这也是一个挑战.
我已经看过关于语法fw的.info文档,并且很明智,但是......仍然有些东西并没有真正为我澄清,这些东西是如何真正起作用的.
所以
Q1:有关在emacs中调试明智语法的任何提示吗?有没有办法在语法上运行一个"类似lint"的东西来找出是否有未使用的规则,这样的死胡同?如何能够观察解析器的运行情况呢?有这样的吗?
Q2:关于加速野牛/一般情况的任何提示?我正在考虑的是一种工具,可以让我深入了解规则的运作方式.提供一些透明度的东西,而不是"我没有工作"的经验,我现在正在使用Wisent.
问题3:我应该放弃并成为一名有机农民,而不是继续打击这一点吗?
ps:我知道CEDET/semantic的contrib目录中现有的C#语法.这件事有效,但是......它不支持最新的C#规范,包括LINQ,部分类和方法,yield,匿名方法,对象初始化器等等.此外,它主要解析一堆C#代码.它嗅出了类和方法,然后挽救了.即使是foreach循环也没有做得很好.尽管它很好,但我希望看到它更好.我正在尝试做的是使它成为当前的,并且还扩展它以解析更多的C#代码.
当我使用bison parser.y -d -t编译我的.y文件然后在我的flex文件中包含parser.tab.h文件时,gcc说"错误:数字常量之前的语法错误".它引用第32行,这是yytokentype枚举中的第一行.
enum yytokentype {
BREAK = 258,
... }
Run Code Online (Sandbox Code Playgroud)
该错误大约是"BREAK = 258".老实说,我不知道为什么会这样 - 我真的想使用生成的yylval,我需要从这个头文件中获取它.即使我在我的flex文件中声明yytokentype这样,我也会得到同样的错误.我可能做错什么?
我想知道如何在bison + flex中将缩进实现为块分隔符.就像在python中一样.我正在编写自己的编程语言(主要是为了好玩,但我打算将它与游戏引擎一起使用),我将尝试提出一些特殊的东西,以最小化样板并最大化开发速度.
我已经在C中编写了一个编译器(实际上是一个'langToy'到Nasm翻译器)但是失败了.由于某种原因,它只能处理整个源文件中的一个字符串(好吧,我已经醒了超过48小时 - 所以...你知道,脑子崩溃了).
我不知道大括号和/或开始 - >结尾是否更容易实现(我没有问题)或者只是我的大脑锁定了.
提前致谢!
更新:好的,我不知道如何使用flex进行操作.将多个DEDENT返回给解析器时遇到问题.Flex/Bison对我来说相对较新.
更新2: 这是我到目前为止提出的flex文件; 它不太明白:
%x t
%option noyywrap
%{
int lineno = 0, ntab = 0, ltab = 0, dedent = 0;
%}
%%
<*>\n { ntab = 0; BEGIN(t); }
<t>\t { ++ntab; }
<t>. { int i; /* my compiler complains not c99 if i use for( int i=0... */
if( ntab > ltab )
printf("> indent >\n");
else if( ntab < ltab )
for( …Run Code Online (Sandbox Code Playgroud) 如果我忘记在我的任何文件的末尾添加一个空行,我的程序会出现语法错误.问题是我的语法期望换行结束当前行.由于新行不存在,因此bison不会生成语法错误,因为它没有完成规则.
我该如何解决这个问题?当我这样做时,我试图做出<<EOF>>回报MY_EOF但是因为一次可怕的死亡而崩溃了.我猜其默认EOF中的代码我没有打电话.我不知道它们可能是什么功能.使用EOF创建错误symbol EOF is used, but is not defined as a token and has no rules
我正在寻找一个非常简短的flex和bison工作示例,附带Makefile,它使用了内置规则.我已经尝试过几个谷歌的结果,这些结果很乱,不会构建,或者是C++,这是不可接受的.赞赏良好的在线资源和简短的示例代码.
额外
# Makefile example -- scanner and parser.
# Creates "myprogram" from "scan.l", "parse.y", and "myprogram.c"
#
LEX = flex
YACC = bison -y
YFLAGS = -d
objects = scan.o parse.o myprogram.o
myprogram: $(objects)
scan.o: scan.l parse.c
parse.o: parse.y
myprogram.o: myprogram.c
Run Code Online (Sandbox Code Playgroud)
我想要一个看起来与此类似的Makefile,附带的源文件可以做任意简单的事情.
我几乎在网上搜索了所有资料.但我仍然困惑为什么lexer无法识别yylval.
情况就是这样:我已经定义了一堆ADT node.h并实现它们node.c,我的目的是在正确存储这些结构后生成AST.但我被困在野牛档案中.
首先,我改%union到union YYSTYPE {...};和typedef union YYSTYPE YYSTYPE;,我不知道为什么我要做到这一点,在网上发布一些其他文件,似乎一道很好地工作%uinion.
然后,我被yylval事情困扰了.我已经做了bison -d一些事情,并且已经检查过了parser.c(我已经指定了bison输出),所以我认为extern YYSTYPE yylval;应该可行.但事实并非如此.所以我想知道是否还有另一种解决yylval未申报问题的方法.
我只使用两种类型的YYSTYPE结构,int并且char *,我可以YYSYTPE将AST 的联合和结构分开吗?这意味着,非终结符将没有关联类型.你们有其他想法吗?
我为类似C语言编写了一个解释器,使用Flex和Bison作为扫描器/解析器.它在执行完整的程序文件时工作正常.
现在我正在尝试在解释器中实现REPL以进行交互式使用.我希望它像Ruby或ML中的命令行解释器一样工作:
我的语法从一个top_level生产开始,它代表了该语言中的一个语句.词法分析器配置为stdin上的交互模式.我在全文件和REPL模式下使用相同的扫描器和语法,因为两个接口没有语义差异.
我的主要评估循环是这样构建的.
while (!interpreter.done) {
if (interpreter.repl)
printf(prompt);
int status = yyparse(interpreter);
if (status) {
if (interpreter.error)
report_error(interpreter);
}
else {
if (interpreter.repl)
puts(interpreter.result);
}
}
Run Code Online (Sandbox Code Playgroud)
除了提示和回显逻辑之外,这种方法很好.如果用户在一行上输入多个语句,则此循环将打印出多余的提示和表达式.如果表达式在多行上继续,则此代码不会打印出连续提示.出现这些问题是因为提示/回显逻辑的粒度是top_level语法中的一个语句,但是行读取逻辑在词法分析器中很深.
重构评估循环以处理REPL提示和回显的最佳方法是什么?那是:
(我宁愿不改变扫描仪语言来传递换行标记,因为这会严重改变语法.修改YY_INPUT和添加一些动作到Bison语法会很好.而且,我使用的是Flex 2.5.35和与Xcode一起发货的Bison 2.3.)