def parse
state1 = :HEAD
state2 = nil
state3 = nil
lastmodes = []
while st = next_line
case state1
when :FOOT
add_footer st
when :HEAD
ss = StringScanner.new(st)
if ss.scan(/class/)
state1 = :CLASS
st = ss.post_match.strip
if st =~ /^(\S+)::(\S+)/
@module_name = $1
@class_name = $2
else
@module_name = nil
@class_name = st
end
else
add_header st
end
when :CLASS
s = st.strip
next if s.size == 0 or s[0,1] == '#'
ss = StringScanner.new(st)
if ss.scan(/option.*$/)
state2 = :OPTION
next
end
if ss.scan(/inner.*$/)
state2 = :INNER
next
end
if ss.scan(/macro.*$/)
state2 = :MACRO
next
end
if ss.scan(/rule.*$/)
state2 = :RULE
next
end
if ss.scan(/end.*$/)
state1 = :FOOT
next
end
case state2
when :OPTION
add_option st
when :INNER
add_inner st
when :MACRO
add_macro st
when :RULE
case state3
when nil
rule_state, rule_expr, rule_action = parse_rule(st)
if rule_action =~ /\s*\{/
lastmodes = parse_action(rule_action, lastmodes)
if lastmodes.empty?
add_rule rule_state, rule_expr, rule_action
else
state3 = :CONT
rule_action += "\n"
end
else
add_rule rule_state, rule_expr
end
when :CONT
rule_action += "#{st}\n"
lastmodes = parse_action(st, lastmodes)
if lastmodes.empty?
state3 = nil
add_rule rule_state, rule_expr, rule_action
else
end
end
end
end
end
end