我可以将ANTLR用于未预处理的代码吗?

时间:2011-01-28 11:49:29

标签: c# .net parsing antlr

我即将为OpenEdge(4GL数据库语言)编写解析器,我想使用ANTLR(或类似的)。

我认为这可能是一个问题有两个原因:

  1. OpenEdge是一种4GL数据库语言,允许使用以下结构:

    assign
        customer.name = 'Customer name'
        customer.age = 20
    .
    

    最后.是行分隔符,此语句结合了两个数据库字段的赋值。 OpenEdge有更多这些结构;

  2. 我需要保留源文件的所有细节,所以在解析文件之前我无法展开预处理器语句,所以:

    // file myinc.i
    7 * 14
    
    // source.p
    assign customer.age = {myinc.i}.
    

    在上面的示例中,我需要保留使用customer.age而不是{myinc.i}分配7 * 14的事实。

  3. 我可以使用ANTLR来解决这个问题,还是需要编写自己的解析器?

    更新
    我需要这个解析器不从它生成可执行文件,而是用于代码分析。这就是为什么我需要AST来包含使用include的事实。

5 个答案:

答案 0 :(得分:3)

只是为了澄清:ANTLR不是解析器,而是解析器生成器。

您可以为该语言编写自己的解析器,也可以为其编写(ANTLR)语法,让ANTLR为您生成词法分析器和解析器。您可以在语法中混合自定义代码以跟踪您的分配。

所以,答案是:是的,你可以使用ANTLR。

注意我不熟悉OpenEdge,但SQL语法通常很难编写解析器或语法。看看ANTLR wiki,看一下从头开始写一个并不是一件轻而易举的事。你没有提到它,但我认为你已经看过可以解析你的语言的现有解析器了吗?

仅供参考:您可能已经拥有它,但这里是文档的链接,包括OpenEdge SQL方言的BNF语法:http://www.progress.com/progress/products/documentation/docs/dmsrf/dmsrf.pdf

答案 1 :(得分:2)

解决方案在于OpenEdge架构师本身。你应该检查一下openge架构师jar文件(C:\ Progress \ OpenEdge \ oeide \ eclipse \ plugins \ com.openedge.pdt.core_10.2.1.01 \ lib \ progressparser.jar)

在这里,您将找到解析器类。它们一直链接到Eclipse,但我完成了与eclipse框架的分离,并且它可以工作。 progressparser使用antlr,antlr文件可以在以下文件夹中找到... C:\进展\ OpenEdge \ oeide \蚀\插件\ com.openedge.pdt.core_10.2.1.01 \ oe_common_services.jar

在该文件中,您将找到antlr定义(检查opensge.g)。

祝你好运。如果你想要分离的eclipse环境,请给我发邮件。

答案 2 :(得分:1)

您是否知道OpenEdge / Progress 4GL已经有一个开源解析器?它被称为Proparse,使用ANTLR编写(最初它是在OpenEdge本身手工编码,但最终转换为ANTLR)。它是用Java编写的,但我认为你可以使用IKVM在C#中运行它。

许可证是Eclipse许可证,因此它对业务友好。

答案 3 :(得分:0)

你可以做同样的事情,C预处理器正在做 - 用某种设置源位置的pragma扩展你的语法,让你的预处理器生成用这个pragma填充的代码。

答案 4 :(得分:0)

多语言分配的问题很容易在语法中处理。只允许多个分配:

assign_stmt = 'assign' assignments '.' ;
assignements = ;
assignments = assignments target '=' expression ;

您可以使用的一种方法是扩充语法,以便在允许非终结符的地方允许预处理程序标记序列,并且根本不进行预处理程序扩展。对于您的示例,您有一些语法规则:

expression = ... ;

只需添加规则:

expression = '{'  include_reference '}' ;

这种做法在某种程度上不会滥用预处理器来生成跨越非终结边界的几个语言元素。

您打算做什么样的代码?几乎要做任何事情,你需要命名和键入分辨率,这将需要扩展预处理器指令。在这种情况下,您需要一个更复杂的方案,因为您需要扩展树来进行名称解析,并且需要关联的包含信息。

我们的DMS Software Reengineering Toolkit有一个OpenEdge解析器,我们在其中演示了之前的“保留包含文件引用”技巧。 DMS的C解析器向树中添加一个“宏节点”,其中宏(OpenEdge“包含”只是编写宏定义的有趣方式)子节点包含您期望的树,以及引用回来的参考信息宏观定义。这需要一些仔细的组织,并且需要对宏节点进行大量特殊处理。