如何创建用于识别CR的层规则?

时间:2012-10-22 12:17:14

标签: python lexer ply

我在PLY lexer中区分\ r(0x0d)和\ n(0x0a)时遇到了麻烦。

最小的例子是以下程序

import ply.lex as lex

# token names
tokens = ('CR', 'LF')

# token regexes
t_CR = r'\r'
t_LF = r'\n'

# chars to ignore
t_ignore  = 'abc \t'

# Build the lexer
lexer = lex.lex()

# lex
f = open('foo', 'r')
lexer.input(f.read())
while True:
    tok = lexer.token()
    if not tok: break
    print(tok)

现在按如下方式创建文件foo:

printf "a\r\n\r\rbc\r\n\n\r" > foo

验证它看起来没问题:

hd foo
00000000  61 0d 0a 0d 0d 62 63 0d  0a 0a 0d                 |a....bc....|
0000000b

现在我假设我会得到一些CR和一些LF代币,但是:

python3 crlf.py 
WARNING: No t_error rule is defined
LexToken(LF,'\n',1,1)
LexToken(LF,'\n',1,2)
LexToken(LF,'\n',1,3)
LexToken(LF,'\n',1,6)
LexToken(LF,'\n',1,7)
LexToken(LF,'\n',1,8)

事实证明我只获得LF代币。我想知道为什么会这样,以及我应该怎么做。

这是Ubuntu 12.04上的Python 3.2.3

1 个答案:

答案 0 :(得分:2)

您以默认模式打开文件。在该模式中,newline=None,意味着(除其他外) \r\n\r\n中的任何一个被视为行尾和转换为单个\n字符。有关详细信息,请参阅open documentation

您可以将newline=''传递给open来禁用此行为,这意味着它会接受任何类型的换行符,但不会将其标准化为\n