给定一个在 FsLexYacc 中实现的词法分析器,我如何获得所有的标记?

Given a lexer implemented in FsLexYacc, how do I get all of the tokens?

我有一个在 FsLexYacc 中实现的词法分析器和解析器。为了调试词法分析器,我想打印给定字符串的所有标记。

这是我目前的情况:

#load "../.paket/load/net5.0/FsLexYacc.Runtime.fsx"

#load "./Domain.fs"
#load "./Parser.fs"
#load "./Lexer.fs"

open System
open System.IO
open FSharp.Text
open FSharp.Text.Lexing
open Scripting

let allTokens (input : string) =
  let lexBuffer = LexBuffer<char>.FromString input
  Lexer.tokenize lexBuffer // Only gets first token!

printfn "%A" <| allTokens "1 + 1"

NUMBER 1

但这只是第一个令牌!

如何获取列表或序列中的所有标记?

Lexer.tokenize可重复调用获得更多代币

通常您的词法分析器定义可以在到达文件末尾时匹配 eof,并且可以 return 一个特定的标记来指示“文件末尾”。

let tokenize = parse
    ... 
   | eof -> { Token.EOF }

在这种情况下,您可以只调用 Lexer.tokenize,直到收到 EOF 令牌。您当然可以迭代地、递归地或通过组合内置函数来执行此操作。

let allTokens = 
    Seq.initInfinite (fun _ -> Lexer.tokenize lexBuffer)
    |> Seq.takeWhile ( (<>) Token.EOF )

let rec allTokens = 
    match Lexer.tokenize lexBuffer with
    | Token.EOF -> []
    | t -> t :: allTokens