最近,我一直在使用解析器组合在纯JavaScript的一些项目。我将代码抽取到一个单独的项目中; you can find it here。这种方法类似于@DigitalRoss建议的递归下降解析器,但是在解析器特有的代码和一般解析器记账代码之间有更明确的分割。
一个适合您需求的解析器(如果我理解正确的您的要求)将是这个样子:
var open = literal("{"), // matches only '{'
close = literal("}"), // matches only '}'
normalChar = not1(alt(open, close)); // matches any char but '{' and '}'
var form = new Parser(function() {}); // forward declaration for mutual recursion
var block = node('block',
['open', open ],
['body', many0(form)],
['close', close ]);
form.parse = alt(normalChar, block).parse; // set 'form' to its actual value
var parser = many0(form);
,你会使用这样的:
// assuming 'parser' is the parser
var parseResult = parser.parse("abc{def{ghi{}oop}javascript}is great");
的解析结果是一个语法树。
除了回溯,该库还可以帮助您在解析器调用之间生成漂亮的错误消息和线程用户状态。后两个我发现对于生成大括号错误消息非常有用,在出现以下情况时,报告问题以及出错的大括号标记的位置:1)有一个开放的大括号,但没有关闭; 2)存在不匹配的支具类型 - 即(...]
或{...)
; 3)没有匹配打开的近端大括号。
是的,我去了递归下降。这可能需要一些解释来阐明这个概念,但在此之后,代码是非常可读的,流程是不言而喻的。 – slezica 2013-02-21 13:16:47