- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我很好奇 yyrestart 的函数签名 - 即在词法分析器文件中我看到签名是:
void yyrestart (FILE * input_file )
在我的代码中,我使用 yyrestart 刷新缓冲区,但我没有向它传递任何参数,它只是空的:
yyrestart();
除了最新版本的 OS X 之外,它目前在我们测试的每个系统上都在运行。通过 GDB 单步执行,很明显在我的 rhel 机器上,不带参数的调用将文件指针设置为 NULL:
yyrestart (input_file=0x0) at reglexer.c:1489
而在 El Capitan 上它作为垃圾出现,这会导致稍后在生成的代码中出现内存错误:
yyrestart (input_file=0x100001d0d) at reglexer.c:1489
我这辈子都弄不清楚 yyrestart() 的定义位置。 yacc/flex 中是否有一些宏定义了不带参数调用 yyrestart 的行为?如果不是,这甚至是如何编译的?
************ 编辑以澄清编译问题 ************
作为一个小片段来了解我在说什么 - 这是我的 .y 文件中的内容,它正在执行解析器(这是对 this example 的轻微修改):
int main() {
FILE *myfile = fopen("infile.txt", "r");
if (!myfile) {
fprintf(stderr, "can't open infile.txt\n");
return 1;
}
calcYYin = myfile;
do {
calcYYparse();
} while (!feof(calcYYin));
calcYYrestart();
return 0;
}
我可以使用我想要的任何内容作为参数传递给该行的 calcYYrestart() 来构建该存储库。替换
calcYYrestart('a', 1, 5, 'a string');
仍然让我使用 make 编译整个程序(但是得到一个带有错误输入的 segv)。但是查看生成的 parcalc.c 文件,除了文件指针之外,我看不到任何可以让我调用 calcYYrestart 的东西。我只将其视为原型(prototype):
void calcYYrestart (FILE * input_file );
编译器让我可以将任何我想要的内容作为生成函数的参数的神奇之处在哪里?
最佳答案
你期待 C 温柔地带领你穿过迷宫,牵着你的手,在你犯错时责备你,为你的成功鼓掌。
这些对一门语言的期望或许并不是不合理的,但C不是那门语言。 C 按照您的指示执行,仅此而已,当您的指令不够清晰时,它只会让您跌倒。
虽然,在它的辩护中,你可以要求它更冗长一点。如果您在命令行中指定 -Wall
(至少使用 gcc 和 clang),编译器将为您提供一些警告。 [见注释 1。]
在这种情况下,它可能会警告您未声明 calcYYrestart
,这将使您有责任正确设置参数。该函数是在词法分析器中声明和定义的,但在这里您是在解析器中使用它,这是一个单独的编译单元。你真的应该在解析器序言中声明它,但没有任何东西会强制声明的正确性。 (在这种情况下,C++ 将无法链接,但 C 不会在正式函数名称中记录参数类型。)
值得注意的是,您作为工作基础的示例代码存在很多问题。我建议寻找更好的 bison/flex 教程,或者至少阅读 flex 手册中有关如何处理输入的部分。
在这里,我在原始示例中添加了一些注释,它显示了 calc.y
bison 输入文件:
/* This is unnecessary, since `calcYYparse` is defined in this file.
extern int calcYYparse();
*/
extern FILE *calcYYin;
/* Command line arguments are always good */
int main(int argc, char** argv) {
/* If there is an argument, use it. Otherwise, stick with stdin */
/* There is no need for a local variable. We can just use yyin */
if (argc > 1) {
calcYYin = fopen(argv[1], "r");
if (!calcYYin) {
fprintf(stderr, "can't open infile.txt\n");
return 1;
}
}
/* calcYYin = myfile; */
/* This loop is unnecessary, since yyparse parses input until it
* reaches EOF, unless it hits an error. And if it hits an error, it
* will call calcYYerror (below), which in turn calls exit(1), so it
* never returns.
*/
/* do { */
calcYYparse();
/* } while (!feof(calcYYin)); */
return 0;
}
void calcYYerror(const char* s) {
fprintf(stderr, "Error! %s\n", s);
/* Valid arguments to `exit` are 0 and small positive integers. */
exit(EXIT_FAILURE);
}
当然,您可能不希望遇到语法错误就炸毁世界。意图可能是丢弃该行的其余部分,然后继续解析。在这种情况下,由于显而易见的原因,callYYerror
不应调用 exit()
。
默认情况下,调用yyerror
后,yyparse
会立即返回(在清理其本地存储后)并显示错误指示。如果您希望它继续,那么您需要使用 error
产生式,这将是最好的解决方案。
您也可以简单地再次调用 yyparse
,如示例中所示。但是,这会在 flex 缓冲区中留下未知数量的输入文件。 没有理由相信缓冲区完全包含错误行的其余部分。由于 flex 扫描器通常以大块读取那里的输入(交互式输入除外),因此使用 yyrestart
将丢弃随机数量的输入,将输入文件指针留在文件中的随机位置,这可能与新行的开头不对应。
即使情况并非如此,对于无缓冲(交互式)输入,也完全有可能在行尾 检测到错误,在这种情况下,新行已经已被消耗。因此丢弃到当前行的末尾将导致丢弃错误之后的行。
最后,使用 feof(input)
来终止输入循环是一个众所周知的反模式,应该避免在读取输入时遇到 EOF 时终止。对于 flex 生成的扫描器,当检测到 EOF 时,当前输入被丢弃,然后(如果 yywrap
没有成功创建新输入),END
指示返回给解析器。到那时,yyin
不再有效(因为它已被丢弃),调用 feof
是未定义的行为。
-Wextra
获得更多警告。您可以通过告诉编译器使用最新标准 -std=c11
而不是增加了各种 gcc 扩展的 1989 版本(现在大部分已经过时)来使编译器更严格一些。)关于在没有参数的情况下在 bison 中调用 yyrestart 函数导致 El Capitan 上出现 sigsegv,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33376700/
我升级了 Java EE Web 应用程序以使用较新的 PrimeFaces 版本,突然在 PrimeFaces commandlink 的操作属性中调用重载 bean 方法不再起作用。我尝试使用 J
考虑以下代码片段。 var SomeView = Backbone.View.extend({ collection: new SomeCollection(), render: fu
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的 JSP 在 Tomcat 7 中运行良好,但在 Tomcat 6 中不起作用,我认为这是因为您不能从 EL 2.1 调用方法(getter/setter 除外)。 我需要调用的方法不能命名为ge
这个问题在这里已经有了答案: How to nest an EL expression in another EL expression (2 个答案) 关闭 5 年前。 我有 Java 枚举类型,
为什么会这样? ....Some Code 在我的 profielForm 中,我只有一个 getCityOptions() 方法,没有 cityO
我正在关注 backbone.js tutorial并遇到了 2 个函数 initialize() 和 render()。 initialize() 在附加一些 html 时使用了 $(self.el
对于给定的示例,this.el 和 this.$el 之间有什么区别? 我知道 this.$el 指向 this.el 的 jQuery 对象,在本例中是 'li'。 当我呈现 View 时,我可以在
我一直在我的主干应用程序中使用 this.$el,如下所示: render: function() { this.$el.html(this.template); }, 然后我在网上看到代码使
我想使用 EL 在 jsp 中调用一个传递给它的参数的 bean 函数。问题是它不允许这样的事情:“${teacherBean.certificationFor(${particularField})
有没有办法可以在 EL 中获取 ServletContext 中设置的属性,使其最终成为 JavaScript 变量? 我将其设置为 context.setAttribute("testing.por
我正在编写 JSP/JSTL,并且我正在尝试遍历数据库中的几个项目。 我目前在数据库中有三列,${image1} , ${image2}和 ${image3} .我正在尝试使用以下代码为他们打印信息:
this.$el.html 和 this.$el.append 在渲染模板时有区别吗?我对 js、backbone 等完全陌生。在我正在从事的当前项目中,我看到类似 this.$el.append(P
我刚刚学习了一些主干教程,我有一个一般的 jQuery 问题,我实际上已经想知道了一段时间。 有时我会在 jQuery 选择器中看到带有第二个参数的调用,例如 $('ul', this.el)。 选择
有没有办法在 SpEL 中调用静态接口(interface)方法?例如: T(java.util.stream.IntStream).of(new Integer[]{1,2,3}).sum() 当我
这个问题已经有答案了: If a DOM Element is removed, are its listeners also removed from memory? (6 个回答) 已关闭 5 年
JBoss EL resolver online documentation中有这句话: It's important to fully understand how this extension t
使用 JSF 2.0 和 EL,我试图在 POJO 上调用一个方法,它是一个 viewscoped bean 的一个属性。该代码实际上与 @BalusC 非常相似的教程here .当我调用一个不带参数
所以我整个下午都在 this problem 上卡住了我最终解决了。原来我分配的是 el 而不是 $el。 两者有什么区别,我应该在什么时候使用它们? 最佳答案 直接来自 the documentat
我正在努力学习 Backbone 。我知道 el 是正在执行的元素。如果未指定,则为空 div。我正在我的 View 中创建一个模板并返回 View 对象。然后我正在渲染 View ,但我不明白为什么
我是一名优秀的程序员,十分优秀!