【问题标题】:Use PLY to match a normal string使用 PLY 匹配普通字符串
【发布时间】:2014-01-02 13:13:54
【问题描述】:

我正在使用PLY 编写解析器。这个问题类似于How to write a regular expression to match a string literal where the escape is a doubling of the quote character?。但是,我使用双引号来打开和关闭一个字符串。例如:

“我不知道“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)'

请告诉我为什么它不正确。

【问题讨论】:

    标签: python-2.7 lex lexer ply


    【解决方案1】:

    用一个小 PLY 程序探讨了这个问题,我认为您的问题与 handling raw and non-raw strings 在数据处理方面的差异有关,而不是与 PLY 解析和词法匹配本身有关。 (顺便说一句,python V2 and 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 = ' \t\r\n'
    
    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 '"'
    

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

    【讨论】:

      猜你喜欢
      • 2015-07-29
      • 1970-01-01
      • 2017-05-19
      • 1970-01-01
      • 2011-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多