【问题标题】:Pygments lexer for AspectJ用于 AspectJ 的 Pygments 词法分析器
【发布时间】:2023-03-06 06:16:02
【问题描述】:

我刚刚询问了 GitHub 上的支持人员,为什么 AspectJ (*.aj) 文件没有语法高亮显示。答案是他们正在使用 Pygments,但不知道任何现有的 AspectJ 词法分析器。我做了一个快速的网络搜索,也没有找到任何东西。有没有人在这里写过或者可以给我一个现有链接的链接?

很久以前,我为 Kconfig(Linux 内核配置)文件编写了一个词法分析器,但对我来说相当困难,因为我不会说 Python。所以在我再次开始折磨我的大脑之前,我认为我应该先问清楚,而不是重新发明轮子。

【问题讨论】:

    标签: syntax-highlighting aspectj pygments


    【解决方案1】:

    在创建了 JavaLexer 的“复制、粘贴和修改”解决方案后,因为我真的不会说 Python,我设法破解了另一个 quick'n'dirty 解决方案,它继承了 JavaLexer 的子类并将词法分析委托给它大部分。例外是

    • AspectJ 特定的关键字,
    • 处理类型间声明后跟不带空格的冒号不是作为 Java 标签,而是作为 AspectJ 关键字加上“:”运算符和
    • 将类型间注释声明作为 AspectJ 关键字处理,而不是作为 Java 名称装饰器。

    我确信我的小启发式解决方案遗漏了一些细节,但正如 Andrew Eisenberg 所说:一个不完美但可行的解决方案比一个不存在的完美解决方案要好:

    class AspectJLexer(JavaLexer):
        """
        For `AspectJ <http://www.eclipse.org/aspectj/>`_ source code.
        """
    
        name = 'AspectJ'
        aliases = ['aspectj']
        filenames = ['*.aj']
        mimetypes = ['text/x-aspectj']
    
        aj_keywords = [
            'aspect', 'pointcut', 'privileged', 'call', 'execution',
            'initialization', 'preinitialization', 'handler', 'get', 'set',
            'staticinitialization', 'target', 'args', 'within', 'withincode',
            'cflow', 'cflowbelow', 'annotation', 'before', 'after', 'around',
            'proceed', 'throwing', 'returning', 'adviceexecution', 'declare',
            'parents', 'warning', 'error', 'soft', 'precedence', 'thisJoinPoint',
            'thisJoinPointStaticPart', 'thisEnclosingJoinPointStaticPart',
            'issingleton', 'perthis', 'pertarget', 'percflow', 'percflowbelow',
            'pertypewithin', 'lock', 'unlock', 'thisAspectInstance'
        ]
        aj_inter_type = ['parents:', 'warning:', 'error:', 'soft:', 'precedence:']
        aj_inter_type_annotation = ['@type', '@method', '@constructor', '@field']
    
        def get_tokens_unprocessed(self, text):
            for index, token, value in JavaLexer.get_tokens_unprocessed(self, text):
                if token is Name and value in self.aj_keywords:
                    yield index, Keyword, value
                elif token is Name.Label and value in self.aj_inter_type:
                    yield index, Keyword, value[:-1]
                    yield index, Operator, value[-1]
                elif token is Name.Decorator and value in self.aj_inter_type_annotation:
                    yield index, Keyword, value
                else:
                    yield index, token, value
    

    【讨论】:

    • 我为此代码创建了一个 Pygments fork + pull request
    • 更新:我的词法分析器的拉取请求已被接受,因此预计在下一版本的 Pygments 中会突出显示 AspectJ。 :)
    【解决方案2】:

    如果您从 Java 词法分析器开始,aspectj 的语法高亮应该很容易实现。词法分析器将与 Java 相同,但有一些额外的关键字。

    有关 AspectJ 特定关键字的列表,请参见此处: http://git.eclipse.org/c/ajdt/org.eclipse.ajdt.git/tree/org.eclipse.ajdt.core/src/org/eclipse/ajdt/core/AspectJPlugin.java

    这里是 Java 关键字: http://git.eclipse.org/c/ajdt/org.eclipse.ajdt.git/tree/org.eclipse.ajdt.ui/src/org/eclipse/ajdt/internal/ui/editor/AspectJCodeScanner.java

    【讨论】:

    • 语法高亮不仅仅是过滤关键字。 AspectJ 具有用于切入点和建议的特殊语法。但是您的链接是一个好的开始,因为我同意仅通过几个关键字扩展 Java 词法分析器的启发式、不完美的词法分析器总比没有好。所以我有空的时候可能会试一试。感谢您的链接。 P.S.:知道您是 AJDT 提交者,我无意向您讲授 AspectJ 语法。你比我清楚得多。 ;-)
    • 简单和足够好比完美和不存在要好得多。即使只是复制 Java 词法分析器而不做任何更改也总比没有好。仅使用词法分析器,您只能做很多事情。为了让事情变得完美,你需要一个完整的解析器。
    • 我刚刚做到了。这很简单,看起来不错。我把结果发给了 GitHub 的人。稍后我可能还会为 Pygments 维护者创建一个 fork + pull 请求。
    • 这有点过时了,但是在查看您的课程AspectJCodeScanner 时,我注意到您将@type@method@field 列为关键字,但没有@constructor。这是一个错误还是你故意这样做的?
    • 哈!不错的收获。这段代码在我到达 AJDT 之前就已经写好了,我从来没有注意到它。鉴于没有人对此提出错误,我认为@constructor 的使用并不频繁。
    猜你喜欢
    • 1970-01-01
    • 2018-11-29
    • 2012-07-09
    • 1970-01-01
    • 2022-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多