Parsing 在OCaml中构建AST

Parsing 在OCaml中构建AST,parsing,ocaml,grammar,Parsing,Ocaml,Grammar,我正在使用OCaml为Scheme的一个子集构建递归下降解析器。语法如下: S -> a|b|c|(T) T -> ST | Epsilon 所以说我有: type expr = Num of int | String of string | Tuple of expr * expr 伪代码 这些函数必须返回expr类型才能构建AST parseS lr = if head matches '(' then parseL l

我正在使用OCaml为Scheme的一个子集构建递归下降解析器。语法如下:

    S -> a|b|c|(T)
    T -> ST | Epsilon
所以说我有:

   type expr = 
       Num of int | String of string | Tuple of expr * expr
伪代码

这些函数必须返回expr类型才能构建AST

parseS  lr =
   if head matches '(' then
     parseL lr
   else
     match tokens a, b, or c
使用第一组标记和“(”:


我的问题是“既然我不能返回(),如何返回Epsilon部分?”OCaml函数需要相同的返回类型,即使我为Epsilon部分留空,OCaml仍然采用单位类型。

也许与其手动创建解析器函数,不如使用现有的方法:例如,基于LALR(1)或基于camlp4的LL(k)据我所知,你的AST与语法不匹配

通过在AST类型中指定一个空节点来表示语法中的Epsilon,可以解决这个问题

或者,您可以更改语法以计算ε

下面是一个没有ε的等价语法:

S -> a|b|c|()|(T)
T -> S | S T

谢谢大家:)。但是我不能使用现有的实用程序,因为这是一个练习。所以据我所知,要么我必须包含一个Epsilon的占位符,要么像你提到的那样调整给定的语法。这似乎消除了ε问题。这是否意味着每当我看到Epsilon,我就重写语法?我会说是的,在概念上。实际上,这只是意味着您要在解析器中向前看。如果您是手工编写语法分析器,则无需花费大量时间重写语法即可使其正常工作。如果S返回expr类型的a、b、c,我应该为S中的()部分返回什么?我想说您希望使用列表来表示元组。然后为
()
使用空列表。这就是我所说的AST类型与语法不匹配的意思。你自己编写代码——你总是可以解析一个S,然后看看后面会出现什么。
S -> a|b|c|()|(T)
T -> S | S T