简单的 CSV 词法分析器
Posted
技术标签:
【中文标题】简单的 CSV 词法分析器【英文标题】:Simple CSV lexer 【发布时间】:2014-10-19 13:11:21 【问题描述】:我想用 pygments 为 CSV 文件着色,如下所示:
看到同一列用相同的颜色着色。
目前 pygments 不包含 CSV 解析器,因为 CSV 是 said to be obscure format。所以我试着自己写一个最小的。这是我尝试过的:
tokens =
'root': [
(r'^[^,\n]+', Name.Function), # first column
(',', Comment), # separator
(r'[^,\n]+', Name.Decorator), # second column
(',', Comment), # separator
(r'[^,\n]+', Name.Constant), # third column
(',', Comment), # separator
],
但它无法为任何列着色,但首先:
据我所知,pygments 的工作原理是尝试逐个匹配正则表达式:当当前的正则表达式不匹配时,它会转到下一个,然后重新开始。如果没有匹配项,则会发出错误并推进一个字符(并将该字符放入红色框中)。对于嵌套 cmets 等高级案例,有状态,但我认为对于 CSV,一个状态可能就足够了。
然后我尝试了:
tokens =
'root': [
(',', Comment), # separator
(r'^[^,\n]+', Name.Function), # first column
(r'(?:^[^,\n]+)[^,\n]+', Name.Decorator), # second column
],
但它会将所有列着色为第二个:
这是一个示例数据:
account_id,parent_account_id,name,status
,A001,English,active
A001,,Humanities,active
A003,A001,,active
A004,A002,Spanish,
在 Emacs 中,我设法得到了我想要的东西:
(add-hook 'csv-mode-hook
(lambda ()
"colors first 8 csv columns differently"
(font-lock-add-keywords nil '(("^\\([^,\n]*\\),"
1 'font-lock-function-name-face)))
(font-lock-add-keywords nil '(("^\\([^,\n]*\\),\\([^,\n]*\\)"
2 'font-lock-variable-name-face)))
(font-lock-add-keywords nil '(("^\\([^,\n]*\\),\\([^,\n]*\\),\\([^,\n]*\\)"
3 'font-lock-keyword-face)))
(font-lock-add-keywords nil '(("^\\([^,\n]*\\),\\([^,\n]*\\),\\([^,\n]*\\),\\([^,\n]*\\)"
4 'font-lock-type-face)))
))
(我实际上添加了超过 4 列,但这并不重要)
这给出了:
【问题讨论】:
你的第一段和第二段代码是一样的。 如果字段可以为空,您应该使用[^,\n]*
而不是[^,\n]+
。这就是您的 Emacs 版本所做的。
@AntonSavin:修复了,抱歉。
@AlanMoore:如果我这样做,它就会挂起:两种变体。
【参考方案1】:
哦,我使用状态解决了它:
tokens =
'root': [
(r'^[^,\n]*', Name.Function, 'second'),
],
'second': [
(r'(,)([^,\n]*)', bygroups(Comment, Name.Decorator), 'third'),
],
'third': [
(r'(,)([^,\n]*)', bygroups(Comment, Name.Constant), 'fourth'),
],
'fourth': [
(r'(,)([^,\n]*)', bygroups(Comment, Name.Variable), 'fifth'),
],
'fifth': [
(r'(,)([^,\n]*)', bygroups(Comment, Keyword.Type), 'unsupported'),
],
'unsupported': [
(r'.+', Comment),
],
它对前 5 个 CSV 列进行不同的着色,其他所有列作为评论:
【讨论】:
以上是关于简单的 CSV 词法分析器的主要内容,如果未能解决你的问题,请参考以下文章
编译原理-第二章 一个简单的语法指导编译器-2.2 词法分析