Beispiel #1
0
    def __init__(self, lexer, parser, parent):
        Token.__init__(self, 'If-condition', lexer, parser, parent)

        # Expect an expression.
        lexer.expect(self, 'keyword', 'if')
        lexer.expect(self, 'whitespace')
        self.expression = Expression(lexer, parser, parent)
        self.mark_end()

        # Body of the if block.
        self.if_block    = Exscript.interpreter.Code.Code(lexer, parser, parent)
        self.elif_blocks = []
        self.else_block  = None

        # If there is no "else" statement, just return.
        lexer.skip(['whitespace', 'newline'])
        if not lexer.next_if('keyword', 'else'):
            return

        # If the "else" statement is followed by an "if" (=elif),
        # read the next if condition recursively and return.
        lexer.skip(['whitespace', 'newline'])
        if lexer.current_is('keyword', 'if'):
            self.else_block = IfCondition(lexer, parser, parent)
            return

        # There was no "elif", so we handle a normal "else" condition here.
        self.else_block = Exscript.interpreter.Code.Code(lexer, parser, parent)
Beispiel #2
0
    def __init__(self, lexer, parser, parent):
        Token.__init__(self, 'Enter', lexer, parser, parent)

        lexer.expect(self, 'keyword', 'enter')
        lexer.skip(['whitespace', 'newline'])

        self.execute = Execute(lexer, parser, parent, '')
Beispiel #3
0
    def __init__(self, lexer, parser, parent):
        Token.__init__(self, 'If-condition', lexer, parser, parent)

        # Expect an expression.
        lexer.expect(self, 'keyword', 'if')
        lexer.expect(self, 'whitespace')
        self.expression = Expression(lexer, parser, parent)
        self.mark_end()

        # Body of the if block.
        self.if_block = Code.Code(lexer, parser, parent)
        self.elif_blocks = []
        self.else_block = None

        # If there is no "else" statement, just return.
        lexer.skip(['whitespace', 'newline'])
        if not lexer.next_if('keyword', 'else'):
            return

        # If the "else" statement is followed by an "if" (=elif),
        # read the next if condition recursively and return.
        lexer.skip(['whitespace', 'newline'])
        if lexer.current_is('keyword', 'if'):
            self.else_block = IfCondition(lexer, parser, parent)
            return

        # There was no "elif", so we handle a normal "else" condition here.
        self.else_block = Code.Code(lexer, parser, parent)
Beispiel #4
0
    def __init__(self, lexer, parser, parent):
        Token.__init__(self, 'Term', lexer, parser, parent)
        self.term = None
        self.lft  = None
        self.rgt  = None
        self.op   = None

        # Expect a term.
        ttype, token = lexer.token()
        if lexer.current_is('varname'):
            if not parent.is_defined(token):
                lexer.error('Undeclared variable %s' % token, self, ValueError)
            self.term = Variable(lexer, parser, parent)
        elif lexer.current_is('open_function_call'):
            self.term = FunctionCall(lexer, parser, parent)
        elif lexer.current_is('string_delimiter'):
            self.term = String(lexer, parser, parent)
        elif lexer.next_if('number'):
            self.term = Number(token)
        elif lexer.next_if('keyword', 'false'):
            self.term = Number(0)
        elif lexer.next_if('keyword', 'true'):
            self.term = Number(1)
        elif lexer.next_if('octal_number'):
            self.term = Number(int(token[1:], 8))
        elif lexer.next_if('hex_number'):
            self.term = Number(int(token[2:], 16))
        elif lexer.current_is('regex_delimiter'):
            self.term = Regex(lexer, parser, parent)
        else:
            lexer.syntax_error('Expected term but got %s' % ttype, self)
        self.mark_end()
Beispiel #5
0
    def __init__(self, lexer, parser, parent):
        Token.__init__(self, 'FunctionCall', lexer, parser, parent)
        self.funcname  = None
        self.arguments = []

        # Extract the function name.
        _, token = lexer.token()
        lexer.expect(self, 'open_function_call')
        self.funcname = token[:-1]
        function      = self.parent.get(self.funcname)
        if function is None:
            lexer.syntax_error('Undefined function %s' % self.funcname, self)

        # Parse the argument list.
        _, token = lexer.token()
        while 1:
            if lexer.next_if('close_bracket'):
                break
            self.arguments.append(Expression.Expression(lexer, parser, parent))
            ttype, token = lexer.token()
            if not lexer.next_if('comma') and not lexer.current_is('close_bracket'):
                error = 'Expected separator or argument list end but got %s'
                lexer.syntax_error(error % ttype, self)

        if parser.secure_only and not hasattr(function, '_is_secure'):
            msg = 'Use of insecure function %s is not permitted' % self.funcname
            lexer.error(msg, self, PermissionError)

        self.mark_end()
Beispiel #6
0
    def __init__(self, lexer, parser, parent):
        Token.__init__(self, "Enter", lexer, parser, parent)

        lexer.expect(self, "keyword", "enter")
        lexer.skip(["whitespace", "newline"])

        self.execute = Execute(lexer, parser, parent, "")
Beispiel #7
0
    def __init__(self, lexer, parser, parent):
        Token.__init__(self, self.__class__.__name__, lexer, parser, parent)

        # Create a grammar depending on the delimiting character.
        tok_type, delimiter = lexer.token()
        escaped_delimiter = '\\' + delimiter
        data = r'[^\r\n\\' + escaped_delimiter + ']+'
        delimiter_re = re.compile(escaped_delimiter)
        data_re = re.compile(data)
        grammar_with_delim = grammar_c[:]
        grammar_with_delim.append(('string_data', data_re))
        grammar_with_delim.append(('string_delimiter', delimiter_re))
        lexer.set_grammar(grammar_with_delim)

        # Begin parsing the string.
        lexer.expect(self, 'string_delimiter')
        self.string = ''
        while 1:
            if lexer.current_is('string_data'):
                self.string += lexer.token()[1]
                lexer.next()
            elif lexer.current_is('escaped_data'):
                self.string += self._escape(lexer.token()[1])
                lexer.next()
            elif lexer.next_if('string_delimiter'):
                break
            else:
                ttype = lexer.token()[0]
                lexer.syntax_error('Expected string but got %s' % ttype, self)

        # Make sure that any variables specified in the command are declared.
        string_re.sub(self.variable_test_cb, self.string)
        self.mark_end()
        lexer.restore_grammar()
Beispiel #8
0
    def __init__(self, lexer, parser, parent):
        Token.__init__(self, 'Term', lexer, parser, parent)
        self.term = None
        self.lft = None
        self.rgt = None
        self.op = None

        # Expect a term.
        ttype, token = lexer.token()
        if lexer.current_is('varname'):
            if not parent.is_defined(token):
                lexer.error('Undeclared variable %s' % token, self, ValueError)
            self.term = Variable(lexer, parser, parent)
        elif lexer.current_is('open_function_call'):
            self.term = FunctionCall(lexer, parser, parent)
        elif lexer.current_is('string_delimiter'):
            self.term = String(lexer, parser, parent)
        elif lexer.next_if('number'):
            self.term = Number(token)
        elif lexer.next_if('keyword', 'false'):
            self.term = Number(0)
        elif lexer.next_if('keyword', 'true'):
            self.term = Number(1)
        elif lexer.next_if('octal_number'):
            self.term = Number(int(token[1:], 8))
        elif lexer.next_if('hex_number'):
            self.term = Number(int(token[2:], 16))
        elif lexer.current_is('regex_delimiter'):
            self.term = Regex(lexer, parser, parent)
        else:
            lexer.syntax_error('Expected term but got %s' % ttype, self)
        self.mark_end()
Beispiel #9
0
    def __init__(self, lexer, parser, parent):
        Token.__init__(self, self.__class__.__name__, lexer, parser, parent)

        # Create a grammar depending on the delimiting character.
        tok_type, delimiter = lexer.token()
        escaped_delimiter   = '\\' + delimiter
        data                = r'[^\r\n\\' + escaped_delimiter + ']+'
        delimiter_re        = re.compile(escaped_delimiter)
        data_re             = re.compile(data)
        grammar_with_delim  = grammar_c[:]
        grammar_with_delim.append(('string_data',      data_re))
        grammar_with_delim.append(('string_delimiter', delimiter_re))
        lexer.set_grammar(grammar_with_delim)

        # Begin parsing the string.
        lexer.expect(self, 'string_delimiter')
        self.string = ''
        while 1:
            if lexer.current_is('string_data'):
                self.string += lexer.token()[1]
                lexer.next()
            elif lexer.current_is('escaped_data'):
                self.string += self._escape(lexer.token()[1])
                lexer.next()
            elif lexer.next_if('string_delimiter'):
                break
            else:
                ttype = lexer.token()[0]
                lexer.syntax_error('Expected string but got %s' % ttype, self)

        # Make sure that any variables specified in the command are declared.
        string_re.sub(self.variable_test_cb, self.string)
        self.mark_end()
        lexer.restore_grammar()
Beispiel #10
0
    def __init__(self, lexer, parser, parent):
        Token.__init__(self, 'Enter', lexer, parser, parent)

        lexer.expect(self, 'keyword', 'enter')
        lexer.skip(['whitespace', 'newline'])

        self.execute = Execute(lexer, parser, parent, '')
Beispiel #11
0
 def __init__(self, name, lexer, parser, parent=None, *args, **kwargs):
     Token.__init__(self, name, lexer, parser, parent)
     self.variables = kwargs.get('variables', {})
     self.children = []
     self.exit_requested = 0
     for key in self.variables:
         if key.find('.') < 0 and not key.startswith('_'):
             assert type(self.variables[key]) == type([])
Beispiel #12
0
 def __init__(self, name, lexer, parser, parent = None, *args, **kwargs):
     Token.__init__(self, name, lexer, parser, parent)
     self.variables      = kwargs.get('variables', {})
     self.children       = []
     self.exit_requested = 0
     for key in self.variables:
         if key.find('.') < 0 and not key.startswith('_'):
             assert type(self.variables[key]) == type([])
Beispiel #13
0
    def __init__(self, lexer, parser, parent):
        Token.__init__(self, 'Expression', lexer, parser, parent)

        # Parse the expression.
        self.root = ExpressionNode(lexer, parser, parent)

        # Reorder the tree according to the operator priorities.
        self.prioritize(self.root)
        self.mark_end()
Beispiel #14
0
    def __init__(self, lexer, parser, parent):
        Token.__init__(self, 'Expression', lexer, parser, parent)

        # Parse the expression.
        self.root = ExpressionNode(lexer, parser, parent)

        # Reorder the tree according to the operator priorities.
        self.prioritize(self.root)
        self.mark_end()
Beispiel #15
0
    def __init__(self, lexer, parser, parent):
        Token.__init__(self, 'Extract', lexer, parser, parent)
        self.varnames  = []
        self.variables = {}
        self.append    = False
        self.source    = None

        if parser.no_prompt: 
            msg = "'extract' keyword does not work with --no-prompt"
            lexer.syntax_error(msg, self)

        # First expect a regular expression.
        lexer.expect(self, 'keyword', 'extract')
        lexer.expect(self, 'whitespace')
        self.regex = Regex(lexer, parser, parent)

        # Expect "as" keyword.
        lexer.expect(self, 'whitespace')
        if lexer.next_if('keyword', 'as'):
            self.append = False
        elif lexer.next_if('keyword', 'into'):
            self.append = True
        else:
            _, token = lexer.token()
            msg      = 'Expected "as" or "into" but got %s' % token
            lexer.syntax_error(msg, self)

        # Expect a list of variable names.
        while 1:
            # Variable name.
            lexer.expect(self, 'whitespace')
            _, token = lexer.token()
            lexer.expect(self, 'varname')
            if token in self.variables:
                lexer.syntax_error('Duplicate variable name %s', self)
            self.varnames.append(token)
            self.variables[token] = []

            # Comma.
            if lexer.next_if('comma'):
                continue
            break
        self.parent.define(**self.variables)

        if len(self.varnames) != self.regex.n_groups:
            count = (len(self.varnames), self.regex.n_groups)
            error = '%s variables, but regex has %s groups' % count
            lexer.syntax_error(error, self)

        # Handle the "from" keyword.
        lexer.skip('whitespace')
        if lexer.next_if('keyword', 'from'):
            lexer.expect(self, 'whitespace')
            self.source = Term(lexer, parser, parent)
        self.mark_end()
Beispiel #16
0
    def __init__(self, lexer, parser, parent):
        Token.__init__(self, "Extract", lexer, parser, parent)
        self.varnames = []
        self.variables = {}
        self.append = False
        self.source = None

        if parser.no_prompt:
            msg = "'extract' keyword does not work with --no-prompt"
            lexer.syntax_error(msg, self)

        # First expect a regular expression.
        lexer.expect(self, "keyword", "extract")
        lexer.expect(self, "whitespace")
        self.regex = Regex(lexer, parser, parent)

        # Expect "as" keyword.
        lexer.expect(self, "whitespace")
        if lexer.next_if("keyword", "as"):
            self.append = False
        elif lexer.next_if("keyword", "into"):
            self.append = True
        else:
            _, token = lexer.token()
            msg = 'Expected "as" or "into" but got %s' % token
            lexer.syntax_error(msg, self)

        # Expect a list of variable names.
        while 1:
            # Variable name.
            lexer.expect(self, "whitespace")
            _, token = lexer.token()
            lexer.expect(self, "varname")
            if token in self.variables:
                lexer.syntax_error("Duplicate variable name %s", self)
            self.varnames.append(token)
            self.variables[token] = []

            # Comma.
            if lexer.next_if("comma"):
                continue
            break
        self.parent.define(**self.variables)

        if len(self.varnames) != self.regex.n_groups:
            count = (len(self.varnames), self.regex.n_groups)
            error = "%s variables, but regex has %s groups" % count
            lexer.syntax_error(error, self)

        # Handle the "from" keyword.
        lexer.skip("whitespace")
        if lexer.next_if("keyword", "from"):
            lexer.expect(self, "whitespace")
            self.source = Term(lexer, parser, parent)
        self.mark_end()
Beispiel #17
0
    def __init__(self, lexer, parser, parent, command):
        Token.__init__(self, 'Execute', lexer, parser, parent)
        self.string        = command
        self.no_prompt     = parser.no_prompt
        self.strip_command = parser.strip_command

        # The lexer has parsed the command, including a newline.
        # Make the debugger point to the beginning of the command.
        self.start -= len(command) + 1
        self.mark_end(self.start + len(command))

        # Make sure that any variables specified in the command are declared.
        string_re.sub(self.variable_test_cb, command)
        self.parent.define(__response__ = [])
Beispiel #18
0
    def __init__(self, lexer, parser, parent, command):
        Token.__init__(self, 'Execute', lexer, parser, parent)
        self.string        = command
        self.no_prompt     = parser.no_prompt
        self.strip_command = parser.strip_command

        # The lexer has parsed the command, including a newline.
        # Make the debugger point to the beginning of the command.
        self.start -= len(command) + 1
        self.mark_end(self.start + len(command))

        # Make sure that any variables specified in the command are declared.
        string_re.sub(self.variable_test_cb, command)
        self.parent.define(__response__ = [])
Beispiel #19
0
    def __init__(self, lexer, parser, parent):
        Token.__init__(self, 'Assign', lexer, parser, parent)

        # Extract the variable name.
        _, self.varname = lexer.token()
        lexer.expect(self, 'varname')
        lexer.expect(self, 'whitespace')
        lexer.expect(self, 'assign')
        lexer.expect(self, 'whitespace')

        if self.varname.startswith('__'):
            msg = 'Assignment to internal variable ' + self.varname
            lexer.syntax_error(msg, self)

        self.expression = Exscript.interpreter.Expression.Expression(lexer, parser, parent)
        self.parent.define(**{self.varname: None})
Beispiel #20
0
    def __init__(self, lexer, parser, parent):
        Token.__init__(self, 'Assign', lexer, parser, parent)

        # Extract the variable name.
        _, self.varname = lexer.token()
        lexer.expect(self, 'varname')
        lexer.expect(self, 'whitespace')
        lexer.expect(self, 'assign')
        lexer.expect(self, 'whitespace')

        if self.varname.startswith('__'):
            msg = 'Assignment to internal variable ' + self.varname
            lexer.syntax_error(msg, self)

        self.expression = Expression.Expression(lexer, parser, parent)
        self.parent.define(**{self.varname: None})
Beispiel #21
0
    def __init__(self, lexer, parser, parent, parent_node=None):
        # Skip whitespace before initializing the token to make sure that self.start
        # points to the beginning of the expression (which makes for prettier error
        # messages).
        lexer.skip(["whitespace", "newline"])

        Token.__init__(self, "ExpressionNode", lexer, parser, parent)
        self.lft = None
        self.rgt = None
        self.op = None
        self.op_type = None
        self.parent_node = parent_node

        # The "not" operator requires special treatment because it is
        # positioned left of the term.
        if not lexer.current_is("logical_operator", "not"):
            self.lft = Term.Term(lexer, parser, parent)

            # The expression may end already (a single term is also an
            # expression).
            lexer.skip(["whitespace", "newline"])
            if (
                not lexer.current_is("arithmetic_operator")
                and not lexer.current_is("logical_operator")
                and not lexer.current_is("comparison")
                and not lexer.current_is("regex_delimiter")
            ):
                self.mark_end()
                return

        # Expect the operator.
        self.op_type, self.op = lexer.token()
        if (
            not lexer.next_if("arithmetic_operator")
            and not lexer.next_if("logical_operator")
            and not lexer.next_if("comparison")
            and not lexer.next_if("regex_delimiter")
        ):
            self.mark_end()
            msg = "Expected operator but got %s" % self.op_type
            lexer.syntax_error(msg, self)

        # Expect the second term.
        self.rgt = ExpressionNode(lexer, parser, parent, self)
        self.mark_end()
Beispiel #22
0
    def __init__(self, lexer, parser, parent):
        Token.__init__(self, 'Fail', lexer, parser, parent)
        self.expression = None

        # "fail" keyword.
        lexer.expect(self, 'keyword', 'fail')
        lexer.expect(self, 'whitespace')
        self.msg = Expression(lexer, parser, parent)

        # 'If' keyword with an expression.
        #token = lexer.token()
        if lexer.next_if('keyword', 'if'):
            lexer.expect(self, 'whitespace')
            self.expression = Expression(lexer, parser, parent)

        # End of expression.
        self.mark_end()
        lexer.skip(['whitespace', 'newline'])
Beispiel #23
0
    def __init__(self, lexer, parser, parent):
        Token.__init__(self, 'Fail', lexer, parser, parent)
        self.expression = None

        # "fail" keyword.
        lexer.expect(self, 'keyword', 'fail')
        lexer.expect(self, 'whitespace')
        self.msg = Expression(lexer, parser, parent)

        # 'If' keyword with an expression.
        #token = lexer.token()
        if lexer.next_if('keyword', 'if'):
            lexer.expect(self, 'whitespace')
            self.expression = Expression(lexer, parser, parent)

        # End of expression.
        self.mark_end()
        lexer.skip(['whitespace', 'newline'])
Beispiel #24
0
    def __init__(self, lexer, parser, parent):
        Token.__init__(self, 'Append', lexer, parser, parent)

        # First expect an expression.
        lexer.expect(self, 'keyword', 'append')
        lexer.expect(self, 'whitespace')
        self.expr = Term(lexer, parser, parent)

        # Expect "to" keyword.
        lexer.expect(self, 'whitespace')
        lexer.expect(self, 'keyword', 'to')

        # Expect a variable name.
        lexer.expect(self, 'whitespace')
        _, self.varname = lexer.token()
        lexer.expect(self, 'varname')
        self.parent.define(**{self.varname: []})

        self.mark_end()
Beispiel #25
0
    def __init__(self, lexer, parser, parent):
        Token.__init__(self, 'Append', lexer, parser, parent)

        # First expect an expression.
        lexer.expect(self, 'keyword', 'append')
        lexer.expect(self, 'whitespace')
        self.expr = Term(lexer, parser, parent)

        # Expect "to" keyword.
        lexer.expect(self, 'whitespace')
        lexer.expect(self, 'keyword', 'to')

        # Expect a variable name.
        lexer.expect(self, 'whitespace')
        _, self.varname = lexer.token()
        lexer.expect(self, 'varname')
        self.parent.define(**{self.varname: []})

        self.mark_end()
Beispiel #26
0
    def __init__(self, lexer, parser, parent, parent_node=None):
        # Skip whitespace before initializing the token to make sure that self.start
        # points to the beginning of the expression (which makes for prettier error
        # messages).
        lexer.skip(['whitespace', 'newline'])

        Token.__init__(self, 'ExpressionNode', lexer, parser, parent)
        self.lft = None
        self.rgt = None
        self.op = None
        self.op_type = None
        self.parent_node = parent_node

        # The "not" operator requires special treatment because it is
        # positioned left of the term.
        if not lexer.current_is('logical_operator', 'not'):
            self.lft = Term.Term(lexer, parser, parent)

            # The expression may end already (a single term is also an
            # expression).
            lexer.skip(['whitespace', 'newline'])
            if not lexer.current_is('arithmetic_operator') and \
               not lexer.current_is('logical_operator') and \
               not lexer.current_is('comparison') and \
               not lexer.current_is('regex_delimiter'):
                self.mark_end()
                return

        # Expect the operator.
        self.op_type, self.op = lexer.token()
        if not lexer.next_if('arithmetic_operator') and \
           not lexer.next_if('logical_operator') and \
           not lexer.next_if('comparison') and \
           not lexer.next_if('regex_delimiter'):
            self.mark_end()
            msg = 'Expected operator but got %s' % self.op_type
            lexer.syntax_error(msg, self)

        # Expect the second term.
        self.rgt = ExpressionNode(lexer, parser, parent, self)
        self.mark_end()
Beispiel #27
0
    def __init__(self, lexer, parser, parent):
        Token.__init__(self, 'Loop', lexer, parser, parent)
        self.during         = None
        self.until          = None
        self.thefrom        = None
        self.theto          = None
        self.list_variables = []
        self.iter_varnames  = []

        # Expect one ore more lists.
        lexer.expect(self, 'keyword', 'loop')
        lexer.expect(self, 'whitespace')
        if not lexer.current_is('keyword', 'while') and \
           not lexer.current_is('keyword', 'until') and \
           not lexer.current_is('keyword', 'from'):
            self.list_variables = [Term(lexer, parser, parent)]
            lexer.next_if('whitespace')
            while lexer.next_if('comma'):
                lexer.skip(['whitespace', 'newline'])
                self.list_variables.append(Term(lexer, parser, parent))
                lexer.skip(['whitespace', 'newline'])

            # Expect the "as" keyword.
            lexer.expect(self, 'keyword', 'as')

            # The iterator variable.
            lexer.next_if('whitespace')
            _, iter_varname = lexer.token()
            lexer.expect(self, 'varname')
            parent.define(**{iter_varname: []})
            self.iter_varnames = [iter_varname]
            lexer.next_if('whitespace')
            while lexer.next_if('comma'):
                lexer.skip(['whitespace', 'newline'])
                _, iter_varname = lexer.token()
                lexer.expect(self, 'varname')
                parent.define(**{iter_varname: []})
                self.iter_varnames.append(iter_varname)
                lexer.skip(['whitespace', 'newline'])

            if len(self.iter_varnames) != len(self.list_variables):
                error = '%s lists, but only %s iterators in loop' % (len(self.iter_varnames),
                                                                     len(self.list_variables))
                lexer.syntax_error(error, self)

        # Check if this is a "from ... to ..." loop.
        if lexer.next_if('keyword', 'from'):
            lexer.expect(self, 'whitespace')
            self.thefrom = Expression(lexer, parser, parent)
            lexer.next_if('whitespace')
            lexer.expect(self, 'keyword', 'to')
            self.theto = Expression(lexer, parser, parent)
            lexer.next_if('whitespace')

            if lexer.next_if('keyword', 'as'):
                lexer.next_if('whitespace')
                _, iter_varname = lexer.token()
                lexer.expect(self, 'varname')
                lexer.next_if('whitespace')
            else:
                iter_varname = 'counter'
            parent.define(**{iter_varname: []})
            self.iter_varnames = [iter_varname]
        
        # Check if this is a "while" loop.
        if lexer.next_if('keyword', 'while'):
            lexer.expect(self, 'whitespace')
            self.during = Expression(lexer, parser, parent)
            lexer.next_if('whitespace')
        
        # Check if this is an "until" loop.
        if lexer.next_if('keyword', 'until'):
            lexer.expect(self, 'whitespace')
            self.until = Expression(lexer, parser, parent)
            lexer.next_if('whitespace')
        
        # End of statement.
        self.mark_end()

        # Body of the loop block.
        lexer.skip(['whitespace', 'newline'])
        self.block = Code.Code(lexer, parser, parent)
Beispiel #28
0
 def __init__(self, lexer, parser, parent):
     Token.__init__(self, 'Variable', lexer, parser, parent)
     self.varname = lexer.token()[1]
     lexer.expect(self, 'varname')
     self.mark_end()