我有一个词法分析器,用ply编写。 Lexer有两种状态:字符串和宏。宏是一个特殊的表达式放在花括号中。 Lexer非常简单:
states = (
('macro', 'exclusive'),
)
t_STRING = [^{] # any char but curly brace
def t_lcurlybrace(t):
r'{'
t.lexer.begin('macro')
... some other tokens for macro state
def t_macro_rcurlybrace(t):
r'}'
t.lexer.begin('INITIAL')
所以基本上它的工作原理如下:
Two plus two is {2 + 2}
Lexer会生成此行的STRING,NUMBER,OPERATOR,NUMBER等代币。
但是我一直坚持错误处理。如果输入是
Two plus two is {2 + 2
lexer产生与以前相同的令牌流。唯一的区别是词法分析器的最终状态(宏,而不是INITIAL)。
我想在这种情况下引发错误,但我无法在lex中找到任何内置的钩子来执行此类任务。现在我的猜测是将一个词法分析器包装在一个包装器中,当所有输入被消耗时,它将检查词法分析器的状态。
更新
我试着像这样使用t_eof: def t_eof(t): 如果t.lexer.current_state()!=' INITIAL': 提高例外('不平衡的括号')
但它没有用。
UPDATE2:
t_eof必须定义为t_macro_eof,因为在"宏"期间达到了EOF。州, 所以可以这样做:
def t_macro_eof(t):
raise Exception('Unbalanced brackets')