# # ActiveFacts CQL Parser. # Various lexical rules for CQL. # # Copyright (c) 2009 Clifford Heath. Read the LICENSE file. # module ActiveFacts module CQL grammar LexicalRules rule range numeric_range / string_range end rule numeric_range number s tail:( '..' s end:number? s )? { def value if !tail.empty? last = tail.end.value unless tail.end.empty? [ number.value, last ] else number.value end end } / '..' s number s { def value [ nil, number.value ] end } end rule string_range string s tail:( '..' s end:string? s )? { # Ranges require the original text of the string, not the content: def value first = string.text_value if !tail.empty? last = tail.end.text_value unless tail.end.empty? [ first, last ] else first end end } / '..' s string s { def value [ nil, string.value ] end } end rule literal ( boolean_literal / string / number ) s { def value elements[0].value end } end rule boolean_literal ( true { def value; true; end } / false { def value; false; end } ) !alphanumeric { def value; elements[0].value end } end rule string "'" (string_char)* "'" { def value text_value eval(text_value.sub(/\A'(.*)'\Z/,'"\1"')) end } end rule number ( real / fractional_real / hexnumber / octalnumber ) !alphanumeric { def value eval(text_value) end } end # All purely lexical rules from here down, no-one looks at the structure, just the text_value: rule string_char ( '\\' [befntr\\'] / '\\' [0-7] [0-7] [0-7] / '\\0' / '\\x' [0-9A-Fa-f] [0-9A-Fa-f] / '\\u' [0-9A-Fa-f] [0-9A-Fa-f] [0-9A-Fa-f] [0-9A-Fa-f] / (![\'\\\0-\x07\x0A-\x1F] .) ) end rule real [-+]? [1-9] [0-9]* fraction? exponent? end rule fractional_real [-+]? '0' fraction exponent? end rule fraction '.' [0-9]+ end rule exponent ( [Ee] '-'? [0-9]+ ) end rule hexnumber '0x' [0-9A-Fa-f]+ end rule octalnumber '0' [0-7]* end rule mul_op '/' / '%' / '*' end rule id alpha alphanumeric* end rule alpha [A-Za-z_] end rule alphanumeric alpha / [0-9] end rule s # Optional space S? end rule S # Mandatory space (white / comment_to_eol / comment_c_style)+ end rule white [ \t\n\r]+ end rule comment_to_eol '//' (!"\n" .)+ end rule comment_c_style '/*' (!'*/' . )* '*/' end end end end