lex start { ignore /[\t\n ]+/ literal '^', '|', '-', ',', ':', '!', '?', '.' literal '(', ')', '{', '}', '*', '&', '+' literal '--', ':>', ':>>', '<:', '->', '**' token word /[a-zA-Z_][a-zA-Z0-9_]*/ token uint /[0-9]+/ } def start [expression] def expression [term expression_op*] def expression_op ['|' term] | ['&' term] | ['-' term] | ['--' term] def term [factor_rep term_rest] # This list is done manually to get shortest match. def term_rest [] | [term_op term_rest] def term_op [factor_rep] | ['.' factor_rep] | [':>' factor_rep] | [':>>' factor_rep] | ['<:' factor_rep] def factor_rep [factor_neg factor_rep_op*] def factor_rep_op ['*'] | ['**'] | ['?'] | ['+'] | ['{' factor_rep_num '}'] | ['{' ',' factor_rep_num '}'] | ['{' factor_rep_num ',' '}'] | ['{' factor_rep_num ',' factor_rep_num '}'] def factor_rep_num [uint] def factor_neg ['!' factor_neg] | ['^' factor_neg] | [factor] def factor [alphabet_num] | [word] | ['(' expression ')'] def alphabet_num [uint] start S = parse start(stdin) # # Fixed point iteration # bool this_iter_modified() { return true } iter fixed_point( ref any T ) { bool modified = true while modified { modified = false for S:any in T { yield S if this_iter_modified() { modified = true break } } } } for T: any in fixed_point( S ) { print( T '\n' ) } print( S '\n' )