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

如何调整Racket parser-tools/lex的字符串词法规则实现正确匹配?

Racket词法分析器字符串匹配问题解决

我在用Racket的parser-tools/lex和parser-tools/lex-sre编写词法分析器,目标是为字符串生成对应的Token,但当前匹配逻辑存在问题:当遇到"this is" .... "cool"这类内容时,会被识别为单个Token,而非预期的StringToken、中间Tokens、StringToken形式。

我当前使用的词法规则如下:

[
    (: 
    #\" 
    (repetition  
        0
        +inf.0
        (complement 
        (or
            #\newline 
            whitespace
        )
        ) 
    )   
    #\") 
    (begin (token-STRING  lexeme  ))
]

你的问题根源在于当前规则的匹配范围过宽且采用贪婪匹配,导致它会从第一个"一直匹配到最后一个",把中间所有内容都纳入单个Token。要解决这个问题,核心是让字符串匹配在遇到下一个"时立即停止,而非跳过它继续匹配。

调整后的基础规则

把字符串内容的匹配逻辑改为:仅排除双引号和换行符(如果你的语言允许字符串跨行,可去掉换行符限制),而非排除空白字符。修改后的规则如下:

[
    (: 
    #\" 
    (repetition  
        0
        +inf.0
        (complement (or #\" #\newline))  ; 仅排除双引号和换行符
    )   
    #\") 
    (begin (token-STRING lexeme))
]

调整逻辑说明

  • 原规则排除的是换行符和空白字符,这意味着除这两类字符外的所有内容(包括中间的")都会被匹配,自然会把多个字符串连起来识别。
  • 修改后的规则只限制双引号和换行符,匹配到下一个"就会终止,每个被"包裹的部分都会被单独识别为StringToken,中间内容则会交给其他词法规则处理。

额外补充:支持转义双引号的场景

如果你的语言需要支持转义双引号(比如"this is \"cool\" string"),还需要额外处理转义字符,避免转义的"被误判为字符串结束符。此时规则需调整为:

[
    (: 
    #\" 
    (repetition  
        0
        +inf.0
        (or
            (: #\\ any-char)  ; 匹配转义字符及后续任意字符
            (complement (or #\" #\newline))
        )
    )   
    #\") 
    (begin (token-STRING lexeme))
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 12:37:30