Suppose there is a text (assembly code)
st.w av,d15
ld.w d15,av
Suppose we want to match it with grep. We can use this pattern:
pattern=\
'\s+st.w\s+av,.*'\
'\s+ld.w\s+.*,av'
Note: we use .*
to match the register names. In the future these register names can change.
Suppose we want to use special regex for register names.
We add special @reg
keyword:
pattern=\
'\s+st.w\s+av,@reg'\
'\s+ld.w\s+@reg,av'
Then we add a prepossessing function for the grep pattern, where we replace all the special keywords to actual regex patterns:
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"
}
Then we call preprocess_pattern()
before executing grep
:
pattern="$(preprocess_pattern $pattern)"
if ! grep -Pzo $pattern code.asm > /dev/null
then
echo "grep #$i failed (pattern: "$pattern")"
((++failed))
fi
It works, but we want more.
We want to add @preg
, which is previous register.
pattern=\
'\s+st.w\s+av,@reg'\
'\s+ld.w\s+@preg,av'
Now the question: where is (and how) to add the logic, which after the each occurrence of @reg
saves the matched value (in our case d15
) in the special stack / buffer and after each occurrence of the @preg
retrieves the matched value from the stack / buffer and checks this value against the value of the @preg
?
In other words: how to write pattern for matching data with context sensitive elements? Is it possible at all with grep?
If yes (i.e. possible) then how to describe this context sensitivity in the pattern?
If no (i.e. impossible) then how else to solve this challenge?