local program = [[ = [What is] February = [February is] a syntax front end for nova , designed around streaming tokens . = = = ~ [Many Rules] Many Delimiter ~ [February can] let you switch between them on the fly . ~ ~ ~ *** [A note] *** SAYS you don't need those [backets] . BUT they might help with clarity *** *** [What is] February *** *** *** ]] local stream = program:gmatch(".") local char, rule, rule_symbol, label_symbol, depth, symbol, side local tuple, rules, LEFT, RIGHT = {}, {}, 1, 2 repeat rule_symbol, char = "", stream() side, rule = LEFT, {{}, {}} while char and char:match("[%s%.,]") do char = stream() end if char == nil then break elseif char == "[" then depth, char = 1, stream() while char do if char == "[" then depth = depth + 1 end if char == "]" then depth = depth - 1 end if depth == 0 then break end rule_symbol, char = rule_symbol .. char, stream() end else rule_symbol = "" while char and not char:match("%s") do rule_symbol, char = rule_symbol .. char, stream() if char == "[" then io.stderr:write "Warning: symbol contains `[`. A space may be missing?" end end end repeat char = stream() while char and (char:match("[%s]") or not label_symbol and char:match("[%.,]")) do char = stream() end if not char then if label_symbol then table.insert(rule[side], {label_symbol, tuple}) end break end if char:match("[%.,]") then symbol = char elseif char == "[" then symbol, depth, char = "", 1, stream() while char do if char == "[" then depth = depth + 1 end if char == "]" then depth = depth - 1 end if depth == 0 then break end symbol, char = symbol .. char, stream() end else symbol = "" while char and not char:match("%s") do symbol, char = symbol .. char, stream() if char == "[" then io.stderr:write "Warning: symbol contains `[`. A space may be missing?" end end end if symbol == "," then table.insert(rule[side], {label_symbol, tuple}) tuple = {} elseif symbol == "." then table.insert(rule[side], {label_symbol, tuple}) tuple, label_symbol = {}, nil elseif symbol == rule_symbol and side == RIGHT then if label_symbol then table.insert(rule[side], {label_symbol, tuple}) tuple = {} end if #rule[LEFT] == 0 and #rule[RIGHT] == 0 then break else table.insert(rules, rule) side, rule, label_symbol = LEFT, {{}, {}}, nil end elseif symbol == rule_symbol and side == LEFT then if label_symbol then table.insert(rule[side], {label_symbol, tuple}) end tuple, side, label_symbol = {}, RIGHT, nil elseif not label_symbol then label_symbol = symbol else table.insert(tuple, symbol) end until not char if #rule[LEFT] ~= 0 or #rule[RIGHT] ~= 0 then table.insert(rules, rule) end until not char