Rework highlighting metadata GOD

This commit is contained in:
John Doty 2024-09-02 08:50:36 -07:00
parent e4a8ad7b76
commit 591da0c971
2 changed files with 304 additions and 111 deletions

View file

@ -1,5 +1,5 @@
# This is an example grammar.
from parser import alt, Assoc, Grammar, rule, seq, Rule, Terminal, Re, Highlight, mark, opt
from parser import alt, Assoc, Grammar, rule, seq, Rule, Terminal, Re, highlight, mark, opt
class FineGrammar(Grammar):
@ -52,7 +52,7 @@ class FineGrammar(Grammar):
def class_declaration(self) -> Rule:
return seq(
self.CLASS,
mark(self.IDENTIFIER, highlight=Highlight.Entity.Name.Type),
mark(self.IDENTIFIER, highlight=highlight.entity.name.type),
self._class_body,
)
@ -107,7 +107,7 @@ class FineGrammar(Grammar):
def function_declaration(self) -> Rule:
return seq(
self.FUN,
mark(self.IDENTIFIER, highlight=Highlight.Entity.Name.Function),
mark(self.IDENTIFIER, highlight=highlight.entity.name.function),
self.function_parameters,
opt(self.ARROW, self.type_expression),
self.block,
@ -330,32 +330,31 @@ class FineGrammar(Grammar):
BLANKS = Terminal(Re.set(" ", "\t", "\r", "\n").plus())
COMMENT = Terminal(
Re.seq(Re.literal("//"), Re.set("\n").invert().star()),
highlight=Highlight.Comment.Line,
highlight=highlight.comment.line,
)
ARROW = Terminal("->", highlight=Highlight.Keyword.Operator)
AS = Terminal("as", highlight=Highlight.Keyword.Operator.Expression)
BAR = Terminal("|", highlight=Highlight.Keyword.Operator.Expression)
CLASS = Terminal("class", highlight=Highlight.Storage.Type.Class)
COLON = Terminal(":", highlight=Highlight.Punctuation.Separator)
ELSE = Terminal("else", highlight=Highlight.Keyword.Control.Conditional)
FOR = Terminal("for", highlight=Highlight.Keyword.Control)
FUN = Terminal("fun", highlight=Highlight.Storage.Type.Function)
ARROW = Terminal("->", highlight=highlight.keyword.operator)
AS = Terminal("as", highlight=highlight.keyword.operator.expression)
BAR = Terminal("|", highlight=highlight.keyword.operator.expression)
CLASS = Terminal("class", highlight=highlight.storage.type.klass)
COLON = Terminal(":", highlight=highlight.punctuation.separator)
ELSE = Terminal("else", highlight=highlight.keyword.control.conditional)
FOR = Terminal("for", highlight=highlight.keyword.control)
FUN = Terminal("fun", highlight=highlight.storage.type.function)
IDENTIFIER = Terminal(
Re.seq(
Re.set(("a", "z"), ("A", "Z"), "_"),
Re.set(("a", "z"), ("A", "Z"), ("0", "9"), "_").star(),
),
# highlight=Highlight.Variable, #?
)
IF = Terminal("if", highlight=Highlight.Keyword.Control.Conditional)
IMPORT = Terminal("import", highlight=Highlight.Keyword.Other)
IN = Terminal("in", highlight=Highlight.Keyword.Operator)
LCURLY = Terminal("{", highlight=Highlight.Punctuation.CurlyBrace.Open)
RCURLY = Terminal("}", highlight=Highlight.Punctuation.CurlyBrace.Close)
LET = Terminal("let", highlight=Highlight.Keyword.Other)
RETURN = Terminal("return", highlight=Highlight.Keyword.Control)
SEMICOLON = Terminal(";", highlight=Highlight.Punctuation.Separator)
IF = Terminal("if", highlight=highlight.keyword.control.conditional)
IMPORT = Terminal("import", highlight=highlight.keyword.other)
IN = Terminal("in", highlight=highlight.keyword.operator)
LCURLY = Terminal("{", highlight=highlight.punctuation.curly_brace.open)
RCURLY = Terminal("}", highlight=highlight.punctuation.curly_brace.close)
LET = Terminal("let", highlight=highlight.keyword.other)
RETURN = Terminal("return", highlight=highlight.keyword.control)
SEMICOLON = Terminal(";", highlight=highlight.punctuation.separator)
STRING = Terminal(
# Double-quoted string.
Re.seq(
@ -369,27 +368,27 @@ class FineGrammar(Grammar):
(~Re.set("'", "\\") | (Re.set("\\") + Re.any())).star(),
Re.literal("'"),
),
highlight=Highlight.String.Quoted,
highlight=highlight.string.quoted,
)
WHILE = Terminal("while", highlight=Highlight.Keyword.Control)
EQUAL = Terminal("=", highlight=Highlight.Keyword.Operator.Expression)
LPAREN = Terminal("(", highlight=Highlight.Punctuation.Parenthesis.Open)
RPAREN = Terminal(")", highlight=Highlight.Punctuation.Parenthesis.Close)
COMMA = Terminal(",", highlight=Highlight.Punctuation.Separator)
SELF = Terminal("self", name="SELFF", highlight=Highlight.Variable.Language)
OR = Terminal("or", highlight=Highlight.Keyword.Operator.Expression)
IS = Terminal("is", highlight=Highlight.Keyword.Operator.Expression)
AND = Terminal("and", highlight=Highlight.Keyword.Operator.Expression)
EQUALEQUAL = Terminal("==", highlight=Highlight.Keyword.Operator.Expression)
BANGEQUAL = Terminal("!=", highlight=Highlight.Keyword.Operator.Expression)
LESS = Terminal("<", highlight=Highlight.Keyword.Operator.Expression)
GREATER = Terminal(">", highlight=Highlight.Keyword.Operator.Expression)
LESSEQUAL = Terminal("<=", highlight=Highlight.Keyword.Operator.Expression)
GREATEREQUAL = Terminal(">=", highlight=Highlight.Keyword.Operator.Expression)
PLUS = Terminal("+", highlight=Highlight.Keyword.Operator.Expression)
MINUS = Terminal("-", highlight=Highlight.Keyword.Operator.Expression)
STAR = Terminal("*", highlight=Highlight.Keyword.Operator.Expression)
SLASH = Terminal("/", highlight=Highlight.Keyword.Operator.Expression)
WHILE = Terminal("while", highlight=highlight.keyword.control)
EQUAL = Terminal("=", highlight=highlight.keyword.operator.expression)
LPAREN = Terminal("(", highlight=highlight.punctuation.parenthesis.open)
RPAREN = Terminal(")", highlight=highlight.punctuation.parenthesis.close)
COMMA = Terminal(",", highlight=highlight.punctuation.separator)
SELF = Terminal("self", name="SELFF", highlight=highlight.variable.language)
OR = Terminal("or", highlight=highlight.keyword.operator.expression)
IS = Terminal("is", highlight=highlight.keyword.operator.expression)
AND = Terminal("and", highlight=highlight.keyword.operator.expression)
EQUALEQUAL = Terminal("==", highlight=highlight.keyword.operator.expression)
BANGEQUAL = Terminal("!=", highlight=highlight.keyword.operator.expression)
LESS = Terminal("<", highlight=highlight.keyword.operator.expression)
GREATER = Terminal(">", highlight=highlight.keyword.operator.expression)
LESSEQUAL = Terminal("<=", highlight=highlight.keyword.operator.expression)
GREATEREQUAL = Terminal(">=", highlight=highlight.keyword.operator.expression)
PLUS = Terminal("+", highlight=highlight.keyword.operator.expression)
MINUS = Terminal("-", highlight=highlight.keyword.operator.expression)
STAR = Terminal("*", highlight=highlight.keyword.operator.expression)
SLASH = Terminal("/", highlight=highlight.keyword.operator.expression)
NUMBER = Terminal(
Re.seq(
Re.set(("0", "9")).plus(),
@ -403,18 +402,18 @@ class FineGrammar(Grammar):
Re.set(("0", "9")).plus(),
).question(),
),
highlight=Highlight.Constant.Numeric,
highlight=highlight.constant.numeric,
)
TRUE = Terminal("true", highlight=Highlight.Constant.Language)
FALSE = Terminal("false", highlight=Highlight.Constant.Language)
BANG = Terminal("!", highlight=Highlight.Keyword.Operator.Expression)
DOT = Terminal(".", highlight=Highlight.Punctuation.Separator)
MATCH = Terminal("match", highlight=Highlight.Keyword.Other)
EXPORT = Terminal("export", highlight=Highlight.Keyword.Other)
UNDERSCORE = Terminal("_", highlight=Highlight.Variable.Language)
NEW = Terminal("new", highlight=Highlight.Keyword.Operator)
LSQUARE = Terminal("[", highlight=Highlight.Punctuation.SquareBracket.Open)
RSQUARE = Terminal("]", highlight=Highlight.Punctuation.SquareBracket.Close)
TRUE = Terminal("true", highlight=highlight.constant.language)
FALSE = Terminal("false", highlight=highlight.constant.language)
BANG = Terminal("!", highlight=highlight.keyword.operator.expression)
DOT = Terminal(".", highlight=highlight.punctuation.separator)
MATCH = Terminal("match", highlight=highlight.keyword.other)
EXPORT = Terminal("export", highlight=highlight.keyword.other)
UNDERSCORE = Terminal("_", highlight=highlight.variable.language)
NEW = Terminal("new", highlight=highlight.keyword.operator)
LSQUARE = Terminal("[", highlight=highlight.punctuation.square_bracket.open)
RSQUARE = Terminal("]", highlight=highlight.punctuation.square_bracket.close)
if __name__ == "__main__":

View file

@ -2334,90 +2334,284 @@ def dump_lexer_table(table: LexerTable, name: str = "lexer.dot"):
# This here might be enough to produce extremely basic TextMate
# grammars but anything more complicated will want tree patterns
# anyway, and we can only do tree patterns by influencing the grammar.
#
# Here's the info on textmate grammars:
# https://macromates.com/manual/en/language_grammars
class SyntaxMeta:
pass
class Highlight(SyntaxMeta):
class Comment(SyntaxMeta):
class Block(SyntaxMeta):
pass
class HighlightMeta(SyntaxMeta):
scope: str
class Line(SyntaxMeta):
pass
def __init__(self, *scope: str):
self.scope = ".".join(scope)
class Constant(SyntaxMeta):
class Language(SyntaxMeta):
pass
class Numeric(SyntaxMeta):
pass
class CommentHighlight(HighlightMeta):
def __init__(self, *scope: str):
super().__init__("comment", *scope)
class Entity(SyntaxMeta):
class Name(SyntaxMeta):
class Function(SyntaxMeta):
pass
class Type(SyntaxMeta):
pass
class BlockCommentHighlight(CommentHighlight):
def __init__(self, *scope: str):
super().__init__("block", *scope)
class Keyword(SyntaxMeta):
class Control(SyntaxMeta):
class Conditional(SyntaxMeta):
pass
class Operator(SyntaxMeta):
class Expression(SyntaxMeta):
pass
class LineCommentHighlight(CommentHighlight):
def __init__(self, *scope: str):
super().__init__("line", *scope)
class Other(SyntaxMeta):
pass
class Punctuation(SyntaxMeta):
class Separator(SyntaxMeta):
pass
class ConstantHighlight(HighlightMeta):
def __init__(self, *scope: str):
super().__init__("constant", *scope)
class Parenthesis(SyntaxMeta):
class Open(SyntaxMeta):
pass
class Close(SyntaxMeta):
pass
class LanguageConstantHighlight(ConstantHighlight):
def __init__(self, *scope: str):
super().__init__("language", *scope)
class CurlyBrace(SyntaxMeta):
class Open(SyntaxMeta):
pass
class Close(SyntaxMeta):
pass
class NumericConstantHighlight(ConstantHighlight):
def __init__(self, *scope: str):
super().__init__("numeric", *scope)
class SquareBracket(SyntaxMeta):
class Open(SyntaxMeta):
pass
class Close(SyntaxMeta):
pass
class EntityHighlight(HighlightMeta):
def __init__(self, *scope: str):
super().__init__("entity", *scope)
class Storage(SyntaxMeta):
class Type(SyntaxMeta):
class Class(SyntaxMeta):
pass
class Function(SyntaxMeta):
pass
class NameEntityHighlight(EntityHighlight):
def __init__(self, *scope: str):
super().__init__("name", *scope)
class String(SyntaxMeta):
class Quoted(SyntaxMeta):
class Single(SyntaxMeta):
pass
class Double(SyntaxMeta):
pass
class FunctionNameEntityHighlight(NameEntityHighlight):
def __init__(self, *scope: str):
super().__init__("function", *scope)
class Variable(SyntaxMeta):
class Language(SyntaxMeta):
pass
class TypeNameEntityHighlight(NameEntityHighlight):
def __init__(self, *scope: str):
super().__init__("type", *scope)
class KeywordHighlight(HighlightMeta):
def __init__(self, *scope: str):
super().__init__("keyword", *scope)
class ControlKeywordHighlight(KeywordHighlight):
def __init__(self, *scope: str):
super().__init__("control", *scope)
class ConditionalControlKeywordHighlight(ControlKeywordHighlight):
def __init__(self, *scope: str):
super().__init__("conditional", *scope)
class OperatorKeywordHighlight(KeywordHighlight):
def __init__(self, *scope: str):
super().__init__("operator", *scope)
class ExpressionOperatorKeywordHighlight(OperatorKeywordHighlight):
def __init__(self, *scope: str):
super().__init__("expression", *scope)
class OtherKeywordHighlight(KeywordHighlight):
def __init__(self, *scope: str):
super().__init__("other", *scope)
class PunctuationHighlight(HighlightMeta):
def __init__(self, *scope: str):
super().__init__("punctuation", *scope)
class SeparatorPunctuationHighlight(PunctuationHighlight):
def __init__(self, *scope: str):
super().__init__("separator", *scope)
class ParenthesisPunctuationHighlight(PunctuationHighlight):
def __init__(self, *scope: str):
super().__init__("parenthesis", *scope)
class OpenParenthesisPunctuationHighlight(ParenthesisPunctuationHighlight):
def __init__(self, *scope: str):
super().__init__("open", *scope)
class CloseParenthesisPunctuationHighlight(ParenthesisPunctuationHighlight):
def __init__(self, *scope: str):
super().__init__("close", *scope)
class CurlyBracePunctuationHighlight(PunctuationHighlight):
def __init__(self, *scope: str):
super().__init__("curlybrace", *scope)
class OpenCurlyBracePunctuationHighlight(CurlyBracePunctuationHighlight):
def __init__(self, *scope: str):
super().__init__("open", *scope)
class CloseCurlyBracePunctuationHighlight(CurlyBracePunctuationHighlight):
def __init__(self, *scope: str):
super().__init__("close", *scope)
class SquareBracketPunctuationHighlight(PunctuationHighlight):
def __init__(self, *scope: str):
super().__init__("squarebracket", *scope)
class OpenSquareBracketPunctuationHighlight(SquareBracketPunctuationHighlight):
def __init__(self, *scope: str):
super().__init__("open", *scope)
class CloseSquareBracketPunctuationHighlight(SquareBracketPunctuationHighlight):
def __init__(self, *scope: str):
super().__init__("close", *scope)
class StorageHighlight(HighlightMeta):
def __init__(self, *scope: str):
super().__init__("storage", *scope)
class TypeStorageHighlight(StorageHighlight):
def __init__(self, *scope: str):
super().__init__("type", *scope)
class ClassTypeStorageHighlight(TypeStorageHighlight):
def __init__(self, *scope: str):
super().__init__("class", *scope)
class FunctionTypeStorageHighlight(TypeStorageHighlight):
def __init__(self, *scope: str):
super().__init__("function", *scope)
class StructTypeStorageHighlight(TypeStorageHighlight):
def __init__(self, *scope: str):
super().__init__("struct", *scope)
class StringHighlight(HighlightMeta):
def __init__(self, *scope: str):
super().__init__("string", *scope)
class QuotedStringHighlight(StringHighlight):
def __init__(self, *scope: str):
super().__init__("quoted", *scope)
class SingleQuotedStringHighlight(QuotedStringHighlight):
def __init__(self, *scope: str):
super().__init__("single", *scope)
class DoubleQuotedStringHighlight(QuotedStringHighlight):
def __init__(self, *scope: str):
super().__init__("double", *scope)
class VariableHighlight(HighlightMeta):
def __init__(self, *scope: str):
super().__init__("variable", *scope)
class LanguageVariableHighlight(VariableHighlight):
def __init__(self, *scope: str):
super().__init__("language", *scope)
class _Highlight:
class _Comment(CommentHighlight):
line = LineCommentHighlight()
class _Constant(ConstantHighlight):
language = LanguageConstantHighlight()
numeric = NumericConstantHighlight()
class _Entity(EntityHighlight):
class _Name(NameEntityHighlight):
function = FunctionNameEntityHighlight()
type = TypeNameEntityHighlight()
name = _Name()
class _Keyword(KeywordHighlight):
class _Control(ControlKeywordHighlight):
conditional = ConditionalControlKeywordHighlight()
class _Operator(OperatorKeywordHighlight):
expression = ExpressionOperatorKeywordHighlight()
control = _Control()
operator = _Operator()
other = OtherKeywordHighlight()
class _Punctuation:
class _Parenthesis:
open = OpenParenthesisPunctuationHighlight()
close = CloseParenthesisPunctuationHighlight()
class _CurlyBrace:
open = OpenCurlyBracePunctuationHighlight()
close = CloseCurlyBracePunctuationHighlight()
class _SquareBracket:
open = OpenSquareBracketPunctuationHighlight()
close = CloseSquareBracketPunctuationHighlight()
parenthesis = _Parenthesis()
curly_brace = _CurlyBrace()
square_bracket = _SquareBracket()
separator = SeparatorPunctuationHighlight()
class _Storage(StorageHighlight):
class _Type(TypeStorageHighlight):
klass = ClassTypeStorageHighlight() # Sorry.
function = FunctionTypeStorageHighlight()
struct = StructTypeStorageHighlight()
type = _Type()
class _String(StringHighlight):
class _Quoted(QuotedStringHighlight):
single = SingleQuotedStringHighlight()
double = DoubleQuotedStringHighlight()
quoted = _Quoted()
class _Variable(VariableHighlight):
language = LanguageVariableHighlight()
comment = _Comment()
constant = _Constant()
entity = _Entity()
keyword = _Keyword()
punctuation = _Punctuation()
storage = _Storage()
string = _String()
variable = _Variable()
highlight = _Highlight()
###############################################################################
# Finally, the base class for grammars