masaori335 opened a new pull request, #13857:
URL: https://github.com/apache/trafficserver/pull/13857
# Motivation
The CST emitter renders `.conf` text while it walks the parse tree, so
resolving a name and printing it happen in the same step. There is nowhere to
hang a second backend, or a check that needs the resolved program rather than
the text.
# Approach
A resolve pass (`sema`) turns the AST into a backend-neutral resolved tree
(`sema_nodes`), and a `.conf` emitter (`emit_conf`) renders that tree.
`compile_to_conf` wires them together:
```
[parse tree] -> ASTVisitor -> [AST] -> Sema -> [resolved tree] ->
ConfEmitter -> [.conf]
```
Nothing calls it yet. The CLI still goes through the CST emitter, so shipped
behaviour does not change. Until the switchover, comparing the two paths (see
Testing) is what shows the new one is correct.
`symbols.lookup_*`, `procedures.ProcRegistry` and sema's copies of the
argument splitting and `{{...}}` unescaping live next to the CST emitter's
versions instead of replacing them, because the CST emitter still calls those
until it is deleted.
# Testing
Like `tests/test_ast_roundtrip.py`, the new `tests/test_front_end_parity.py`
runs the whole corpus through two paths and requires them to agree. Here the
two paths are the current CST emitter, which acts as the oracle, and the new
Sema path, and both are handed the same parse tree.
```
[corpus .hrw4u]
|
| parse
v
[parse tree]
/ \
/ \
HRW4UVisitor ASTVisitor ---.
(the CST oracle) | |
| [AST] |
| | |
| Sema | compile_to_conf
| | |
| [resolved tree] |
| | |
| ConfEmitter ---'
| |
v v
[config, diagnostics] [config, diagnostics]
^ ^
\ /
'---- must match -----'
```
- **Inputs:** all 159 inputs under `tests/data` (successes, `.fail` cases
and the sandbox fixtures under their own policies), plus 39 synthetic cases for
constructs the corpus has no fixture for. Each runs twice: with an error
collector, and without one, as `--stop-on-error` does.
- **What must match:** the errors and warnings, compared by file, line,
column, message and notes. A wrong line or a dropped note leaves the config
untouched, so a plain "did it fail" check would miss it. Where no error was
reported, the config must match too. A run that reported an error writes no
config, so there is none to compare.
- **One exception:** `procedures/wrong-arity`, where the CST emitter raises
even though it holds an error collector. Sema collects the same error instead.
- **Unit tests:** `tests/test_sema.py` and `tests/test_emit_conf.py` cover
the tree and the emitter directly, including what parity cannot compare because
the CST emitter raises there, such as a cycle between two procedures.
- **`make test`:** 1447 passed.
- **CLI unchanged:** ran the `hrw4u` CLI on every `tests/data` input with 5
flag sets (default, `--stop-on-error`, `--no-comments`, `--output hrw4u`,
`--error-format json`), 795 runs in all. stdout, stderr and the exit code match
`master` byte for byte.
# Follow-ups
- Switch the CLI to `compile_to_conf` and delete the CST emitter. Error
paths where the CST emitter raises despite a collector, such as
`procedures/wrong-arity` and a cycle between two procedures, will then report
collected errors instead.
- After that, move the sandbox checks into a single pass over the resolved
tree.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]