Which of the following is present in a concrete parse tree but typically absent from an AST for the same source code?
AA node representing a function call expression
BParenthesis tokens used to group a sub-expression like (a + b)
CA node for a binary addition operation
DLeaf nodes for variable names
ASTs are 'abstract' because they strip away concrete syntax details — punctuation like parentheses, semicolons, and delimiter keywords that only exist to guide the parser are omitted. Grouping is encoded structurally by nesting: (a + b) * c and a + b * c produce different AST shapes without needing explicit parenthesis nodes. The parse tree records every terminal symbol including punctuation; the AST does not.
Question 2 True / False
The source expressions `(a + b)` and `a + b` will produce different ASTs because they have different surface syntax.
TTrue
FFalse
Answer: False
The whole point of 'abstracting' away from concrete syntax is that semantically equivalent expressions produce identical ASTs. Both `(a + b)` and `a + b` represent the same binary addition and generate the same AST node: a '+' node with children 'a' and 'b'. The parentheses affect the parse tree (which tracks concrete tokens) but not the AST (which captures meaning). This is precisely why compilers use ASTs rather than parse trees for subsequent analysis.
Question 3 Short Answer
What information does a function-call AST node typically need to store, and why is each piece necessary for later compilation phases?
Think about your answer, then reveal below.
Model answer: A function-call node typically stores the callee (function name or expression being called), the list of argument sub-expressions, and source-location metadata. The callee is needed for name resolution and type-checking during semantic analysis. The argument list is needed to verify arity and argument types, and to generate the calling convention during code generation. Source location enables precise error reporting at every phase.
AST node design is driven by downstream requirements: each field exists because a specific later phase needs it. This illustrates why AST design is an architectural decision — compilers often add fields to AST nodes incrementally as they discover what information semantic analysis, optimization, and code generation require.