Module: Tagformula::Parser

Defined in:
lib/tagformula/parser.rb

Defined Under Namespace

Classes: Group, Tag

Class Method Summary collapse

Class Method Details

.parse(str) ⇒ Object

Raises:

  • (SyntaxError)


81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/tagformula/parser.rb', line 81

def parse(str)
	groups = [Group.new]
	scanner = StringScanner.new(str)
	until scanner.eos?
	last = groups.last.last_entry

	if scanner.scan(/\(/)
		raise SyntaxError, "Unexpected tag at #{scanner.pos} - #{scanner.peek(scanner.rest_size)}" unless last.nil? or last.is_a?(Symbol)
		push_group(groups)
	elsif scanner.scan(/\)/)
		raise SyntaxError, "Unexpected group end at #{scanner.pos} - #{scanner.peek(scanner.rest_size)}" if last.nil? or last.is_a?(Symbol)
		grp = pop_group(groups)
		raise SyntaxError, "Empty group at offset #{scanner.pos} - #{scanner.peek(scanner.rest_size)}" if grp.empty?
		raise SyntaxError, "Unmatched braces at offset #{scanner.pos} - #{scanner.peek(scanner.rest_size)}" if groups.empty?
	elsif scanner.scan(/([-0-9a-zA-Z.]+)/)
		raise SyntaxError, "Unexpected tag at #{scanner.pos} - #{scanner.peek(scanner.rest_size)}" unless last.nil? or last.is_a?(Symbol)
		push_tag(groups, scanner[1])
	elsif scanner.scan(/[!~]\s*([-0-9a-zA-Z.]+)/)
		raise SyntaxError, "Unexpected tag at #{scanner.pos} - #{scanner.peek(scanner.rest_size)}" unless last.nil? or last.is_a?(Symbol)
		push_not_tag(groups, scanner[1])
	elsif scanner.scan(/[,|]/)
		raise SyntaxError, "Unexpected operator at #{scanner.pos} - #{scanner.peek(scanner.rest_size)}" if last.is_a?(Symbol)
		push_or(groups)
	elsif scanner.scan(/[&+]/)
		raise SyntaxError, "Unexpected operator at #{scanner.pos} - #{scanner.peek(scanner.rest_size)}" if last.is_a?(Symbol)
		push_and(groups)
   elsif scanner.scan(/\s+/)
	else
		raise SyntaxError, "Error at offset #{scanner.pos} - #{scanner.peek(scanner.rest_size)}"
	end
	end
	raise SyntaxError, "Unmatched braces at offset #{scanner.pos} - #{scanner.peek(scanner.rest_size)}" if groups.size != 1
	groups[0]
end