我有一个学校项目,我们需要使用flex和bison.我想使用C++,这样我就可以访问我编写的STL和我自己的类.我们获得了以下Makefile:
CC = gcc
CFLAGS = -g
OBJs = parse.tab.o symtab.o attr.o lex.yy.o
default: parser
parser: ${OBJs}
${CC} ${CFLAGS} ${OBJs} -o parser -lfl
lex.yy.c: scan.l parse.tab.h attr.h
flex -i scan.l
parse.tab.c: parse.y attr.h symtab.h
bison -dv parse.y
parse.tab.h: parse.tab.c
clean:
rm -f parser lex.yy.c *.o parse.tab.[ch] parse.output
depend:
makedepend -I. *.c
Run Code Online (Sandbox Code Playgroud)
scan.l和parse.y有一些初始的flex/bison东西来生成扫描器和解析器.我需要将自己的东西添加到这些文件中.symtab.{h,c}应该是符号表的实现.attr.{h,c}用于某些属性魔法.我想制作symtab.ca .cc文件,以便我可以使用STL.我还有其他原因想要使用C++.
我尝试使用parse.ypp文件,以便生成.cpp文件.但问题是我没有得到正确的.h文件.我将Makefile更改为如下所示:
CC = g++ # Change gcc to g++
CFLAGS = -g
OBJs = lex.yy.o parse.tab.o symtab.o attr.o
default: lex.yy.c parser # added lex.yy.c so I could …Run Code Online (Sandbox Code Playgroud) 我正在使用Flex和Bison作为解析器生成器,但是我的扫描器中的启动状态有问题.
我正在使用独占规则来处理评论,但这个语法似乎与引用的标记不匹配:
%x COMMENT
// { BEGIN(COMMENT); }
<COMMENT>[^\n] ;
<COMMENT>\n { BEGIN(INITIAL); }
"==" { return EQUALEQUAL; }
. ;
Run Code Online (Sandbox Code Playgroud)
在这个简单的例子中:
// a == b
Run Code Online (Sandbox Code Playgroud)
除非我包含此规则,否则不完全匹配评论:
<COMMENT>"==" ;
Run Code Online (Sandbox Code Playgroud)
如何在不必将所有这些令牌添加到我的独家规则中的情况下解决这个问题?
我有一个从bison(解析器)生成的控制台应用程序,我想为它构建一个简单的gui,所以我可以将这个gui的输入发送到控制台,并从控制台输出到gui.我试图用java进程类做到这一点,但它对我不起作用,请帮我用qt做到这一点.
我知道如何让YACC生成一个AST,但是你如何才能获得它?我的意思是,你如何从YACC获得根节点的价值?
如何将一个aditional参数(不是类型的标记辅助YYSTYPE)传递给yypush_parse()函数?
解析器确实是可重入的,但是这个aditional变量对于我需要集成解析器的应用程序的线程安全性至关重要(它是PHP扩展,所以我们讨论的是TSRM).
我不能只是摆脱那个参数,因为在动作代码中我将调用函数,这些函数将以用户可访问的形式生成AST.
我试图破解YYPUSH_DECLS它并且就声明函数而言它起作用,但是几千个LOC下来实现了yypush_parse,我看不到任何方法来覆盖函数签名的实现yypush_parse开始.
YYPARSE_PARAM 仅在解析器不是推送器时使用(据我所知),但在我的情况下,我需要它是因为我必须在处理循环中执行的操作,在lexing之后和添加新的之前令牌到解析堆栈.
所以我想知道是否有%directive可能有所帮助的东西.
另一方面YYPARSE_PARAM,无论它是什么类型的解析器,我都认为应该根据它的定义使用它.遗憾的是,它不是.
我正在尝试编写一个简单的YAML解析器,我从yaml.org读取规范,在开始之前,我想知道编写手动解析器或者使用lex(flex/bison)是否更好.我看了看libyaml(C库) - 好像没用lex/yacc.YAML(不包括流样式)似乎更面向行,因此,编写手动解析器或使用flex/bison
Thanks 更容易.
这更像是一个"原则上"问题,而不是一个实际问题.是Yacc减少产生的顺序,并从定义的词法分析器中读取新的标记.也就是说,如果我有以下一组令牌:
INTEGER_BEGIN
INTEGER_VALUE
LESS_THAN
INTEGER_BEGIN
INTEGER_VALUE
Run Code Online (Sandbox Code Playgroud)
Yacc可以在其语义中读取LESS_THAN词法分析器中的令牌,然后将其缩减INTEGER BEGIN INTEGER_VALUE为单个内容,给出一组产生,例如:
expr : expr LESS_THAN expr
| integer
integer : INTEGER_BEGIN INTEGER_VALUE
Run Code Online (Sandbox Code Playgroud)
如果使用语义操作定义了这些更改的规则吗?
我对维基百科的以下引用感到困惑:
换句话说,如果一种语言足够合理以允许高效的单遍解析器,则它可以由 LR(k) 语法来描述。并且该语法总是可以机械地转换为等效(但更大)的 LR(1) 语法。因此,从理论上讲,LR(1) 解析方法足以处理任何合理的语言。在实践中,许多编程语言的自然语法接近 LR(1)。[需要引用]
这意味着如果能够将语法转换为语法,则解析器生成器(如bison)将非常强大(因为它可以处理LR(k)语法)。是否存在一些这样的例子,或者如何做到这一点的秘诀?我想知道这一点,因为我的语法中有移位/归约冲突,但我认为这是因为它是一种语法,并且想将其转换为语法。附带问题:是一种不合理的语言,因为我读过,生成的解析器无法解析它。LR(k)LR(1)LR(2)LR(1)C++bison
我有使用复制字符串lexeme的flex代码strdup().
%{
#include "json.tab.h"
#define YY_DECL extern "C" int yylex()
%}
%option noyywrap
%%
[ \t\n]+ ;
\"[a-zA-Z]+\" {yylval.sval = strdup(yytext); return STRING; }
[0-9]+ {yylval.ival = atoi(yytext); return NUMBER; }
. {return yytext[0];} ;
%%
Run Code Online (Sandbox Code Playgroud)
strdup()分配内存并将输入字符串复制到其中并返回(strdup() - 它在C中做了什么?),所以我想当我不再需要它时我需要释放它.
从这篇文章:什么是在BISON中调用%析构函数?,我%destructor { free($$); printf("free");} STRING在yacc文件中添加了.
但是,free()即使yylval.sval从返回的新字符串赋值,我也看不到调用strdup().
可能有什么问题?如何释放flex/bison中分配的字符串?
我想如下使用静态分配的sval:
%union {
int ival;
char sval[100]; // char* sval;
}
Run Code Online (Sandbox Code Playgroud)
flex代码现在变为(如果yytext小于100字节,则没有检查代码):
\"[a-zA-Z]+\" {
//yylval.sval = strdup(yytext);
memset(yylval.sval, …Run Code Online (Sandbox Code Playgroud) 我有一组用"A"语言编写的文件,需要翻译成语言"B"的相应文件.我想创建一个可以自动执行此任务的程序/解析器(可能是工具链而不是单个程序).但是,我正在努力为我的工具链的程序找到合适的选择.

语言A是嵌入式软件代码,即低级语言.它是90%标准C代码和10%"自定义"代码,即文件还包含标准C编译器无法理解的小段.90%的C代码不是 C中可能的任何随机C构造(这对于语义很难解析),而是遵循某些重复的表达式,动作和模式.并且它总是以(或多或少)相同的方式遵循这些模式.它主要对内存执行写操作,不包括复杂的结构,如C-struct或enum等.
语言A中常规低级C代码的示例:
#define MYMACRO 0x123
uint32_t regAddr;
regAddr = MYMACRO;
*(uint32_t*)(regAddr) = 0xdeadbeef;
Run Code Online (Sandbox Code Playgroud)
语言A中"自定义代码"的示例:
custom_printf("hello world! Cpu number: %d \n", cpu_nr);
Run Code Online (Sandbox Code Playgroud)
语言B是100%自定义语言.此转换是必要的,以便在另一个工具中使用该文件进行调试.上面例子的翻译看起来大致如下:
definemacro MYMACRO 0x123
define_local_int regAddr
localint.set regAddr = MYMACRO
data.write regAddr 0xdeadbeef
Run Code Online (Sandbox Code Playgroud)
注意:我很清楚Stackoverflow并不是一个关于"您更喜欢哪种工具?"的公开讨论的网站.但我认为这个问题更像是"我至少需要一个能够完成工作的有意义的工具集",也就是说,无论如何,可能没有那么多明智的讨论选择.
到目前为止,这些是我的考虑和方法:
有人可以给我一些关于这项任务的一套有意义的工具的建议吗?
编辑: 如果这似乎是一个模糊的问题,我道歉,我试着尽可能准确地说出来.我为语言A和B添加了一个示例,以使语言的组成更加清晰,并且为了表明语言A遵循某些重复出现的模式,这些模式可以很容易地理解语义.
如果这个编辑没有提高清晰度和广度,我将按照建议重新发布给程序员.
编辑2:好的,由于这个主题似乎仍然在这里被取消,我在这里撤回了这个问题.我已经从前几张海报中收到了一些有价值的信息,这些信息鼓励我使用通用解析器生成器进行进一步的实验.