这里有几件事。
最重要的是,您必须意识到 PEG是贪婪的。这意味着您的(DOT id)*
规则匹配所有 DOT id 序列,包括您在startRule
as中的一个DOT b:id
。
这可以使用前瞻来解决。
另一件事是你必须记住使用join
,因为默认情况下它会将每个字符作为数组的成员返回。
我还添加了分号规则。
尝试这个:
start =
namespace:namespace DOT name:string OPEN_BRACE CLOSE_BRACE SM nl?
{
return { namespace : namespace, name : name };
}
/* Here I'm using the lookahead: (member !OPEN_BRACE)* */
namespace =
first:string rest:(member !OPEN_BRACE)*
{
rest = rest.map(function (x) { return x[0]; });
rest.unshift(first);
return rest;
}
member =
DOT str:string
{ return str; }
DOT =
'.'
OPEN_BRACE =
'('
CLOSE_BRACE =
')'
SM =
';'
nl =
"\n"
string =
str:[a-zA-Z]+
{ return str.join(''); }
据我所知,我正确地解析了那条线。