Как оценить совпадающее число позже в регулярном выражении? - Лексирование дескриптора редактирования FORTRAN 'H' с Ply

Я использую Ply для интерпретации строки формата FORTRAN. У меня возникли проблемы с написанием регулярного выражения для соответствия 'H ' изменить дескриптор, который имеет вид

xHccccc...

где x указывает количество символов для чтения после 'H'

Ply сопоставляет токены с одним регулярным выражением, но у меня возникают проблемы с использованием регулярного выражения для выполнения вышеуказанного. Я ищу что-то вроде,

(\d+)[Hh].{\1}

где \1 анализируется как целое число и оценивается как часть регулярного выражения, однако это не так.

Кажется, что невозможно использовать совпадающие числа позже в том же регулярном выражении, так ли это?

Есть ли у кого-нибудь другие решения, которые могут использовать Ply?


person Brendan    schedule 07.02.2010    source источник


Ответы (3)


Regex не может делать такие вещи. Однако вы можете взломать его:

(1[Hh].|2[Hh]..|3[Hh]...|etc...)

Уродливый!

person Mark Byers    schedule 07.02.2010
comment
Грубо и ограниченно, но эффективно. Хорошая идея на раз. - person dmckee --- ex-moderator kitten; 07.02.2010

Вот что приходит из мысли, что регулярные выражения могут заменить лексер.

Краткая версия: регулярные выражения могут работать только с тем небольшим подмножеством всех возможных языков, которые называются «обычными» (знаю, большой сюрприз). Но «регулярный» не изоморфен человеческому пониманию «простого», поэтому даже в очень простых языках могут быть нерегулярные выражения.

Написать лексер для простого языка не так уж сложно.

Этот канонический вопрос о переполнении стека для ресурсов по этой теме: Учимся писать компилятор.


Ах. Кажется, я неправильно понял вопрос. Моя вина.

Я не знаком с ply, и прошло некоторое время с тех пор, как я использовал flex, но думаю, что вы бы съели любое количество следующих цифр, а затем проверили в соответствующем блоке кода если бы правила соблюдались.

person dmckee --- ex-moderator kitten    schedule 07.02.2010
comment
Ply — это библиотека Python, которая реализует правила стиля lex и yacc в Python для создания лексера/парсера. У меня сложилось впечатление, что использование lex/yacc избавит меня от утомительного кодирования при написании парсеров. - person Brendan; 07.02.2010

Pyparsing включает адаптивное выражение, очень похожее на это, которое называется countedArray. countedArray(expr) анализирует начальное целое число 'n', а затем анализирует 'n' экземпляров expr, возвращая весь массив в виде единого списка. Это работает следующим образом: countedArray анализирует начальное целочисленное выражение, за которым следует неинициализированное выражение Forward. К ведущему целочисленному выражению присоединено действие синтаксического анализа, которое присваивает следующему выражению Forward значение 'n'*expr. Затем синтаксический анализатор продолжает работу и анализирует следующие 'n' выражений. Так что это своего рода самомодифицирующийся парсер.

Чтобы проанализировать ваше выражение, это будет выглядеть примерно так:

integer = Word(nums).setParseAction(lambda t:int(t[0]))
following = Forward()
integer.addParseAction(lambda t: following << Word(printables+" ",exact=t[0]))
H_expr = integer + 'H' + following
print H_expr.parseString("22HThis is a test string.This is not in the string")

Отпечатки:

[22, 'H', 'This is a test string.']

Если у Ply есть что-то подобное, возможно, вы могли бы использовать эту технику.

person PaulMcG    schedule 08.02.2010
comment
Спасибо, это полезно знать. Раньше я рассматривал Pyparsing, но решил пойти с более старой школой UNIX'ey lex/yacc Ply - и теперь синтаксический анализатор почти написан, за исключением этой последней детали! - person Brendan; 08.02.2010