Exemple #1
0
    def test_optional(self):
        parser = ~Char('A')
        self.assertEqual(parser('X').result, [])
        self.assertEqual(parser('A').result, ['A'])

        parser = ~Char('A') + Char('B')
        self.assertEqual(parser('B').result, [['B']])
        self.assertEqual(parser('AB').result, [['A'], ['B']])
Exemple #2
0
    def test_seq(self):
        parser = Seq([Char('A'), Char('B'), Char('C')])
        result = parser('ABC').result
        self.assertEqual(result, [['A'], ['B'], ['C']])

        parser = Seq('ABC')
        result = parser('ABC').result
        self.assertEqual(result, [['A'], ['B'], ['C']])
Exemple #3
0
    def test_any(self):
        parser = Any([Char('A'), Char('B'), Char('C')])
        result = parser('BC').result
        self.assertEqual(result, ['B'])

        parser = Any('ABC')
        result = parser('BC').result
        self.assertEqual(result, ['B'])
Exemple #4
0
    def test_ZeroOrMore(self):
        parser = ZeroOrMore(Char('A'))
        self.assertEqual(parser('X').result, [])
        self.assertEqual(parser('A').result, [['A']])
        self.assertEqual(parser('AAAA').result, [['A'], ['A'], ['A'], ['A']])

        parser = ZeroOrMore(Any('12345'))
        self.assertEqual(parser('X').result, [])
        self.assertEqual(parser('1').result, [['1']])
        self.assertEqual(parser('1234').result, [['1'], ['2'], ['3'], ['4']])
Exemple #5
0
    def test_OneOrMore(self):
        parser = OneOrMore(Char('A'))
        self.assertEqual(parser('X').success, False)
        self.assertEqual(parser('A').result, [['A']])
        self.assertEqual(parser('AAAA').result, [['A'], ['A'], ['A'], ['A']])

        parser = OneOrMore(Any('12345'))
        self.assertEqual(parser('X').success, False)
        self.assertEqual(parser('1').result, [['1']])
        self.assertEqual(parser('1234').result, [['1'], ['2'], ['3'], ['4']])
Exemple #6
0
def exp_parser():
    number = number_parser()

    # exponent -> ( exp ) | NUMBER
    exponent = Between(Char('('), Ref('exp'), Char(')')) | number
    # a reference to 'exp' parser is used since its not defined yet

    # factor -> exponent factor'
    # factor' -> ^ exponent factor' | NULL
    factor = (exponent + ZeroOrMore(Char('^') + exponent)).map(eval_exp)

    # term -> factor term'
    # term' -> * factor term' | / factor term' | NULL
    term = (factor + ZeroOrMore(Any('*/') + factor)).map(eval_exp)

    # exp -> term exp'
    # exp' -> + term exp' | - term exp' | NULL
    exp = (term + ZeroOrMore(Any('+-') + term)).map(eval_exp)

    # linking reference to actual parser
    Ref.link({'exp': exp})

    return StripWhitespace() + exp + End()
Exemple #7
0
def number_parser():
    # based on JSON's specs for number

    # digit: any char from 0 - 9
    digit = Any('0123456789')

    # non zero numbers: digits without a leading 0
    non_zero = Any('123456789') + ZeroOrMore(digit)

    # int: optional minus sign, followed by a 0 OR non zero numbers
    integer = ~Char('-') + (Char('0') | non_zero)

    # decimal: point followed by digits
    decimal = Char('.') + OneOrMore(digit)

    # exponent: e or E with a optional sign followed by digits
    exp = Seq([Any('eE'), ~Any('+-'), OneOrMore(digit)])

    # all combinations of integer, decimal and exponent
    number = ((integer + decimal + exp) | (integer + decimal) | (integer + exp)
              |
              integer).map(lambda result: float(''.join(x[0] for x in result)))
    # ^ map the result list to float
    return number
def json_parser():
    # NULL, TRUE, FALSE parser
    null = Seq('null').map(lambda r: None)
    true = Seq('true').map(lambda r: True)
    false = Seq('false').map(lambda r: False)

    # NUMBER and STRING parser
    number = number_parser()
    # json string: QUOTE string QUOTE
    string = Between(Char('"'), string_parser(), Char('"'))

    # value -> STRING | NUMBER | TRUE | FALSE | NULL | list | object
    value = Any([string, number, null, true, false, Ref('lst'), Ref('obj')])
    # references to 'lst' and 'obj' are use since they are not defined yet

    # pair -> STRING COLON value
    to_dict = lambda result: {result[0][0]: result[2][0]}
    pair = (string + Char(':') + value).map(to_dict)

    # pairs_list -> pair COMMA pairs_list | pair
    pairs_list = (pair + ZeroOrMore(Char(',') + pair)).map(concat_dicts)

    # object -> OPEN_CURLYBRACE pairs_list CLOSE_CURLYBRACE
    obj = Between(Char('{'), pairs_list, Char('}'))

    # values_list -> value COMMA values_list | value
    values_list = (value + ZeroOrMore(Char(',') + value)).map(concat_lists)

    # list -> OPEN_SQBRACE values_list CLOSE_BRACE
    lst = Between(Char('['), values_list, Char(']'))

    # linking references to actual parsers
    Ref.link({'lst': lst, 'obj': obj})

    # json -> value
    parser = StripWhitespace() + value + End()
    parser.map(lambda result: result[0][0])
    return parser
Exemple #9
0
    def test_between(self):
        parser = Between(Char('A'), Char('B'), Char('C'))
        self.assertEqual(parser('ABC').result, ['B'])

        parser = Between(Char('A'), (Char('B') + Char('C')), Char('D'))
        self.assertEqual(parser('ABCD').result, [['B'], ['C']])
Exemple #10
0
 def test_ref(self):
     parser = Ref('A_and_B') + Char('C')
     A_and_B = Char('A') + Char('B')
     Ref.link({'A_and_B': A_and_B})
     self.assertEqual(parser('ABC').result, [['A'], ['B'], ['C']])
Exemple #11
0
 def test_and_multiple(self):
     parser = Char('A') + Char('B') + Char('C') + Char('D') + Char('E')
     result = parser('ABCDE').result
     self.assertEqual(result, [['A'], ['B'], ['C'], ['D'], ['E']])
Exemple #12
0
 def test_and(self):
     parser = Char('A') + Char('B')
     result = parser('ABC').result
     self.assertEqual(result, [['A'], ['B']])
Exemple #13
0
 def test_single_char(self):
     parse_A = Char('A')
     self.assertEqual(parse_A('ABC').result, ['A'])
     self.assertEqual(parse_A('DBC').success, False)
Exemple #14
0
 def test_and_complex(self):
     parser_AB = Char('A') + Char('B')
     parser_CD = Char('C') + Char('D')
     parser = parser_AB + parser_CD
     result = parser('ABCDE').result
     self.assertEqual(result, [['A'], ['B'], ['C'], ['D']])
Exemple #15
0
 def test_or(self):
     parser = Char('A') | Char('B')
     result = parser('ABC').result
     self.assertEqual(result, ['A'])
Exemple #16
0
 def test_end(self):
     parser = Char('A') + End()
     self.assertEqual(parser('A').result, [['A']])
     self.assertEqual(parser('ABCD').success, False)
Exemple #17
0
 def test_or_multiple(self):
     parser = Char('A') | Char('B') | Char('C') | Char('D') | Char('E')
     result = parser('CDE').result
     self.assertEqual(result, ['C'])