Parsing Ply-Lex解析问题

Parsing Ply-Lex解析问题,parsing,lex,ply,Parsing,Lex,Ply,我使用ply作为我的lex解析器。我的规格如下: t_WHILE = r'while' t_THEN = r'then' t_ID = r'[a-zA-Z_][a-zA-Z0-9_]*' t_NUMBER = r'\d+' t_LESSEQUAL = r'<=' t_ASSIGN = r'=' t_ignore = r' \t' t_WHILE=r'WHILE' t_THEN=r'THEN' t_ID=r'[a-zA-Z_][a-zA-Z0-9_]*' t\

我使用ply作为我的lex解析器。我的规格如下:

t_WHILE = r'while'  
t_THEN = r'then'  
t_ID = r'[a-zA-Z_][a-zA-Z0-9_]*'  
t_NUMBER = r'\d+'  
t_LESSEQUAL = r'<='  
t_ASSIGN = r'='  
t_ignore  = r' \t'  
t_WHILE=r'WHILE'
t_THEN=r'THEN'
t_ID=r'[a-zA-Z_][a-zA-Z0-9_]*'
t\u编号=r'\d+'

t_LESSEQUAL=r'这不起作用的原因与ply优先匹配令牌的方式有关,首先测试最长的令牌正则表达式

防止此问题的最简单方法是匹配相同类型的标识符和保留字,并根据匹配情况选择适当的令牌类型。下面的代码类似于中的示例

import ply.lex
令牌=['ID'、'NUMBER'、'LESSEQUAL'、'ASSIGN']
保留={
‘while’:‘while’,
“那么”:“那么”
}
令牌+=保留的.values()
t_ignore='\t'
t_编号='\d+'

t_LESSEQUAL='\PLY根据最长的正则表达式对声明为简单字符串的标记进行优先级排序,但声明为函数的标记具有优先级

从文档中:

在构建主正则表达式时,将在 顺序如下:

  • 所有由函数定义的标记都按照它们在lexer文件中出现的顺序添加
  • 通过按减少正则表达式长度的顺序对字符串定义的标记进行排序,然后添加标记(添加更长的表达式) 首先)
  • 因此,另一种解决方案是简单地将您希望优先排序的令牌指定为函数,而不是字符串,如下所示:

    def t_WHILE(t): r'while'; return t
    def t_THEN(t): r'then'; return t
    t_ID = r'[a-zA-Z_][a-zA-Z0-9_]*'
    t_NUMBER = r'\d+'
    t_LESSEQUAL = r'<='
    t_ASSIGN = r'='
    t_ignore = ' \t'
    
    def t_WHILE(t):r'WHILE';返回t
    定义t_THEN(t):r'THEN';返回t
    t_ID=r'[a-zA-Z_][a-zA-Z0-9_]*'
    t\u编号=r'\d+'
    
    t_LESSEQUAL=r'事实上,我发现由于t_ignore=r“\t”,它忽略了字母“t”(不要问我为什么!)。所以我删除了它,现在它开始以“then”作为标记。@Karan:
    r'\t'
    是一个原始字符串。我的猜测是
    \t
    无法在其中转义,如果您删除首字母
    r
    =>
    t\u ignore='\t'
    LexToken(ID,'while',1,0)  
    LexToken(ID,'n',1,6)  
    LexToken(LESSEQUAL,'<=',1,8)  
    LexToken(NUMBER,'0',1,11)  
    LexToken(ID,'hen',1,14)      ------> PROBLEM!  
    LexToken(ID,'h',1,18)  
    LexToken(ASSIGN,'=',1,20)  
    LexToken(NUMBER,'1',1,22)  
    
    import ply.lex
    
    tokens = [ 'ID', 'NUMBER', 'LESSEQUAL', 'ASSIGN' ]
    reserved = {
        'while' : 'WHILE',
        'then' : 'THEN'
    }
    tokens += reserved.values()
    
    t_ignore    = ' \t'
    t_NUMBER    = '\d+'
    t_LESSEQUAL = '\<\='
    t_ASSIGN    = '\='
    
    def t_ID(t):
        r'[a-zA-Z_][a-zA-Z0-9_]*'
        if t.value in reserved:
            t.type = reserved[ t.value ]
        return t
    
    def t_error(t):
        print 'Illegal character'
        t.lexer.skip(1)
    
    lexer = ply.lex.lex()
    lexer.input("while n <= 0 then h = 1")
    while True:
        tok = lexer.token()
        if not tok:
            break
        print tok
    
    def t_WHILE(t): r'while'; return t
    def t_THEN(t): r'then'; return t
    t_ID = r'[a-zA-Z_][a-zA-Z0-9_]*'
    t_NUMBER = r'\d+'
    t_LESSEQUAL = r'<='
    t_ASSIGN = r'='
    t_ignore = ' \t'