在以下侏儒文本上运行c++默认的lexer:class foo{};,结果如下:
(Token.Keyword, 'class')
(Token.Text, ' ')
(Token.Name.Class, 'foo')
(Token.Punctuation, '{')
(Token.Punctuation, '}')
(Token.Punctuation, ';')注意,toke foo的类型为Token.Name.Class。
如果我将类名更改为foobar,我希望能够只在被触摸的令牌上运行默认 lexer,在本例中是原始令牌foo和{。
问:我如何保存lexer状态,以便将foobar{标记化为Token.Name.Class类型的令牌
例如,拥有此功能将优化遭受更改(用户正在键入文本)的大型源文件的语法突出显示。似乎没有记录在案的方法来做这件事,也没有关于如何使用默认的侏儒词汇来做到这一点的信息。
是否有其他语法突出显示系统支持此行为?
编辑:
关于性能,这里有一个例子:http://tpcg.io/ESYjiF
发布于 2018-06-23 15:57:25
根据我对源代码的理解,您想要的是不可能的。
我不会挖掘和尝试解释每一行相关的代码,但基本上,下面是所发生的事情:
pygments.lexers.c_cpp.CLexer,它继承自pygments.lexer.RegexLexer。pygments.lex(lexer, code)函数只会调用lexer上的get_tokens方法并处理错误。lexer.get_tokens基本上是用unicode字符串解析源代码并调用self.get_tokens_unprocessed。get_tokens_unprocessed由每个词表定义,在您的例子中,相关的方法是pygments.lexers.c_cpp.CFamilyLexer.get_tokens_unprocessed。CFamilyLexer.get_tokens_unprocessed基本上从RegexLexer.get_tokens_unprocessed获取令牌并重新处理其中的一些令牌。最后,对定义的令牌类型(类似于RegexLexer.get_tokens_unprocessed )和每种类型(function、class、comment.)进行循环。在源文本中查找所有匹配项,然后处理下一个类型。
这种行为使您想要的东西变得不可能,因为它循环在令牌类型上,而不是在文本上。
为了更清楚地说明我的观点,我在库,线路: 628中添加了2行代码
for rexmatch, action, new_state in statetokens:
print('looking for {}'.format(action))
m = rexmatch(text, pos)
print('found: {}'.format(m))并使用以下代码运行它:
import pygments
import pygments.lexers
lexer = pygments.lexers.get_lexer_for_filename("foo.h")
sample="""
class foo{};
"""
print(list(lexer.get_tokens(sample)))输出:
[...]
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'>
[...]如您所见,标记类型是代码迭代的内容。
考虑到这一点(就像塔伦·拉瓦尼在评论中说的那样),一个新字符可以破坏整个源代码结构,在每次更新时重新定义整个文本是最好的选择。
https://stackoverflow.com/questions/50943417
复制相似问题