使用 PLY 匹配普通字符串



我正在使用PLY编写解析器。问题类似于这个问题如何编写正则表达式以匹配字符串文字,其中转义是引号字符的加倍?但是,我使用双引号来打开和关闭字符串。例如:

"我不知道"A"是什么"

我将普通的字符串词法分析器定义为:

t_NORMSTRING = r'"([^"n]|(\"))*"$'

我还有一个变量的词法分析器:

def t_VAR(t):
   r'[a-zA-Z_][a-zA-Z_0-9]*'

问题是我的词法分析器无法识别"我不知道 \"A\" 是什么"作为 NORMSTRING 标记。它返回错误

Illegal character '"' at 1
Syntax error at 'LexToken(VAR,'do',10,210)'

请让我知道为什么它不正确。

用一个小的 PLY 程序探讨了这个问题,我认为您的问题与数据处理中处理原始和非原始字符串之间的差异有关,而不是与 PLY 解析和词法匹配本身有关。(作为旁注,python V2 和 python v3 在字符串处理方面存在细微差异。我已将我的代码限制为 python v2)。

仅当您使用非原始字符串或使用input而不是raw_input时,您才会看到错误。这从我的示例代码和下面的结果中显示出来:

命令:

$ python --version
Python 2.7.5
$ python string.py
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
tokens = (
    'NORMSTRING',
    'VAR'
)
def t_NORMSTRING(t):
     r'"([^"n]|(\"))*"$'
     print "String: '%s'" % t.value
def t_VAR(t):
   r'[a-zA-Z_][a-zA-Z_0-9]*'
t_ignore = ' trn'
def t_error(t):
    print "Illegal character '%s'" % t.value[0]
    t.lexer.skip(1)
lexer = lex.lex()
data = r'"I do not know what "A" is"'
print "Data: '%s'" % data
lexer.input(data)
while True:
   tok = lexer.token()
   if not tok: break
   print tok

输出:

Data: '"I do not know what "A" is"'
String: '"I do not know what "A" is"'
data = '"I do not know what "A" is"'
print "Data: '%s'" % data
lexer.input(data)
while True:
   tok = lexer.token()
   if not tok: break
   print tok

输出:

Data: '"I do not know what "A" is"'
Illegal character '"'
Illegal character '"'
String: '" is"'
lexer.input(raw_input("Please type your line: "));
while True:
   tok = lexer.token()
   if not tok: break
   print tok

输出:

Please type your line: "I do not know what "A" is"
String: '"I do not know what "A" is"'
lexer.input(input("Please type your line: "));
while True:
   tok = lexer.token()
   if not tok: break
   print tok

输出:

Please type your line: "I do not know what "A" is"
Illegal character '"'
Illegal character '"'

最后,您可能不需要正则表达式中的字符串锚点$

最新更新