A Simple Ompass Cempiler — Syntax-directed translation

🧠 What Does “Syntax-Directed” Really Mean?

Let’s take a simple idea:

  • When a compiler sees an addition like a + 3,
    it should compute or generate code for that.
  • When it sees an assignment like x = ...,
    it should store the result.

Every piece of work the compiler does is attached to a rule in the syntax.

So, the syntax (grammar) decides the structure,
and the translation rules decide the meaning or action.

It’s like:

  • Grammar = the skeleton
  • Translation rules = the muscles that move the skeleton

Both work together.


🧩 How Syntax-Directed Translation Works (Friendly Breakdown)

Let’s create a tiny Ompass language again, just like earlier:

  • It supports assignments
  • It allows arithmetic expressions
  • It uses variables and numbers

Here’s a simple grammar, but this time with translation rules added:

<statement> → <id> = <expression>     { print("assign " + id.name) }

<expression> → <expression> + <term>  { print("add") }
<expression> → <expression> - <term>  { print("sub") }
<expression> → <term>

<term> → <term> * <factor>            { print("mul") }
<term> → <term> / <factor>            { print("div") }
<term> → <factor>

<factor> → <number>                   { print("push " + number.value) }
<factor> → <id>                       { print("push " + id.name) }
<factor> → ( <expression> )

Don’t worry about the code in curly braces — it simply describes what the compiler does when that rule matches.

For example:

  • When it sees a number like 7, the rule says:
    → push 7
    meaning: “Store this value for later use.”
  • When it sees +, the rule says:
    → add
    meaning: “Combine the top two values.”

This is the heart of syntax-directed translation.


Translation

Let’s translate this tiny program:

x = a + 3

What happens?

  1. The compiler sees a → push a
  2. Then sees 3 → push 3
  3. Then sees + → add
  4. Then the assignment rule prints assign x

So the final output (or intermediate code) looks like:

push a
push 3
add
assign x

This is how a simple Ompass compiler would understand and translate code.


🌳 Diagram: Syntax-Directed Translation Tree

Below is a simple, hand-drawn style diagram showing how translation happens alongside the parse tree.

                       <statement>
                           |
         --------------------------------------------------
         |                                                |
       <id>                                        <expression>
        |                                              |
        x                        ----------------------------------------
                                   |                                    |
                                 <expression>                         + <term>
                                     |                                      |
                                   <term>                                 <factor>
                                      |                                      |
                                    <factor>                                 3
                                      |
                                      a

Attached translation actions (shown in order they fire):

push a
push 3
add
assign x

The compiler processes the tree bottom-up.
As it reaches each node, it triggers the action connected to that rule.


🧩 Why Syntax-Directed Translation Is Important

Syntax-directed translation helps a compiler:

✔ generate intermediate code
✔ evaluate expressions
✔ type-check values
✔ build symbol tables
✔ simplify later stages like optimization and code generation

It’s like giving the compiler a map that says:

“Whenever you see this, produce that.”

This keeps everything organized and predictable.