Парсер функций с RegEx в Python - PullRequest
2 голосов
/ 12 марта 2009

У меня есть исходный код на Фортране (почти не имеет значения), и я хочу проанализировать имена функций и аргументы.

например, используя

(\w+)\([^\(\)]+\)

с

a(b(1 + 2 * 2), c(3,4))

Я получаю следующее: (как и ожидалось)

b, 1 + 2 * 2
c, 3,4

где мне нужно будет

a, b(1 + 2 * 2), c(3,4)
b, 1 + 2 * 2
c, 3,4

Есть предложения?

Спасибо за ваше время ...

Ответы [ 5 ]

2 голосов
/ 13 марта 2009

Вы можете взглянуть на PLY (Python Lex-Yacc) , он (на мой взгляд) очень прост в использовании и хорошо документирован, и поставляется с примером калькулятора которая может быть хорошей отправной точкой.

2 голосов
/ 12 марта 2009

Это нелинейная грамматика - вы должны иметь возможность выполнять рекурсию по набору разрешенных правил. Посмотрите на pyparsing , чтобы выполнить простой синтаксический анализ CFG (Context Free Grammar) с помощью читаемых спецификаций.

Прошло много времени с тех пор, как я выписал CFG, и я, вероятно, ржавый, поэтому я отсылаю вас к Python EBNF , чтобы получить представление о том, как вы можете сконструировать его для подмножество языкового синтаксиса.

Редактировать: Если пример всегда будет простым, вы можете закодировать небольшой класс / функцию конечного автомата, который перебирает входную строку с токенами, как подсказывает @ Девин Жанпьер . 1013 *

2 голосов
/ 12 марта 2009

Это можно сделать с помощью регулярных выражений - используйте их для токенизации строки и работы с токенами. то есть см. re.Scanner. Кроме того, просто используйте pyparsing.

2 голосов
/ 12 марта 2009

Я не думаю, что это работа для регулярных выражений ... они действительно не могут обрабатывать вложенные шаблоны.

Это связано с тем, что регулярные выражения компилируются в конечные автоматы. Чтобы проанализировать произвольно вложенные выражения, вы не можете использовать FSM, потому что вам нужно бесконечно много состояний, чтобы отслеживать произвольную вложенность. Также смотрите это ТА потока .

1 голос
/ 12 марта 2009

Вы не можете сделать это только с помощью регулярного выражения. Это как бы рекурсивно. Сначала вы должны сопоставить наиболее внешнюю функцию и ее аргументы, распечатать имя функции, а затем сделать то же самое (сопоставить имя функции, затем ее аргументы) со всеми ее аргументами. Одного Regex недостаточно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...