【发布时间】:2011-06-09 17:19:43
【问题描述】:
有没有一种简单的方法可以将 Bison/Flex/Yacc 集成到 XCode 中?
我想编写自己的语言进行解析,它与我的 ObjC 对象交互。
但是这些工具只会将 STDIN 作为输入,并且只会生成 C 代码,而不是 ObjC。它们基本上只对命令行工具有用,否则每次我重新生成解析器代码时,它们都需要非常痛苦地覆盖输出。
【问题讨论】:
标签: objective-c xcode parsing yacc bison
有没有一种简单的方法可以将 Bison/Flex/Yacc 集成到 XCode 中?
我想编写自己的语言进行解析,它与我的 ObjC 对象交互。
但是这些工具只会将 STDIN 作为输入,并且只会生成 C 代码,而不是 ObjC。它们基本上只对命令行工具有用,否则每次我重新生成解析器代码时,它们都需要非常痛苦地覆盖输出。
【问题讨论】:
标签: objective-c xcode parsing yacc bison
简而言之,给你的语法文件一个 .ym 扩展名而不是 .y。然后 Xcode 将使用必要的魔法运行 Bison,以支持 Objective-C。
奇怪的是,我发现这个问题是因为我想做同样的事情。我记得在 Apple 的 cocoa-dev 邮件列表上有一个关于它的讨论,但这个问题在我的谷歌搜索中出现得更高。我找到了我记得的讨论,on CocoaBuilder - 最后有一个相当广泛的例子。希望对我们俩都有帮助,哈哈!
(编辑)顺便说一句,让我大吃一惊 - 我仍然没有找到任何有关它的官方文档。
【讨论】:
sourcecode.yacc 是 Xcode 支持的文件类型之一。如果您打开 Xcode 的 Info.plist,您将看到 Yacc (Bison) 源文件的可识别扩展名列表; ym 就是其中之一。
Xcode 确实知道如何处理 yacc 和 flex 文件,并且会自动将生成的代码文件编译到您的项目中。诀窍是找出它期望的扩展。在 Xcode 4 中,单击源列表中的顶级项目以获取项目设置。在下一个列表中单击您的目标,然后在表视图标题中单击构建规则。向下滚动到“系统 Lex 规则”和“系统 Yacc 规则”,然后将光标悬停在每个文件中的“源文件”上,以获取带有用于该规则的扩展名的工具提示。 (……什么?这不是很明显吗?)
对于 Lex,它是:*.l *.lm *.lmm *.lpp *.lp *.lxx
对于 Yacc,它是:*.y *.ym *.ymm *.ypp *.yp *.yxx
如果您的 lex/yacc 文件中有任何 Objective-C 代码,您需要使用 .?m 扩展名来告诉 Xcode 生成一个 .m 文件;同样,.?mm 用于 Objective-C++。 (我猜 .?pp、.?p 和 .?xx 都是 C++。)据我所见,这个 Just Works,不需要 Makefile。如果您想保留 .flex 扩展名,可以单击 Lex 规则中的“复制到目标”按钮并为该扩展名创建新规则。
现在“有趣”的部分是尝试将 yacc 集成到您的代码中。默认情况下,使整个事情顺利进行的 yyparse() 函数需要来自 STDIN 的输入,除非您跳过一堆箍以使其正常工作。如果您一心想使用 yacc,那么网上有很多关于如何随心所欲地使用 yacc 的信息。但是,如果您使用像 lemon 这样的现代解析器生成器,您的额头上的键盘凹痕可能会减少。语法是基于 yacc 的,它是 LALR(1)(不管这意味着什么),所以你所知道的关于 shift/reduce 冲突的一切仍然有效。我发现它比 yacc/flex 更容易使用。
编辑:我似乎记得 Xcode 没有自动将 .l 文件添加到构建阶段,但它确实添加了 .y 文件。通过单击 Xcode 源列表中的顶级项目检查您的构建阶段,单击您的目标,单击 Build Phases 表头,然后展开 Compile Sources 行。如果您的 .l 文件不在其中,请将其从源列表中拖入。
【讨论】:
我找到了一个很好的例子:https://github.com/epatel/ParserTest。它已有 3 年历史,但适用于 Xcode 6 和 7。
【讨论】:
这都是古老的 - 但您可以将 YACC 重新定义为任何内容,并将 LEX 重新定义为用户定义的设置。
【讨论】: