REJECT 等效层

REJECT equivalent in ply

ply 中的 flex REJECT 等价物是什么? 对于我的代码,我希望 ply 检测同一文本的令牌 LETTER 和 WORD,但只检测到 LETTER 令牌。

import ply.lex as lex
from ply.lex import TOKEN


tokens = (
    'LETTER',
    'WORD'
)


@TOKEN(r'[a-zA-Z]')
def t_LETTER(t):
    print('L')
    return t


@TOKEN(rf'{t_LETTER}*')
def t_WORD(t):
    print('W')
    return t


# Error handling rule

def t_error(t):
    print("Illegal character '%s'" % t.value[0])
    t.lexer.skip(1)

 # Build the lexer
lexer = lex.lex()

# Test it out

# Give the lexer some input
while True:
    lexer.input(input())

    # Tokenize
    while True:
        tok = lexer.token()
        if not tok:
            break      # No more input
        print(tok)

当我执行输入 av 的代码时,输​​出是: 大号 LexToken(字母,'a',1,0) 大号 LexToken(字母,'v',1,1) 但我希望也能检测到令牌 WORD。 在 flex 中,我拒绝了这个,但实际上我还没有找到替代方案。

在 Ply 中没有等同于 REJECT 的东西。但这不是您的程序无法识别 WORD 标记的原因;这些无法识别,因为当 Python 扩展 f'{t_LETTER}*' 时,它不会产生 '[a-zA-Z]*',因为 t_LETTER 的值是一个函数,而不是字符串。

在 (f)lex 中的 WORD 操作中使用 REJECT 可能也不是您想要的,但无论如何 REJECT 是一个非常低效的操作并且不推荐用于现代代码。 Flex 会将 abcd 标记为

WORD abc
WORD ab
WORD a
LETTER a
WORD bcd
WORD bc
WORD b
LETTER b
WORD cd
WORD c
LETTER c
WORD d
LETTER d

也许这就是你所期望的,但我觉得有点奇怪。在 Ply 和 flex 中,您可以通过组合将字符推回输入流(在 flex 中使用 yylessunput,或在 Ply 中修改 lex.lexpos)来获得类似的结果,并使用开始条件更改词法分析器状态。