次の形式を解析しようとしています: (identifier/)?identifier(/keyword)?
、最初の識別子とオプションのキーワードを使用します。キーワードを識別子として使用することはできません。たとえば、up
がキーワードの場合:
simple
2 番目の識別子に一致し、first/second
first
最初の識別子として一致しsecond
、2 番目の識別子として、second/up
second
2 番目の識別子およびup
キーワードとして一致します。
Ruby でRagelを使用して、次の FSM を定義しました。
%%{
machine simple;
keyword = "up";
separator = '/';
ident_char = any - separator;
identifier = ident_char+ - keyword;
action start_string { $start_string = p }
action first_string { puts "First: #{get_string(data, p)}" }
action second_string { puts "Second: #{get_string(data, p)}" }
action keyword_string { puts "Keyword: #{get_string(data, p)}" }
main := ( identifier >start_string %first_string separator )?
:> identifier >start_string %second_string
( separator keyword >start_string %keyword_string )?
;
}%%
%% write data;
def get_string(data, p)
data[$start_string...p].pack("c*")
end
def parse(data)
data = data.unpack("c*")
eof = pe = data.length
%% write init;
%% write exec;
end
parse("first/second")
puts("---")
parse("second/up")
これにより、次の出力が得られます。
$ ragel -R simple.rl ; ruby simple.rb
Second: first
---
Second: second
Keyword: up
最初の部分は である必要があるため、これは正しくありませんが、私が与えた優先順位First: first
Second: second
により予想されます。:>
さまざまな優先順位の組み合わせを試しましたが、期待した結果を得ることができませんでした。この問題を Ragel で解決する方法はありますか (つまり、先読みなしで解決できますか)?