Skip to main content
replaced http://programmers.stackexchange.com/ with https://softwareengineering.stackexchange.com/
Source Link

"Let's build a compiler" is a great series for teaching the principles of parsing, but compiler output is not its strong point. The way real compilers deal with this is to separate the parser from the code generator. The parser produces an Abstract Syntax Tree (exampleexample), a tree of in-memory objects that represent the meaning of the code. The AST is passed to a code generator, which produces output from it, but optimizations can be applied, either in between the creation of the AST and the code generation or during the code generation phase.

For example, your code generator could have one or more internal member variables called "current variable" that keeps track of the last variable(s) that the code operated on, and as long as the code continues to work on the same variables, it doesn't need to write out the pops and pushes.

One example of optimization before code generation would be if the tree contains a node for an arithmetic operation, and both operands are constant values, (3 * 5) the compiler could perform the calculation at compile time and then replace the node with a constant value node (15) instead of writing out code to perform the calculation.

"Let's build a compiler" is a great series for teaching the principles of parsing, but compiler output is not its strong point. The way real compilers deal with this is to separate the parser from the code generator. The parser produces an Abstract Syntax Tree (example), a tree of in-memory objects that represent the meaning of the code. The AST is passed to a code generator, which produces output from it, but optimizations can be applied, either in between the creation of the AST and the code generation or during the code generation phase.

For example, your code generator could have one or more internal member variables called "current variable" that keeps track of the last variable(s) that the code operated on, and as long as the code continues to work on the same variables, it doesn't need to write out the pops and pushes.

One example of optimization before code generation would be if the tree contains a node for an arithmetic operation, and both operands are constant values, (3 * 5) the compiler could perform the calculation at compile time and then replace the node with a constant value node (15) instead of writing out code to perform the calculation.

"Let's build a compiler" is a great series for teaching the principles of parsing, but compiler output is not its strong point. The way real compilers deal with this is to separate the parser from the code generator. The parser produces an Abstract Syntax Tree (example), a tree of in-memory objects that represent the meaning of the code. The AST is passed to a code generator, which produces output from it, but optimizations can be applied, either in between the creation of the AST and the code generation or during the code generation phase.

For example, your code generator could have one or more internal member variables called "current variable" that keeps track of the last variable(s) that the code operated on, and as long as the code continues to work on the same variables, it doesn't need to write out the pops and pushes.

One example of optimization before code generation would be if the tree contains a node for an arithmetic operation, and both operands are constant values, (3 * 5) the compiler could perform the calculation at compile time and then replace the node with a constant value node (15) instead of writing out code to perform the calculation.

Source Link
Mason Wheeler
  • 83.3k
  • 24
  • 238
  • 312

"Let's build a compiler" is a great series for teaching the principles of parsing, but compiler output is not its strong point. The way real compilers deal with this is to separate the parser from the code generator. The parser produces an Abstract Syntax Tree (example), a tree of in-memory objects that represent the meaning of the code. The AST is passed to a code generator, which produces output from it, but optimizations can be applied, either in between the creation of the AST and the code generation or during the code generation phase.

For example, your code generator could have one or more internal member variables called "current variable" that keeps track of the last variable(s) that the code operated on, and as long as the code continues to work on the same variables, it doesn't need to write out the pops and pushes.

One example of optimization before code generation would be if the tree contains a node for an arithmetic operation, and both operands are constant values, (3 * 5) the compiler could perform the calculation at compile time and then replace the node with a constant value node (15) instead of writing out code to perform the calculation.