src/rdsl/lexer.rl
# lib/manamana/rdsl/lexer.rb is autogenerated by
# ragel from src/rdsl/lexer.rl. Please edit the
# .rl file and not the .rb file.
%%{
machine lexer;
newline = ('\n' | '\r\n');
tab_or_space = [\t ];
string = [A-Za-z0-9\(\)\[\]\{\}`<\\] print*;
req_string = [A-Za-z0-9<] print*;
underline = '===' '='*;
pipe = '|';
group_name = string tab_or_space* newline tab_or_space* underline;
text = string tab_or_space* (newline tab_or_space* string)* (newline newline)*;
requirement = '* ' req_string tab_or_space* (newline tab_or_space* (string|underline))* (newline newline)*;
table_row = pipe print* pipe;
main := |*
group_name => { emit_group_name(token_array, data, ts, te) };
requirement => { emit_requirement(token_array, data, ts, te) };
table_row => { emit_row(data, token_array, ts, te) };
text => { emit_text(token_array, data, ts, te) };
space;
*|;
}%%
module ManaMana
module RDSL
class Lexer
def initialize
%% write data;
# %% this just fixes syntax highlighting in TextMate et al.
end
def emit_group_name(token_array, data, ts, te)
value = data[ts...te].pack("c*").split(/=+/)[0].strip
token_array << [:GROUP, { value: value, offset: ts }]
end
def emit_row(data, target_array, ts, te)
cells = data[(ts + 1)...( te - 1)].pack("c*")
# ignore borders
return if /^\-+/ =~ cells
target_array << [:ROW, { offset: ts }]
cells.split('|').each do |cell|
target_array << [:CELL, { value: cell.strip }]
end
end
def emit_requirement(token_array, data, ts, te)
# Split the string by code block delimiters. Even elements will be
# non code blocks. Odd elements will be code blocks
str_arr = data[ts...te].pack("c*").gsub(/^\* /, '').split('```')
value = ''
reserved_chars = /(\[|\])/
# Iterate through blocks and non code blocks, copying code blocks verbatim
# and stripping non-codeblocks
str_arr.each_with_index do |str, i|
value << (i.odd? ? " ```#{str.rstrip.gsub(reserved_chars){|m| '\\' + m }}``` " : str.split.join(' '))
end
value.strip!
token_array << [:REQUIREMENT, { value: value, offset: ts }]
end
def emit_text(token_array, data, ts, te)
value = data[ts...te].pack("c*").strip.split.join(' ')
token_array << [:TEXT, { value: value, offset: ts }]
end
def tokenize(data)
data = data.unpack("c*") if(data.is_a?(String))
eof = data.length
token_array = []
%% write init;
%% write exec;
token_array
end
end
end
end