最近,我一直在为一些纯 Javascript 的项目使用解析器组合器。我将代码提取到一个单独的项目中;你可以在这里找到它。这种方法类似于@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) 大括号类型不匹配——即(...]
or {...)
; 3) 没有匹配的开括号的闭括号。