【问题标题】:FsLex aborts with parse error on '{'FsLex 中止并在“{”上出现解析错误
【发布时间】:2016-11-11 09:50:19
【问题描述】:

我的 Lexer 应该在词法分析期间区分括号并维护一堆打开的括号。为此,我在我的 fsl 文件中指定了一个辅助函数,如下所示:

let updateBracketStack sign =  // whenever a bracket is parsed, update the stack accordingly
    match sign with
    | '[' -> push sign
    | '{' -> push sign
    | ']' -> if top() = '[' then pop() else ()
    | '}' -> if top() = '{' then pop() else ()
    | _ -> ()

堆栈当然是 char 列表的引用。并且push、top、pop都相应的实现了。

问题是在我添加{ 字符之前一切正常。现在 FsLex 简单地死于 error: parse error

如果我将字符更改为字符串,即写入"{" FsLex 再次正常,因此解决方法是将实现更改为字符串堆栈而不是字符。

但是,我的问题是,这种行为从何而来?如果 FsLex 这是一个错误吗?

【问题讨论】:

  • 您发布的代码在一个匹配分支中将top() 的结果与'['(一个字符)和另一个匹配分支中的"{"(一个字符串)进行比较。那不应该编译! top() 的返回类型可以是 charstring,但无论哪种方式,F# 编译器都应该在这两个分支之一上给您一个类型错误。您确定在粘贴此问题的代码时没有在某处出现复制粘贴错误吗?
  • 修正错字,谢谢。但是,这与问题无关。不是 F# 编译器没有编译,而是 fslex 无法接受输入并生成任何 F# 代码。

标签: f# lex fsyacc fslex


【解决方案1】:

FsLex 的解析器是使用 FsLexYacc 生成的。消息“解析错误”表示(您的 .fsl 文件的)词法分析,直到错误位置成功但在该位置解析失败。要找到根本原因,您需要将完整的输入文本发布到 FsLex。

这只是猜测。 FsLex 可能会被“{”字符混淆,因为它也是嵌入式代码块的开放标记?或者您的输入文本包含一些特殊的 Unicode 字符,但在编辑器上看起来像空格?

一种可能的解决方法是,在 LexHelper.fs 中创建另一个模块和 .fs 文件,即 LexHelper 模块,并将您的辅助函数放入其中,然后从 .fsl 文件中打开它。

编辑

查看 FsLexYacc 的源代码,它不处理嵌入式 F# 代码中用单引号括起来的 } 字符,但在用双引号括起来时可以。

https://github.com/fsprojects/FsLexYacc/blob/master/src/FsLex/fslexlex.fsl

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-25
    • 1970-01-01
    • 2014-08-12
    • 1970-01-01
    相关资源
    最近更新 更多