接受定义语言的每个前缀的野牛语法
Bison grammar that accepts every prefix of a defined language
我尝试为 Haskell 语言编写解析器,但需要注意的是,所解析的程序可以是任何有效 Haskell 源代码的任何前缀。
例如,在我的例子中这是有效的来源:
func x = (x +
此处有 Haskell 的类似 BNF 的规范:https://www.haskell.org/onlinereport/syntax-iso.html#sect9.5 .
有没有一种将BNF文法转换为接受这种前缀语言的bison文法的示意图?
本练习的上下文是 Emacs 编辑器,源代码是正在编写的程序,目的是在程序员编写源代码时提供缩进提示。
获取 CFG 并将其转换为匹配所有前缀的语言的 CFG 相当简单:
对于每个非终端,添加一个额外的 -prefix 版本的非终端
对于 X := A B C
形式的每个规则,添加 X_prefix := A B C_prefix | A B | A B_prefix | A | A_prefix
形式的规则
删除所有引用terminal_prefix
的规则,然后对Y_prefix
递归,其中Y_prefix
已经没有规则了。
当然,这个新的 CFG 可能不是 LALR(1),因此不能轻易地被 bison 直接使用——您可能需要重构它以使其成为 LALR(1),或者使用 GLR 解析器适当的合并规则。
我尝试为 Haskell 语言编写解析器,但需要注意的是,所解析的程序可以是任何有效 Haskell 源代码的任何前缀。
例如,在我的例子中这是有效的来源:
func x = (x +
此处有 Haskell 的类似 BNF 的规范:https://www.haskell.org/onlinereport/syntax-iso.html#sect9.5 .
有没有一种将BNF文法转换为接受这种前缀语言的bison文法的示意图?
本练习的上下文是 Emacs 编辑器,源代码是正在编写的程序,目的是在程序员编写源代码时提供缩进提示。
获取 CFG 并将其转换为匹配所有前缀的语言的 CFG 相当简单:
对于每个非终端,添加一个额外的 -prefix 版本的非终端
对于
X := A B C
形式的每个规则,添加X_prefix := A B C_prefix | A B | A B_prefix | A | A_prefix
形式的规则
删除所有引用
terminal_prefix
的规则,然后对Y_prefix
递归,其中Y_prefix
已经没有规则了。
当然,这个新的 CFG 可能不是 LALR(1),因此不能轻易地被 bison 直接使用——您可能需要重构它以使其成为 LALR(1),或者使用 GLR 解析器适当的合并规则。