如何使用 parser-tools/lex-sre 匹配换行符或文件结尾

How to match newline or end of file using parser-tools/lex-sre

我正在尝试在 Racket 中编写一个忽略行注释的词法分析器(即,从开头 # 开始,直到行尾)。在我看来,该行的结尾可能是 #\newline(eof),但以下显然不起作用,因为 (eof) 在此位置无效:

(define comment-lexer
  (lexer
    [(:or #\newline (eof))
     (cons `(COMMENT) (main-lexer input-port))]

    [any-char
     (comment-lexer input-port)]))

是否可以像我在上面尝试的那样将它们组合起来,或者我是否必须为每个单独编写规则?

在我看来,无论何时对一个潜在的多行字符串进行词法分析,都会遇到这个问题。因此,这是错误的做法吗? (eof) 处理应该只在最顶层的词法分析器中完成吗?

词法分析器理解的正则表达式语法包含规则:

`re ::= ... | (union re ...) `

这意味着 union 期望所有子表单都是正则表达式,并且由于 (eof)没有列在re中,不是正则表达式。事实上 (eof) 被列为 trigger.

因此(union #\newline (eof))不是正则表达式(注意这里的:orunion的缩写)

结论是您需要将规则 "a line comment starts with a # and ends in a newline or an eof" 移至语法中。一种方法是制定一个词法分析器规则,将“# 后跟任何不是换行符或 eof 的内容”转换为行注释标记。然后在解析器的语法中,要求行注释后跟换行符或eof。