# Copyright 2014-2017 The Meson development team

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

#     http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import re
import codecs
import textwrap
import types
import typing as T
from .mesonlib import MesonException
from . import mlog

if T.TYPE_CHECKING:
    from .ast import AstVisitor

# This is the regex for the supported escape sequences of a regular string
# literal, like 'abc\x00'
ESCAPE_SEQUENCE_SINGLE_RE = re.compile(r'''
    ( \\U[A-Fa-f0-9]{8}   # 8-digit hex escapes
    | \\u[A-Fa-f0-9]{4}   # 4-digit hex escapes
    | \\x[A-Fa-f0-9]{2}   # 2-digit hex escapes
    | \\[0-7]{1,3}        # Octal escapes
    | \\N\{[^}]+\}        # Unicode characters by name
    | \\[\\'abfnrtv]      # Single-character escapes
    )''', re.UNICODE | re.VERBOSE)

class MesonUnicodeDecodeError(MesonException):
    def __init__(self, match: str) -> None:
        super().__init__(match)
        self.match = match

def decode_match(match: T.Match[str]) -> str:
    try:
        return codecs.decode(match.group(0).encode(), 'unicode_escape')
    except UnicodeDecodeError:
        raise MesonUnicodeDecodeError(match.group(0))

class ParseException(MesonException):
    def __init__(self, text: str, line: str, lineno: int, colno: int) -> None:
        # Format as error message, followed by the line with the error, followed by a caret to show the error column.
        super().__init__("{}\n{}\n{}".format(text, line, '{}^'.format(' ' * colno)))
        self.lineno = lineno
        self.colno = colno

class BlockParseException(MesonException):
    def __init__(
                self,
                text: str,
                line: str,
                lineno: int,
                colno: int,
                start_line: str,
                start_lineno: int,
                start_colno: int,
            ) -> None:
        # This can be formatted in two ways - one if the block start and end are on the same line, and a different way if they are on different lines.

        if lineno == start_lineno:
            # If block start and end are on the same line, it is formatted as:
            # Error message
            # Followed by the line with the error
            # Followed by a caret to show the block start
            # Followed by underscores
            # Followed by a caret to show the block end.
            super().__init__("{}\n{}\n{}".format(text, line, '{}^{}^'.format(' ' * start_colno, '_' * (colno - start_colno - 1))))
        else:
            # If block start and end are on different lines, it is formatted as:
            # Error message
            # Followed by the line with the error
            # Followed by a caret to show the error column.
            # Followed by a message saying where the block started.
            # Followed by the line of the block start.
            # Followed by a caret for the block start.
            super().__init__("%s\n%s\n%s\nFor a block that started at %d,%d\n%s\n%s" % (text, line, '%s^' % (' ' * colno), start_lineno, start_colno, start_line, "%s^" % (' ' * start_colno)))
        self.lineno = lineno
        self.colno = colno

TV_TokenTypes = T.TypeVar('TV_TokenTypes', int, str, bool)

class Token(T.Generic[TV_TokenTypes]):
    def __init__(self, tid: str, filename: str, line_start: int, lineno: int, colno: int, bytespan: T.Tuple[int, int], value: TV_TokenTypes):
        self.tid = tid                # type: str
        self.filename = filename      # type: str
        self.line_start = line_start  # type: int
        self.lineno = lineno          # type: int
        self.colno = colno            # type: int
        self.bytespan = bytespan      # type: T.Tuple[int, int]
        self.value = value            # type: TV_TokenTypes

    def __eq__(self, other: object) -> bool:
        if isinstance(other, str):
            return self.tid == other
        elif isinstance(other, Token):
            return self.tid == other.tid
        return NotImplemented

class Lexer:
    def __init__(self, code: str):
        self.code = code
        self.keywords = {'true', 'false', 'if', 'else', 'elif',
                         'endif', 'and', 'or', 'not', 'foreach', 'endforeach',
                         'in', 'continue', 'break'}
        self.future_keywords = {'return'}
        self.token_specification = [
            # Need to be sorted longest to shortest.
            ('ignore', re.compile(r'[ \t]')),
            ('fstring', re.compile(r"f'([^'\\]|(\\.))*'")),
            ('id', re.compile('[_a-zA-Z][_0-9a-zA-Z]*')),
            ('number', re.compile(r'0[bB][01]+|0[oO][0-7]+|0[xX][0-9a-fA-F]+|0|[1-9]\d*')),
            ('eol_cont', re.compile(r'\\\n')),
            ('eol', re.compile(r'\n')),
            ('multiline_string', re.compile(r"'''(.|\n)*?'''", re.M)),
            ('comment', re.compile(r'#.*')),
            ('lparen', re.compile(r'\(')),
            ('rparen', re.compile(r'\)')),
            ('lbracket', re.compile(r'\[')),
            ('rbracket', re.compile(r'\]')),
            ('lcurl', re.compile(r'\{')),
            ('rcurl', re.compile(r'\}')),
            ('dblquote', re.compile(r'"')),
            ('string', re.compile(r"'([^'\\]|(\\.))*'")),
            ('comma', re.compile(r',')),
            ('plusassign', re.compile(r'\+=')),
            ('dot', re.compile(r'\.')),
            ('plus', re.compile(r'\+')),
            ('dash', re.compile(r'-')),
            ('star', re.compile(r'\*')),
            ('percent', re.compile(r'%')),
            ('fslash', re.compile(r'/')),
            ('colon', re.compile(r':')),
            ('equal', re.compile(r'==')),
            ('nequal', re.compile(r'!=')),
            ('assign', re.compile(r'=')),
            ('le', re.compile(r'<=')),
            ('lt', re.compile(r'<')),
            ('ge', re.compile(r'>=')),
            ('gt', re.compile(r'>')),
            ('questionmark', re.compile(r'\?')),
        ]

    def getline(self, line_start: int) -> str:
        return self.code[line_start:self.code.find('\n', line_start)]

    def lex(self, filename: str) -> T.Generator[Token, None, None]:
        line_start = 0
        lineno = 1
        loc = 0
        par_count = 0
        bracket_count = 0
        curl_count = 0
        col = 0
        while loc < len(self.code):
            matched = False
            value = None  # type: T.Union[str, bool, int]
            for (tid, reg) in self.token_specification:
                mo = reg.match(self.code, loc)
                if mo:
                    curline = lineno
                    curline_start = line_start
                    col = mo.start() - line_start
                    matched = True
                    span_start = loc
                    loc = mo.end()
                    span_end = loc
                    bytespan = (span_start, span_end)
                    match_text = mo.group()
                    if tid == 'ignore' or tid == 'comment':
                        break
                    elif tid == 'lparen':
                        par_count += 1
                    elif tid == 'rparen':
                        par_count -= 1
                    elif tid == 'lbracket':
                        bracket_count += 1
                    elif tid == 'rbracket':
                        bracket_count -= 1
                    elif tid == 'lcurl':
                        curl_count += 1
                    elif tid == 'rcurl':
                        curl_count -= 1
                    elif tid == 'dblquote':
                        raise ParseException('Double quotes are not supported. Use single quotes.', self.getline(line_start), lineno, col)
                    elif tid in {'string', 'fstring'}:
                        # Handle here and not on the regexp to give a better error message.
                        if match_text.find("\n") != -1:
                            mlog.warning(textwrap.dedent("""\
                                    Newline character in a string detected, use ''' (three single quotes) for multiline strings instead.
                                    This will become a hard error in a future Meson release.\
                                """),
                                self.getline(line_start),
                                str(lineno),
                                str(col)
                            )
                        value = match_text[2 if tid == 'fstring' else 1:-1]
                        try:
                            value = ESCAPE_SEQUENCE_SINGLE_RE.sub(decode_match, value)
                        except MesonUnicodeDecodeError as err:
                            raise MesonException(f"Failed to parse escape sequence: '{err.match}' in string:\n  {match_text}")
                    elif tid == 'multiline_string':
                        tid = 'string'
                        value = match_text[3:-3]
                        lines = match_text.split('\n')
                        if len(lines) > 1:
                            lineno += len(lines) - 1
                            line_start = mo.end() - len(lines[-1])
                    elif tid == 'number':
                        value = int(match_text, base=0)
                    elif tid == 'eol_cont':
                        lineno += 1
                        line_start = loc
                        break
                    elif tid == 'eol':
                        lineno += 1
                        line_start = loc
                        if par_count > 0 or bracket_count > 0 or curl_count > 0:
                            break
                    elif tid == 'id':
                        if match_text in self.keywords:
                            tid = match_text
                        else:
                            if match_text in self.future_keywords:
                                mlog.warning(f"Identifier '{match_text}' will become a reserved keyword in a future release. Please rename it.",
                                             location=types.SimpleNamespace(filename=filename, lineno=lineno))
                            value = match_text
                    yield Token(tid, filename, curline_start, curline, col, bytespan, value)
                    break
            if not matched:
                raise ParseException('lexer', self.getline(line_start), lineno, col)

class BaseNode:
    def __init__(self, lineno: int, colno: int, filename: str, end_lineno: T.Optional[int] = None, end_colno: T.Optional[int] = None):
        self.lineno = lineno      # type: int
        self.colno = colno        # type: int
        self.filename = filename  # type: str
        self.end_lineno = end_lineno if end_lineno is not None else self.lineno
        self.end_colno = end_colno if end_colno is not None else self.colno

        # Attributes for the visitors
        self.level = 0            # type: int
        self.ast_id = ''          # type: str
        self.condition_level = 0  # type: int

    def accept(self, visitor: 'AstVisitor') -> None:
        fname = 'visit_{}'.format(type(self).__name__)
        if hasattr(visitor, fname):
            func = getattr(visitor, fname)
            if callable(func):
                func(self)

class ElementaryNode(T.Generic[TV_TokenTypes], BaseNode):
    def __init__(self, token: Token[TV_TokenTypes]):
        super().__init__(token.lineno, token.colno, token.filename)
        self.value = token.value        # type: TV_TokenTypes
        self.bytespan = token.bytespan  # type: T.Tuple[int, int]

class BooleanNode(ElementaryNode[bool]):
    def __init__(self, token: Token[bool]):
        super().__init__(token)
        assert isinstance(self.value, bool)

class IdNode(ElementaryNode[str]):
    def __init__(self, token: Token[str]):
        super().__init__(token)
        assert isinstance(self.value, str)

    def __str__(self) -> str:
        return "Id node: '%s' (%d, %d)." % (self.value, self.lineno, self.colno)

class NumberNode(ElementaryNode[int]):
    def __init__(self, token: Token[int]):
        super().__init__(token)
        assert isinstance(self.value, int)

class StringNode(ElementaryNode[str]):
    def __init__(self, token: Token[str]):
        super().__init__(token)
        assert isinstance(self.value, str)

    def __str__(self) -> str:
        return "String node: '%s' (%d, %d)." % (self.value, self.lineno, self.colno)

class FormatStringNode(ElementaryNode[str]):
    def __init__(self, token: Token[str]):
        super().__init__(token)
        assert isinstance(self.value, str)

    def __str__(self) -> str:
        return "Format string node: '{self.value}' ({self.lineno}, {self.colno})."

class ContinueNode(ElementaryNode):
    pass

class BreakNode(ElementaryNode):
    pass

class ArgumentNode(BaseNode):
    def __init__(self, token: Token[TV_TokenTypes]):
        super().__init__(token.lineno, token.colno, token.filename)
        self.arguments = []  # type: T.List[BaseNode]
        self.commas = []     # type: T.List[Token[TV_TokenTypes]]
        self.kwargs = {}     # type: T.Dict[BaseNode, BaseNode]
        self.order_error = False

    def prepend(self, statement: BaseNode) -> None:
        if self.num_kwargs() > 0:
            self.order_error = True
        if not isinstance(statement, EmptyNode):
            self.arguments = [statement] + self.arguments

    def append(self, statement: BaseNode) -> None:
        if self.num_kwargs() > 0:
            self.order_error = True
        if not isinstance(statement, EmptyNode):
            self.arguments += [statement]

    def set_kwarg(self, name: IdNode, value: BaseNode) -> None:
        if name.value in [x.value for x in self.kwargs.keys() if isinstance(x, IdNode)]:
            mlog.warning(f'Keyword argument "{name.value}" defined multiple times.', location=self)
            mlog.warning('This will be an error in future Meson releases.')
        self.kwargs[name] = value

    def set_kwarg_no_check(self, name: BaseNode, value: BaseNode) -> None:
        self.kwargs[name] = value

    def num_args(self) -> int:
        return len(self.arguments)

    def num_kwargs(self) -> int:
        return len(self.kwargs)

    def incorrect_order(self) -> bool:
        return self.order_error

    def __len__(self) -> int:
        return self.num_args() # Fixme

class ArrayNode(BaseNode):
    def __init__(self, args: ArgumentNode, lineno: int, colno: int, end_lineno: int, end_colno: int):
        super().__init__(lineno, colno, args.filename, end_lineno=end_lineno, end_colno=end_colno)
        self.args = args              # type: ArgumentNode

class DictNode(BaseNode):
    def __init__(self, args: ArgumentNode, lineno: int, colno: int, end_lineno: int, end_colno: int):
        super().__init__(lineno, colno, args.filename, end_lineno=end_lineno, end_colno=end_colno)
        self.args = args

class EmptyNode(BaseNode):
    def __init__(self, lineno: int, colno: int, filename: str):
        super().__init__(lineno, colno, filename)
        self.value = None

class OrNode(BaseNode):
    def __init__(self, left: BaseNode, right: BaseNode):
        super().__init__(left.lineno, left.colno, left.filename)
        self.left = left    # type: BaseNode
        self.right = right  # type: BaseNode

class AndNode(BaseNode):
    def __init__(self, left: BaseNode, right: BaseNode):
        super().__init__(left.lineno, left.colno, left.filename)
        self.left = left    # type: BaseNode
        self.right = right  # type: BaseNode

class ComparisonNode(BaseNode):
    def __init__(self, ctype: str, left: BaseNode, right: BaseNode):
        super().__init__(left.lineno, left.colno, left.filename)
        self.left = left    # type: BaseNode
        self.right = right  # type: BaseNode
        self.ctype = ctype  # type: str

class ArithmeticNode(BaseNode):
    def __init__(self, operation: str, left: BaseNode, right: BaseNode):
        super().__init__(left.lineno, left.colno, left.filename)
        self.left = left            # type: BaseNode
        self.right = right          # type: BaseNode
        self.operation = operation  # type: str

class NotNode(BaseNode):
    def __init__(self, token: Token[TV_TokenTypes], value: BaseNode):
        super().__init__(token.lineno, token.colno, token.filename)
        self.value = value  # type: BaseNode

class CodeBlockNode(BaseNode):
    def __init__(self, token: Token[TV_TokenTypes]):
        super().__init__(token.lineno, token.colno, token.filename)
        self.lines = []  # type: T.List[BaseNode]

class IndexNode(BaseNode):
    def __init__(self, iobject: BaseNode, index: BaseNode):
        super().__init__(iobject.lineno, iobject.colno, iobject.filename)
        self.iobject = iobject  # type: BaseNode
        self.index = index      # type: BaseNode

class MethodNode(BaseNode):
    def __init__(self, filename: str, lineno: int, colno: int, source_object: BaseNode, name: str, args: ArgumentNode):
        super().__init__(lineno, colno, filename)
        self.source_object = source_object  # type: BaseNode
        self.name = name                    # type: str
        assert(isinstance(self.name, str))
        self.args = args                    # type: ArgumentNode

class FunctionNode(BaseNode):
    def __init__(self, filename: str, lineno: int, colno: int, end_lineno: int, end_colno: int, func_name: str, args: ArgumentNode):
        super().__init__(lineno, colno, filename, end_lineno=end_lineno, end_colno=end_colno)
        self.func_name = func_name  # type: str
        assert(isinstance(func_name, str))
        self.args = args  # type: ArgumentNode

class AssignmentNode(BaseNode):
    def __init__(self, filename: str, lineno: int, colno: int, var_name: str, value: BaseNode):
        super().__init__(lineno, colno, filename)
        self.var_name = var_name  # type: str
        assert(isinstance(var_name, str))
        self.value = value  # type: BaseNode

class PlusAssignmentNode(BaseNode):
    def __init__(self, filename: str, lineno: int, colno: int, var_name: str, value: BaseNode):
        super().__init__(lineno, colno, filename)
        self.var_name = var_name  # type: str
        assert(isinstance(var_name, str))
        self.value = value  # type: BaseNode

class ForeachClauseNode(BaseNode):
    def __init__(self, token: Token, varnames: T.List[str], items: BaseNode, block: CodeBlockNode):
        super().__init__(token.lineno, token.colno, token.filename)
        self.varnames = varnames  # type: T.List[str]
        self.items = items        # type: BaseNode
        self.block = block        # type: CodeBlockNode

class IfNode(BaseNode):
    def __init__(self, linenode: BaseNode, condition: BaseNode, block: CodeBlockNode):
        super().__init__(linenode.lineno, linenode.colno, linenode.filename)
        self.condition = condition  # type: BaseNode
        self.block = block          # type: CodeBlockNode

class IfClauseNode(BaseNode):
    def __init__(self, linenode: BaseNode):
        super().__init__(linenode.lineno, linenode.colno, linenode.filename)
        self.ifs = []          # type: T.List[IfNode]
        self.elseblock = None  # type: T.Union[EmptyNode, CodeBlockNode]

class UMinusNode(BaseNode):
    def __init__(self, current_location: Token, value: BaseNode):
        super().__init__(current_location.lineno, current_location.colno, current_location.filename)
        self.value = value  # type: BaseNode

class TernaryNode(BaseNode):
    def __init__(self, condition: BaseNode, trueblock: BaseNode, falseblock: BaseNode):
        super().__init__(condition.lineno, condition.colno, condition.filename)
        self.condition = condition    # type: BaseNode
        self.trueblock = trueblock    # type: BaseNode
        self.falseblock = falseblock  # type: BaseNode

comparison_map = {'equal': '==',
                  'nequal': '!=',
                  'lt': '<',
                  'le': '<=',
                  'gt': '>',
                  'ge': '>=',
                  'in': 'in',
                  'notin': 'not in',
                  }

# Recursive descent parser for Meson's definition language.
# Very basic apart from the fact that we have many precedence
# levels so there are not enough words to describe them all.
# Enter numbering:
#
# 1 assignment
# 2 or
# 3 and
# 4 comparison
# 5 arithmetic
# 6 negation
# 7 funcall, method call
# 8 parentheses
# 9 plain token

class Parser:
    def __init__(self, code: str, filename: str):
        self.lexer = Lexer(code)
        self.stream = self.lexer.lex(filename)
        self.current = Token('eof', '', 0, 0, 0, (0, 0), None)  # type: Token
        self.getsym()
        self.in_ternary = False

    def getsym(self) -> None:
        try:
            self.current = next(self.stream)
        except StopIteration:
            self.current = Token('eof', '', self.current.line_start, self.current.lineno, self.current.colno + self.current.bytespan[1] - self.current.bytespan[0], (0, 0), None)

    def getline(self) -> str:
        return self.lexer.getline(self.current.line_start)

    def accept(self, s: str) -> bool:
        if self.current.tid == s:
            self.getsym()
            return True
        return False

    def accept_any(self, tids: T.Sequence[str]) -> str:
        tid = self.current.tid
        if tid in tids:
            self.getsym()
            return tid
        return ''

    def expect(self, s: str) -> bool:
        if self.accept(s):
            return True
        raise ParseException(f'Expecting {s} got {self.current.tid}.', self.getline(), self.current.lineno, self.current.colno)

    def block_expect(self, s: str, block_start: Token) -> bool:
        if self.accept(s):
            return True
        raise BlockParseException(f'Expecting {s} got {self.current.tid}.', self.getline(), self.current.lineno, self.current.colno, self.lexer.getline(block_start.line_start), block_start.lineno, block_start.colno)

    def parse(self) -> CodeBlockNode:
        block = self.codeblock()
        self.expect('eof')
        return block

    def statement(self) -> BaseNode:
        return self.e1()

    def e1(self) -> BaseNode:
        left = self.e2()
        if self.accept('plusassign'):
            value = self.e1()
            if not isinstance(left, IdNode):
                raise ParseException('Plusassignment target must be an id.', self.getline(), left.lineno, left.colno)
            assert isinstance(left.value, str)
            return PlusAssignmentNode(left.filename, left.lineno, left.colno, left.value, value)
        elif self.accept('assign'):
            value = self.e1()
            if not isinstance(left, IdNode):
                raise ParseException('Assignment target must be an id.',
                                     self.getline(), left.lineno, left.colno)
            assert isinstance(left.value, str)
            return AssignmentNode(left.filename, left.lineno, left.colno, left.value, value)
        elif self.accept('questionmark'):
            if self.in_ternary:
                raise ParseException('Nested ternary operators are not allowed.',
                                     self.getline(), left.lineno, left.colno)
            self.in_ternary = True
            trueblock = self.e1()
            self.expect('colon')
            falseblock = self.e1()
            self.in_ternary = False
            return TernaryNode(left, trueblock, falseblock)
        return left

    def e2(self) -> BaseNode:
        left = self.e3()
        while self.accept('or'):
            if isinstance(left, EmptyNode):
                raise ParseException('Invalid or clause.',
                                     self.getline(), left.lineno, left.colno)
            left = OrNode(left, self.e3())
        return left

    def e3(self) -> BaseNode:
        left = self.e4()
        while self.accept('and'):
            if isinstance(left, EmptyNode):
                raise ParseException('Invalid and clause.',
                                     self.getline(), left.lineno, left.colno)
            left = AndNode(left, self.e4())
        return left

    def e4(self) -> BaseNode:
        left = self.e5()
        for nodename, operator_type in comparison_map.items():
            if self.accept(nodename):
                return ComparisonNode(operator_type, left, self.e5())
        if self.accept('not') and self.accept('in'):
            return ComparisonNode('notin', left, self.e5())
        return left

    def e5(self) -> BaseNode:
        return self.e5addsub()

    def e5addsub(self) -> BaseNode:
        op_map = {
            'plus': 'add',
            'dash': 'sub',
        }
        left = self.e5muldiv()
        while True:
            op = self.accept_any(tuple(op_map.keys()))
            if op:
                left = ArithmeticNode(op_map[op], left, self.e5muldiv())
            else:
                break
        return left

    def e5muldiv(self) -> BaseNode:
        op_map = {
            'percent': 'mod',
            'star': 'mul',
            'fslash': 'div',
        }
        left = self.e6()
        while True:
            op = self.accept_any(tuple(op_map.keys()))
            if op:
                left = ArithmeticNode(op_map[op], left, self.e6())
            else:
                break
        return left

    def e6(self) -> BaseNode:
        if self.accept('not'):
            return NotNode(self.current, self.e7())
        if self.accept('dash'):
            return UMinusNode(self.current, self.e7())
        return self.e7()

    def e7(self) -> BaseNode:
        left = self.e8()
        block_start = self.current
        if self.accept('lparen'):
            args = self.args()
            self.block_expect('rparen', block_start)
            if not isinstance(left, IdNode):
                raise ParseException('Function call must be applied to plain id',
                                     self.getline(), left.lineno, left.colno)
            assert isinstance(left.value, str)
            left = FunctionNode(left.filename, left.lineno, left.colno, self.current.lineno, self.current.colno, left.value, args)
        go_again = True
        while go_again:
            go_again = False
            if self.accept('dot'):
                go_again = True
                left = self.method_call(left)
            if self.accept('lbracket'):
                go_again = True
                left = self.index_call(left)
        return left

    def e8(self) -> BaseNode:
        block_start = self.current
        if self.accept('lparen'):
            e = self.statement()
            self.block_expect('rparen', block_start)
            return e
        elif self.accept('lbracket'):
            args = self.args()
            self.block_expect('rbracket', block_start)
            return ArrayNode(args, block_start.lineno, block_start.colno, self.current.lineno, self.current.colno)
        elif self.accept('lcurl'):
            key_values = self.key_values()
            self.block_expect('rcurl', block_start)
            return DictNode(key_values, block_start.lineno, block_start.colno, self.current.lineno, self.current.colno)
        else:
            return self.e9()

    def e9(self) -> BaseNode:
        t = self.current
        if self.accept('true'):
            t.value = True
            return BooleanNode(t)
        if self.accept('false'):
            t.value = False
            return BooleanNode(t)
        if self.accept('id'):
            return IdNode(t)
        if self.accept('number'):
            return NumberNode(t)
        if self.accept('string'):
            return StringNode(t)
        if self.accept('fstring'):
            return FormatStringNode(t)
        return EmptyNode(self.current.lineno, self.current.colno, self.current.filename)

    def key_values(self) -> ArgumentNode:
        s = self.statement()  # type: BaseNode
        a = ArgumentNode(self.current)

        while not isinstance(s, EmptyNode):
            if self.accept('colon'):
                a.set_kwarg_no_check(s, self.statement())
                potential = self.current
                if not self.accept('comma'):
                    return a
                a.commas.append(potential)
            else:
                raise ParseException('Only key:value pairs are valid in dict construction.',
                                     self.getline(), s.lineno, s.colno)
            s = self.statement()
        return a

    def args(self) -> ArgumentNode:
        s = self.statement()  # type: BaseNode
        a = ArgumentNode(self.current)

        while not isinstance(s, EmptyNode):
            potential = self.current
            if self.accept('comma'):
                a.commas.append(potential)
                a.append(s)
            elif self.accept('colon'):
                if not isinstance(s, IdNode):
                    raise ParseException('Dictionary key must be a plain identifier.',
                                         self.getline(), s.lineno, s.colno)
                a.set_kwarg(s, self.statement())
                potential = self.current
                if not self.accept('comma'):
                    return a
                a.commas.append(potential)
            else:
                a.append(s)
                return a
            s = self.statement()
        return a

    def method_call(self, source_object: BaseNode) -> MethodNode:
        methodname = self.e9()
        if not(isinstance(methodname, IdNode)):
            raise ParseException('Method name must be plain id',
                                 self.getline(), self.current.lineno, self.current.colno)
        assert isinstance(methodname.value, str)
        self.expect('lparen')
        args = self.args()
        self.expect('rparen')
        method = MethodNode(methodname.filename, methodname.lineno, methodname.colno, source_object, methodname.value, args)
        if self.accept('dot'):
            return self.method_call(method)
        return method

    def index_call(self, source_object: BaseNode) -> IndexNode:
        index_statement = self.statement()
        self.expect('rbracket')
        return IndexNode(source_object, index_statement)

    def foreachblock(self) -> ForeachClauseNode:
        t = self.current
        self.expect('id')
        assert isinstance(t.value, str)
        varname = t
        varnames = [t.value]  # type: T.List[str]

        if self.accept('comma'):
            t = self.current
            self.expect('id')
            assert isinstance(t.value, str)
            varnames.append(t.value)

        self.expect('colon')
        items = self.statement()
        block = self.codeblock()
        return ForeachClauseNode(varname, varnames, items, block)

    def ifblock(self) -> IfClauseNode:
        condition = self.statement()
        clause = IfClauseNode(condition)
        self.expect('eol')
        block = self.codeblock()
        clause.ifs.append(IfNode(clause, condition, block))
        self.elseifblock(clause)
        clause.elseblock = self.elseblock()
        return clause

    def elseifblock(self, clause: IfClauseNode) -> None:
        while self.accept('elif'):
            s = self.statement()
            self.expect('eol')
            b = self.codeblock()
            clause.ifs.append(IfNode(s, s, b))

    def elseblock(self) -> T.Union[CodeBlockNode, EmptyNode]:
        if self.accept('else'):
            self.expect('eol')
            return self.codeblock()
        return EmptyNode(self.current.lineno, self.current.colno, self.current.filename)

    def line(self) -> BaseNode:
        block_start = self.current
        if self.current == 'eol':
            return EmptyNode(self.current.lineno, self.current.colno, self.current.filename)
        if self.accept('if'):
            ifblock = self.ifblock()
            self.block_expect('endif', block_start)
            return ifblock
        if self.accept('foreach'):
            forblock = self.foreachblock()
            self.block_expect('endforeach', block_start)
            return forblock
        if self.accept('continue'):
            return ContinueNode(self.current)
        if self.accept('break'):
            return BreakNode(self.current)
        return self.statement()

    def codeblock(self) -> CodeBlockNode:
        block = CodeBlockNode(self.current)
        cond = True
        while cond:
            curline = self.line()
            if not isinstance(curline, EmptyNode):
                block.lines.append(curline)
            cond = self.accept('eol')
        return block
