我已经找到了答案,但我没有得到任何快速回复的简单例子.
我想使用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) 有没有人知道lex/yacc格式语法的在线存储库?我正在寻找一种Java语法来制作一个快速的源代码转换器.
谢谢!
编辑:我最好是寻找lex/yacc因为我想使用fslex/fsyacc尽可能少的语法重写.
我正在尝试使用FLEX和BISON解析遗留语言(类似于'C').除了匹配字符串之外,一切都很好用.
这种相当奇怪的遗留语言不支持在字符串文字中引用字符,因此以下都是有效的字符串文字:
"hello"
""
"\"
Run Code Online (Sandbox Code Playgroud)
我正在使用以下规则来匹配字符串文字:
\".*\" { yylval.strval = _strdup( yytext ); return LIT_STRING; }
Run Code Online (Sandbox Code Playgroud)
不幸的是,这是一个贪婪的匹配,所以它匹配如下代码:
"hello", "world"
Run Code Online (Sandbox Code Playgroud)
作为单个字符串(hello", "world).
通常的非贪婪量词.*?似乎在FLEX中不起作用.有任何想法吗?
我正在寻找Sublime Text中的语法,以一种使它们可读的方式突出我的Flex和Bison文件(或lex/yacc)... Sublime Text自动选择Lisp for Flex文件,但这并不能解决问题一切都很好.尝试其他语法的任何建议?或者是否有一个有用的插件(到目前为止还没找到任何东西)?
我正在编写一个解析器,用于使用缩进等非常复杂的配置文件.我决定使用Lex将输入分解为令牌,因为它似乎使生活更轻松.问题是我找不到任何使用Qi错误报告工具(on_error)的示例,其中解析器使用令牌流而不是字符进行操作.
要使用的错误处理程序on_error需要一些能够准确指示错误在输入流中的位置.所有示例都只是std::string从迭代器对构造并打印出来.但是如果使用Lex,则迭代器是标记序列的迭代器,而不是字符.在我的程序中,这导致std::string在我注意到无效的迭代器类型之前挂起构造函数.
据我所知,令牌可以将输入流的一对迭代器作为其值.这是默认属性类型(如果类型是这样lex::lexertl::token<>).但是,如果我想我的令牌包含一些解析(更多有用的int,std::string等等),这些迭代器都将丢失.
如何在使用带Qi的Lex时生成指示输入流中位置的人性化错误消息?有这种用法的例子吗?
谢谢.
我正在尝试使用flex和bison来创建一个简单的脚本语言.现在,我只是想让计算器正常工作.
但是我无法编译它.当我运行这个makefile时:
OBJECTS = hug.tab.o hug.yy.o
PROGRAM = hug.exe
CPP = g++
LEX = flex
YACC = bison
.PHONY: all clean
all: $(OBJECTS)
$(CPP) $^ -o $(PROGRAM)
clean:
$(RM) *.o *.output *.tab.* *.yy.* $(PROGRAM)
%.tab.o: %.tab.cpp
$(CPP) -c -o $@ $<
%.tab.cpp: %.ypp
$(YACC) -vd $<
%.yy.o: %.yy.c
$(CPP) -c -o $@ $<
%.yy.c: %.l
$(LEX) -o $@ $<
%.o: %.cpp
$(CPP) -c -o $@ $<
Run Code Online (Sandbox Code Playgroud)
在我的.l和.ypp文件中,我收到此错误:
undefined reference to `yylex()'
Run Code Online (Sandbox Code Playgroud)
如果我这样做命令all:
$(CPP) $^ -o $(PROGRAM) -lfl
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
我为类似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.)
我需要在C中处理一个字符串,其中某些单词(如果存在)必须转换为大写.我的第一选择是在LEX中使用这样的东西:
%%
word1 {setToUppercase(yytext);RETURN WORD1;}
word2 {setToUppercase(yytext);RETURN WORD2;}
word3 {setToUppercase(yytext);RETURN WORD3;}
%%
Run Code Online (Sandbox Code Playgroud)
我看到的问题是我没有检测到某些字符是否为大写(fe Word1,wOrd1 ......).这可能意味着一个接一个地列出:
%%
word1 |
Word1 |
WOrd1
{setToUppercase(yytext);RETURN WORD1;}
%%
Run Code Online (Sandbox Code Playgroud)
有没有一种方法可以定义这种特定的令牌在不区分大小写的模式下进行比较?我发现我可以编译词法分析器不区分大小写,但这会影响我程序的其他部分.
如果没有,任何解决方案建议?
lex ×10
bison ×6
yacc ×5
flex-lexer ×4
c ×2
c++ ×2
boost ×1
boost-spirit ×1
eof ×1
g++ ×1
java ×1
regex ×1
sublimetext2 ×1
sublimetext3 ×1