我被分配了为一个简单的计算器构建词法分析器的任务。
为此,我们被允许使用外部库,我在进行一些Google搜索后选择了rply
。
代码可以正常工作,但是我在一个特殊的要求下苦苦挣扎:如果出现词法错误(例如无效令牌),应该为用户显示一条错误消息,并且执行应恢复到下一个字符。
>这是我到目前为止的Lexer课程(lexer.py
):
from rply import LexerGenerator
class Lexer:
"""
Custom Lexer
"""
def __init__(self):
self.lexer = LexerGenerator()
def _add_tokens(self):
"""
Method to set the RegEx rules for the language,
as well as the token names
"""
self.lexer.add('OPADD', r'\+') # sum
self.lexer.add('OPSUB', r'\-') # subtraction
self.lexer.add('OPMUL', r'\*') # multiplication
self.lexer.add('OPDIV', r'\/') # division
self.lexer.add('OPEN_PARENTHESIS', r'\(')
self.lexer.add('CLOSE_PARENTHESIS', r'\)')
self.lexer.add('DECIMAL', r'(\d+\.(\d*)?|\.\d+)') # decimal
self.lexer.add('INTEGER', r'\d+') # integer
self.lexer.ignore('\s+') # skip whitespaces
def get_lexer(self):
"""
Adds the tokens to the lexer and builds the token table
"""
self._add_tokens()
return self.lexer.build()
为了测试,这是我的代码:
from rply.errors import LexingError
# Test loop
while True:
try:
expr = input('calc> ') # gets input expression
except EOFError:
break
if not expr: # no input was given
continue
if expr.lower() in ['quit', 'exit']:
print('INFO: Exiting Lexer...')
break
lexer = Lexer().get_lexer() # instantiate the lexer
try:
tokens = lexer.lex(expr) # try to tokenize the input
for token in tokens:
print(token)
except LexingError as e: # here we catch the exception and print the error
print('ERROR: invalid token \'{invalid_token}\''.format(
invalid_token=expr[e.source_pos.idx]))
pass
到目前为止,我知道引发异常通常意味着我们要暂停程序/算法,但是我找不到找到打印错误并在错误之后继续执行的方法。
作为示例测试,输入3 + 4. * (3.2 - .2314141)
产生以下输出:
Token('INTEGER', '3')
Token('OPADD', '+')
Token('DECIMAL', '4.')
Token('OPMUL', '*')
Token('OPEN_PARENTHESIS', '(')
Token('DECIMAL', '3.2')
Token('OPSUB', '-')
Token('DECIMAL', '.2314141')
Token('CLOSE_PARENTHESIS', ')')
打印输入3a + 4.
时:
Token('INTEGER', '3')
ERROR: invalid token 'a'
何时打印:
Token('INTEGER', '3')
ERROR: invalid token 'a'
Token('OPADD', '+')
Token('DECIMAL', '4')
有什么方法可以实现所需的行为?我是否需要重写整个lexer.lex()
方法?在此先感谢您的任何信息。另外,欢迎使用其他模块或建议。