Beispiel #1
0
 def build(self):
     '''
     Construct the parser.
     '''
     
     # Avoid dependency loops
     from lepl.matchers.derived import Drop, Eos, AnyBut, Upper
     from lepl.matchers.core import Any, Lookahead, Literal, Delayed
     from lepl.matchers.error import make_error
     from lepl.matchers.variables import TraceVariables
     from lepl.support.node import node_throw
 
     with TraceVariables(False):
 
         # these two definitions enforce the conditions above, providing only
         # special characters appear as literals in the grammar
         escaped  = Drop(self.alphabet.escape) & self.alphabet.escaped
         raw      = ~Lookahead(self.alphabet.escape) & \
                         AnyBut(self.alphabet.illegal)
         close    = Drop(')')
         extend   = (Drop('(*') & Upper()[1:,...] & close)        >> self.extend
         
         single   = escaped | raw | extend
         
         any_     = Literal('.')                                  >> self.dot
         letter   = single                                        >> self.dup
         pair     = single & Drop('-') & single                   > self.tup
          
         interval = pair | letter
         brackets = Drop('[') & interval[1:] & Drop(']')
         inverted = Drop('[^') & interval[1:] & Drop(']')         >= self.invert      
         char     = inverted | brackets | letter | any_ | extend  > self.char
     
         item     = Delayed()
         
         open     = Drop('(?:')
         range    = Drop(self.alphabet.escape) & self.alphabet.range
         seq      = (char | item | range)[0:]                     > self.sequence
         group    = open & seq & close
         alts     = open & seq[2:, Drop('|')] & close             > self.choice
         star     = (alts | group | char) & Drop('*')             > self.star
         plus     = (alts | group | char) & Drop('+')             > self.plus
         opt      = (alts | group | char) & Drop('?')             > self.option
         bad_grp  = (Drop('(') & ~Lookahead('?:') & seq & close) \
                         ** make_error(
                             "Lepl's own regular expressions do not currently "
                             "support matched groups.\n"
                             "Use '(?:...)' to group expressions without "
                             "matching.") 
         
         item    += alts | group | star | plus | opt | bad_grp
         
         expr     = ((char | item)[:] & Drop(Eos())) >> node_throw
 
     # Empty config here avoids loops if the default config includes
     # references to alphabets
     expr.config.clear()
     return expr.parse_string
Beispiel #2
0
    def build(self):
        '''
        Construct the parser.
        '''

        # Avoid dependency loops
        from lepl.matchers.derived import Drop, Eos, AnyBut, Upper
        from lepl.matchers.core import Any, Lookahead, Literal, Delayed
        from lepl.matchers.error import make_error
        from lepl.matchers.variables import TraceVariables
        from lepl.support.node import node_throw

        with TraceVariables(False):

            # these two definitions enforce the conditions above, providing only
            # special characters appear as literals in the grammar
            escaped = Drop(self.alphabet.escape) & self.alphabet.escaped
            raw      = ~Lookahead(self.alphabet.escape) & \
                            AnyBut(self.alphabet.illegal)
            close = Drop(')')
            extend = (Drop('(*') & Upper()[1:, ...] & close) >> self.extend

            single = escaped | raw | extend

            any_ = Literal('.') >> self.dot
            letter = single >> self.dup
            pair = single & Drop('-') & single > self.tup

            interval = pair | letter
            brackets = Drop('[') & interval[1:] & Drop(']')
            inverted = Drop('[^') & interval[1:] & Drop(']') >= self.invert
            char = inverted | brackets | letter | any_ | extend > self.char

            item = Delayed()

            open = Drop('(?:')
            range = Drop(self.alphabet.escape) & self.alphabet.range
            seq = (char | item | range)[0:] > self.sequence
            group = open & seq & close
            alts = open & seq[2:, Drop('|')] & close > self.choice
            star = (alts | group | char) & Drop('*') > self.star
            plus = (alts | group | char) & Drop('+') > self.plus
            opt = (alts | group | char) & Drop('?') > self.option
            bad_grp  = (Drop('(') & ~Lookahead('?:') & seq & close) \
                            ** make_error(
                                "Lepl's own regular expressions do not currently "
                                "support matched groups.\n"
                                "Use '(?:...)' to group expressions without "
                                "matching.")

            item += alts | group | star | plus | opt | bad_grp

            expr = ((char | item)[:] & Drop(Eos())) >> node_throw

        # Empty config here avoids loops if the default config includes
        # references to alphabets
        expr.config.clear()
        return expr.parse_string
Beispiel #3
0
 def test_bad_format(self):
     '''
     Test a message with bad formatting.
     '''
     try:
         parser = (Literal('abc') > 'name')**make_error('msg {0}')
         parser.config.no_full_first_match()
         list(parser.match('abc'))
         assert False, 'expected error'
     except IndexError:
         pass
Beispiel #4
0
 def test_formatted(self):
     '''
     Test a message with formatting.
     '''
     parser = (Literal('abc') > 'name')**make_error('msg {stream_in}')
     parser.config.no_full_first_match()
     node = parser.parse('abc')[0]
     assert isinstance(node, Error)
     assert node[0] == 'msg abc', node[0]
     assert str(node).startswith('msg abc ('), str(node)
     assert isinstance(node, Exception), type(node)
Beispiel #5
0
 def test_bad_format(self):
     '''
     Test a message with bad formatting.
     '''
     try:
         parser = (Literal('abc') > 'name') ** make_error('msg {0}')
         parser.config.no_full_first_match()
         list(parser.match('abc'))
         assert False, 'expected error'
     except IndexError:
         pass
Beispiel #6
0
 def test_formatted(self):
     '''
     Test a message with formatting.
     '''
     parser = (Literal('abc') > 'name') ** make_error('msg {stream_in}')
     parser.config.no_full_first_match()
     node = parser.parse('abc')[0]
     assert isinstance(node, Error)
     assert node[0] == 'msg abc', node[0]
     assert str(node).startswith('msg abc ('), str(node)
     assert isinstance(node, Exception), type(node)
Beispiel #7
0
 def test_fmtted(self):
     '''
     Test a message with fmtting.
     '''
     parser = (Literal('abc') > 'name')**make_error('msg {in_rest}')
     parser.config.no_full_first_match()
     node = parser.parse('abc')[0]
     assert isinstance(node, Error)
     assert node[0] == "msg 'abc'", node[0]
     assert str(node).startswith("msg 'abc' ("), str(node)
     assert isinstance(node, Exception), type(node)
Beispiel #8
0
 def test_fmtted(self):
     '''
     Test a message with fmtting.
     '''
     parser = (Literal('abc') > 'name') ** make_error('msg {in_rest}')
     parser.config.no_full_first_match()
     node = parser.parse('abc')[0]
     assert isinstance(node, Error)
     assert node[0] == "msg 'abc'", node[0]
     assert str(node).startswith("msg 'abc' ("), str(node)
     assert isinstance(node, Exception), type(node)
Beispiel #9
0
 def test_list(self):
     '''
     Code has an exception for handling lists.
     '''
     #basicConfig(level=DEBUG)
     with TraceVariables():
         parser = (Literal([1, 2, 3]) > 'name')**make_error('msg {in_str}')
     parser.config.no_full_first_match()
     node = parser.parse([1, 2, 3])[0]
     assert isinstance(node, Error)
     assert node[0] == 'msg 1', node[0]
     assert str(node).startswith('msg 1 ('), str(node)
     assert isinstance(node, Exception), type(node)
Beispiel #10
0
 def test_list(self):
     '''
     Code has an exception for handling lists.
     '''
     #basicConfig(level=DEBUG)
     with TraceVariables():
         parser = (Literal([1, 2, 3]) > 'name') ** make_error('msg {stream_in}')
     parser.config.no_full_first_match()
     node = parser.parse([1, 2, 3])[0]
     assert isinstance(node, Error)
     assert node[0] == 'msg [1, 2, 3]', node[0]
     assert str(node).startswith('msg [1, 2, 3] ('), str(node)
     assert isinstance(node, Exception), type(node)