我在业余时间一直在研究 Lua fslex 词法分析器,使用 ocamllex 手册作为参考。
我在尝试正确标记长字符串时遇到了一些障碍。“长字符串”由'[' ('=')* '['
和']' ('=')* ']'
标记分隔;标志的数量=
必须相同。
在第一个实现中,词法分析器似乎无法识别[[
模式,LBRACKET
尽管最长匹配规则产生了两个标记,而[=[
正确识别出变化。此外,正则表达式无法确保使用正确的结束标记,在第一次']' ('=')* ']'
捕获时停止,无论实际的长字符串“级别”如何。此外,fslex 似乎不支持正则表达式中的“as”结构。
let lualongstring = '[' ('=')* '[' ( escapeseq | [^ '\\' '[' ] )* ']' ('=')* ']'
(* ... *)
| lualongstring { (* ... *) }
| '[' { LBRACKET }
| ']' { RBRACKET }
(* ... *)
我一直在尝试用词法分析器中的另一条规则来解决这个问题:
rule tokenize = parse
(* ... *)
| '[' ('=')* '[' { longstring (getLongStringLevel(lexeme lexbuf)) lexbuf }
(* ... *)
and longstring level = parse
| ']' ('=')* ']' { (* check level, do something *) }
| _ { (* aggregate other chars *) }
(* or *)
| _ {
let c = lexbuf.LexerChar(0);
(* ... *)
}
但是我被卡住了,有两个原因:首先,我认为我不能“推动”,可以说,一旦我读完长字符串,我就不能“推动”下一条规则;其次,我不喜欢在找到正确的结束标记之前逐个字符地读取字符的想法,这使得当前的设计毫无用处。
如何在 fslex 中标记 Lua 长字符串?谢谢阅读。