我正在尝试解析以下格式:(identifier/)?identifier(/keyword)?
,带有第一个标识符以及可选的关键字。关键字不能用作标识符。例如,如果up
是关键字,则:
simple
匹配第二个标识符,first/second
匹配first
作为第一个标识符,second
作为第二个标识符,second/up
second
作为第二个标识符和up
关键字匹配。
将Ragel与 Ruby 结合使用,我定义了以下 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 解决这个问题(即,这可以在没有前瞻的情况下解决)?