Parsing 为解析器/词法分析器规范提供类型系统?

Parsing 为解析器/词法分析器规范提供类型系统?,parsing,functional-programming,f#,lex,type-systems,Parsing,Functional Programming,F#,Lex,Type Systems,人们通常认为,与Python或JavaScript等动态语言相比,Ocaml或F#等函数式编程语言的类型系统允许我们花更多的时间编写代码,而花更少的时间进行调试 现在,我正在编写一个解析器规范,用于FsLexYacc,即F#Lexer和parser包。解析器规范有如下内容,用于解析整数和标识符名称: %token <int> CSTINT %token <string> NAME ... Expr: NAME {VAR $1} |CSTINT {CSTI $1}

人们通常认为,与Python或JavaScript等动态语言相比,Ocaml或F#等函数式编程语言的类型系统允许我们花更多的时间编写代码,而花更少的时间进行调试

现在,我正在编写一个解析器规范,用于FsLexYacc,即F#Lexer和parser包。解析器规范有如下内容,用于解析整数和标识符名称:

%token <int> CSTINT
%token <string> NAME
...
Expr: 
  NAME {VAR $1}
 |CSTINT {CSTI $1}
%token csint
%令牌名
...
表达式:
名称{VAR$1}
|CSTINT{CSTI$1}
此类代码不再用函数编程语言编写,因此,它们不再受到类型系统的“保护”。我想奇怪的虫子很容易溜进来(不过不太确定)


问:是否有任何工作(理论或实践)试图通过为解析器/词法分析器规范提供一种类型系统来解决这个问题?

您可以使用。这样,您将获得使用F#type系统的所有好处。使用F#中的FParsec可将上述内容描述如下:

type Expression=StringExpr of String | numberxpr of int
让alphanumericString=letter.>>。(许多字符(字母数字))
>>=(fun(c,s)->预翻转(StringExpr(c.ToString()+s)))
let number=多个字符的数字
>>=(乐趣n->preturn(numberxpr(Int32.Parse n)))
let expression=alphanumericString number

是的,在这个领域已经有了一定数量的研究

应该注意的是,尽管LR解析算法中使用的语义值堆栈具有异构类型,但该算法本身是类型安全的。但是,当然,在算法的实现中可能会有错误,因此,如果编译器本身能够验证解析器生成器生成的代码类型是否正确,这将是理想的。事实证明这是可能的,并且已经产生了许多实现

我手头没有一份完整的参考书目,但我手头有两篇论文,都是2006年发表的,它们似乎很相关:

  • 弗朗索瓦·波蒂埃(François Pottier)和雅恩·雷吉斯·吉亚纳斯(Yann Régis Gianas):

    与许多函数式编程语言实现捆绑在一起的LR解析器生成器会生成非类型化、不必要的低效或两者兼而有之的代码。我们表明,使用广义代数数据类型,可以生成类型良好(因此它们不会意外崩溃或失败)但仍然有效的解析器

  • 拉尔夫·辛兹和罗斯·帕特森:

    本文描述了LR解析的纯功能实现。 我们从打印的相反方向开始,通过一系列步骤正式推导解析器。与传统的LR解析实现不同,生成的解析器是全类型、无堆栈和无表的。解析函数与由连续参数表示的每个备选方案并行地追求备选方案。直接实现为优化提供了许多机会,与传统的表驱动解析器相比,初始测量显示了优异的性能


我用几篇参考文献回答了这个问题,但我认为问题和答案实际上超出了SO的范围,这阻碍了寻求非现场资源的问题。关于计算机科学理论方面的问题通常最好提交给。
type Expression = StringExpr of String | NumberExpr of int

     
let alphanumericString = letter .>>. (manyChars (letter <|> digit)) 
                          >>= (fun (c,s)-> preturn (StringExpr(c.ToString()+s)))

let number = manyChars digit 
                 >>= (fun n -> preturn (NumberExpr (Int32.Parse n)))

let expression = alphanumericString <|> number