class DelphiLexer(Lexer): """ For Delphi (Borland Object Pascal),
Turbo Pascal and Free Pascal source code.
Additional options accepted:
`turbopascal`
Highlight Turbo Pascal specific keywords (default: ``True``).
`delphi`
Highlight Borland Delphi specific keywords (default: ``True``).
`freepascal`
Highlight Free Pascal specific keywords (default: ``True``).
`units`
A list of units that should be considered builtin, supported are
``System``, ``SysUtils``, ``Classes`` and ``Math``.
Default is to consider all of them builtin. """
name = 'Delphi'
aliases = ['delphi', 'pas', 'pascal', 'objectpascal']
filenames = ['*.pas', '*.dpr']
mimetypes = ['text/x-pascal']
url = 'https://www.embarcadero.com/products/delphi'
version_added = ''
# XXX: those aren't global. but currently we know no way for defining # them just for the type context.
DIRECTIVES = { 'absolute', 'abstract', 'assembler', 'cppdecl', 'default', 'far', 'far16', 'forward', 'index', 'oldfpccall', 'private', 'protected', 'published', 'public'
}
if get_bool_opt(options, 'turbopascal', True):
self.keywords.update(self.TURBO_PASCAL_KEYWORDS) if get_bool_opt(options, 'delphi', True):
self.keywords.update(self.DELPHI_KEYWORDS) if get_bool_opt(options, 'freepascal', True):
self.keywords.update(self.FREE_PASCAL_KEYWORDS) for unit in get_list_opt(options, 'units', list(self.BUILTIN_UNITS)):
self.builtins.update(self.BUILTIN_UNITS[unit])
if stack[-1] == 'initial': if scanner.scan(r'\s+'):
token = Whitespace elifnot self.is_portugol and scanner.scan(r'\{.*?\}|\(\*.*?\*\)'): if scanner.match.startswith('$'):
token = Comment.Preproc else:
token = Comment.Multiline elif scanner.scan(r'//.*?$'):
token = Comment.Single elif self.is_portugol and scanner.scan(r'(<\-)|(>=)|(<=)|%|<|>|-|\+|\*|\=|(<>)|\/|\.|:|,'):
token = Operator elifnot self.is_portugol and scanner.scan(r'[-+*\/=<>:;,.@\^]'):
token = Operator # stop label highlighting on next ";" if collect_labels and scanner.match == ';':
collect_labels = False elif scanner.scan(r'[\(\)\[\]]+'):
token = Punctuation # abort function naming ``foo = Function(...)``
next_token_is_function = False # if we are in a function block we count the open # braces because ootherwise it's impossible to # determine the end of the modifier context if in_function_block or in_property_block: if scanner.match == '(':
brace_balance[0] += 1 elif scanner.match == ')':
brace_balance[0] -= 1 elif scanner.match == '[':
brace_balance[1] += 1 elif scanner.match == ']':
brace_balance[1] -= 1 elif scanner.scan(r'[A-Za-z_][A-Za-z_0-9]*'):
lowercase_name = scanner.match.lower() if lowercase_name == 'result':
token = Name.Builtin.Pseudo elif lowercase_name in self.keywords:
token = Keyword # if we are in a special block and a # block ending keyword occurs (and the parenthesis # is balanced) we end the current block context if self.is_portugol: if lowercase_name in ('funcao', 'procedimento'):
in_function_block = True
next_token_is_function = True else: if (in_function_block or in_property_block) and \
lowercase_name in self.BLOCK_KEYWORDS and \
brace_balance[0] <= 0 and \
brace_balance[1] <= 0:
in_function_block = False
in_property_block = False
brace_balance = [0, 0]
block_labels = set() if lowercase_name in ('label', 'goto'):
collect_labels = True elif lowercase_name == 'asm':
stack.append('asm') elif lowercase_name == 'property':
in_property_block = True
next_token_is_property = True elif lowercase_name in ('procedure', 'operator', 'function', 'constructor', 'destructor'):
in_function_block = True
next_token_is_function = True # we are in a function block and the current name # is in the set of registered modifiers. highlight # it as pseudo keyword elifnot self.is_portugol and in_function_block and \
lowercase_name in self.FUNCTION_MODIFIERS:
token = Keyword.Pseudo # if we are in a property highlight some more # modifiers elifnot self.is_portugol and in_property_block and \
lowercase_name in ('read', 'write'):
token = Keyword.Pseudo
next_token_is_function = True # if the last iteration set next_token_is_function # to true we now want this name highlighted as # function. so do that and reset the state elif next_token_is_function: # Look if the next token is a dot. If yes it's # not a function, but a class name and the # part after the dot a function name ifnot self.is_portugol and scanner.test(r'\s*\.\s*'):
token = Name.Class # it's not a dot, our job is done else:
token = Name.Function
next_token_is_function = False
if self.is_portugol:
block_labels.add(scanner.match.lower())
# same for properties elifnot self.is_portugol and next_token_is_property:
token = Name.Property
next_token_is_property = False # Highlight this token as label and add it # to the list of known labels elifnot self.is_portugol and collect_labels:
token = Name.Label
block_labels.add(scanner.match.lower()) # name is in list of known labels elif lowercase_name in block_labels:
token = Name.Label elif self.is_portugol and lowercase_name in self.PORTUGOL_BUILTIN_TYPES:
token = Keyword.Type elifnot self.is_portugol and lowercase_name in self.BUILTIN_TYPES:
token = Keyword.Type elifnot self.is_portugol and lowercase_name in self.DIRECTIVES:
token = Keyword.Pseudo # builtins are just builtins if the token # before isn't a dot elifnot self.is_portugol andnot was_dot and lowercase_name in self.builtins:
token = Name.Builtin else:
token = Name elif self.is_portugol and scanner.scan(r"\""):
token = String
stack.append('string') elifnot self.is_portugol and scanner.scan(r"'"):
token = String
stack.append('string') elifnot self.is_portugol and scanner.scan(r'\#(\d+|\$[0-9A-Fa-f]+)'):
token = String.Char elifnot self.is_portugol and scanner.scan(r'\$[0-9A-Fa-f]+'):
token = Number.Hex elif scanner.scan(r'\d+(?![eE]|\.[^.])'):
token = Number.Integer elif scanner.scan(r'\d+(\.\d+([eE][+-]?\d+)?|[eE][+-]?\d+)'):
token = Number.Float else: # if the stack depth is deeper than once, pop if len(stack) > 1:
stack.pop()
scanner.get_char()
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.