Exemplo n.º 1
0
def lexQuote(l: lexer) -> Optional[stateFn]:
    """lexQuote scans a quoted string."""
    while True:
        x = l.next()
        if x == '\\':
            r = l.next()
            if r != eof and r != '\n':
                break
            if x == 'eof' or x == '\n':
                raise ParseError('unterminated quoted string')
        elif x == 'eof' or x == '\n':
            raise ParseError('unterminated quoted string')
        elif x == '"':
            break
    l.emit(itemType.itemString)
    return lexInsideAction
Exemplo n.º 2
0
def lexComment(l: lexer) -> Optional[stateFn]:
    l.pos += len(leftComment)
    i = l.input[l.pos:].find(rightComment)
    if i < 0:
        raise ParseError('Unclosed comment')
    l.pos += i + len(rightComment)
    delim, trimSpace = l.atRightDelim()
    if not delim:
        raise ParseError('comment ends before closing delimiter')
    if l.emitComment:
        l.emit(itemType.itemComment)
    if trimSpace:
        l.pos += trimMarkerLen
    l.pos += len(l.rightDelim)
    if trimSpace:
        l.pos += leftTrimLength(l.input[l.pos:])
    l.ignore()
    return lexText
Exemplo n.º 3
0
def lexRawQuote(l: lexer) -> Optional[stateFn]:
    """lexRawQuote scans a raw quoted string."""
    while True:
        x = l.next()
        if x == eof:
            raise ParseError('unterminated raw quoted string')
        elif x == '`':
            break
    l.emit(itemType.itemRawString)
    return lexInsideAction
Exemplo n.º 4
0
def lexChar(l: lexer) -> Optional[stateFn]:
    """
    lexChar scans a character constant. The initial quote is already
    scanned. Syntax checking is done by the parser.
    """
    while True:
        x = l.next()
        if x == '\\':
            r = l.next()
            if r != eof and r != '\n':
                break
            if x == eof or x == '\n':
                raise ParseError('unterminated character constant')
        elif x == eof or x == '\n':
            raise ParseError('unterminated character constant')
        elif x == "'":
            break
    l.emit(itemType.itemCharConstant)
    return lexInsideAction
Exemplo n.º 5
0
def lexNumber(l: lexer) -> Optional[stateFn]:
    """
    lexNumber scans a number: decimal, octal, hex, float, or imaginary. This
    isn't a perfect number scanner - for instance it accepts "." and "0x0.2"
    and "089" - but when it's wrong the input is invalid and the parser (via
    strconv) will notice.
    """
    if not l.scanNumber():
        raise ParseError('bad number syntax: {}'.format(
            l.input[l.start:l.pos]))
    sign = l.peek()
    if sign == '+' or sign == '-':
        # Complex: 1+2i. No spaces, must end in 'i'.
        if not l.scanNumber() or l.input[l.pos - 1] != 'i':
            raise ParseError('bad number syntax: {}'.format(
                l.input[l.start:l.pos]))
        l.emit(itemType.itemComplex)
    else:
        l.emit(itemType.itemNumber)
    return lexInsideAction
Exemplo n.º 6
0
def IsEmptyTree(n: Optional[Node]) -> bool:
    if n is None:
        return True
    elif isinstance(n, ActionNode) or isinstance(n, CommentNode):
        return True
    elif isinstance(n, IfNode) or isinstance(n, ListNode):
        for node in n.Nodes:
            if not IsEmptyTree(node):
                return False
        return True
    elif isinstance(n, RangeNode) or isinstance(n, TemplateNode) or isinstance(
            n, TextNode):
        return len(n.Text.strip()) == 0
    # elif isinstance(n, WithNode):
    else:
        raise ParseError('unknown node: {}'.format(n.String()))
Exemplo n.º 7
0
def lexFieldOrVariable(l: lexer, typ: itemType) -> Optional[stateFn]:
    """
    lexVariable scans a field or variable: [.$]Alphanumeric.
    The . or $ has been scanned.
    """
    if l.atTerminator():  # Nothing interesting follows -> "." or "$".
        if typ == itemType.itemVariable:
            l.emit(itemType.itemVariable)
        else:
            l.emit(itemType.itemDot)
        return lexInsideAction
    while True:
        r = l.next()
        if not isAlphaNumeric(r):
            l.backup()
            break
    if not l.atTerminator():
        raise ParseError('bad character {}'.format(r))
    l.emit(typ)
    return lexInsideAction
Exemplo n.º 8
0
def lexIdentifier(l: lexer) -> Optional[stateFn]:
    """lexIdentifier scans an alphanumeric."""
    while True:
        r = l.next()
        if isAlphaNumeric(r):
            pass  # absorb.
        else:
            l.backup()
            word = l.input[l.start:l.pos]
            if not l.atTerminator():
                raise ParseError('bad character {}'.format(r))
            if key[word] > itemType.itemKeyword:
                l.emit(key[word])
            elif word[0] == '.':
                l.emit(itemType.itemField)
            elif word == 'true' or word == 'false':
                l.emit(itemType.itemBool)
            else:
                l.emit(itemType.itemIdentifier)
            break
    return lexInsideAction
Exemplo n.º 9
0
 def recover(self, errp: Any):
     raise ParseError('Recover not supported')
Exemplo n.º 10
0
 def errorf(self, format: str, *args: Any) -> None:
     """errorf formats the error and terminates processing."""
     self.Root = None
     format = "template: %s:%d: %s".format(self.ParseName,
                                           self.token[0].line, format)
     raise ParseError(format.format(*args))
Exemplo n.º 11
0
def lexInsideAction(l: lexer) -> Optional[stateFn]:
    """lexInsideAction scans the elements inside action delimiters."""
    # Either number, quoted string, or identifier.
    # Spaces separate arguments; runs of spaces turn into itemSpace.
    # Pipe symbols separate and are emitted.
    delim, _ = l.atRightDelim()
    if delim:
        if l.parenDepth == 0:
            return lexRightDelim
        raise ParseError('unclosed left paren')

    r = l.next()
    if r == eof:
        raise ParseError('unclosed action')
    elif isSpace(r):
        l.backup()  # Put space back in case we have " -}}".
        return lexSpace
    elif r == '=':
        l.emit(itemType.itemAssign)
    elif r == ':':
        if l.next() != '=':
            raise ParseError('expected :=')
        l.emit(itemType.itemDeclare)
    elif r == '|':
        l.emit(itemType.itemPipe)
    elif r == '"':
        return lexQuote
    elif r == '`':
        return lexRawQuote
    elif r == '$':
        return lexVariable
    elif r == "'":
        return lexChar
    elif r == '.':
        # special look-ahead for ".field" so we don't break l.backup().
        if l.pos < len(l.input):
            r = l.input[l.pos]
            if r < '0' or '9' < r:
                return lexField
        # '.' can start a number.
        if r == '+' or r == '-' or ('0' <= r and r <= '9'):
            l.backup()
            return lexNumber
    elif r == '+' or r == '-' or ('0' <= r and r <= '9'):
        l.backup()
        return lexNumber
    elif isAlphaNumeric(r):
        l.backup()
        return lexIdentifier
    elif r == '(':
        l.emit(itemType.itemLeftParen)
        l.parenDepth += 1
    elif r == ')':
        l.emit(itemType.itemRightParen)
        l.parenDepth -= 1
        if l.parenDepth < 0:
            raise ParseError('unexpected right paren {}'.format(r))
    elif r <= MaxASCII and r.isprintable():
        l.emit(itemType.itemChar)
    else:
        raise ParseError('unrecognized character in action: {}'.format(r))
    return lexInsideAction