Соответствие регулярному выражению для удаления определенных случаев использования символа точки - PullRequest
4 голосов
/ 28 октября 2011

У меня есть несколько исходных файлов на Fortran 77, которые я пытаюсь преобразовать из нестандартного синтаксиса STRUCTURE и RECORD в стандартизированный синтаксис Fortran 90 TYPE.Один хитрый аспект этого заключается в другом способе адресации элементов структуры.

Нестандартный:

s.member = 1

Стандарт:

s%member = 1

Итак, мне нужноперехватывать все случаи использования в таких сценариях и заменять их % символами.Не так уж плохо, за исключением тех случаев, когда вы думаете обо всех способах использования периодов (десятичные точки в числах, имена файлов в операторах include, знаки препинания в комментариях, операторы отношений Fortran 77, возможно, другие).Я сделал некоторую предварительную обработку, чтобы исправить реляционные операторы для использования символов Фортрана-90, и я не очень беспокоюсь о том, чтобы искажать грамматику комментариев, но я не нашел хорошего подхода для перевода . в% для случаев выше.Кажется, что я должен быть в состоянии сделать это с помощью sed, но я не уверен, как сопоставить случаи, которые мне нужно исправить.Вот правила, о которых я подумал:

Построчно:

  • Если строка начинается с <whitespace>include, то мы не должныничего не делать с этой линией;передать его на выход, чтобы мы не испортили имя файла внутри оператора include.

  • Следующие строки являются операторами, которые не имеют символьных эквивалентов, поэтому они должны бытьоставлено в покое: .not. .and. .or. .eqv. .neqv.

  • В противном случае, если мы находим период, который окружен 2 нечисловыми символами (так что это не десятичная точка), то это должен быть оператор, которыйЯ ищу заменить.Измените этот период на %.

Я сам не являюсь носителем языка Фортран, поэтому вот несколько примеров:

include 'file.inc'        ! We don't want to do anything here. The line can
                          ! begin with some amount of whitespace

if x == 1 .or. y > 2.0    ! In this case, we don't want to touch the periods that
                          ! are part of the logical operator ".or.". We also don't
                          ! want to touch the period that is the decimal point 
                          ! in "2.0".
if a.member < 4.0 .and. b.othermember == 1.0 ! We don't want to touch the periods
                                             ! inside the numbers, but we need to
                                             ! change the "a." and "b." to "a%"
                                             ! and "b%".

Любой хороший способрешая эту проблему?

Редактировать: На самом деле я нашел несколько дополнительных операторов, которые содержат точку, в которой нет символьных эквивалентов.Я обновил список правил выше.

Ответы [ 6 ]

2 голосов
/ 29 октября 2011

Я не настолько разбираюсь в регулярных выражениях, поэтому, наверное, я бы попробовал заняться этим с другой стороны.Если вы grep для ключевого слова STRUCTURE, вы получите список всех STRUCTURES, используемых в коде.Как только он у вас есть, для каждого STRUCTURE S вы можете просто заменить все экземпляры S. на S%.

Таким образом, вам не нужно беспокоиться о таких вещах, как .true., .and., .neq. и их родственники.Основное беспокойство тогда должно было быть в состоянии разобрать объявления STRUCTURE.

2 голосов
/ 29 октября 2011

Если кодовая база не действительно ОГРОМНАЯ (и очень серьезно думаю, так ли это на самом деле), я бы просто взял редактор вроде Vim ( вертикальный выбор и выбор блока - ваши друзья ) a * и отведите вторую половину дня, чтобы сделать это вручную *.Однажды днем, я думаю, вы закончите с большей частью, если не со всеми . После полудня много времени.Только представьте, сколько случаев вы могли бы охватить только за эти 2 часа.

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

Конечно, вопрос напрашивается сам собой ... если код F77, который все компиляторы все еще поддерживают, и код работает ... почему вы так заинтересованыменяя это?

2 голосов
/ 28 октября 2011

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

Если бы мне пришлось делать то, что нужно, я бы сделал это вручную, если только кодовая база не огромна. Если первое применимо, сначала замените все [a-zA-Z0-9]. [A-zA-Z] на что-то очень странное, которое гарантированно никогда не скомпилируется, что-то вроде «@ WHATEVER @», а затем продолжайте искать все записи и заменить их вручную после ручного управления.

Если объем кода огромен, вам нужно написать парсер. Я бы посоветовал вам использовать python для токенизации базовых конструкций fortran, но помните, что fortran - не простой язык для анализа. Работайте «по порядку» и пытайтесь найти все используемые имена переменных, используя их в качестве фильтра. Если вы столкнулись с чем-то вроде a.whatever и знаете, что a находится в списке локальных или глобальных переменных, примените изменение.

0 голосов
/ 29 октября 2011

Судя по вашим примерам, я полагаю, что этого будет достаточно, чтобы защитить строки в кавычках, а затем заменить точки алфавитами с обеих сторон.

perl -pe '1 while s%(\x27[^\x27]+)\.([^\x27]+\x27)%$1@@::@@$2%;
    s/([a-z])\.([a-z])/$1%$2/g;
    s/@@::@@/./g' file.f

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

0 голосов
/ 28 октября 2011

Этот седелинер может быть началом

sed -r '/^\s*include/b;/^\s*! /b;G;:a;s/^(\.(not|and|or|eqv|neqv)\.)(.*\n.*)/\3\1/;ta;s/^\.([^0-9]{2,})(.*\n.*)/\2%\1/;ta;s/^(.)(.*\n.*)/\2\1/;ta;s/\n//'
0 голосов
/ 28 октября 2011

Хотя регулярное выражение ниже:

(?<!')\b([^.\s]+)(?<!\.(?:not|and|or|eqv|neqv))(?<=\D)\.(?=\D)(?!(?:not|and|or|eqv|neqv)\.)([^.\s]+)\b(?!')

Заменить $1%$2

Отлично подходит для ваших примеров, я бы не советовал использовать его с вашей текущей задачей. Это точно не охватит все ваши дела. Теперь, если вы заботитесь о покрытии на 80% или о чем-то другом, вы можете использовать его, но вам, вероятно, следует сделать резервную копию своих источников. Я уверен, что из-за ограниченного набора входных ящиков, будут случаи, когда регулярное выражение заменит то, что не должно.

Удачи:)

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