【问题标题】:Parser doesn't stop parsing arbitrary newlines and whitespaces解析器不会停止解析任意换行符和空格
【发布时间】:2014-05-17 13:15:13
【问题描述】:

所以,我正在尝试在 pegjs 中编写一个非常基本的 Lisp 解析器,只要 Lisp 代码在语法上有效并且适合一行,我就让它吐出相同的代码。

我希望扩展解析器,使其能够接受插入到任何地方的任何换行符以及代码中的额外空格。

下面是工作的代码,只要所有内容都在一行上:

Start
  = List

Character
  = [^\n" ""("")"]

LeftParenthesis
  = "("

RightParenthesis
  = ")"

WhiteSpace
  = " "

NewLine
  = "\n"

Token
  = token:Character+{return token.join("");}

Tuple
  = left:Token WhiteSpace+ right:List?{
        return left.concat([" "]).concat(right);
    }
  / Token

List
  = left:LeftParenthesis tuple:Tuple right:RightParenthesis{
        return left.concat(tuple).concat(right);
    }
  / Tuple

然后,为了允许换行符和空格,我尝试将“元组”的规则更改为

Tuple
  = left:Token WhiteSpace+ (NewLine* WhiteSpace*)* right:List?{
        return left.concat([" "]).concat(right);
    }
  / Token

但是这种变化会导致 pegjs 进入一个无限循环,虽然添加到规则中看起来是非递归的。

注意:如果不清楚我要做什么,我正在编写一个语法,以便 pegjs 吐出一个解析器来解析

(f x 
  (g y 
    (h z t)))

并吐出与字符串相同的代码或只是

"(f x (g y (h z t)))" 

两者都适合我。

我目前的工作语法是采取

(f x (g y (h z t)))

和输出

"(f x (g y (h z t)))"

虽然在每个“令牌”或“元组”之后只允许一个换行符是微不足道的,但我希望接受以下作为合法代码:

(f x

   (g     y (

       h z t) ) )

【问题讨论】:

    标签: parsing lisp peg pegjs


    【解决方案1】:

    原来这个问题和Ignore whitespace with PEG.js非常相似

    这完全是为了忽略空格和换行符。我其实不知道为什么上面的代码会失败,但是在玩了一圈之后,我设法让 pegjs 做我想做的事

    Start
      = List
    
    Character
      = [^ \t\r\n"("")"]
    
    LeftParenthesis
      = "("
    
    RightParenthesis
      = ")"
    
    Separator
      = [ \t\r\n]
    
    Token
      = List
      / token:Character+{return token.join("");}
    
    Tuple
      = first:Token second:Separator+ rest:Tuple*{
            return rest.length > 0 ? first.concat([" "]).concat(rest) : first;
        }
      / Token
    
    List
      = left:LeftParenthesis Separator* token:Tuple Separator* right:RightParenthesis{
            return [left].concat(token).concat([right]).join("");
         }
    

    所以,当你给下面的字符串解析时:

    (f x
    
       (g     y (
    
           h z t) ) )
    

    解析器输出

    "(f x (g y (h z t)))"
    

    这正是我想要的

    【讨论】:

      猜你喜欢
      • 2014-07-06
      • 2012-11-21
      • 1970-01-01
      • 2015-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多