我收到警告
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++。)谢谢。
我们不知道如何跟踪 yacc 解析器中的错误。yylineno我们尝试在 lex 文件中使用并尝试添加%option yylineno,但它仍然不起作用,我们无法在 yacc 中访问这些变量。
error我们想要的只是使用yacc 和行号打印出语法错误。
这是我们的.l文件
%{
#include <stdio.h>
#include <stdlib.h>
#include "y.tab.h"
int yylineno=1;
%}
%option yylineno
identifier [a-zA-Z_][a-zA-Z0-9_]*
int_constant [0-9]+
delimiter ;
%%
"int" {return INT;}
{int_constant} return INT_CONST;
{identifier} return IDENT;
\= {return ASOP;}
\+ {return PLUS;}
\- {return MINUS;}
\* {return MULT;}
\/ {return DIV;}
\, {return COMMA;}
\( {return OP;} /*OP CP = Opening Closing Parenthesis*/
\) {return CP;}
\[ {return OB;} /*OB …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) 我正在用yacc / bison编写一个简单的计算器。
表达式的语法看起来有点像这样:
expr
: NUM
| expr '+' expr { $$ = $1 + $3; }
| expr '-' expr { $$ = $1 - $3; }
| expr '*' expr { $$ = $1 * $3; }
| expr '/' expr { $$ = $1 / $3; }
| '+' expr %prec '*' { $$ = $1; }
| '-' expr %prec '*' { $$ = $1; }
| '(' expr ')' { $$ = …Run Code Online (Sandbox Code Playgroud) 我认为 Bison 和 Yacc 经常用于解析编程语言的语法。(以及用于标记化的 lex/flex...)
我的问题是:所有编译器都是用这个工具制作的还是有人从头开始编写解析器?(我主要是在没有“编译器编译器”的情况下完成的,但我知道它们)
在没有这些工具的情况下构建解析器是否“有利可图”?
yacc/bison 和 lex/flex 是否有更“开放”且不那么严格的替代方案。是否存在 C 库可以为我做这件事(解析)?是否有另一种选择可以在没有 yacc 的情况下构建解析器,但也不从头开始编写它?
最好的问候卢卡斯