module Animal grammar Rules rule parenthesized_conditionals parenthesized_conditional required_space boolean_join required_space parenthesized_conditionals { def conditions all_nodes = {} all_nodes[:conditions] = [] all_nodes[:conjunction] = boolean_join.conjunction all_nodes[:conditions] << parenthesized_conditional.conditions all_nodes[:conditions] << parenthesized_conditionals.conditions all_nodes end } / '(' parenthesized_conditionals ')' { def conditions parenthesized_conditionals.conditions end } / parenthesized_conditional end rule parenthesized_conditional '(' parenthesized_conditional ')' { def conditions parenthesized_conditional.conditions end } / conditional_items end rule conditional_items conditional_item required_space boolean_join required_space conditional_items { def conditions all_nodes = {} all_nodes[:conditions] = [] all_nodes[:conjunction] = boolean_join.conjunction all_nodes[:conditions] << conditional_item.conditions all_nodes[:conditions] << conditional_items.conditions all_nodes end } / conditional_item end rule boolean_join ( and_keyword / or_keyword ) { def conjunction text_value.downcase.to_sym end } end rule conditional_item plugin_class quoted_text close_bracket space conditional_operator space compared_value { def conditions { :operator => conditional_operator.value, :plugin => plugin_class.name, :key => quoted_text.content, :value => compared_value.content } end } end rule plugin_class ([A-Z] [a-zA-Z0-9]+) open_bracket { def name elements[0].text_value end } end rule compared_value (number / boolean / quoted_text) end rule open_bracket '[' end rule close_bracket ']' end rule required_space [\s]+ end rule space [\s]* end rule quoted_text '"' text '"' { def content elements[1].content end } end rule conditional_operator ('!=' / '>=' / '<=' / '=' / '>' / '<' / like_keyword) { def value text_value.downcase.to_sym end } end rule like_keyword [lL] [iI] [kK] [eE] end rule and_keyword [aA] [nN] [dD] end rule or_keyword [oO] [rR] end rule number ('-'? [1-9] [0-9]* / '0') { def content text_value.to_i end } end rule boolean ('true' / 'false') { def content text_value == 'true' end } end rule text [^"]* { def content text_value end } end end end