You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用FsLexYacc实现词法分析器时如何获取全部token?

你当前的代码仅调用了一次Lexer.tokenize方法,因此只能返回首个token。FsLexYacc的词法分析器设计为每次调用tokenize方法时,从传入的LexBuffer中消费对应长度的字符、返回当前匹配的token,同时将LexBuffer的读取指针移动到下一个token的起始位置,因此你需要循环调用该方法直到命中输入结束标记,即可拿到完整的token序列。

修改后的代码示例

#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
  // 循环生成token序列
  seq {
    while true do
      match Lexer.tokenize lexBuffer with
      // 此处的EOF请替换为你自己项目中定义的输入结束对应的token名称
      | EOF -> 
          yield EOF
          yield! Seq.empty
      | token -> yield token
  }
  // 如果需要直接返回列表,取消下面这行的注释即可
  // |> List.ofSeq

// 测试输出所有token
printfn "%A" <| allTokens "1 + 1"

注意事项

  • 请确保你的Lexer.fsl词法规则文件中定义了输入结束的匹配规则,示例如下:
    | eof { EOF }
    
  • 如果你不需要在结果中包含结束标记EOF,可以使用如下实现:
    let allTokensWithoutEOF (input : string) =
      let lexBuffer = LexBuffer<char>.FromString input
      Seq.unfold (fun _ ->
        let token = Lexer.tokenize lexBuffer
        if token = EOF then None
        else Some (token, ())
      ) ()
    

修改后运行你的测试用例"1 + 1",就会输出完整的token列表:[NUMBER 1; PLUS; NUMBER 1; EOF](具体token名称以你自己的定义为准)。


内容的提问来源于stack exchange,提问作者sdgfsdh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 23:09:03