Вступление немного длинное, поэтому, пожалуйста, несите меня. :)Регулярное выражение для синтаксического анализа аналогичных инструкций ассемблера
Я пишу простой парсер, основанный на регулярном выражении, для большого исходного файла, написанного на ассемблере. Большинство этих инструкций просто перемещаются, добавляются, вычитаются и перескакивают, но это довольно большой файл, который мне нужно переносить на два разных языка, и я слишком ленив, чтобы сделать это вручную. Это требование, и я не могу много сделать »(так что, пожалуйста, не отвечайте на такие вещи, как« почему бы вам просто не использовать ANTLR »).
Итак, после выполнения некоторой предварительной обработки (я уже выполнил эту часть: заменил define и макросы и разделил лишние пробелы и комментарии), теперь я в основном должен читать файл по строкам и анализировать один или потенциально больше строк в " промежуточных "инструкций, которые я буду использовать для создания более или менее эквивалента 1 к 1 (с использованием фактической целочисленной арифметики и группы GOTO).
Таким образом, предполагая, что я могу иметь все эти различные режимы адресации:
Я могу пойти двумя различными способами:
- имеют единый МОВ регулярное выражение, которое будет обрабатывать все эти случаи , или
- Имеются несколько регулярных выражений MOV для каждого типа инструкции. Проблема с этим подходом заключается в том, что я должен был тщательно спроектировать каждое регулярное выражение, чтобы избежать какой-либо двусмысленности. И похоже, что будет много дубликатов, поскольку операнды источника и адресата разделяют многие режимы адресации.
Мой вопрос: если у меня есть одно регулярное выражение для всех инструкций, как я должен указывать свои группы и записи, чтобы иметь возможность просто различать разные режимы?
Или я просто поймаю все, а затем обработаю адрес источника/получателя после начального совпадения?
E.g. довольно простой матч-все регулярное выражение будет:
^MOV\s+(?<dest>[^\s,]+)[\s,]*(?<src>[^\s,]+)$
(Разделить на несколько строк с комментариями):
^MOV (?#instruction)
\s+ (?#some whitespace)
(?<dest>[^\s,]+) (?#match everything except whitespace and comma)
\s*,\s* (?#match comma, allow some whitespace)
(?<src>[^\s,]+) (?#match everything except whitespace and comma)$
Итак, я, безусловно, может сделать это, а затем обработать dest
и src
группы отдельно. Но было бы лучше создать неприятное сложное регулярное выражение для соответствия всем случаям из таблицы ниже? В этом случае я не уверен, как я буду интерпретировать эти снимки, чтобы понять, какой режим адресации был согласован.
Я использую C#, если это имеет значение.
Не пытайтесь всегда решать такую проблему с ** просто чистым Regex **, на самом деле нам нужно больше ** предварительной обработки и постобработки **, кроме вывода, которое может вывести Regex. –
Почему бы не просто разобрать его сверху вниз? .. зачем нужно регулярное выражение? –
Хм, ваши комментарии имеют смысл, я, вероятно, слишком задумываюсь об этом. Дело в том, что у меня уже есть множество регулярных выражений для других инструкций, которые быстрее мне писать и тестировать, чем повторять по символам вручную, но для этих инструкций с несколькими вариантами (например, MOV), вероятно, лучше всего просто сопоставить код операции и затем проанализируйте оставшуюся часть, используя пару if-clauses. – Lou