Python pygments lexer状态保存

2024-04-29 14:46:45 发布

您现在位置:Python中文网/ 问答频道 /正文

对以下c++文本运行pygments默认lexer:class foo{};,结果如下:

(Token.Keyword, 'class')
(Token.Text, ' ')
(Token.Name.Class, 'foo')
(Token.Punctuation, '{')
(Token.Punctuation, '}')
(Token.Punctuation, ';')

注意托克foo的类型是Token.Name.Class。在

如果我将类名改为foobar,我希望能够只在接触的令牌上运行默认lexer,在本例中是原始标记foo和{}。在

问:如何保存lexer状态,使标记化foobar{将给出类型为Token.Name.Class的标记?在

拥有这个特性可以优化大型源文件的语法高亮显示,例如,在文件中间发生了更改(用户正在键入文本)。似乎没有文档化的方法来实现这一点,也没有关于如何使用默认的pygments lexers来实现这一点的信息。在

有没有其他语法高亮显示系统支持这种行为?在

编辑:

这里有一个关于性能的例子:http://tpcg.io/ESYjiF


Tags: textname标记文本token类型pygmentsfoo
1条回答
网友
1楼 · 发布于 2024-04-29 14:46:45

从我对源代码的理解来看,你想要什么是不可能的。在

我不会挖掘并试图解释每一行相关的代码,但基本上,发生的事情如下:

  • Lexer类是^{},它继承自^{}。在
  • ^{}函数只对lexer调用get_tokens方法并处理错误。在
  • ^{}基本上解析unicode字符串中的源代码并调用self.get_tokens_unprocessed
  • ^{}由每个Lexer定义,在您的例子中,相关的方法是^{}。在
  • ^{}基本上从{a8}获取令牌并重新处理其中的一些。在

最后,^{}循环定义的标记类型(类似于(("function", ('pattern-to-find-c-function',)), ("class", ('function-to-find-c-class',)))),对于每个类型(functionclasscomment…)查找源文本中的所有匹配项,然后处理下一个类型。在

这种行为使您想要的不可能实现,因为它在标记类型上循环,而不是在文本上循环。在


为了使我的观点更加明显,我在lib中添加了2行代码,file: ^{}, line: 628

for rexmatch, action, new_state in statetokens:
    print('looking for {}'.format(action))
    m = rexmatch(text, pos)
    print('found: {}'.format(m))

用这个代码运行它:

^{pr2}$

输出:

[...]
looking for Token.Keyword.Reserved
found: None
looking for Token.Name.Builtin
found: None
looking for <function bygroups.<locals>.callback at 0x7fb1f29b52f0>
found: None
looking for Token.Name
found: <_sre.SRE_Match object; span=(6, 9), match='foo'>
[...]

如您所见,令牌类型是代码迭代的对象。在


考虑到这一点和(正如Tarun Lalwani在评论中所说的)一个新字符可以破坏整个源代码结构这一事实,在每次更新时重新对整个文本进行词法分析是再好不过的了。在

相关问题 更多 >