Repository navigation
Print what the parser reads - #706
Merged
Rafael-SOWNet merged 1 commit intoAug 4, 2026
Merged
Conversation
Stringize's contract is that parsing what it prints gives back what was printed, and four kinds of expression broke it -- silently, since a wrong reading is still a valid expression. (2 ^ 3) ^ 2 printed as 2 ^ 3 ^ 2. Powers group to the right, so it is the base that needs bracketing when it is a power of its own, the mirror of the rule the left-associative operators use. The first is 64 and the second is 512. lambda(x, x + 1) printed as x -> x + 1, and -> is the implication operator, so it came back as x implies x + 1. apply(f, 2) printed by juxtaposition, which came back as a power. piecewise(1 provided x > 0) printed as (1 if x > 0), and there is no `if` in the grammar, so it came back as a product with `if` read as an undeclared variable. With two cases it did not parse at all. The three without an operator spelling now print as the function call the parser has. Latexise is unaffected: nothing parses LaTeX, and it had the power right in any case. Adds a round-trip test over 98 expressions covering every node kind, and a syntax reference under Docs/Usage, since the grammar was the only statement of what the language accepts and it is ANTLR source. Suite 4461 passed, 0 failed -- no existing test had pinned the wrong output.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #706 +/- ##
==========================================
+ Coverage 80.99% 81.79% +0.80%
==========================================
Files 155 159 +4
Lines 13687 13795 +108
Branches 1957 2329 +372
==========================================
+ Hits 11086 11284 +198
+ Misses 1990 1858 -132
- Partials 611 653 +42 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stringize's contract is that parsing what it prints gives back what was printed. Four kinds of expression broke it, and all four broke it silently — a wrong reading is still a valid expression, so nothing threw.The one that changes a value
Powers group to the right, so it is the base that needs bracketing when it is a power of its own — the mirror of the rule the left-associative operators use (
Divfalready does<on the left and<=on the right;Powfneeds the opposite).Latexisehad it right all along, which is how I knew where to look.The three that come back as a different node
lambda(x, x + 1)x -> x + 1x implies x + 1—->is the implication operatorapply(lambda(x, x + 1), 2)(x -> x + 1) 2(x implies x + 1) ^ 2piecewise(1 provided x > 0)(1 if x > 0)1 * if * x > 0—ifread as an undeclared variablepiecewise(1 provided x > 0, 2 provided x < 0)(1 if x > 0, 2 if x < 0)None of
->for lambda, juxtaposition for application, oriffor piecewise is in the grammar. They now print as the function call the parser does have:lambda(x, x + 1),apply(f, 2),piecewise(a provided p, b provided q). The piecewise one is the same class of defect as #687 — a printed form that comes back as an implicit product of undeclared variables.Latexiseis untouched. Nothing parses LaTeX, so it is under no such obligation.Tests
A round-trip test over 98 expressions covering every node kind — arithmetic and grouping, all the trigonometric and hyperbolic families, calculus nodes, booleans and comparisons, sets and intervals, matrices, numbers, and the four above. It went from 88/98 to 98/98.
Worth recording what the ten failures were, since two of them are not bugs: the hyperbolic and inverse-hyperbolic functions,
cbrtandsqrare rewritten as they are parsed —sinh(x)is(e^x - e^(-x))/2andarsinh(x)isln(x + sqrt(x^2+1))— so they never print back as themselves. What round-trips is the expression, not the spelling, and the test asserts that.Also: a syntax reference
Sources/AngouriMath/Docs/Usage/Syntax.md. There was none, and the grammar was the only statement of what the language accepts — which is ANTLR source, and not something a user reads. It covers the precedence table, the round-trip contract, the function names, and a short list of the things that catch people out (^groups right; an unknown name is a silent product; intervals use;where vectors use,;->is implication). Every claim in it was checked against the parser rather than read off the grammar.Suite:
Failed: 0, Passed: 4461, Skipped: 14, Total: 4475— no existing test had pinned the wrong output, so nothing needed its expectation changed.Independent of #703 and #705.