Missing/misspelled variable name recommendations

This is the equivalent of PR #1776 but for variables instead of keywords. 

I've moved some of the reusable recommendation code from `namespace.py` to `utils/match.py` in a new `FuzzyMatcher` class. Trying to balance code duplication and complexity in this refactoring was tricky, so criticism/ideas are welcome.

There are a lot of special cases for variable naming, including accessing variable indexes, accessing extended variables, and accessing nested variables. I have only partially handled these special cases - recommendations for misspellings of the base variable name will generally work, but anything more complex will not work, and the recommendations will not include the index or extended variable syntax. 

I reworded some of the missing variable error messages, just to make them subjectively sound better. For example, `Non-existing variable '%s'` is now `Variable '%s' not found`. This breaks many tests throughout `atest`, but in this PR I have not fixed those tests yet. I'll fix them if this rewording/rephrasing is approved. 

For example recommendations, please see the new test cases I've added.
Good point. Didn't realize that recommendations are found based on candidates mapping that has lists as values. That is a bit odd API for a generic utility, but I'm not sure can we come up with anything that would be more generic but not more complicated to use in our two concrete use cases.