Section 2.2 of the Happy user manual建议你使用左递归而不是右递归,因为右递归是“低效的”。基本上他们说如果你试图解析一长串项目,右递归将溢出解析堆栈,而左递归使用常量堆栈。给出的规范示例是
items : item { $1 : [] }
| items "," item { $3 : $1 }
不幸的是,这意味着项目列表会向后出现。
现在很容易在最后应用reverse
(尽管令人讨厌的是你必须在处理的任何地方,而不是在定义< / em>的)。但是,如果项目列表很大,肯定reverse
也会溢出Haskell堆栈吗?否?
基本上,我如何制作它以便我可以解析任意大的文件并仍以正确的顺序得到结果?
答案 0 :(得分:3)
如果你想要的只是每次items
整个reverse
,你可以定义
items : items_ {reverse $1}
items_ : item { $1 : [] }
| items_ "," item { $3 : $1 }
reverse
不会溢出堆栈。如果您需要说服自己,请尝试评估length $ reverse [1..10000000]