簡(jiǎn)單字符串解析
我已經(jīng)以好幾種方式使用 Perl 6 解析用引號(hào)引起的字符串了。 但是我想知道有沒(méi)有更好更干凈的方法。下面有一個(gè)為引起的字符串準(zhǔn)備的小型 grammar 而且還有一些測(cè)試:
grammar String::Simple::Grammar {
our $quote;
rule TOP {^ <string> $}
# Note for now, {} gets around a rakudo binding issue
token string { <quote> {} :temp $quote = $<quote>; <quotebody> $<quote> }
token quote { '"' | "'" }
token quotebody { ( <escaped> | <!before $quote> . )* }
token escaped { '\\' ( $quote | '\\' ) }
}
class String::Simple::Actions {
method TOP($/) { make $<string>.made }
method string($/) { make $<quotebody>.made }
method quotebody($/) { make [~] $0.map: {$^e<escaped>.made or ~$^e} }
method escaped($/) { make ~$0 }
}
use Test;
plan(5);
my $grammar = ::String::Simple::Grammar;
my $actions = String::Simple::Actions.new();
# The semantics of our string are:
# * Backslash before a backslash is backslash
# * Backslash before a quote of the type enclosing the string is that quote
# * All chars including backslash are otherwise literal
ok $grammar.parse(q{"foo"}, :$actions), "Simple string parsing";
is $grammar.parse(q{"foo"}, :$actions).made, "foo", "Content of matched string";
is $grammar.parse(q{"f\oo"}, :$actions).made, "f\\oo", "Content of matched string";
is $grammar.parse(q{"f\"oo"}, :$actions).made, "f\"oo", "Content of matched string";
is $grammar.parse(q{"f\\\\oo"}, :$actions).made, "f\\oo", "Content of matched string";
另外一個(gè)版本:
grammar String::Simple::Grammar {
rule TOP {^ <string> $}
# Note for now, {} gets around a rakudo binding issue
token string { <quote> {} <quotebody($<quote>)> $<quote> }
token quote { '"' | "'" }
token quotebody($quote) { ( <escaped($quote)> | <!before $quote> . )* }
token escaped($quote) { '\\' ( $quote | '\\' ) }
}
class String::Simple::Actions {
method TOP($/) { make $<string>.made }
method string($/) { make $<quotebody>.made }
method quotebody($/) { make [~] $0.map: {.<escaped>.made // .Str} }
method escaped($/) { make ~$0 }
}
不同之處是:
- 參數(shù)化的 rule 用于傳遞開(kāi)始的引號(hào)
- 更簡(jiǎn)單版本的
quotebody
方法使用了一元的點(diǎn)號(hào)和//
用于定義。