rply异常后继续执行

时间:2018-08-07 17:44:36

标签: exception-handling python-3.6 lexer lexical-analysis ply

我被分配了为一个简单的计算器构建词法分析器的任务。 为此,我们被允许使用外部库,我在进行一些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()方法?在此先感谢您的任何信息。另外,欢迎使用其他模块或建议。

0 个答案:

没有答案