Skip to content

Instantly share code, notes, and snippets.

@vird
Last active August 29, 2015 14:01
Show Gist options
  • Save vird/e74ff0b256be1116be81 to your computer and use it in GitHub Desktop.
Save vird/e74ff0b256be1116be81 to your computer and use it in GitHub Desktop.
name = rgx(/[a-z]+/i).then (s)-> s.toLowerCase()
char = rgx /[^"&]/i
quoted = seq(txt('"'), rep(char), txt('"')).then (r)-> r[1].join ''
attr = seq(name, txt('='), quoted).then (r)-> name: r[0], value: r[2]
wsp = rgx /\s+/
attrs = rep(attr, wsp).then (r)->
m = {}
r.forEach(a -> (m[a.name] = a.value))
m
header = seq(txt('<?xml'), wsp, attrs, txt('?>')).then (r)-> r[2]
text = rep(char).then (r)-> r.join ''
subnode = new Pattern (str, pos) -> node.exec(str, pos)
node = seq(
txt('<'), name, wsp, attrs, txt('>'),
rep(any(text, subnode), opt(wsp)),
txt('</'), name, txt('>'))
.then (r)-> name: r[1], attrs: r[3], nodes: r[5]
xml = seq(header, node).then (r)-> root: r[1], attrs: r[0]
h.name = prs /[a-z]+/i, (s) -> s.toLowerCase()
h.char = prs /[^"&]/i
h.quoted= prs '\'"\' rep.char \'"\'', (r) -> r[1].join ''
h.attr = prs 'seq(name "=" quoted)', (r) -> name: r[0], value: r[2]
h.wsp = prs /\s+/
h.attrs = prs "rep(attr wsp)", (r) ->
m = {}
m[a.name] = a.value for a in r
m
h.header= prs 'seq("<?xml" wsp attrs "?>")', (r) -> r[2]
h.text = prs "rep.char", (r) -> r.join ''
h.node = prs """
seq
"<" name wsp attrs ">"
rep.any(text _self) wsp?
"</" name ">"
""", (r) -> { name: r[1], attrs: r[3], nodes: r[5] }
h.xml = prs "seq(header node)", (r) => { root: r[1], attrs: r[0] }
parser = prs() # если вызывать без аргументов, то работает по-другому
h = parser.hash
h.name = prs /[a-z]+/i, (s) -> s.toLowerCase() # второй аргумент prs это то, что было в then
h.char = prs /[^"&]/i # кавычки не нужны, можно просто писать reg exp если он один
h.quoted= prs '\'"\' rep.char \'"\'', (r) -> r[1].join ''
h.attr = prs 'seq(name "=" quoted)', (r) -> name: r[0], value: r[2] # {} не нужны
# внутри () запятые не нужны, как и внутри prs
# txt не нужен, просто пишем 'text' или "text"
h.wsp = prs /\s+/
h.attrs = prs "rep(attr wsp)", (r) ->
m = {}
m[a.name] = a.value for a in r # Прим. работает быстрее чем foreach+callback
m
h.header= prs 'seq("<?xml" wsp attrs "?>")', (r) -> r[2]
h.text = prs "rep.char", (r) -> r.join ''
# subnode не нужен
h.node = prs """
seq
"<" name wsp attrs ">"
rep.any(text _self) wsp?
"</" name ">"
""", (r) -> { name: r[1], attrs: r[3], nodes: r[5] }
# вместо () можно использовать indent
# вместо opt постфиксный ? как в regexp
# rep.any короче, чем rep(any)
# _self ссылается на результат, который получит prs
h.xml = prs "seq(header node)", (r) => { root: r[1], attrs: r[0] }
ready_to_use = parser.init 'xml'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment