解析过程需要一种玩具语言

问题描述

我有某种玩具语言,它使用EBNF语法定义了过程和过程调用:

program = procedure,{procedure} ;
procedure = "procedure",NAME,bracedblock ;
bracedBlock = "{",statementlist,"}" ;
statementlist = statement,{ statement } ;
statement = define | if | while | call | // others omitted for brevity  ;
define = NAME,"=",expression,";"
if = "if",conditionalblock,"then",bracedBlock,"else",bracedBlock
call = "call",";" ;
// other definitions omitted for brevity

已经实现了使用该语言的程序的标记器,并返回标记向量。

现在,无需程序调用就解析该程序非常简单:可以直接使用上述语法定义递归下降解析器,并简单地通过标记进行解析。其他注意事项:

  1. 每个过程都可以直接或间接(任何其他过程 ,并且这些过程不必按照出现的顺序进行源代码中的内容(即B可以在A之后定义,A可以调用B,反之亦然)。

  2. 过程名称必须唯一,并且“保留关键字”可以用作变量/过程名称。

  3. 空格无关紧要,至少在不同类型的令牌中是如此:类似于C / C ++。

  4. 没有作用域规则:所有变量都是全局变量。

  5. “行号”的概念很重要:每个语句都有一个或多个与其关联的行号:例如,define语句每个只有一个行号,而{{1 }}语句本身是两个语句列表的父级,具有多个行号。例如:

if
    在整个程序中,
  1. 行号是连续的;没有为过程定义和关键字LN CODE procedure A { 1. a = 5; 2. b = 7; 3. c = 3; 4. 5. if (b < c) then { call C; } else { 6. call B; } procedure B { 7. d = 5; 8. while (d > 2) { 9. d = d + 1; } } procedure C { 10. e = 10; 11. f = 8; 12. call B; } 分配行号。行号是由语法定义的,而不是它们在源代码中的位置:例如,考虑“行” else4

  2. 在给定每个语句及其行号,使用的变量,变量 set 和子容器的数据库中,需要设置一些关系。 这是一个关键考虑因素

因此,我的问题是:我如何解析这些函数调用,保持行号的完整性以及设置关系?

我已经考虑过“ OS”的处理方式:遇到过程调用时,请寻找与所述被调用过程匹配的过程,解析被调用者,然后将调用堆栈展开回调用者。但是,这破坏了行号的排序:如果要以这种方式解析上述程序,则5的行号为C6,而不是8 10(含)。

另一种解决方案是依次解析整个程序一次,维护过程调用的拓扑,然后按照所述拓扑对第二次进行解析。由于实现细节,这是有问题的。

有没有可能更好的方法呢?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)