faye-1.1.2/lib/faye/protocol/grammar.rb
module Faye
module Grammar
def self.rule(&block)
source = instance_eval(&block)
%r{^#{string(source)}$}
end
def self.choice(*list)
'(' + list.map(&method(:string)) * '|' + ')'
end
def self.repeat(*pattern)
'(' + string(pattern) + ')*'
end
def self.oneormore(*pattern)
'(' + string(pattern) + ')+'
end
def self.string(item)
return item.map(&method(:string)) * '' if Array === item
String === item ? item : item.source.gsub(/^\^/, '').gsub(/\$$/, '')
end
LOWALPHA = rule {[ '[a-z]' ]}
UPALPHA = rule {[ '[A-Z]' ]}
ALPHA = rule {[ choice(LOWALPHA, UPALPHA) ]}
DIGIT = rule {[ '[0-9]' ]}
ALPHANUM = rule {[ choice(ALPHA, DIGIT) ]}
MARK = rule {[ choice(*%w[\\- \\_ \\! \\~ \\( \\) \\$ \\@]) ]}
STRING = rule {[ repeat(choice(ALPHANUM, MARK, ' ', '\\/', '\\*', '\\.')) ]}
TOKEN = rule {[ oneormore(choice(ALPHANUM, MARK)) ]}
INTEGER = rule {[ oneormore(DIGIT) ]}
CHANNEL_SEGMENT = rule {[ TOKEN ]}
CHANNEL_SEGMENTS = rule {[ CHANNEL_SEGMENT, repeat('\\/', CHANNEL_SEGMENT) ]}
CHANNEL_NAME = rule {[ '\\/', CHANNEL_SEGMENTS ]}
WILD_CARD = rule {[ '\\*{1,2}' ]}
CHANNEL_PATTERN = rule {[ repeat('\\/', CHANNEL_SEGMENT), '\\/', WILD_CARD ]}
VERSION_ELEMENT = rule {[ ALPHANUM, repeat(choice(ALPHANUM, '\\-', '\\_')) ]}
VERSION = rule {[ INTEGER, repeat('\\.', VERSION_ELEMENT) ]}
CLIENT_ID = rule {[ oneormore(ALPHANUM) ]}
ID = rule {[ oneormore(ALPHANUM) ]}
ERROR_MESSAGE = rule {[ STRING ]}
ERROR_ARGS = rule {[ STRING, repeat(',', STRING) ]}
ERROR_CODE = rule {[ DIGIT, DIGIT, DIGIT ]}
ERROR = rule {[ choice(string([ERROR_CODE, ':', ERROR_ARGS, ':', ERROR_MESSAGE]),
string([ERROR_CODE, ':', ':', ERROR_MESSAGE])) ]}
end
end