class Synvert::Core::NodeQuery::Lexer macros OPEN_ATTRIBUTE /\[/ CLOSE_ATTRIBUTE /\]/ OPEN_ARRAY /\(/ CLOSE_ARRAY /\)/ OPEN_SELECTOR /\(/ CLOSE_SELECTOR /\)/ OPEN_DYNAMIC_ATTRIBUTE /{{/ CLOSE_DYNAMIC_ATTRIBUTE /}}/ NODE_TYPE /\.[a-z]+/ IDENTIFIER /[\.\w]+/ IDENTIFIER_VALUE /[\.\w!&:\?<>=]+/ FALSE /false/ FLOAT /\d+\.\d+/ INTEGER /\d+/ NIL /nil/ REGEXP_BODY /(?:[^\/]|\\\/)*/ REGEXP /\/(#{REGEXP_BODY})(?=]+/ TRUE /true/ SINGLE_QUOTE_STRING /'(.*?)'/ DOUBLE_QUOTE_STRING /"(.*?)"/ rules # [:state] pattern [actions] /\s+/ /:first-child/ { [:tINDEX, 0] } /:last-child/ { [:tINDEX, -1] } /:nth-child\(\d+\)/ { [:tINDEX, text.sub(':nth-child(', '').to_i - 1] } /:nth-last-child\(\d+\)/ { [:tINDEX, -text.sub(':nth-last-child(', '').to_i] } /:has/ { [:tPSEUDO_CLASS, text[1..-1]] } /:not_has/ { [:tPSEUDO_CLASS, text[1..-1]] } /#{NODE_TYPE}/ { [:tNODE_TYPE, text[1..]] } />/ { [:tCHILD, text] } /~/ { [:tSUBSEQUENT_SIBLING, text] } /\+/ { [:tNEXT_SIBLING, text] } /#{OPEN_SELECTOR}/ { [:tOPEN_SELECTOR, text] } /#{CLOSE_SELECTOR}/ { [:tCLOSE_SELECTOR, text] } /#{OPEN_ATTRIBUTE}/ { @nested_count += 1; @state = :KEY; [:tOPEN_ATTRIBUTE, text] } :KEY /\s+/ :KEY /!=/ { @state = :VALUE; [:tNOT_EQUAL, text] } :KEY /=~/ { @state = :VALUE; [:tMATCH, text] } :KEY /!~/ { @state = :VALUE; [:tNOT_MATCH, text] } :KEY />=/ { @state = :VALUE; [:tGREATER_THAN_OR_EQUAL, text] } :KEY /<=/ { @state = :VALUE; [:tLESS_THAN_OR_EQUAL, text] } :KEY />/ { @state = :VALUE; [:tGREATER_THAN, text] } :KEY /