解析子程序列表

时间:2013-10-14 14:05:12

标签: parsing ocaml lexical-analysis ocamllex ocamlyacc

我写了parser_sub.mlylexer_sub.mll,可以解析subroutinesubroutine是由SubEnd Sub嵌入的语句块。

实际上,我想要处理的原始文件包含一个子程序列表和一些无用的文本。这是一个例子:

' a example file
Sub f1()
  ...
End Sub
haha
' hehe
Sub f2()
  ...
End Sub

所以我需要编写parser.mlylexer.mll,它可以通过忽略所有注释(例如haha' hehe等)来解析此文件并调用{{ 1}},并返回子程序列表。

  1. 有人能告诉我如何让解析器忽略所有无用的句子(parser_sub.mainSub之外的句子)?

    以下是我试图写的End Sub的一部分:

    parser.mly
  2. %{ open Syntax %} %start main %type <Syntax.ev> main %% main: subroutine_declaration* { $1 }; subroutine_declaration: SUB name = subroutine_name LPAREN RPAREN EOS body = procedure_body? END SUB { { subroutine_name = name; procedure_body_EOS_opt = body; } } 的规则和解析很复杂,实际上是在procedure_bodyparser_sub.mly中定义的,所以我怎样才能让lexer_sub.mll和{{1}不要重复定义它,只需调用parser.mly

2 个答案:

答案 0 :(得分:1)

当我们进入子程序时,也许我们可以设置一些标志:

sub_starts:
  SUB { inside:=true };
sub_ends:
  ENDSUB { inside:=false };    
subroutine_declaration:
  sub_starts name body sub_ends { ... }

如果没有设置此标志,您只是跳过任何输入?

答案 1 :(得分:0)

如果你想要的东西如此跳过可以有任何形式(不一定是你的语言的有效令牌),你几乎必须通过黑客攻击你的词法分析来解决这个问题,正如卡卡杜所说的那样。无论如何,这可能是最简单的事情。

如果填充(要跳过的东西)包含有效标记,并且您想要跳过使用语法规则,那么在我看来,主要问题是定义一个与END以外的任何标记匹配的非终结符。这对于保持最新状态是不愉快的,但似乎是可能的。

最后,您遇到的问题是您的结束标记是两个符号END SUB。你必须处理你看到END后面没有SUB的情况。这甚至比较棘手,因为SUB也是你的开始标记。同样,简化这种方法的一种方法是破解你的词法分析器,使其将END SUB视为单个标记。 (通常这比你想象的要复杂,比如说你想允许END和SUB之间的评论。)