PLY не соответствует правильному терминалу - PullRequest
0 голосов
/ 13 ноября 2018

Я создал простой парсер в PLY, который имеет два правила:

  • когда : появляется первым, появляется имя
  • когда = появляется первым, появляется число

Соответствующий код:

from ply import lex, yacc

tokens = ['Name', 'Number']

def t_Number(t):
    r'[0-9]'
    return t

def t_Name(t):
    r'[a-zA-Z0-9]'
    return t

literals = [':', '=']

def t_error(t):
    print("lex error: " + str(t.value[0]))
    t.lexer.skip(1)

lex.lex()

def p_name(p):
    '''
    expression : ':' Name
    '''
    print("name: " + str(list(p)))

def p_number(p):
    '''
    expression : '=' Number
    '''
    print("number: " + str(list(p)))

def p_error(p):
    print("yacc error: " + str(p.value))

yacc.yacc()
yacc.parse("=3")
yacc.parse(":a")
yacc.parse(":3")

Я ожидаю, что если он увидит : или =, он войдет в соответствующее правило и попытается сопоставить соответствующий терминал. Тем не менее, в третьем примере он соответствует номеру, который должен быть именем, а затем потерпеть неудачу. Afaik грамматика должна быть контекстно-свободной (что необходимо для анализа), так ли это? Кроме того, как бы я справился со случаем, когда один токен является надмножеством другого токена?

1 Ответ

0 голосов
/ 13 ноября 2018

Сгибайте токены до обращения к грамматике, поэтому контекст не влияет на токенизацию. (Точнее, парсер получает поток токенов, созданных лексером. Два процесса чередуются на практике, но они сохраняютсянезависимый.)

Вы можете встроить контекст в свой лексер, но это становится ужасно быстро.(Тем не менее, это общая стратегия.)

Лучше всего написать свои лексические правила для получения максимально детализированного результата, а затем написать грамматику для принятия всех альтернатив:

def p_name(p):
    '''
    expression : ':' Name
    expression : ':' Number
    '''
    print("name: " + str(list(p)))

def p_number(p):
    '''
    expression : '=' Number
    '''
    print("number: " + str(list(p)))

Это предполагает, что вы меняете свои лексические правила, чтобы поставить самый конкретный шаблон первым.

...