大佬教程收集整理的这篇文章主要介绍了f# – 在fslex中使用Lua长字符串,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图正确地标记长字符串时遇到了一些障碍. “长串”由'[‘(‘=’)*'[‘和’]'(‘=’)*’]’标记分隔; =符号的数量必须相同.
在第一个实现中,词法分析器似乎无法识别[[模式,尽管匹配规则最长,但产生两个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); (* ... *) }
但是我被卡住了,原因有两个:第一,我不认为我可以“推”,可以说,一旦我读完长串,就会成为下一个规则的标记;第二,我不喜欢通过char读取char的想法,直到找到正确的结束标记,使得当前的设计无用.
如何在fslex中标记Lua长字符串?谢谢阅读.
我使用LexBuffer< _> .bufferLocalStore属性在lexer函数调用中保持状态,该属性只是一个可写的IDictionary实例.
注意:长括号和多行注释都使用长括号.这通常是Lua语法的一个被忽视的部分.
let beginlongbracket = '[' ('=')* '[' let endlongbracket = ']' ('=')* ']' rule tokenize = parse | beginlongbracket { longString (longBracketLevel(lexeme lexbuf)) lexbuf } (* ... *) and longString level = parse | endlongbracket { if longBracketLevel(lexeme lexbuf) = level then LUAStriNG(endLongString(lexbuf)) else longString level lexbuf } | _ { toLongString lexbuf (lexeme lexbuf); longString level lexbuf } | eof { failwith "Unexpected end of file in String." }
以下是我用来简化将数据存储到BufferLocalStore中的函数:
let longBracketLevel (str : String) = str.Count(fun c -> c = '=') let createLongStringStorage (lexbuf : LexBuffer<_>) = let sb = new StringBuilder(1000) lexbuf.bufferLocalStore.["longString"] <- box sb sb let toLongString (lexbuf : LexBuffer<_>) (c : String) = let hasString,sb = lexbuf.bufferLocalStore.TryGetValue("longString") let storage = if hasString then (sb :?> StringBuilder) else (createLongStringStorage lexbuf) storage.Append(c.[0]) |> ignore let endLongString (lexbuf : LexBuffer<_>) : String = let hasString,sb = lexbuf.bufferLocalStore.TryGetValue("longString") let ret = if not hasString then "" else (sb :?> StringBuilder).ToString() lexbuf.bufferLocalStore.Remove("longString") |> ignore ret
也许它不是很实用,但它似乎正在完成工作.
>使用tokenize规则,直到找到长括号的开头
>切换到longString规则并循环,直到找到相同级别的结束长括号
>将与同一级别的结束长括号不匹配的每个词位存储到StringBuilder中,而StringBuilder又存储在LexBuffer BufferLocalStore中.
>一旦longString结束,清除BufferLocalStore.
编辑:您可以在http://ironlua.codeplex.com找到该项目.词汇和解析应该没问题.我打算使用DLR.评论和建设性批评欢迎.
以上是大佬教程为你收集整理的f# – 在fslex中使用Lua长字符串全部内容,希望文章能够帮你解决f# – 在fslex中使用Lua长字符串所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。