util/kconfig_lint: Turn handle_expressions() into a parser
commitf6b2baa3e883c174e3e0fa79bc9e739d2b0971dd
authorNico Huber <nico.h@gmx.de>
Fri, 2 Apr 2021 19:23:32 +0000 (2 21:23 +0200)
committerPatrick Georgi <pgeorgi@google.com>
Sun, 18 Apr 2021 20:35:18 +0000 (18 20:35 +0000)
tree4cba3caa4ea3e90ec485a0acff6ee1ba1edb3443
parent4681b2778b32b8a1d1b1269e58ee4b8dd5f04f6e
util/kconfig_lint: Turn handle_expressions() into a parser

I wished there was a way to do this in smaller steps, but with
every line fixed an error somewhere else became visible. Here
is a (probably incomplete) list of the issues:

* Only one set of parentheses was supported. This is a hard
  to solve problem without a real parser (one solution is to
  use an recursive RE, see below).

* The precedence order was wrong. Might have been adapted just
  to give a positive result for the arbitrary state of the tree.

* Numbered match variables (e.g. $1, $2, etc.) are not local.
  Calling handle_expressions() recursively once with $1, then
  with $2, resulted in using the final $2 after the first
  recursive call (garbage, practically).

Also, symbol and expression parsing was mixed, making things
harder to follow.

To remedy the issues:

* Split handle_symbol() out. It is called with whitespace
  stripped, to keep the uglier REs in handle_expressions().

* Match balanced parentheses and quotes when splitting
  expressions. In this recursive RE

    /(\((?:[^\(\)]++|(?-1))*\))/

  the `(?-1)` references the outer-most group, thus the whole
  expression itself. So it matches a pair of parentheses with
  a mix of non-parentheses and the recursive rule itself inside.
  This allows us to:

* Order the expression matches according to their precedence
  rules. Now we can match `<expr> '||' <expr>` first as we should
  and everything else falls into its place.

* Remove the bail-out that silenced the undefined behavior.

Change-Id: Ibc1be79adc07792f0721f0dc08b50422b6da88a9
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/52067
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
util/lint/kconfig_lint