如何检查与正则表达式不匹配的字符序列

How to check for a sequence of characters that do not match a Regex

我目前正在尝试实现一个稍后将成为编译器一部分的词法扫描器。该程序使用正则表达式来匹配输入程序文件。如果一系列非 white-space 字符与正则表达式匹配,则匹配的输入部分将转换为一个标记,该标记将与其他标记一起发送到解析器。我有代码可以正确输出正确的标记,但我需要这样做,以便扫描器在一系列非白色 space 字符时引发异常(通过方法 no_token() 调用)被发现不匹配任何给定的正则表达式。这是我第一次 post 在这里,所以如果您有任何关于如何改进我的 post 的提示,请告诉我,或者如果您需要有关问题或代码的更多信息,请询问。

def get_token(self):
    '''Returns the next token and the part of input_string it matched.
       The returned token is None if there is no next token.
       The characters up to the end of the token are consumed.
       Raise an exception by calling no_token() if the input contains
       extra non-white-space characters that do not match any token.'''
    self.skip_white_space()
    # find the longest prefix of input_string that matches a token
    token, longest = None, ''
    for (t, r) in Token.token_regexp:
        match = re.match(r, self.input_string[self.current_char_index:])
        if match is None:
            self.no_token()
        elif match and match.end() > len(longest):
            token, longest = t, match.group()
    self.current_char_index += len(longest)
    return (token, longest)

如你所见,我尝试使用

if match is None:
    self.no_token()

但这会产生异常并在开始时退出程序,并且不会返回任何标记,但如果我将其注释掉,代码就可以正常工作。显然,如果非 white-space 字符不匹配任何正则表达式,我需要此部分产生异常,否则它将在开发的后期阶段引起问题

方法skip_white_space()消耗所有白色-space直到下一个非白色-space字符, 正则表达式存储在 token_regexp 中,self.input_string[self.current_char_index:]) 给出当前字符。

对于作为 .txt 文件的程序:

z := 2;
if z < 3 then
  z := 1
end

没有调用 no_token 输出是:

ID z

BEC

NUM 2

SEM

IF

ID z

LESS

NUM 3

THEN

ID z

BEC

NUM 1

END

这是正确的,但是当我尝试实现 no_token() 调用时,我得到:

lexical error: no token found at the start of z := 2;
if z < 3 then
  z := 1
end

这是 no_token() 方法输出的内容,如果有一系列字符与我在扫描仪中实现的正则表达式不匹配,但此输入不是这种情况。这里所有的字符序列都是有效的。

一切都安排妥当了。干杯

def get_token(self):
    '''Returns the next token and the part of input_string it matched.
       The returned token is None if there is no next token.
       The characters up to the end of the token are consumed.
       Raise an exception by calling no_token() if the input contains
       extra non-white-space characters that do not match any token.'''
    self.skip_white_space()
    # find the longest prefix of input_string that matches a token
    token, longest = None, ''
    for (t, r) in Token.token_regexp:
        match = re.match(r, self.input_string[self.current_char_index:])
        if match and match.end() > len(longest):
            token, longest = t, match.group()

    self.current_char_index += len(longest)
    if token == None and self.current_char_index < len(self.input_string):
        self.no_token()
    return (token, longest)

是最终的工作代码