blob: bd5a1ba1a5a3c8f4ca1dae74d0b5cea4f5dc7d47 [file] [log] [blame]
#
# -*- coding: utf-8 -*-
#
# This file is part of reclass
#
import pyparsing as pp
STR = 1
REF = 2
INV = 3
def _string(string, location, tokens):
token = tokens[0]
tokens[0] = (STR, token)
def _reference(string, location, tokens):
token = list(tokens[0])
tokens[0] = (REF, token)
def _invquery(string, location, tokens):
token = list(tokens[0])
tokens[0] = (INV, token)
def get_ref_parser(escape_character, reference_sentinels, export_sentinels):
_ESCAPE = escape_character
_DOUBLE_ESCAPE = _ESCAPE + _ESCAPE
_REF_OPEN = reference_sentinels[0]
_REF_CLOSE = reference_sentinels[1]
_REF_CLOSE_FIRST = _REF_CLOSE[0]
_REF_ESCAPE_OPEN = _ESCAPE + _REF_OPEN
_REF_ESCAPE_CLOSE = _ESCAPE + _REF_CLOSE
_REF_DOUBLE_ESCAPE_OPEN = _DOUBLE_ESCAPE + _REF_OPEN
_REF_DOUBLE_ESCAPE_CLOSE = _DOUBLE_ESCAPE + _REF_CLOSE
_REF_EXCLUDES = _ESCAPE + _REF_OPEN + _REF_CLOSE
_INV_OPEN = export_sentinels[0]
_INV_CLOSE = export_sentinels[1]
_INV_CLOSE_FIRST = _INV_CLOSE[0]
_INV_ESCAPE_OPEN = _ESCAPE + _INV_OPEN
_INV_ESCAPE_CLOSE = _ESCAPE + _INV_CLOSE
_INV_DOUBLE_ESCAPE_OPEN = _DOUBLE_ESCAPE + _INV_OPEN
_INV_DOUBLE_ESCAPE_CLOSE = _DOUBLE_ESCAPE + _INV_CLOSE
_INV_EXCLUDES = _ESCAPE + _INV_OPEN + _INV_CLOSE
_EXCLUDES = _ESCAPE + _REF_OPEN + _REF_CLOSE + _INV_OPEN + _INV_CLOSE
double_escape = pp.Combine(pp.Literal(_DOUBLE_ESCAPE) + pp.MatchFirst([pp.FollowedBy(_REF_OPEN), pp.FollowedBy(_REF_CLOSE),
pp.FollowedBy(_INV_OPEN), pp.FollowedBy(_INV_CLOSE)])).setParseAction(pp.replaceWith(_ESCAPE))
ref_open = pp.Literal(_REF_OPEN).suppress()
ref_close = pp.Literal(_REF_CLOSE).suppress()
ref_not_open = ~pp.Literal(_REF_OPEN) + ~pp.Literal(_REF_ESCAPE_OPEN) + ~pp.Literal(_REF_DOUBLE_ESCAPE_OPEN)
ref_not_close = ~pp.Literal(_REF_CLOSE) + ~pp.Literal(_REF_ESCAPE_CLOSE) + ~pp.Literal(_REF_DOUBLE_ESCAPE_CLOSE)
ref_escape_open = pp.Literal(_REF_ESCAPE_OPEN).setParseAction(pp.replaceWith(_REF_OPEN))
ref_escape_close = pp.Literal(_REF_ESCAPE_CLOSE).setParseAction(pp.replaceWith(_REF_CLOSE))
ref_text = pp.CharsNotIn(_REF_EXCLUDES) | pp.CharsNotIn(_REF_CLOSE_FIRST, exact=1)
ref_content = pp.Combine(pp.OneOrMore(ref_not_open + ref_not_close + ref_text))
ref_string = pp.MatchFirst([double_escape, ref_escape_open, ref_escape_close, ref_content]).setParseAction(_string)
ref_item = pp.Forward()
ref_items = pp.OneOrMore(ref_item)
reference = (ref_open + pp.Group(ref_items) + ref_close).setParseAction(_reference)
ref_item << (reference | ref_string)
inv_open = pp.Literal(_INV_OPEN).suppress()
inv_close = pp.Literal(_INV_CLOSE).suppress()
inv_not_open = ~pp.Literal(_INV_OPEN) + ~pp.Literal(_INV_ESCAPE_OPEN) + ~pp.Literal(_INV_DOUBLE_ESCAPE_OPEN)
inv_not_close = ~pp.Literal(_INV_CLOSE) + ~pp.Literal(_INV_ESCAPE_CLOSE) + ~pp.Literal(_INV_DOUBLE_ESCAPE_CLOSE)
inv_escape_open = pp.Literal(_INV_ESCAPE_OPEN).setParseAction(pp.replaceWith(_INV_OPEN))
inv_escape_close = pp.Literal(_INV_ESCAPE_CLOSE).setParseAction(pp.replaceWith(_INV_CLOSE))
inv_text = pp.CharsNotIn(_INV_CLOSE_FIRST)
inv_content = pp.Combine(pp.OneOrMore(inv_not_close + inv_text))
inv_string = pp.MatchFirst([double_escape, inv_escape_open, inv_escape_close, inv_content]).setParseAction(_string)
inv_items = pp.OneOrMore(inv_string)
export = (inv_open + pp.Group(inv_items) + inv_close).setParseAction(_invquery)
text = pp.CharsNotIn(_EXCLUDES) | pp.CharsNotIn('', exact=1)
content = pp.Combine(pp.OneOrMore(ref_not_open + inv_not_open + text))
string = pp.MatchFirst([double_escape, ref_escape_open, inv_escape_open, content]).setParseAction(_string)
item = reference | export | string
line = pp.OneOrMore(item) + pp.StringEnd()
return line
def get_simple_ref_parser(escape_character, reference_sentinels, export_sentinels):
_ESCAPE = escape_character
_REF_OPEN = reference_sentinels[0]
_REF_CLOSE = reference_sentinels[1]
_INV_OPEN = export_sentinels[0]
_INV_CLOSE = export_sentinels[1]
_EXCLUDES = _ESCAPE + _REF_OPEN + _REF_CLOSE + _INV_OPEN + _INV_CLOSE
string = pp.CharsNotIn(_EXCLUDES).setParseAction(_string)
ref_open = pp.Literal(_REF_OPEN).suppress()
ref_close = pp.Literal(_REF_CLOSE).suppress()
reference = (ref_open + pp.Group(string) + ref_close).setParseAction(_reference)
line = pp.StringStart() + pp.Optional(string) + reference + pp.Optional(string) + pp.StringEnd()
return line