Yacc 不允许传递对象。由于 %union 只能包含 POD 类型,因此必须新建复杂对象并通过指针传递。如果发生语法错误,yacc 解析器就会停止运行,并且对所有这些创建的对象的引用都会丢失。
我提出的唯一解决方案是所有新对象都继承特定的基类,在分配时添加到容器中,如果出现错误,则可以删除该容器中的所有内容。
有谁知道有更好的 yacc 技巧来解决这个问题吗?
请不要告诉我选择不同的解析器。
我收到警告
warning, -s option given but default rule can be matched
Run Code Online (Sandbox Code Playgroud)
如果您在 google 上搜索“给出的选项,但可以匹配默认规则”,您将在“诊断”部分的旧 Flex 联机帮助页中找到 Flex 手册关于诊断的章节和此条目:
警告,“-s 选项给出,但可以匹配默认规则”意味着默认规则(匹配任何单个字符)可能(可能仅在特定开始条件下)是唯一匹配特定输入的规则。既然
-s给出了,大概这不是故意的。
我的构建文件没有-s选项。我写
bison -y -d calc1.y
flex calc1.l
gcc code...
Run Code Online (Sandbox Code Playgroud)
如何修复此警告?
这是我的 lex 文件的一个小版本。此文件也会触发警告
%{
#include "y.tab.h"
%}
%option noyywrap nodefault yylineno
%%
[0-9]+ {
return INTEGER;
}
[-+()=/*{},;\n] { return *yytext; }
[ \t] /* skip whitespace */
[a-zA-Z0-9_]* { printf("lex Unknown character = '%s'", yytext); yyerror("lex Unknown character"); }
%%
Run Code Online (Sandbox Code Playgroud) 我应该写一个程序来做 2 + 2 = 4 和 2.2 + 2 = 4.2。
我已经这样做了,因此它将所有内容都视为浮点数,但这是“错误的”。我必须区分它们。这是我到目前为止所拥有的:
%{
#include <stdio.h>
#include <ctype.h>
%}
%token <dval> FLOAT
%token <ival> INTEGER
%union
{
float dval;
int ival;
}
%type <dval> command exp term factor
%%
command : exp {printf("%f\n",$1);}
;
exp : exp '+' term {$$ = $1 + $3;}
| exp '-' term {$$ = $1 - $3;}
| term {$$ = $1;}
;
term : term '*' factor {$$ = $1 * $3;}
| …Run Code Online (Sandbox Code Playgroud) %token <token> PLUS MINUS INT
%left PLUS MINUS
Run Code Online (Sandbox Code Playgroud)
这有效:
exp : exp PLUS exp;
exp : exp MINUS exp;
exp : INT;
Run Code Online (Sandbox Code Playgroud)
这有 2 个转移/减少冲突:
exp : exp binaryop exp;
exp : INT;
binaryop: PLUS | MINUS ;
Run Code Online (Sandbox Code Playgroud)
为什么?
我正在尝试了解 flex/bison,但文档对我来说有点困难,而且我可能严重误解了某些内容。这是一个测试用例:http : //namakajiri.net/misc/bison_charlit_test/
文件“a”包含单个字符“a”。“foo.y”有一个像这样的简单语法:
%%
file: 'a' ;
Run Code Online (Sandbox Code Playgroud)
生成的解析器无法解析文件“a”;它给出了一个语法错误。
语法“bar.y”几乎相同,只是我更改了命名标记的字符文字:
%token TOK_A;
%%
file: TOK_A;
Run Code Online (Sandbox Code Playgroud)
然后在 bar.lex 中:
a { return TOK_A; }
Run Code Online (Sandbox Code Playgroud)
这个工作得很好。
我在尝试将字符文字直接用作野牛终端时做错了什么,就像在文档中一样?
我希望我的语法看起来像“statement: selector '{' property ':' value ';' '}'" 而不是 "statement: selector LBRACE property COLON value SEMIC RBRACE"...
我在 debian wheezy 中运行 bison 2.5 和 flex 2.5.35。
我在https://github.com/Habbie/autoyacc-problem上发布了一个存储库来演示我的问题。
在 automake 1.11 及以下版本中,AC_PROG_YACC在 configure.ac 和AM_YFLAGS=-dMakefile.am 中使用,parser.yy 将变成 parser.cc 和 parser.h。使用 automake 1.12,我得到 parser.cc 和 parser.hh。因为 mybin.cc 有include "parser.h",这意味着 1.12 破坏了我的构建。
我感觉这是一个向后不兼容的更改,但我觉得应该有一种理智的方法来处理这个问题。
展示:
git clone https://github.com/Habbie/autoyacc-problem.git
cd autoyacc-problem/
autoreconf -i
./configure
make
Run Code Online (Sandbox Code Playgroud)
automake 1.11 的结果:mybin 被构建。automake 1.12 的结果:
mybin.cc:1:20: error: parser.h: No such file or directory
Run Code Online (Sandbox Code Playgroud)
帮助!
注意:本示例中没有实际的 C++ 代码,但对于我的实际问题,我确实需要 g++。
我知道这是有原因的,但我还没有找到一个好的、简洁的解释来解释为什么 LEX/YACC 不能用于 C++。我也有兴趣知道 LEX/YACC 是否可以用来解析 Objective C,或者该语言是否遇到同样的问题。(请注意,我指的是 ObjC,而不是 Obj-C++。)谢谢。
我正在尝试编写一个能够使用以下输入的语法:
begin #this is a example
x = 56;
while x > 0 do
begin
point 15.6 78.96;
end;
end;
Run Code Online (Sandbox Code Playgroud)
这是 lexer.l 文件:
%option noyywrap
%{
#include "parser.h"
#include <stdlib.h>
#include <stdio.h>
const char * const unrecognizedToken = "Unrecognized token";
%}
NewLine \n
WhiteSpaces [\r\t\f\v ]+
Semicolon ;
digit [0-9]
number1 {digit}+\.?([eE][-+]?{digit}+)?
number2 {digit}*\.{digit}+([eE][-+]?{digit}+)?
double_number {number1}|{number2}
BEGIN "begin"
END "end"
WHILE "while"
DO "do"
POINT "point"
%x POINT_DEFINITIONS
%%
{WhiteSpaces} {
printf("WhiteSpaces");
printf("\n");
}
{NewLine} {
printf("NewLine");
printf("\n");
}
{WHILE} …Run Code Online (Sandbox Code Playgroud) 我的语法允许:
C ?id := E // 将值/表达式赋给变量 (VAR)
C ?打印(id)//打印变量(VAR)值
为了完成它,我的 lex 文件是:
[a-z]{
yylval.var_index=get_var_index(yytext);
return VAR;
}
Run Code Online (Sandbox Code Playgroud)
get_var_index 返回列表中变量的索引,如果它不存在则创建一个。这是工作!
该问题是:
我该如何解决?
yacc文件的一部分:
%union {
int int_val;
int var_index;
}
%token <int_val> INTEGER
%token <var_index> VAR
...
| PRINT '(' VAR ')'{
n_lines++;
printf("%d\n",values[$3]);
}
...
| VAR {$$ =values[$1];}
Run Code Online (Sandbox Code Playgroud)