use v6; my $str = q:to/END/; author={Belayneh,M. and Geiger,S. and Matth{\"{a}}i,S.K.},END $str .= chomp; grammar ExtractBraced { rule TOP { 'author=' <braced-item> .* } rule braced-item { '{' <-[}]>* '}' } } ExtractBraced.parse( $str ).say;
输出:
「author={Belayneh,」 braced-item => 「{Belayneh,S. and Matth{\"{a}」
现在,为了使解析器接受嵌套大括号,我想保留当前解析的开括号数量的计数器,当遇到右大括号时,我们减少计数器.如果计数器达到零,我们假设我们已经解析了完整的项目.
为了遵循这个想法,我试图拆分括号项正则表达式,以对每个char实现语法操作. (下面的braced-item-char正则表达式的action方法应该处理大括号计数器):
grammar ExtractBraced { rule TOP { 'author=' <braced-item> .* } rule braced-item { '{' <braced-item-char>* '}' } rule braced-item-char { <-[}]> } }
但是,现在突然解析失败了.可能是一个愚蠢的错误,但我不明白为什么它现在应该失败?
my $str = 「author={Belayneh,」; grammar ExtractBraced { token TOP { 'author=' $<author> = <.braced-item> .* } token braced-item { '{' ~ '}' [ || <- [{}] >+ || <.before '{'> <.braced-item> ]* } } ExtractBraced.parse( $str ).say;
「author={Belayneh,」 author => 「{Belayneh,S.K.}」
如果你想要更多的结构它可能看起来更像这样:
my $str = 「author={Belayneh,」; grammar ExtractBraced { token TOP { 'author=' $<author> = <.braced-item> .* } token braced-part { || <- [{}] >+ || <.before '{'> <braced-item> } token braced-item { '{' ~ '}' <braced-part>* } } class Print { method TOP ($/){ make $<author>.made } method braced-part ($/){ make $<braced-item>.?made // ~$/ } method braced-item ($/){ make [~] @<braced-part>».made } } my $r = ExtractBraced.parse( $str,:actions(Print) ); say $r; put(); say $r.made;
「author={Belayneh,S.K.}」 braced-part => 「Belayneh,S. and Matth」 braced-part => 「{\"{a}}」 braced-item => 「{\"{a}}」 braced-part => 「\"」 braced-part => 「{a}」 braced-item => 「{a}」 braced-part => 「a」 braced-part => 「i,S.K.」 Belayneh,S. and Matth\"ai,S.K.
请注意,on< - [{}]>是一个优化,以及<之前'{'>,两者都可以省略,它仍然可以工作.