---
The second phase of the compiler is syntax analysis or parsing. The parser uses the first components of the tokens produced by the lexical analyzer to create a tree-like intermediate representation that depicts the grammatical structure of the token stream. A typical representation is a syntax tree in which each interior node represents an operation and the children of the node represent the arguments of the operation. A syntax tree for the token stream (1.2) is shown as the output of the syntactic analyzer in Fig. 1.7.
This tree shows the order in which the operations in the assignment
position = initial + rate * 60
are to be performed.---
For context, token stream 1.2 is the sequence of lexer output "ID1 = ID2 + ID3 * 60" (7 tokens long), and Figure 1.7 shows that sequence being transformed by a parser into the tree "[= ID1 [+ ID2 [* ID3 60]]]".
Back to the textbook:
---
The subsequent phases of the compiler use the grammatical structure to help analyze the source program and generate the target program.
---
I'm struggling to see where this disagrees with my earlier comment in even the most minor detail.
I notice that the quote you provide comes from a later chapter, "A Simple Syntax-Directed Translator", and that there is no suggestion there that parsing involves semantic actions. Rather, semantic actions annotated on to a finished parse tree are presented as a tool for generating translations.
Had you moved on to the chapter section immediately following the one you quoted from -- the one titled "Parsing" (page 60) -- you might have seen that it opens by saying this:
Parsing is the process of determining how a string of terminals can be generated by a grammar.
But that's just a false claim. The book does no such thing. The book, in the quote you pulled, talks about attaching semantic actions to finished parser output. At that point, the parser has already completed its work. It will never do anything again. The actions will neither affect it nor be seen by it. It's kind of like saying that illustration is part of writing a novel because an artist inserts their work into the finished manuscript.
Did you not notice that your quote doesn't contain any form of the word "parse"?
In the diagram displayed in section 1.2 ("The Structure of a Compiler"), we see a statement processed in turn by a lexical analyzer, a syntax analyzer, a semantic analyzer, an intermediate code generator, a code optimizer, and finally a code generator.
The book informs us explicitly that a "syntax analyzer" and a "parser" are the same thing.
But those semantic actions are associated with the intermediate code generator two steps down the pipeline. They've got nothing to do with the parser.
so that's another community's vote for actions as something belonging to The Parser over and above the strict grammar by which that parsing is done.
Even in declarative languages like Haskell, your parser combinators will usually operate in a state monad so you can do things like this. True context-free grammars are rare; many real programmer convenience features have some level of context sensitivity, which is usually handled more easily by side effects in the semantic actions than by generalizing to a context-sensitive parser.
For a simple ambiguous arithmetical grammar, the output of a parser fed "1 + 2 * 3" might be something like "[Mul [Add 1 2] 3]", or "[Add 1 [Mul 2 3]]", or "1 2 3 Mul Add". The form of the representation doesn't matter; it's just an indication of the sequence of steps that gets you from 'nothing' to whatever input string was provided.
But there's not really a concept of 'actions' to go with parsing. Parsing tells you how some string was constructed, or how it might have been constructed.