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

如何在PLY中将列表元素指定为Token的规格

高效定义PLY词法分析器中的Token集合

嘿,我刚好之前用PLY折腾过类似的小型英语子集解析器,太懂你这种一个个写Token规则的麻烦了!针对你提到的名词列表、不同类型动词的Token定义,这里有几个高效的实现方案:

1. 动态生成正则规则,批量匹配同类Token

不用给每个名词/动词单独写def t_XXX(t): ...,我们可以把词集合转成正则的选择分支,用一个规则就能覆盖所有同类型的词:

import ply.lex as lex

# 先定义你的词集合,后续维护只需要改这里!
NOUNS = ["Harry", "Ron", "Hermione", "Draco", "Snape"]
INTRANSITIVE_VERBS = ["sleeps", "runs", "laughs"]
TRANSITIVE_VERBS = ["sees", "likes", "hates"]
DATIVE_VERBS = ["gives", "shows", "tells"]

# 定义所有需要的Token类型
tokens = (
    'NOUN',
    'INTRANSITIVE_VERB',
    'TRANSITIVE_VERB',
    'DATIVE_VERB'
)

# 动态生成名词的正则匹配式
def t_NOUN(t):
    r'(' + '|'.join(NOUNS) + r')'
    return t

# 不及物动词的规则
def t_INTRANSITIVE_VERB(t):
    r'(' + '|'.join(INTRANSITIVE_VERBS) + r')'
    return t

# 及物动词规则
def t_TRANSITIVE_VERB(t):
    r'(' + '|'.join(TRANSITIVE_VERBS) + r')'
    return t

# 与格动词规则
def t_DATIVE_VERB(t):
    r'(' + '|'.join(DATIVE_VERBS) + r')'
    return t

# 别忘了定义忽略空白字符的规则
def t_ignore(t):
    r'\s+'
    pass

2. 用装饰器简化写法(可选)

PLY支持@lex.token()装饰器,结合动态正则能让代码更简洁:

@lex.token(r'(' + '|'.join(NOUNS) + r')')
def t_NOUN(t):
    return t

3. 优先级与边界处理小技巧

  • 如果你的词集合里有长短重叠的词(比如假设你有"run"和"runs"),一定要把更长的词放在正则的前面,比如r'runs|run',避免短词被优先匹配。不过你的专有名词和动词应该不存在这个问题,放心用。
  • 如果需要支持大小写不敏感的输入(比如"harry"也能被识别),可以在Token函数里统一转换大小写:
    def t_NOUN(t):
        r'(' + '|'.join(NOUNS) + r')'
        t.value = t.value.lower()  # 统一转成小写,方便语法分析阶段处理
        return t
    

4. 扩展维护更轻松

以后要加新的名词或者动词,只需要修改顶部的NOUNS、INTRANSITIVE_VERBS等列表,不用动Token规则的代码,维护成本直接降下来了!


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:31:45