grep + regex: как написать шаблон для сопоставления данных с контекстно-зависимыми элементами?

grep + regex: как написать шаблон для сопоставления данных с контекстно-зависимыми элементами?

Предположим, что есть текст (код ассемблера)

st.w    av,d15
ld.w    d15,av

Предположим, мы хотим сопоставить его с grep. Мы можем использовать этот шаблон:

pattern=\
'\s+st.w\s+av,.*'\
'\s+ld.w\s+.*,av'

Примечание: мы используем .*для сопоставления имен регистров. В будущем эти имена регистров могут измениться.

Предположим, мы хотим использовать специальное регулярное выражение для имен регистров. Добавляем специальное @regключевое слово:

pattern=\
'\s+st.w\s+av,@reg'\
'\s+ld.w\s+@reg,av'

Затем мы добавляем предварительную функцию для шаблона grep, в которой мы заменяем все специальные ключевые слова на реальные шаблоны регулярных выражений:

preprocess_pattern () {
    local result=$1
    # Replace @reg to exact regex pattern [a..d][0..15].
    result=${result//'@reg'/'[a-d](1[0-5]|[0-9])'}
    # Add other replacements (if need).
    #result=${result//''/''}
    echo "$result"
}

Затем мы вызываем preprocess_pattern()перед выполнением grep:

pattern="$(preprocess_pattern $pattern)"
if ! grep -Pzo $pattern code.asm > /dev/null
then
    echo "grep #$i failed (pattern: "$pattern")"
    ((++failed))
fi

Это работает, но мы хотим большего.

Мы хотим добавить @preg, что этопредыдущий регистр.

pattern=\
'\s+st.w\s+av,@reg'\
'\s+ld.w\s+@preg,av'

Теперь вопрос: где (и как) добавить логику, которая после каждого появления@reg сохраняетсовпавшее значение (в нашем случае d15) в специальном стеке/буфере и после каждого появления@preg извлекаетсовпавшее значение из стека/буфера и сравнивает это значение со значением @preg?

Другими словами: как написать шаблон для сопоставления данных сконтекстно-зависимыйэлементы? Возможно ли это вообще с grep?

Если да (т.е. возможно), то как это описать?чувствительность к контекстув узоре?

Если нет (т.е. невозможно), то как еще решить эту задачу?

решение1

То, чего вы пытаетесь достичь, может быть достигнуто с помощью grep + regex, но это будет сложно. Для вашей задачи нужен полноценный скрипт или программа на каком-то языке.

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

  1. Контекст Grep: единственный контекст, который предоставляет grep, — это количество строк beforeи afterсовпавшая строка [ -A, -B, -C(комбинация предыдущих двух)]
  2. Awk и Sed: с их помощью можно искать текст по двум шаблонам.

Но опять же, это будет сложно. Насколько я понимаю, вы пытаетесь написать какой-то парсер, поэтому вам следует изучить и попробовать использовать инструмент записи, прежде чем переходить к написанию сложных команд.

Связанный контент