【问题标题】:Happy resolution of an error愉快地解决错误
【发布时间】:2014-03-16 21:54:46
【问题描述】:

在正则表达式中,我可以这样写:

a(.)*b

这将匹配整个字符串,例如

acdabb

我尝试在 Happy 中使用令牌流来模拟这一点。

t : a wildcard b
wildcard : {- empty -} | wild wildcard
wild : a | b | c | d | whatever

但是Happy生成的解析器不识别

acdabb

有没有办法解决这个问题/我做错了吗?

【问题讨论】:

  • 可以通过将上述转换为左递归形式(通配符:|通配符通配符)来消除移位/减少错误。我认为左递归或右递归对于 LALR 解析器并不重要。但是,如果我遗漏了什么,我仍然很好奇。
  • 原因是 Happy 使用的前瞻次数的限制。正确的递归版本是 LALR(1)。
  • 我的意思是左递归版本是 LALR(1),右递归版本不是;对此感到抱歉。

标签: parsing haskell lex happy


【解决方案1】:

正如您所说,Happy 使用 LALR(1) 解析器,即noted in the documentation。您在 cmets 中指出,更改为右递归可以解决问题,但对于新手来说,可能不清楚如何实现。要更改递归,wilcard wild 被重写为wild wildcard,这会产生以下文件:

{
module ABCParser (parse) where
}

%tokentype { Char }

%token a { 'a' }
%token b { 'b' }
%token c { 'c' }
%token d { 'd' }
%token whatever { '\n' }

%name parse t

%%

t 
 : a wildcard b
  { }

wildcard 
  : 
   { }  
  | wildcard wild
     { }

wild 
   : a 
    { }
   | b 
     { }
   | c 
     { }
   | d
     { }
   | whatever
     { }

现在生成一个工作解析器。

【讨论】:

    猜你喜欢
    • 2021-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多