Module refinery.lib.scripts.vba.token

Expand source code Browse git
from __future__ import annotations

import enum

from dataclasses import dataclass


class VbaTokenKind(enum.Enum):
    INTEGER        = 'integer'     # noqa
    FLOAT          = 'float'       # noqa
    STRING         = 'string'      # noqa
    DATE_LITERAL   = 'date'        # noqa
    BOOLEAN_TRUE   = 'true'        # noqa
    BOOLEAN_FALSE  = 'false'       # noqa

    IDENTIFIER     = 'identifier'  # noqa

    SUB            = 'sub'         # noqa
    FUNCTION       = 'function'    # noqa
    END            = 'end'         # noqa
    IF             = 'if'          # noqa
    THEN           = 'then'        # noqa
    ELSE           = 'else'        # noqa
    ELSEIF         = 'elseif'      # noqa
    FOR            = 'for'         # noqa
    TO             = 'to'          # noqa
    STEP           = 'step'        # noqa
    NEXT           = 'next'        # noqa
    DO             = 'do'          # noqa
    LOOP           = 'loop'        # noqa
    WHILE          = 'while'       # noqa
    WEND           = 'wend'        # noqa
    UNTIL          = 'until'       # noqa
    SELECT         = 'select'      # noqa
    CASE           = 'case'        # noqa
    WITH           = 'with'        # noqa
    SET            = 'set'         # noqa
    LET            = 'let'         # noqa
    DIM            = 'dim'         # noqa
    REDIM          = 'redim'       # noqa
    PUBLIC         = 'public'      # noqa
    PRIVATE        = 'private'     # noqa
    STATIC         = 'static'      # noqa
    CONST          = 'const'       # noqa
    AS             = 'as'          # noqa
    NEW            = 'new'         # noqa
    BYVAL          = 'byval'       # noqa
    BYREF          = 'byref'       # noqa
    OPTIONAL       = 'optional'    # noqa
    PARAMARRAY     = 'paramarray'  # noqa
    CALL           = 'call'        # noqa
    GOTO           = 'goto'        # noqa
    GOSUB          = 'gosub'       # noqa
    RETURN         = 'return'      # noqa
    EXIT           = 'exit'        # noqa
    ON             = 'on'          # noqa
    ERROR          = 'error'       # noqa
    RESUME         = 'resume'      # noqa
    OPTION         = 'option'      # noqa
    DECLARE        = 'declare'     # noqa
    TYPE           = 'type'        # noqa
    ENUM           = 'enum'        # noqa
    CLASS          = 'class'       # noqa
    MODULE         = 'module'      # noqa
    PROPERTY       = 'property'    # noqa
    GET            = 'get'         # noqa
    NOTHING        = 'nothing'     # noqa
    NULL           = 'null'        # noqa
    EMPTY          = 'empty'       # noqa
    ME             = 'me'          # noqa
    AND            = 'and'         # noqa
    OR             = 'or'          # noqa
    NOT            = 'not'         # noqa
    XOR            = 'xor'         # noqa
    EQV            = 'eqv'         # noqa
    IMP            = 'imp'         # noqa
    MOD            = 'mod'         # noqa
    LIKE           = 'like'        # noqa
    IS             = 'is'          # noqa
    EACH           = 'each'        # noqa
    IN             = 'in'          # noqa
    PRESERVE       = 'preserve'    # noqa
    EXPLICIT       = 'explicit'    # noqa
    COMPARE        = 'compare'     # noqa
    BASE           = 'base'        # noqa
    ERASE          = 'erase'       # noqa
    STOP           = 'stop'        # noqa
    DEBUG          = 'debug'       # noqa
    PRINT          = 'print'       # noqa
    EVENT          = 'event'       # noqa
    RAISEEVENT     = 'raiseevent'  # noqa
    IMPLEMENTS     = 'implements'  # noqa
    LIB            = 'lib'         # noqa
    ALIAS          = 'alias'       # noqa
    WITHEVENTS     = 'withevents'  # noqa
    TYPEOF         = 'typeof'      # noqa

    PLUS           = '+'           # noqa
    MINUS          = '-'           # noqa
    STAR           = '*'           # noqa
    SLASH          = '/'           # noqa
    BACKSLASH      = '\\'          # noqa
    CARET          = '^'           # noqa
    AMPERSAND      = '&'           # noqa
    EQ             = '='           # noqa
    NEQ            = '<>'          # noqa
    ASSIGN         = ':='          # noqa
    LT             = '<'           # noqa
    GT             = '>'           # noqa
    LTE            = '<='          # noqa
    GTE            = '>='          # noqa
    DOT            = '.'           # noqa
    BANG           = '!'           # noqa

    LPAREN         = '('           # noqa
    RPAREN         = ')'           # noqa
    COMMA          = ','           # noqa
    SEMICOLON      = ';'           # noqa
    COLON          = ':'           # noqa

    NEWLINE        = 'newline'     # noqa
    COMMENT        = 'comment'     # noqa
    EOF            = 'eof'         # noqa

    @property
    def is_keyword(self):
        return self in _KEYWORDS_SET

    @property
    def is_comparison(self):
        return self in _COMPARISON_SET

    @property
    def is_logical(self):
        return self in _LOGICAL_SET

    @property
    def is_end_of_statement(self):
        return self in (VbaTokenKind.NEWLINE, VbaTokenKind.COLON, VbaTokenKind.EOF)


_KEYWORDS: dict[str, VbaTokenKind] = {
    'sub'        : VbaTokenKind.SUB,
    'function'   : VbaTokenKind.FUNCTION,
    'end'        : VbaTokenKind.END,
    'if'         : VbaTokenKind.IF,
    'then'       : VbaTokenKind.THEN,
    'else'       : VbaTokenKind.ELSE,
    'elseif'     : VbaTokenKind.ELSEIF,
    'for'        : VbaTokenKind.FOR,
    'to'         : VbaTokenKind.TO,
    'step'       : VbaTokenKind.STEP,
    'next'       : VbaTokenKind.NEXT,
    'do'         : VbaTokenKind.DO,
    'loop'       : VbaTokenKind.LOOP,
    'while'      : VbaTokenKind.WHILE,
    'wend'       : VbaTokenKind.WEND,
    'until'      : VbaTokenKind.UNTIL,
    'select'     : VbaTokenKind.SELECT,
    'case'       : VbaTokenKind.CASE,
    'with'       : VbaTokenKind.WITH,
    'set'        : VbaTokenKind.SET,
    'let'        : VbaTokenKind.LET,
    'dim'        : VbaTokenKind.DIM,
    'redim'      : VbaTokenKind.REDIM,
    'public'     : VbaTokenKind.PUBLIC,
    'private'    : VbaTokenKind.PRIVATE,
    'static'     : VbaTokenKind.STATIC,
    'const'      : VbaTokenKind.CONST,
    'as'         : VbaTokenKind.AS,
    'new'        : VbaTokenKind.NEW,
    'byval'      : VbaTokenKind.BYVAL,
    'byref'      : VbaTokenKind.BYREF,
    'optional'   : VbaTokenKind.OPTIONAL,
    'paramarray' : VbaTokenKind.PARAMARRAY,
    'call'       : VbaTokenKind.CALL,
    'goto'       : VbaTokenKind.GOTO,
    'gosub'      : VbaTokenKind.GOSUB,
    'return'     : VbaTokenKind.RETURN,
    'exit'       : VbaTokenKind.EXIT,
    'on'         : VbaTokenKind.ON,
    'error'      : VbaTokenKind.ERROR,
    'resume'     : VbaTokenKind.RESUME,
    'option'     : VbaTokenKind.OPTION,
    'declare'    : VbaTokenKind.DECLARE,
    'type'       : VbaTokenKind.TYPE,
    'enum'       : VbaTokenKind.ENUM,
    'class'      : VbaTokenKind.CLASS,
    'module'     : VbaTokenKind.MODULE,
    'property'   : VbaTokenKind.PROPERTY,
    'get'        : VbaTokenKind.GET,
    'nothing'    : VbaTokenKind.NOTHING,
    'null'       : VbaTokenKind.NULL,
    'empty'      : VbaTokenKind.EMPTY,
    'me'         : VbaTokenKind.ME,
    'and'        : VbaTokenKind.AND,
    'or'         : VbaTokenKind.OR,
    'not'        : VbaTokenKind.NOT,
    'xor'        : VbaTokenKind.XOR,
    'eqv'        : VbaTokenKind.EQV,
    'imp'        : VbaTokenKind.IMP,
    'mod'        : VbaTokenKind.MOD,
    'like'       : VbaTokenKind.LIKE,
    'is'         : VbaTokenKind.IS,
    'each'       : VbaTokenKind.EACH,
    'in'         : VbaTokenKind.IN,
    'preserve'   : VbaTokenKind.PRESERVE,
    'explicit'   : VbaTokenKind.EXPLICIT,
    'compare'    : VbaTokenKind.COMPARE,
    'base'       : VbaTokenKind.BASE,
    'erase'      : VbaTokenKind.ERASE,
    'stop'       : VbaTokenKind.STOP,
    'debug'      : VbaTokenKind.DEBUG,
    'print'      : VbaTokenKind.PRINT,
    'true'       : VbaTokenKind.BOOLEAN_TRUE,
    'false'      : VbaTokenKind.BOOLEAN_FALSE,
    'event'      : VbaTokenKind.EVENT,
    'raiseevent' : VbaTokenKind.RAISEEVENT,
    'implements' : VbaTokenKind.IMPLEMENTS,
    'lib'        : VbaTokenKind.LIB,
    'alias'      : VbaTokenKind.ALIAS,
    'withevents' : VbaTokenKind.WITHEVENTS,
    'typeof'     : VbaTokenKind.TYPEOF,
}

_KEYWORDS_SET = frozenset(_KEYWORDS.values())

_COMPARISON_SET = frozenset({
    VbaTokenKind.EQ,
    VbaTokenKind.NEQ,
    VbaTokenKind.LT,
    VbaTokenKind.GT,
    VbaTokenKind.LTE,
    VbaTokenKind.GTE,
    VbaTokenKind.IS,
    VbaTokenKind.LIKE,
})

_LOGICAL_SET = frozenset({
    VbaTokenKind.AND,
    VbaTokenKind.OR,
    VbaTokenKind.XOR,
    VbaTokenKind.EQV,
    VbaTokenKind.IMP,
    VbaTokenKind.NOT,
})

_TYPE_SUFFIX_MAP: dict[str, str] = {
    '%' : 'Integer',
    '&' : 'Long',
    '!' : 'Single',
    '#' : 'Double',
    '@' : 'Currency',
    '$' : 'String',
}


@dataclass
class VbaToken:
    kind: VbaTokenKind
    value: str
    offset: int

    def __repr__(self):
        v = self.value
        if len(v) > 40:
            v = v[:37] + '...'
        return F'Token({self.kind.name}, {v!r}, @{self.offset})'

Classes

class VbaTokenKind (*args, **kwds)

Create a collection of name/value pairs.

Example enumeration:

>>> class Color(Enum):
...     RED = 1
...     BLUE = 2
...     GREEN = 3

Access them by:

  • attribute access:

Color.RED

  • value lookup:

Color(1)

  • name lookup:

Color['RED']

Enumerations can be iterated over, and know how many members they have:

>>> len(Color)
3
>>> list(Color)
[<Color.RED: 1>, <Color.BLUE: 2>, <Color.GREEN: 3>]

Methods can be added to enumerations, and members can have their own attributes – see the documentation for details.

Expand source code Browse git
class VbaTokenKind(enum.Enum):
    INTEGER        = 'integer'     # noqa
    FLOAT          = 'float'       # noqa
    STRING         = 'string'      # noqa
    DATE_LITERAL   = 'date'        # noqa
    BOOLEAN_TRUE   = 'true'        # noqa
    BOOLEAN_FALSE  = 'false'       # noqa

    IDENTIFIER     = 'identifier'  # noqa

    SUB            = 'sub'         # noqa
    FUNCTION       = 'function'    # noqa
    END            = 'end'         # noqa
    IF             = 'if'          # noqa
    THEN           = 'then'        # noqa
    ELSE           = 'else'        # noqa
    ELSEIF         = 'elseif'      # noqa
    FOR            = 'for'         # noqa
    TO             = 'to'          # noqa
    STEP           = 'step'        # noqa
    NEXT           = 'next'        # noqa
    DO             = 'do'          # noqa
    LOOP           = 'loop'        # noqa
    WHILE          = 'while'       # noqa
    WEND           = 'wend'        # noqa
    UNTIL          = 'until'       # noqa
    SELECT         = 'select'      # noqa
    CASE           = 'case'        # noqa
    WITH           = 'with'        # noqa
    SET            = 'set'         # noqa
    LET            = 'let'         # noqa
    DIM            = 'dim'         # noqa
    REDIM          = 'redim'       # noqa
    PUBLIC         = 'public'      # noqa
    PRIVATE        = 'private'     # noqa
    STATIC         = 'static'      # noqa
    CONST          = 'const'       # noqa
    AS             = 'as'          # noqa
    NEW            = 'new'         # noqa
    BYVAL          = 'byval'       # noqa
    BYREF          = 'byref'       # noqa
    OPTIONAL       = 'optional'    # noqa
    PARAMARRAY     = 'paramarray'  # noqa
    CALL           = 'call'        # noqa
    GOTO           = 'goto'        # noqa
    GOSUB          = 'gosub'       # noqa
    RETURN         = 'return'      # noqa
    EXIT           = 'exit'        # noqa
    ON             = 'on'          # noqa
    ERROR          = 'error'       # noqa
    RESUME         = 'resume'      # noqa
    OPTION         = 'option'      # noqa
    DECLARE        = 'declare'     # noqa
    TYPE           = 'type'        # noqa
    ENUM           = 'enum'        # noqa
    CLASS          = 'class'       # noqa
    MODULE         = 'module'      # noqa
    PROPERTY       = 'property'    # noqa
    GET            = 'get'         # noqa
    NOTHING        = 'nothing'     # noqa
    NULL           = 'null'        # noqa
    EMPTY          = 'empty'       # noqa
    ME             = 'me'          # noqa
    AND            = 'and'         # noqa
    OR             = 'or'          # noqa
    NOT            = 'not'         # noqa
    XOR            = 'xor'         # noqa
    EQV            = 'eqv'         # noqa
    IMP            = 'imp'         # noqa
    MOD            = 'mod'         # noqa
    LIKE           = 'like'        # noqa
    IS             = 'is'          # noqa
    EACH           = 'each'        # noqa
    IN             = 'in'          # noqa
    PRESERVE       = 'preserve'    # noqa
    EXPLICIT       = 'explicit'    # noqa
    COMPARE        = 'compare'     # noqa
    BASE           = 'base'        # noqa
    ERASE          = 'erase'       # noqa
    STOP           = 'stop'        # noqa
    DEBUG          = 'debug'       # noqa
    PRINT          = 'print'       # noqa
    EVENT          = 'event'       # noqa
    RAISEEVENT     = 'raiseevent'  # noqa
    IMPLEMENTS     = 'implements'  # noqa
    LIB            = 'lib'         # noqa
    ALIAS          = 'alias'       # noqa
    WITHEVENTS     = 'withevents'  # noqa
    TYPEOF         = 'typeof'      # noqa

    PLUS           = '+'           # noqa
    MINUS          = '-'           # noqa
    STAR           = '*'           # noqa
    SLASH          = '/'           # noqa
    BACKSLASH      = '\\'          # noqa
    CARET          = '^'           # noqa
    AMPERSAND      = '&'           # noqa
    EQ             = '='           # noqa
    NEQ            = '<>'          # noqa
    ASSIGN         = ':='          # noqa
    LT             = '<'           # noqa
    GT             = '>'           # noqa
    LTE            = '<='          # noqa
    GTE            = '>='          # noqa
    DOT            = '.'           # noqa
    BANG           = '!'           # noqa

    LPAREN         = '('           # noqa
    RPAREN         = ')'           # noqa
    COMMA          = ','           # noqa
    SEMICOLON      = ';'           # noqa
    COLON          = ':'           # noqa

    NEWLINE        = 'newline'     # noqa
    COMMENT        = 'comment'     # noqa
    EOF            = 'eof'         # noqa

    @property
    def is_keyword(self):
        return self in _KEYWORDS_SET

    @property
    def is_comparison(self):
        return self in _COMPARISON_SET

    @property
    def is_logical(self):
        return self in _LOGICAL_SET

    @property
    def is_end_of_statement(self):
        return self in (VbaTokenKind.NEWLINE, VbaTokenKind.COLON, VbaTokenKind.EOF)

Ancestors

  • enum.Enum

Class variables

var INTEGER

The type of the None singleton.

var FLOAT

The type of the None singleton.

var STRING

The type of the None singleton.

var DATE_LITERAL

The type of the None singleton.

var BOOLEAN_TRUE

The type of the None singleton.

var BOOLEAN_FALSE

The type of the None singleton.

var IDENTIFIER

The type of the None singleton.

var SUB

The type of the None singleton.

var FUNCTION

The type of the None singleton.

var END

The type of the None singleton.

var IF

The type of the None singleton.

var THEN

The type of the None singleton.

var ELSE

The type of the None singleton.

var ELSEIF

The type of the None singleton.

var FOR

The type of the None singleton.

var TO

The type of the None singleton.

var STEP

The type of the None singleton.

var NEXT

The type of the None singleton.

var DO

The type of the None singleton.

var LOOP

The type of the None singleton.

var WHILE

The type of the None singleton.

var WEND

The type of the None singleton.

var UNTIL

The type of the None singleton.

var SELECT

The type of the None singleton.

var CASE

The type of the None singleton.

var WITH

The type of the None singleton.

var SET

The type of the None singleton.

var LET

The type of the None singleton.

var DIM

The type of the None singleton.

var REDIM

The type of the None singleton.

var PUBLIC

The type of the None singleton.

var PRIVATE

The type of the None singleton.

var STATIC

The type of the None singleton.

var CONST

The type of the None singleton.

var AS

The type of the None singleton.

var NEW

The type of the None singleton.

var BYVAL

The type of the None singleton.

var BYREF

The type of the None singleton.

var OPTIONAL

The type of the None singleton.

var PARAMARRAY

The type of the None singleton.

var CALL

The type of the None singleton.

var GOTO

The type of the None singleton.

var GOSUB

The type of the None singleton.

var RETURN

The type of the None singleton.

var EXIT

The type of the None singleton.

var ON

The type of the None singleton.

var ERROR

The type of the None singleton.

var RESUME

The type of the None singleton.

var OPTION

The type of the None singleton.

var DECLARE

The type of the None singleton.

var TYPE

The type of the None singleton.

var ENUM

The type of the None singleton.

var CLASS

The type of the None singleton.

var MODULE

The type of the None singleton.

var PROPERTY

The type of the None singleton.

var GET

The type of the None singleton.

var NOTHING

The type of the None singleton.

var NULL

The type of the None singleton.

var EMPTY

The type of the None singleton.

var ME

The type of the None singleton.

var AND

The type of the None singleton.

var OR

The type of the None singleton.

var NOT

The type of the None singleton.

var XOR

The type of the None singleton.

var EQV

The type of the None singleton.

var IMP

The type of the None singleton.

var MOD

The type of the None singleton.

var LIKE

The type of the None singleton.

var IS

The type of the None singleton.

var EACH

The type of the None singleton.

var IN

The type of the None singleton.

var PRESERVE

The type of the None singleton.

var EXPLICIT

The type of the None singleton.

var COMPARE

The type of the None singleton.

var BASE

The type of the None singleton.

var ERASE

The type of the None singleton.

var STOP

The type of the None singleton.

var DEBUG

The type of the None singleton.

var PRINT

The type of the None singleton.

var EVENT

The type of the None singleton.

var RAISEEVENT

The type of the None singleton.

var IMPLEMENTS

The type of the None singleton.

var LIB

The type of the None singleton.

var ALIAS

The type of the None singleton.

var WITHEVENTS

The type of the None singleton.

var TYPEOF

The type of the None singleton.

var PLUS

The type of the None singleton.

var MINUS

The type of the None singleton.

var STAR

The type of the None singleton.

var SLASH

The type of the None singleton.

var BACKSLASH

The type of the None singleton.

var CARET

The type of the None singleton.

var AMPERSAND

The type of the None singleton.

var EQ

The type of the None singleton.

var NEQ

The type of the None singleton.

var ASSIGN

The type of the None singleton.

var LT

The type of the None singleton.

var GT

The type of the None singleton.

var LTE

The type of the None singleton.

var GTE

The type of the None singleton.

var DOT

The type of the None singleton.

var BANG

The type of the None singleton.

var LPAREN

The type of the None singleton.

var RPAREN

The type of the None singleton.

var COMMA

The type of the None singleton.

var SEMICOLON

The type of the None singleton.

var COLON

The type of the None singleton.

var NEWLINE

The type of the None singleton.

var COMMENT

The type of the None singleton.

var EOF

The type of the None singleton.

Instance variables

var is_keyword
Expand source code Browse git
@property
def is_keyword(self):
    return self in _KEYWORDS_SET
var is_comparison
Expand source code Browse git
@property
def is_comparison(self):
    return self in _COMPARISON_SET
var is_logical
Expand source code Browse git
@property
def is_logical(self):
    return self in _LOGICAL_SET
var is_end_of_statement
Expand source code Browse git
@property
def is_end_of_statement(self):
    return self in (VbaTokenKind.NEWLINE, VbaTokenKind.COLON, VbaTokenKind.EOF)
class VbaToken (kind, value, offset)

VbaToken(kind: 'VbaTokenKind', value: 'str', offset: 'int')

Expand source code Browse git
@dataclass
class VbaToken:
    kind: VbaTokenKind
    value: str
    offset: int

    def __repr__(self):
        v = self.value
        if len(v) > 40:
            v = v[:37] + '...'
        return F'Token({self.kind.name}, {v!r}, @{self.offset})'

Instance variables

var kind

The type of the None singleton.

var value

The type of the None singleton.

var offset

The type of the None singleton.