Пример #1
0
def parse_common_block(s: str) -> List[str]:
    """Parse a common block."""
    myword = Word(alphanums + "_")
    inside = OneOrMore(myword + ZeroOrMore("*") + ZeroOrMore(","))
    parenthesis = ZeroOrMore(Char("(") + inside + Char(")"))
    parser = Literal("common") + Char('/') + myword + Char('/') + \
        OneOrMore(Group(myword + parenthesis + ZeroOrMore(Char(","))))

    return parser.parseString(s).asList()
Пример #2
0
    def task_from_md(md_lines, root=None):
        st = StepTask()

        if root is None:
            root = StepTask.Root
        else:
            root = Path(root)

        WRDs = OneOrMore(WRD)
        equality = Char('=') + WRDs

        name_template = 'name' + equality
        repo_template = 'repo' + equality
        statement_template = 'statement' + equality
        checker_template = 'checker' + equality
        solution_template = 'solution' + equality
        tests_template = 'tests' + equality
        score_template = 'score' + Char('=') + Word(nums)

        for line in md_lines:
            # print(line)

            if line == repo_template:
                repo = repo_template.parseString(line)[2]
                st.params['repo'] = root / repo
            elif line == score_template:
                score = score_template.parseString(line)[2]
                st.params['score'] = int(score)

            elif line == statement_template:
                statement = statement_template.parseString(line)[2]
                st.params['statement'] = statement
            elif line == name_template:
                name = name_template.parseString(line)[2]
                st.params['name'] = name
            elif line == checker_template:
                checker = checker_template.parseString(line)[2]
                st.params['checker'] = checker
            elif line == solution_template:
                solution = solution_template.parseString(line)[2]
                st.params['solution'] = solution
            elif line == tests_template:
                tests = tests_template.parseString(line)[2]
                st.params['tests'] = tests

        st.set_attrs()

        return st
Пример #3
0
def parse_define(
        define_line):  # type: (str) -> typing.Any[typing.Type[ParserElement]]

    # Group for parsing literal suffix of a numbers, e.g. 100UL
    literal_symbol = Group(CaselessLiteral('L') | CaselessLiteral('U'))
    literal_suffix = OneOrMore(literal_symbol)

    # Define name
    name = Word(alphas, alphas + nums + '_')

    # Define value, either a hex, int or a string
    hex_value = Combine(
        Literal('0x') + Word(hexnums) +
        Optional(literal_suffix).suppress())('hex_value')
    int_value = Word(nums)('int_value') + ~Char('.') + Optional(
        literal_suffix)('literal_suffix')
    str_value = QuotedString('"')('str_value')

    # Remove optional parenthesis around values
    value = Optional('(').suppress() + (
        hex_value ^ int_value ^ str_value)('value') + Optional(')').suppress()

    expr = '#define' + Optional(name)('name') + Optional(value)
    res = expr.parseString(define_line)

    return res
Пример #4
0
def parse_task_language(line):
    """Разбирает строку вида lang=язык_задач, если язык пустой, возвращает None."""
    lang_template = 'lang' + Char('=') + Word('_' + alphanums)
    lang = None
    if line == lang_template:
        lang_tokens = lang_template.parseString(line)
        logger.info(f'lang_tokens={lang_tokens}')
        lang = lang_tokens[2]
    return lang
Пример #5
0
    def expr(self) -> ParserElement:
        NL = LineEnd()
        LIST_BREAK = NL + Optional(White(" \t")) + NL | StringEnd()
        IGNORE = BlockQuote(**self.init_kwargs).expr | Panel(
            **self.init_kwargs).expr | Color(**self.init_kwargs).expr
        ROW = LineStart() + Combine(
            Optional(self.nested_token, default="") +
            ListIndent(self.indent_state, self.tokens) +
            SkipTo(NL + Char(self.nested_token + self.tokens) | LIST_BREAK,
                   ignore=IGNORE) + Optional(NL), )

        return OneOrMore(ROW, stopOn=LIST_BREAK).setParseAction(self.action)
Пример #6
0
    def _create_grammar(self):
        """
        Pyparsing implementation of a where clause grammar based on http://pyparsing.wikispaces.com/file/view/simpleSQL.py

        The query language is a series of statements separated by AND or OR operators and parentheses can be used to group/provide
        precedence.

        A statement is a combination of three strings "<filter> <operator> <value>" or "<filter> <operator> <filter>".

        A value can be a string, integer or a real(floating) number or a (ISO YYYY-MM-DD) date.

        An operator must be one of "= != < > >= <= !:" and are translated into django __lte or equivalent suffixes.
        See self.as_q

        Example
        something < 10 AND other >= 2015-01-01 AND (foo < 1 OR bar > 1)

        """
        quoted_string_excluding_quotes = QuotedString(
            '"',
            escChar='\\').setParseAction(lambda token: StringValue(token[0]))
        and_ = Keyword('and', caseless=True)
        or_ = Keyword('or', caseless=True)
        binary_op = oneOf('=> =< = < > >= <= : != !:',
                          caseless=True).setResultsName('operator')

        # define query tokens
        identifier = Word(alphas, alphanums + '_$-.').setName('identifier')
        raw_value_chars = alphanums + '_$-+/$%*;?@[]\\^`{}|~.'
        raw_value = Word(raw_value_chars, raw_value_chars).setName('raw_value')
        value_string = quoted_string_excluding_quotes | raw_value

        # Define a where expression
        where_expression = Forward()
        binary_operator_statement = (identifier + binary_op +
                                     value_string).setParseAction(
                                         self._binary_op_to_q)
        unary_operator_statement = (identifier |
                                    (Char('!') + identifier)).setParseAction(
                                        self._unary_op_to_q)
        free_text_statement = quotedString.copy().setParseAction(
            self._freetext_to_q)
        operator_statement = binary_operator_statement | free_text_statement | unary_operator_statement
        where_condition = Group(operator_statement
                                | ('(' + where_expression + ')'))
        where_expression << where_condition + ZeroOrMore(
            (and_ | or_) + where_expression)

        # define the full grammar
        query_statement = Forward()
        query_statement << Group(where_expression).setResultsName("where")
        return query_statement
Пример #7
0
 def expr(self) -> ParserElement:
     MENTION = Combine(
         "[" + Optional(
             SkipTo("|", failOn="]") + Suppress("|"),
             default="",
         ) + "~" + Optional(CaselessLiteral("accountid:")) +
         Word(alphanums + ":-").setResultsName("accountid") + "]", )
     return ((StringStart()
              | Optional(PrecededBy(White(), retreat=1), default=" ")) +
             MENTION.setParseAction(self.action) +
             (StringEnd() | Optional(FollowedBy(
                 White() | Char(punctuation, excludeChars="[") | MENTION),
                                     default=" ")))
Пример #8
0
    def expr(self) -> ParserElement:
        NON_ALPHANUMS = Regex(r"\W", flags=re.UNICODE)
        TOKEN = Suppress(self.TOKEN)
        IGNORE = White() + TOKEN | self.get_ignore_expr()
        ELEMENT = Combine(
            TOKEN + (~White() & ~Char(self.TOKEN)) +
            SkipTo(TOKEN, ignore=IGNORE, failOn="\n") + TOKEN +
            FollowedBy(NON_ALPHANUMS | StringEnd()), )

        return (StringStart()
                | PrecededBy(NON_ALPHANUMS, retreat=1)) + Combine(
                    ELEMENT.setParseAction(self.action) +
                    Optional(~ELEMENT, default=" "), )
Пример #9
0
def parse_lesson_id(line):
    """
    Разбирает строку line вида
    lesson = число
    и возвращает это число.
    """
    id_template = 'lesson' + Char('=') + Word(nums)

    if not line == id_template:
        error(f'Expect lesson id as lesson=number, now = {line}')

    lesson = id_template.parseString(line)
    lesson_id = int(lesson[2])
    return lesson_id
Пример #10
0
def param_substitude(lines, param_dict):
    mask_par = (CharsNotIn('{{}}')[0, ] + '{{' + WRD_p + '}}' +
                CharsNotIn('{{}}')[0, ])[1, ] + Char('\n')[0, 1]
    # mask_par.setParseAction(param_set)
    mask_par.setParseAction(lambda tokens: param_set(tokens, param_dict))

    for line_to, line in enumerate(lines):
        line = line.rstrip()

        if not line:
            continue

        lines[line_to] = mask_par.transformString(line)

    return lines
Пример #11
0
def create_ast(expression_str: str) -> List[Union[str, List]]:
    """Evaluates the given expression"""
    expression = Forward()
    operand = Group(Char(alphas) + ZeroOrMore("'")) | Group(
        Group("(" + expression + ")") + ZeroOrMore("'"))

    expression <<= infixNotation(
        operand,
        [
            (Empty(), 2, opAssoc.LEFT),
            ("*", 2, opAssoc.LEFT),
            ("+", 2, opAssoc.LEFT),
        ],
    )
    return expression.parseString(expression_str, parseAll=True).asList()
Пример #12
0
#  :label - exported/global label
#  OPCODE .label - .label gets turned into the corresponding address
#  OPCODE :label+4 - same, but with an offset
labelprefix = oneOf(': .')
label = Combine(labelprefix + Word(alphanums + "_"))
label.setName('label')
labeloffset = Combine(labelprefix + Word(':', alphanums + "_-+"))
labeloffset.setName('labeloffset')
# Bytes can be represented in binary, hex, char, or a number (0-255 or -128-127)
# and may include embedded arithmetic
#  OPCODE 0b00001100
#  OPCODE 0x0b
#  OPCODE 'a'
#  OPCODE 254-0x0a
#  OPCODE 'a'&0b00001111
binbyte = Combine(Literal('0b') + Char('01') * 8)
binbyte.setName('binbyte')
binbyte.setParseAction(lambda t: [int(t[0], 2)])
hexbyte = Combine(Literal('0x') + Char(srange("[0-9a-fA-F]")) * 2)
hexbyte.setName('hexbyte')
hexbyte.setParseAction(lambda t: [int(t[0], 16)])
chrbyte = QuotedString(quoteChar="'", unquoteResults=True)
chrbyte.setName('char')
chrbyte.setParseAction(lambda t: [ord(t[0])])
number = Word(nums + '-')
number.setName('number')
number.setParseAction(lambda t: [int(t[0])])
allbytes = binbyte | hexbyte | chrbyte | number
mathtoken = Combine(oneOf('+ - & |') + allbytes)
bytemathexpression = Combine(allbytes + OneOrMore(mathtoken))
bytemathexpression.setParseAction(lambda t: [eval(t[0])])
Пример #13
0
lisp_integer = Word(nums)
lisp_integer.setParseAction(lambda s, l, t: Int(t[0]))

lisp_float = Combine(Word(nums) + '.' + Word(nums))
lisp_float.setParseAction(lambda s, l, t: float(t[0]))

lisp_number = lisp_integer | lisp_float

lisp_string = QuotedString(quoteChar='"', escChar='\\', multiline=True)
lisp_string.setParseAction(lambda s, l, t: String(t[0]))

special = "_-+*/^><=:'"
#lisp_symbol = Word(alphas + nums + '_-' + '?!') # any order
#lisp_symbol = Combine(Char(alphas) + Word(alphas + nums + '?' + '!')) # starts with alphas
lisp_symbol = Combine(
    Char(alphas + special) + Optional(Word(alphas + nums + special)) +
    Optional(Char('?!')))  # Ruby style

lisp_symbol.setParseAction(lambda s, l, t: Symbol(t[0]))

lisp_atom = lisp_symbol | lisp_string | lisp_number

lisp_list = nestedExpr(opener='(',
                       closer=')',
                       content=lisp_atom,
                       ignoreExpr=lisp_string)
#lisp_list.setParseAction(lambda s,l,t: List(t)) # does not work

lisp_expr = lisp_atom | lisp_list

Пример #14
0
    TREE,
    CATCH,
    FINALLY,
    THROWS,
    PROTECTED,
    PUBLIC,
    PRIVATE,
) = map(
    Keyword,
    """src scope options tokens fragment id lexer parser grammar tree catch finally throws protected 
       public private """.split())
KEYWORD = MatchFirst(keywords)

# Tokens
EOL = Suppress(LineEnd())  # $
SGL_PRINTABLE = Char(printables)
singleTextString = originalTextFor(
    ZeroOrMore(~EOL + (White(" \t") | Word(printables)))).leaveWhitespace()
XDIGIT = hexnums
INT = Word(nums)
ESC = BSLASH + (oneOf(list(r'nrtbf\">' + "'")) |
                ('u' + Word(hexnums, exact=4)) | SGL_PRINTABLE)
LITERAL_CHAR = ESC | ~(APOS | BSLASH) + SGL_PRINTABLE
CHAR_LITERAL = APOS + LITERAL_CHAR + APOS
STRING_LITERAL = APOS + Combine(OneOrMore(LITERAL_CHAR)) + APOS
DOUBLE_QUOTE_STRING_LITERAL = '"' + ZeroOrMore(LITERAL_CHAR) + '"'
DOUBLE_ANGLE_STRING_LITERAL = '<<' + ZeroOrMore(SGL_PRINTABLE) + '>>'
TOKEN_REF = Word(alphas.upper(), alphanums + '_')
RULE_REF = Word(alphas.lower(), alphanums + '_')
ACTION_ESC = (BSLASH.suppress() + APOS
              | BSLASH.suppress()
Пример #15
0
rr_type_set.setName('<rr_type>')

#  a series of RR types (without a semicolon separator)
rr_type_series = OneOrMore(
    rr_type_set(
        ''
    )  # remove this label so we can float result to a bigger, later label
)('rr_types')
rr_type_series.setName('<rr_type ...>')

#  a series of RR types (with a semicolon separator)
rr_type_list_series = OneOrMore(rr_type_set + semicolon)('rr_type_list')
rr_type_list_series.setName('<rr_type; ...;>')

#  Following is commonly used in association with DNS zone records
rr_fqdn_w_absolute = Combine(domain_generic_fqdn + Optional(Literal('.')))
rr_fqdn_w_absolute.setName('<rr_fqdn_with_abs>')

# rr_domain_name is uzed in association with DNS zone records
# by 'update-policy', a zone-specific option
rr_domain_name = Combine(domain_generic_fqdn + Optional(Literal('.')))
rr_domain_name.setName('<rr_domain_name>')

# rr_domain_name may be '*.example.net', '*.congress.gov.', or '*'
rr_domain_name_or_wildcard = (rr_domain_name | Char(domain_charset_wildcard))
rr_domain_name_or_wildcard.setName('<target_rr_name>')

#  ( <fqdn> | '.' )
rr_domain_name_or_root = (rr_domain_name | Literal('.'))
rr_domain_name_or_root.setName('<rr_domain_or_root>')
Пример #16
0
    '~~', endQuoteChar='~~').setParseAction(wiki_italic_parse_action)


def wiki_underline_parse_action(start, length, tokens):
    return f'<u>{tokens[0]}</u>'


underline = QuotedString(
    '__', endQuoteChar='__').setParseAction(wiki_underline_parse_action)


def literal_parse_action(start, length, tokens):
    return tokens[0]


literal = Literal('\\').setParseAction(nil_parse_action) + Char(
    printables).setParseAction(literal_parse_action)

divider = Literal('{divider}').setParseAction(
    lambda start, length, tokens: '<hr>')

wikiMarkup = literal | link | quote | bold | italic | underline | divider


def wiki_render(s):
    return mark_safe(
        wikiMarkup.transformString(s))  # TODO: yea, this isn't safe...


@register.filter
def wiki(value):
    return wiki_render(value)
Пример #17
0
from pyparsing import (Empty, alphas, alphanums, nums, Literal, Word, Char,
                       ParserElement, Forward, Combine, OneOrMore, Group,
                       Regex, ZeroOrMore, White, CaselessKeyword, Optional)
import re

## TERMINALS
identifier = Word(alphas + '_', alphanums + '_')
lBrace = Literal('{').suppress()
rBrace = Literal('}').suppress()
eq = Literal('=').suppress()
escapedSymbol = Literal('~').suppress() + Char('{}~"\'/')

## GRAMMAR
source: ParserElement = Forward()
item: ParserElement = Forward()


#### ARGS
##### ARGVALUES
def Quote(q):
    q = Literal(q).suppress()
    quotedStringBit = Combine(
        OneOrMore(escapedSymbol
                  | (~q +
                     Regex('[^{}]', re.S))))('stringBit').leaveWhitespace()
    quotedString = q + (OneOrMore(
        Group(item.leaveWhitespace() | source.leaveWhitespace()
              | quotedStringBit)) | Empty())('value') + q
    return quotedString

Пример #18
0
def assertParseElementFalse(af_parse_element, af_test_data,
                            af_expected_result):
    """
    A nice wrapper routine to ensure that the word 'False' is in the
    function name.
    """
    assertParseElement(a_parse_element=af_parse_element,
                       a_test_data=af_test_data,
                       a_expected_result=af_expected_result,
                       a_assert_flag=False)


addr = Word(alphanums + '_-./:').setResultsName('addr').setName('<addr>')
semicolon, lbrack, rbrack = map(Suppress, ';{}')
exclamation = Char('!')

aml_nesting = Forward()
aml_nesting << (
    lbrack + (
        ZeroOrMore(
            Group(
                (exclamation('not') + aml_nesting)
                | (exclamation('not') + addr + semicolon)
                | (aml_nesting)
                | (
                    addr + semicolon
                )  # never set a ResultsLabel here, you get duplicate but un-nested 'addr'
            )  # never set a ResultsLabel here, you get no []
        )(None))('aml_nesting') + rbrack +
    semicolon)(
Пример #19
0
class ChoiceTree:
    '''
        Class that parses strings representing possible combinations, and returns possible combinations.
        e.g.
            "abc[de|fg]" → [ "abcde", "abcfg" ]
            "I [eat|like] [|hot]dogs" → [ "I eat dogs", "I like dogs", "I eat hotdogs", "I like hotdogs" ]

        Escape symbol is '~'
        e.g.
            "abc~[def~]" → [ "abc[def]" ]
        Due to reasons, an escaped escape '~~' is not turned into a literal '~',
            if this is not up to liking, simply .replace('~~', '~') yourself after parsing.
        
        Essentially, consider the noncommutative Semiring of (unordered) lists of strings,
            so that in python notation: list1+list2 == [*list1, *list2] the concatenation of lists
            and list1*list2 == [a+b for a in list1 for b in list2] the concatenation of each pair of strings.
            (This ring has as neutral element the list of the empty string, and as zero element the empty list.)
        We write addition using the "|" symbol, the product is implicit (i.e. a*b == ab), and use [] as parentheses,
            so that in python notation e.g. "abc" == ["abc"] and "a|b|c" == ["a", "b", "c"]

        What ChoiceTree does is parse such expressions, and using the distributivity rule ( [a|b]c == ab|ac )
            it simplifies the expression to a sum of products.
    '''
    class Text:
        def __init__(self, text):
            self.text = text if text == '' else ''.join(text.asList())
            self.count = 1
            self.reset()

        __str__ = __repr__ = lambda s: s.text

        def next(self):
            self.done = True
            return self.text

        def random(self):
            return self.text

        def reset(self):
            self.done = False

        def current(self):
            return self.text

    class Choice:
        def __init__(self, vals):
            self.vals = vals.asList()
            self.count = sum(v.count for v in self.vals)
            self.reset()

        __str__ = __repr__ = lambda s: '[{}]'.format('|'.join(
            [str(v) for v in s.vals]))

        def next(self):
            next = self.vals[self.i]
            out = next.next()
            if next.done:
                self.i += 1
                if self.i == len(self.vals):
                    self.done = True
            return out

        def random(self):
            # Weighted based on the number of different possible branches each child has.
            return np.random.choice(self.vals,
                                    p=list(v.count / self.count
                                           for v in self.vals)).random()

        def reset(self):
            self.i = 0
            self.done = False
            [c.reset() for c in self.vals]

        def current(self):
            return self.vals[self.i].current()

    class Group:
        def __init__(self, vals):
            self.vals = vals.asList()
            self.count = functools.reduce(lambda x, y: x * y,
                                          (c.count for c in self.vals), 1)
            self.reset()

        __str__ = __repr__ = lambda s: ''.join([str(v) for v in s.vals])

        def next(self):
            i = 0
            out = ''
            while True:
                out += self.vals[i].next()
                if self.vals[i].done:
                    if i == len(self.vals) - 1:
                        self.done = True
                        break
                    else:
                        self.vals[i].reset()
                else:
                    break
                i += 1
            i += 1

            while i < len(self.vals):
                out += self.vals[i].current()
                i += 1

            return out

        def random(self):
            return ''.join(v.random() for v in self.vals)

        def reset(self):
            self.done = False
            [c.reset() for c in self.vals]

        def current(self):
            return ''.join([c.current() for c in self.vals])

    escapedSymbol = Char('~').suppress() + Char('[|]')
    escapedEsc = Literal('~~')
    soleEsc = Char('~')
    lbr = Literal('[').suppress()
    rbr = Literal(']').suppress()
    div = Literal('|').suppress()
    _text = Regex(
        r'[^\[\|\]~]+'
    )  # any sequence of characters not containing '[', ']', '|' or '~'

    text = pGroup(
        OneOrMore(escapedSymbol | escapedEsc | soleEsc
                  | _text)).setParseAction(lambda t: ChoiceTree.Text(t[0]))
    group = Forward()
    choice = pGroup(lbr + group + ZeroOrMore(div + group) +
                    rbr).setParseAction(lambda t: ChoiceTree.Choice(t[0]))
    empty = Empty().setParseAction(lambda t: ChoiceTree.Text(''))
    group <<= pGroup(OneOrMore(text | choice) | empty).setParseAction(
        lambda t: ChoiceTree.Group(t[0])).leaveWhitespace()

    def __init__(self,
                 text,
                 parse_flags=False,
                 add_brackets=False,
                 leave_escapes=False):
        self.flag_random = False
        if parse_flags:
            if text[:3] == '[?]':
                text = text[3:]
                self.flag_random = True

        if add_brackets: text = '[' + text + ']'

        self.root: ChoiceTree.Group = ChoiceTree.group.parseString(text)[0]
        self.count = self.root.count

    def __iter__(self):
        if self.flag_random:
            yield self.random()
            return
        while not self.root.done:
            yield self.root.next()
        self.root.reset()

    def random(self):
        return self.root.random()
Пример #20
0
    def task_from_md(md_lines, params):
        st = StepTask(params.get('task_lang'))

        if 'task_root' in params:
            root = Path(params['task_root'])
        else:
            root = StepTask.Root

        # TODO вынести в parse.py и избавиться от перечислений (свернуть код?) и разрешить русские буквы в пути к файлам
        WRDs = OneOrMore(alphanums)
        equality = Char('=') + WRDs

        name_template = 'name' + equality
        repo_template = 'repo' + equality
        statement_template = 'statement' + equality
        checker_template = 'checker' + equality
        solution_template = 'solution' + equality
        tests_template = 'tests' + equality
        header_template = 'header' + equality
        footer_template = 'footer' + equality
        score_template = 'score' + Char('=') + Word(nums)
        visible_tst_num_template = 'visible_tst_num' + Char('=') + Word(nums)

        for line in md_lines:
            # print(line)

            if line == repo_template:
                repo = repo_template.parseString(line)[2]
                st.params['repo'] = root / repo
            elif line == score_template:
                score = score_template.parseString(line)[2]
                st.params['score'] = int(score)
            elif line == visible_tst_num_template:
                visible_tst_num = visible_tst_num_template.parseString(line)[2]
                st.params['visible_tst_num'] = int(visible_tst_num)

            elif line == statement_template:
                statement = statement_template.parseString(line)[2]
                st.params['statement'] = statement
            elif line == name_template:
                name = name_template.parseString(line)[2]
                st.params['name'] = name
            elif line == checker_template:
                checker = checker_template.parseString(line)[2]
                st.params['checker'] = checker
            elif line == solution_template:
                solution = solution_template.parseString(line)[2]
                st.params['solution'] = solution
            elif line == tests_template:
                tests = tests_template.parseString(line)[2]
                st.params['tests'] = tests
            elif line == header_template:
                header = header_template.parseString(line)[2]
                st.params['header'] = header
            elif line == footer_template:
                footer = footer_template.parseString(line)[2]
                st.params['footer'] = footer

        st.set_attrs()

        return st
Пример #21
0
"""
import os
import os.path
import errno
import sys
import argparse
from pprint import PrettyPrinter
from pyparsing import Literal, CaselessLiteral, \
    ParseException, ParseSyntaxException, \
    Word, alphanums, Group, Optional, nums, Combine, Char, \
    cppStyleComment, pythonStyleComment, OneOrMore, \
    Suppress, ungroup

unix_pipe_support = False
period = Literal('.')
exclamation = Char('!')
exclamation.setName('not')
lbrack, rbrack, semicolon, slash = map(Suppress, '{};/')
dquote = Literal('"').setName("'\"'")
squote = Literal("'").setName('"\'"')
isc_boolean = (
        CaselessLiteral('yes')
        | CaselessLiteral('no')
        | Literal('1')
        | Literal('0')
        | CaselessLiteral('True')
        | CaselessLiteral('False')
)
isc_boolean.setName('<boolean>')

# alphanums_series = Group(Word(alphanums) + Word(alphanums)) + semicolon
Пример #22
0
    Combine,
    Group,
    Optional,
    Word,
    ZeroOrMore,
    alphanums,
    printables,
)

from collections import namedtuple
from typing import List, Optional as Opt

__all__ = ["parse_cli_string"]

d = "-"
dash = Char(d)
arg_identifier = Combine(dash + Optional(dash))
arg_name = Word(alphanums + d)
kwarg = Combine(arg_identifier + arg_name)

value_bgn = "".join([p for p in list(printables) if p != d])
value = Combine(Char(value_bgn) + ZeroOrMore(Word(printables)))

kwarg_and_value = kwarg + value
bool_arg = kwarg
varargs_and_values = kwarg + value[2, ...]

arg = (kwarg_and_value("kwarg") ^ bool_arg("flag")
       ^ varargs_and_values("varargs"))
cli = ZeroOrMore(Group(arg))
Пример #23
0
                        + '){0,16}' + \
                        domain_label_regex + '\.' \
                    + '){0,1}'\
                    + tld_label_regex
domain_fqdn = Regex(domain_fqdn_regex)
domain_fqdn.setName('<strict-fqdn>')
domain_fqdn.setResultsName('domain_name')

# Generic fully-qualified domain name (less stringent)
domain_generic_fqdn = Combine(
    domain_generic_label
    + ZeroOrMore(
        Literal('.')
        + domain_generic_label
    )
    + Optional(Char('.'))
)
domain_generic_fqdn.setName('<generic-fqdn>')
domain_generic_fqdn.setResultsName('domain_name')

quoted_domain_generic_fqdn = (
        Combine(squote - domain_generic_fqdn - squote)
        | Combine(dquote - domain_generic_fqdn - dquote)
)
quoted_domain_generic_fqdn.setName('<quoted_domain_name>')

quotable_domain_generic_fqdn = (
        Combine(squote - domain_generic_fqdn - squote)
        | Combine(dquote - domain_generic_fqdn - dquote)
        | domain_generic_fqdn
)
Пример #24
0
    def from_aiken(md_lines):
        st = StepMultipleChoice()

        WRDs = ZeroOrMore(WRD)

        opt_template = Char(alphas) + (Char(')') ^ Char('.')) + WRDs
        ans_template = 'ANSWER:' + OneOrMore(Char(alphas) + Char(',')[0, 1])

        class Status(Enum):
            QUESTION = 0
            VARIANT = 1
            ANSWER = 3

        letter_seq = []  # letter sequence from aiken variant, A, B, C, D, etc
        md_part = []
        status = Status.QUESTION
        for line in md_lines:
            # Is it SHUFFLE option?
            """if line.startswith('SHUFFLE:'):
                sh = ('SHUFFLE:' + WRD).parseString(line)

                if sh[1].lower() == 'true':
                    st.preserve_order = False
                elif sh[1].lower() == 'false':
                    st.preserve_order = True
                else:
                    logger.warning(f'Unknown value SHUFFLE: [{sh[1]}]')
                continue"""

            if line.startswith('SHUFFLE:'):
                st.preserve_order = not bool_check(
                    'SHUFFLE', line
                )  # единсвенная проблема в том, что при неправильном написании true или false будет автоматом ставиться true
                continue

            # variant begin by A) or A.
            if line == opt_template:
                opt = opt_template.parseString(line)

                letter = opt[0]
                txt = ' '.join(opt[2:])

                if status == Status.QUESTION:
                    # first answer begin, question end
                    status = Status.VARIANT
                    st.text = html(md_part)
                elif status == Status.VARIANT:
                    # next variant, commit previous variant
                    st.add_option(md_part)
                md_part = [txt]
                letter_seq.append(letter)
            elif line == ans_template and status == Status.VARIANT:
                # end of question
                st.add_option(md_part)

                ans = ans_template.parseString(line)
                ans_str = " ".join(ans[1:])

                logger.debug(f'group1 = {ans_str}')
                letters = [s.strip() for s in ans_str.split(',')]
                logger.debug(f'letters={letters}')
                st.is_multiple_choice = len(letters) > 1
                for letter in letters:
                    ind = letter_seq.index(letter)
                    st.options[ind]['is_correct'] = True
                return st
            else:
                # continue a question or answer
                md_part.append(line)
Пример #25
0
question in AIKEN format
"""

import logging
from pyparsing import Char, Word, CharsNotIn, ZeroOrMore, nums, alphas, alphanums, printables, srange

logger = logging.getLogger('deploy_scripts')

# TODO нужны ли kir_letter вместе с srange(['а-я_']) + srange(['А-Я_']) ?
kir_letter = 'абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ_'
WRD = Word(printables + kir_letter + srange(['а-я_']) + srange(['А-Я_']))
WRD_p = Word(alphanums + kir_letter + srange(['а-я_']) + srange(['А-Я_']))

WRDs = ZeroOrMore(WRD)

sharp = Char('#')
not_sh = CharsNotIn('#')


def error(message="Error"):
    raise ValueError(message)


def bool_check(param_name, line):
    """
    Разбирает line по формату 'param_name:true|false', возвращает True или False (case insensitive), в случае ошибки возвращает False
    :param param_name: ключ
    :param line: разбираемая строка
    :return: True или False в разбираемой строке
    """
    # Todo подумать, надо ли в слушае ошибки False или лучше exception
Пример #26
0
isc_boolean = (CaselessLiteral('yes')
               | CaselessLiteral('no')
               | Literal('1')
               | Literal('0')
               | CaselessLiteral('True')
               | CaselessLiteral('False'))
isc_boolean.setName('<boolean>')

charset_key_id_base = alphanums + '_-'
charset_key_id_dquotable = charset_key_id_base + "'"
charset_key_id_squotable = charset_key_id_base + '"'

key_id_base = Word(charset_key_id_base, max=62)
key_id_dquotable = Combine(
    Char('"') + Word(charset_key_id_dquotable, max=64) + Char('"'))
key_id_squotable = Combine(
    Char("'") + Word(charset_key_id_squotable, max=64) + Char("'"))

key_id = (key_id_dquotable ^ key_id_squotable ^ key_id_base)('key_id')
key_id.setName('<key_id>')

charset_keysecret_base = alphanums + '+/='
charset_keysecret_dquotable = charset_keysecret_base + "'"
charset_keysecret_squotable = charset_keysecret_base + '"'

keysecret_base = Word(charset_keysecret_base, max=32767)
keysecret_dquotable = Combine(
    Char('"') + Word(charset_keysecret_dquotable, max=32765) + Char('"'))
keysecret_squotable = Combine(
    Char("'") + Word(charset_keysecret_squotable, max=32765) + Char("'"))