Pyparsing: как реализовать специальную обработку комментариев в стиле C?

Я хочу воспользоваться преимуществами переменной cStyleComment, но вместо того, чтобы просто игнорировать эти комментарии, я хочу специально их обработать. Есть ли способ заставить pyparsing вызывать мой обработчик для части ввода, которую он распознает как комментарий, прежде чем он будет выброшен?

Я обрабатываю некоторый код C, который содержит некоторые «специальные» директивы внутри комментариев.


person rincewind    schedule 10.02.2012    source источник


Ответы (1)


Ни в одном из выражений xxxStyleComment, определенных в pyparsing, нет ничего, что заставляло бы их игнорировать. Они здесь для удобства, тем более, что в некоторых форматах комментариев легко ошибиться. Они не будут проигнорированы, если вы не вызовете метод ignore для своей более крупной грамматики, например:

cHeaderParser.ignore(cStyleComment)

(где cHeaderParser может быть чем-то, что вы написали для чтения файлов .h, например, для извлечения информации об API.)

И наличие встроенного обратного вызова обработчика pyparsing, просто используйте cStyleComment.setParseAction(commentHandler). Pyparsing может обрабатывать действия синтаксического анализа с любой из этих сигнатур:

def commentHandler(inputString, locn, tokens):
def commentHandler(locn, tokens):
def commentHandler(tokens):
def commentHandler():

Если ваш commentHandler возвращает строку или список строк или новый ParseResults, они будут использоваться для замены входных токенов — если он возвращает None или опускает оператор return, то используется объект tokens. Вы также можете изменить объект маркеров на месте (например, добавить новые имена результатов).

Таким образом, вы можете написать что-то вроде этого, чтобы ваши комментарии были прописными:

def commentHandler(tokens):
    return tokens[0].upper()    
cStyleComment.setParseAction(commentHandler)

(такое простое действие синтаксического анализа можно было бы даже записать cStyleComment.setParseAction(lambda t:t[0].upper()))

При написании подобного преобразования синтаксического анализа можно было бы использовать transformString, а не parseString,

print cStyleComment.transformString(source)

Это напечатает исходный код, но все комментарии будут в верхнем регистре.

person PaulMcG    schedule 10.02.2012
comment
Спасибо, transformString() помог мне! Сейчас использую 2 прохода. Первый — cStyleComment.setParseAction(processComments).transformString(src), чтобы оставить только такие вещи, как @annotation или @annotation(value), а остальную часть комментария отбросить, а второй — вызвать parseString() в моей основной грамматике. Мне немного не нравится, что мне приходится обрабатывать аннотации дважды - в первый раз я извлекаю их с помощью модуля re, но объединяю их обратно в необработанную строку только для обработки во второй раз во время вызова parseString(). Тем не менее, это работает! - person rincewind; 11.02.2012
comment
Если вы хотите, вы можете попробовать проанализировать аннотации в рамках действия синтаксического анализа, которое вы прикрепили к cStyleComment, и выполнить только один проход. Но трудно спорить с решением, которое выполняет свою работу. Поздравляем и добро пожаловать на pyparsing! - person PaulMcG; 11.02.2012