0

我在 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"

1号

但这只是第一个令牌!

如何将所有标记作为列表或序列获取?

4

1 回答 1

1

Lexer.tokenize可以重复调用以获得更多令牌。

通常,您的词法分析器定义可以在eof到达文件末尾时匹配,并且可能会返回特定标记以指示“文件结尾”。

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
于 2021-11-21T23:11:55.597 回答