Как удалить нетерминал в файле грамматики с помощью PLY (Python Lex-Yacc) - PullRequest
3 голосов
/ 27 февраля 2012

Я столкнулся с проблемой при использовании PLY. Я хочу создать генератор графа вызовов с помощью PLY. В некоторых ситуациях мне нужно сбросить некоторые токены в файле грамматики. Это потому, что мне нужно что-то делать, когда синтаксический анализатор распознает этот токен, прежде чем я его сбрасываю, поэтому Я не могу просто выбросить в файл лексера. Например, токен 'IF' - это тот, от которого я хочу отказаться. Поэтому я пытаюсь что-то сделать, чтобы отменить это в файле грамматики. Прямо как:

def p_if(p):
    'if : IF'
    print "if"
    parser.symstack.pop()

Но все пошло не так, как я думаю. Я печатаю symstack (это атрибут parser, а parser это экземпляр LRParser для yacc.py), и список symstack просто содержит предыдущие токены, но не «если». Поэтому мне интересно, как отказаться от токена в этой ситуации. Кто-нибудь может мне помочь? Большое спасибо!

Ответы [ 2 ]

1 голос
/ 07 марта 2012

Вы спрашивали об этом некоторое время назад, но пока нет комментариев или ответов. Вот возможное объяснение, почему.

Смотрю документацию в http://www.dabeaz.com/ply/ply.html. Там нет ничего о манипулировании parser.symstack. Похоже, это не открытый документированный интерфейс.

т.е. ты втыкаешь вилку в тостер.

Не думаете ли вы, что парсер может быть сбит с толку, если вы запутаетесь с его внутренней структурой данных или что он может порваться со следующей версией генератора парсера и т. Д.? Кроме того, вы не можете адекватно объяснить, что вы пытаетесь сделать. Какова цель отказа от нетерминальных символов, и что именно это означает? Что это за ситуации и в чем проблема? Может быть, проблема может быть решена без использования объекта парсера.

Кроме того, нет задокументированного объекта глобального синтаксического анализатора. Вы должны были определить эту переменную синтаксического анализатора, например, «parser = yacc.yacc ()» (задокументировано в Разделе 7: Несколько парсеров и лексеров). Поскольку вы затем ссылаетесь на эту переменную в самих правилах синтаксического анализатора, это выглядит очень глупо. Есть правильный способ для правил ссылаться на анализатор, и это через параметр p, который они получают: вы хотите p.parser. (Задокументировано в разделе 7, снова).

0 голосов
/ 10 марта 2012

Спасибо большое !!На самом деле, я нашел способ решить мою проблему.Вы правы, parser.symstack никогда не следует манипулировать.Поскольку мой английский не очень хороший (мой родной язык не английский), я не объяснил свою проблему четко. Но я все еще благодарен за ваш совет.Следующее - мое решение, и я надеюсь, что это поможет кому-то еще в будущем.

I.определить функцию p_error (p)

def p_error(p):
tok = yacc.token() # Get the next token
yacc.errok()
return tok #Return the next token

II.поднять синтаксическую ошибку в нужной вам функции

def p_somerule(p):
' a : A '
raise SyntaxError
...