我正在尝试编写一个可以分析混合语言并生成它的AST的Parser。我首先尝试在Java中自己构建它并且失败了,因为这对于Parser-beginner来说是一个相当难的主题。然后我用Google搜索并找到了http://www2.cs.tum.edu/projects/cup/examples.php和JFlex。
现在的问题是:最好的方法是什么?
例如我有一个Codefile,它包含几个Tags,JS Code和一些$ CMS_SET(x,y)$ Code。解决这个问题的最佳方法是为CUP中的所有内容定义一个语法,让CUP根据我的语法生成一个Parser,它可以分析那些混合语言文件并生成它的AST Tree吗?
感谢所有有用的答案。 :)
编辑:我需要用Java做...
答案 0 :(得分:4)
即使对于这方面的专家来说,这个话题也很难,我认为自己也是如此;检查我的生物。
第一个问题是为每个子语言构建单独的解析器。您将发现的第一件事是为特定语言定义解析器实际上很难;你可以阅读无穷无尽的SO请求列表"我可以获得X&#34的解析器吗?或者"如何修复X"的解析器。大多数情况下,我认为这些要求最终无法进入任何地方解析引擎不是很好,你必须扭曲语法和解析器才能使它们适用于真正的语言,没有任何类似于纯粹的HTML"标准文档不一致,你的客户总是在他的代码中有一些你不准备的东西。最后还有与字符集编码相关的故障,换行符结尾的变化以及使解析解析问题复杂化的预处理器。 C ++预处理器比你想象的要复杂得多,你必须拥有这个权利。解决此问题的最简单方法是找到一些已预定义语言的解析器生成器。 ANTLR有一堆现已弃用的ANTLR3;我们无法保证这些解析器是健壮的,更不用说与您的目的兼容了。
CUP不是一个特别有用的解析器生成器; LL(x)或LALR(x)解析器生成器中没有一个真正有用,因为没有真正的语言符合它们可以解析的事物的类别。结果是:无休止的请求(在SO!上)以获得帮助"解决我的转移 - 减少冲突"或者#34;消除正确的递归"。唯一经过时间考验的解析器生成器IMHO是一个GLR解析器生成器(我听说GLL的好东西,但这是最近的)。我们使用一个 GLR解析器生成器完成了40多种语言,包括生产IBM COBOL,完整的C ++ 14和Java8。
你的第二个问题是构建AST。您可以手动编写AST构建过程的代码,但是当您必须经常更改语法和/或您有许多语法时,这会很快变旧。这可以用汗水击败你的方式。 (我们之所以选择推the problem of building ASTs into the parser,那么我们就不必为构建语法付出任何精力;要做到这一点,你的解析器引擎必须为你提供这种帮助而且没有主流的帮助。)
现在你需要编写解析器。当需要出现时,您需要让一个人调用另一个;当然,您选择的解析器并非设计用于执行此操作,因此您必须将其扭曲。第一个难点是为解析器提供线索,在输入流中出现子语言,并将其解析为sublangauge解析器,并让它将树传递回父解析器&# 39; s树,大概有某种标记,所以你可以知道树中不同子语言之间的过渡。你经常可以通过黑客攻击一种语言的词法分析器,当它看到线索时,调用另一种;但是你用它返回的树做了什么?没有办法将该树提供给当前的解析器,并说"整合这个"。你可以通过以神秘的方式修改解析机制来解决这个问题。
但以上所有问题都不是问题所在。
解析不方便,但只需要以任何有趣的方式分析程序所需的一小部分;您需要符号表,控制和数据流分析,可能需要进行点分析,而这些工程的工程将淹没上面列出的工作。请参阅我的论文"解析后的生活" (谷歌或通过我的生物)长期讨论你还需要什么。
简而言之,我认为你正在解决一个巨大的任务,只是解析",你甚至没有告诉我们你打算如何处理结果。欢迎你从这条道路开始,但很少有人成功;我的团队花了50多年的博士水平工程来实现我们的目标,我们很难完成。
Java不会让解决方案变得更容易或更难;你解决上述所有问题的语言是无关紧要的。