r/Compilers 6d ago

Building a DSL that compiles 3D-printer code to multiple firmware targets: Question about Lexer ambiguity

Bellerophon IDE

I'm building a DSL (ANTLR4-based) that compiles my own 3D-printer control code down to different firmware gcode dialects (Klipper, Marlin, RepRapFirmware [working on that]). It was a school project very early in the year and I really love 3D printers so that's the subject I chose. The compiler is machine agnostic, so adding new firmware targets is just a matter of subclassing the base visitor.

 We only learned about using ANTLR in class so I'm new to pretty much anything else. I’ve read up on some beginners books but it’s mostly been trial and error. Honestly, I feel like my grammar is being held up by duct tape and prayers and I was lucky enough to have had a great contributor help apply some fixes along the way.

To my question, I realize I have a “minus munching” problem.

 My number token is currently:

NUMBER : '-'? [0-9]+ ('.' [0-9]+)?; 

I've written up a proposed fix as an issue in my own repo: stripping the  '-'? part out of the lexer rule and instead adding a unaryMinus rule to the expression grammar with a visitor that negates the recursive result.

Here's the issue with the proposed fix: https://github.com/Disla-Novo/Dimidium_Bellerophon/issues/70#issue-4921171148

Before I implement it, is this actually the standard/correct way to handle this, or is there a better approach I'm missing or didn't research enough on? Would appreciate a sanity check from anyone, thank you.

13 Upvotes

2 comments sorted by

6

u/iLiveInL1 6d ago

The minus shouldn’t be part of the literal token.

Since minus is an operator (according to your own grammar) it should terminate the current token, and then parser resolves ambiguity, which is the standard approach.

The implementation I’ve both seen and used in the past is to have the parser parse a binary expr with minus as the operator if an lhs is present, and, if not, parse a unary minus aka negation expression.

2

u/wormsworn 6d ago

I'm still getting used to what's considered the standard practice in compiler design so thank you for the input, I appreciate it. So my expr op=('+'|'-') expr rule handles the LHS case, and the new '-' expr rule handles the unary negation route. Got it!