解析器不会停止解析任意换行符和空格

时间:2014-04-05 03:10:48

标签: parsing lisp peg pegjs

所以,我试图在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"到

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)))"

虽然在每个" Token"之后只允许一个换行符是微不足道的。或者" Tuple",我希望接受以下法律代码:

(f x

   (g     y (

       h z t) ) )

1 个答案:

答案 0 :(得分:0)

原来这个问题与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)))"

这正是我想要的