skip to content

questions

21

In a grammar written down as production rules, what distinguishes a terminal from a nonterminal?

level: juniorimportance: must knowfreq 60%

answer

  1. one kind of symbol never changes
  2. placeholders versus the words users type
  3. check which side of the arrow
  4. never on a left-hand side means terminal
  5. one nonterminal is designated the start

basics

~10 s

Terminals are the literal symbols that appear in the generated text; nonterminals are named placeholders that some rule rewrites. A derivation starts at one designated start symbol and rewrites nonterminals until only terminals remain.

solid answer

~40 s

A production rule has one nonterminal on its left and a sequence of symbols on its right. **Terminals** are the atoms of the language — the words, operators and punctuation a user actually types; nothing ever rewrites them. **Nonterminals** are names for structure, such as `FILTER`, `TERM` or `VALUE`; each one must be replaced by the right-hand side of some rule before the text is finished. One nonterminal is the **start symbol**, and the language the grammar defines is exactly the set of terminal-only strings reachable from it. The mechanical test is positional: if a symbol never appears on the left-hand side of any rule, it is a terminal. So in `TERM -> FIELD is VALUE`, the word `is` is a terminal and the three uppercase names are nonterminals.

go deeper

for a junior

Recall the positional test: a symbol that never appears on the left of an arrow is a terminal and ends up in the text; everything else is a placeholder that must be rewritten first.

for a middle

Explain the four parts of a grammar and walk an unfamiliar rule set out loud: name the terminals, the nonterminals, the alternatives hidden behind a vertical bar, and the designated start symbol.

for a senior

Show that you read a rule set as a specification of legal inputs, and name the two faults that make one wrong in production: a nonterminal with no production, and rules unreachable from the start symbol.

for a principal

Argue when a team is better served by a written rule set than by a hand-written validator as the definition of its input language, and who owns keeping the two in step.

## A grammar is a generator, not a parser A grammar written down as production rules is not code and not a parser. It is a **rewriting system** that generates strings. Formally it has four parts: 1. a finite set of **terminals** — the alphabet of the language being defined; 2. a finite set of **nonterminals** — names for the structures in it, disjoint from the terminals; 3. a finite set of **productions**, each of the form `A -> alpha`, where `A` is a single nonterminal and `alpha` is a possibly empty sequence of terminals and nonterminals; 4. a designated **start symbol**, one of the nonterminals. A string belongs to the language exactly when you can begin at the start symbol, repeatedly replace some nonterminal by the right-hand side of one of its productions, and end up with that string of terminals. Nothing else counts as membership, and no parser is needed to define it. ## The two kinds of symbol Take a four-rule set for a dashboard's saved-filter expression language, written before anyone has built a parser for it: ``` FILTER -> TERM and FILTER | TERM TERM -> FIELD is VALUE FIELD -> status | owner VALUE -> open | me ``` Here the terminals are `and`, `is`, `status`, `owner`, `open` and `me` — six literal words that can appear in something a user types, such as `status is open and owner is me`. The nonterminals are `FILTER`, `TERM`, `FIELD` and `VALUE`; none of them ever appears in a finished filter, because each is a placeholder waiting to be rewritten. `FILTER` is the start symbol. | | Terminal | Nonterminal | |---|---|---| | Appears on a left-hand side | never | always, in at least one rule | | Survives into the generated string | yes | no | | Can be rewritten | no | yes, by any of its productions | | Typical role | a keyword, operator, literal or punctuation mark | a named structure such as an expression or a clause | | Written how | often quoted, or in lower case by convention | often in angle brackets, or in upper case by convention | The notation varies — some documents quote every terminal, some put nonterminals in angle brackets, some rely on case alone — but the structural distinction never varies, and neither does the positional test: a symbol that is never on the left of an arrow cannot be rewritten, so it is a terminal. ## What the start symbol buys you The start symbol is **designated, not inferred**. A grammar with the same rules but a different start symbol defines a different language: starting from `TERM` in the rule set above gives only single comparisons such as `owner is me`, never a chain joined by `and`. Listing a rule first is a common convention for marking the start symbol, but it is a convention, and a careful spec states it outright. ## Alternatives, and two ways a rule set goes wrong The vertical bar is shorthand for several productions sharing one left-hand side: `FIELD -> status | owner` is two productions, not one. Alternatives are choices offered to the generator, so a derivation picks exactly one of them each time it rewrites that nonterminal. Two structural faults show up when reading an unfamiliar rule set, and both are worth naming aloud: - **A nonterminal with no production.** Any derivation that introduces it can never finish, because nothing can rewrite it and it is not a terminal. Such a rule set generates fewer strings than its author intended, sometimes none at all. - **A nonterminal unreachable from the start symbol.** Its rules are dead text: no derivation can ever introduce it, so deleting them changes nothing about the language. Neither fault is detectable by eye in a large rule set, which is why grammar tooling reports both. ## Why an engineer is asked this The distinction is the entry fee for every later conversation about syntax. A team that writes its saved-filter language down as a rule set gets one artefact that says precisely which strings are legal, independent of whichever hand-written validator happens to be deployed. Reading that artefact means knowing which symbols are the surface the user types and which are the structure the team invented to describe it. If a candidate cannot separate the two, nothing built on top of a grammar — a derivation, a tree, a generated parser, a diagnostic message — can be discussed with them.

  • How do you know which nonterminal is the start symbol?
    It is designated by the grammar, not derived from the rules. Many documents adopt the convention that the first rule listed defines it, but that is only a convention. Changing the start symbol while keeping every rule changes the language: starting from a comparison rule generates single comparisons only, never the chained form the author intended.
  • What does the vertical bar in a production mean?
    It is shorthand for several productions that share one left-hand side, so `FIELD -> status | owner` is two productions written on one line. Each is an alternative the generator may choose when it rewrites that nonterminal, and exactly one of them is used at each rewriting step.
  • What happens if a nonterminal appears on some right-hand side but has no production of its own?
    Every derivation that introduces it becomes stuck: the symbol is not a terminal so the string is not finished, and no rule can replace it. The rule set therefore generates fewer strings than intended, and in the worst case none. Grammar tooling reports this alongside the opposite fault, a nonterminal unreachable from the start symbol.

saying these in an interview costs you the question

  • Calls every symbol in the rules a keyword of the language.
  • Thinks nonterminals can appear in the finished string.
  • Believes any nonterminal may serve as the start symbol.
  • Treats quoted punctuation as decoration rather than a terminal.
  • Says a rule set defines a parser rather than a set of strings.
  • Reads a vertical bar as one production instead of several.
open as a page

Under a condition grammar, one saved rule string has two parse trees — what does calling that grammar ambiguous mean?

level: middleimportance: must knowfreq 64%

basics

~20 s

Ambiguity means the grammar admits two distinct parse trees for one string, so the tree — and therefore the meaning the string denotes — is not fixed by the grammar alone. Two conforming parsers may legitimately disagree.

open as a page

How does a leftmost derivation of a string differ from a rightmost derivation of the same string?

level: middleimportance: must knowfreq 52%

basics

~20 s

Both rewrite the same nonterminal occurrences by the same rules, but in a different order: a leftmost derivation always rewrites the leftmost nonterminal of the current line, a rightmost derivation always the rightmost one. The intermediate lines differ; the rule applications do not.

open as a page

A pushdown automaton is a finite-state control plus one unbounded stack; what does that stack let it recognise that finite state alone cannot?

level: middleimportance: must knowfreq 66%

basics

~20 s

The stack is memory that grows with the input, so the machine can match nesting of any depth: push a marker on every opener, pop and compare on every closer, and accept a run whose store ends exhausted.

open as a page

How do you rewrite a directly left-recursive rule such as `list -> list ',' item` so a top-down parser can use it?

level: middleimportance: must knowfreq 66%

basics

~20 s

Split the alternatives: replace A -> A alpha | beta with A -> beta A2 and A2 -> alpha A2 | empty. The recursive part becomes a repeating tail, so the parser consumes the leading beta before re-entering and the recursion terminates.

open as a page

In a rule language with optional else branches, why does "if A then if B then X else Y" parse two ways?

level: seniorimportance: must knowfreq 57%

basics

~20 s

Because the grammar lets a conditional be a statement with or without an else, the single else can attach to either if, giving two trees. Implementations settle it by convention — nearest unmatched if — and a grammar-level fix splits statements into matched and unmatched forms.

open as a page

A pushdown automaton accepts a^n b^n but none accepts a^n b^n c^n; why does one stack stop there?

level: seniorimportance: must knowfreq 52%

basics

~20 s

One stack holds one live count and spending it destroys it. Matching the b's pops away the record of how many a's there were, so nothing remains to check the c's against, and two independent matched counts are beyond the model.

open as a page

How do you rewrite a flat expression grammar so that operator precedence and associativity follow from the rule shape?

level: middleimportance: should knowfreq 52%

basics

~20 s

Split the single expression rule into one layer per precedence level — expression, term, factor — so a tighter operator is reachable only by descending. Recurse on the left for left-associative operators and on the right for right-associative ones.

open as a page

How does an EBNF repetition group expand back into plain BNF productions?

level: middleimportance: should knowfreq 38%

basics

~10 s

A repetition group becomes a fresh nonterminal with two productions: one that consumes a single occurrence and recurses, and one empty alternative that ends the chain. The sugar disappears, the language stays the same.

open as a page

How can one sentence have many derivations from a grammar yet only one parse tree?

level: middleimportance: should knowfreq 44%

basics

~20 s

A parse tree records which production was applied to which symbol occurrence, not the order the rewrites happened in. Many derivations that differ only in ordering describe the same parent-child structure, so they draw one tree.

open as a page

In a pushdown automaton, what is the difference between accepting by empty stack and accepting in a final state?

level: middleimportance: should knowfreq 44%

basics

~20 s

Accepting by empty stack ends a successful run with the store exhausted, wherever the control sits; accepting in a final state ends it in a designated state, whatever the store holds. For machines that may guess, the two conventions describe the same languages.

open as a page

Two alternatives of a directive rule both begin with the keyword `import`; why does that defeat a one-token-lookahead parser?

level: middleimportance: should knowfreq 50%

basics

~20 s

A predictive parser chooses an alternative from the next token alone, and both alternatives start with the same one, so the choice is undecidable at that point. Left factoring pulls the shared prefix out and defers the decision until the rules differ.

open as a page

Why can some languages be accepted by a nondeterministic pushdown automaton but by no deterministic one?

level: seniorimportance: should knowfreq 37%

basics

~20 s

A deterministic machine must commit at every step, and some languages hide the point where pushing should turn into popping. Even-length words that read the same both ways carry no midpoint marker, so only a machine allowed to guess accepts them.

open as a page

After you remove the obvious left recursion, a top-down generator still calls the rule set left recursive; how do you find what it means?

level: seniorimportance: should knowfreq 36%

basics

~20 s

Look for indirect recursion: a cycle in the can-begin-with relation, where one nonterminal's first symbol is another that eventually leads back. Substitute the intermediate rules inline until the recursion becomes direct, then apply the usual tail rewrite.

open as a page

An ambiguous condition grammar leaves two evaluators disagreeing about thousands of saved rules — how do you get to one meaning?

level: principalimportance: should knowfreq 33%

basics

~20 s

Choose the single intended reading deliberately, then make it unforgeable: pin it in the grammar, re-parse every stored rule to find the subset whose two trees differ, review that subset with its owners, and version the language rather than rewriting meanings silently.

open as a page

Your envelope reader is a stack machine, but the model's unbounded store meets finite memory; how do you set and enforce a nesting-depth limit?

level: principalimportance: should knowfreq 31%

basics

~20 s

Treat depth as untrusted input: measure the deepest legitimate document, set a limit with headroom above it, check it at the push rather than waiting for memory to run out, reject over-deep input with a distinct reason, and publish the number as part of the format contract.

open as a page

A readable published rule set is left recursive and your top-down generator rejects it — do you rewrite the rules or change parser family?

level: principalimportance: should knowfreq 40%

basics

~20 s

Decide by who reads the rules. If the rule set is a published specification, keep it as authored and let a parser family that accepts left recursion consume it; if it is an internal input to one tool, rewrite it and treat the transformed form as generated output.

open as a page

Why can no tool certify an arbitrary context-free grammar as unambiguous before you ship a rule language?

level: seniorimportance: nice to knowfreq 24%

basics

~20 s

Deciding whether an arbitrary context-free grammar is ambiguous is undecidable, so no checker can be both sound and complete. Tools instead search for a witness string, which can only ever find ambiguity, or restrict the grammar to a class whose successful construction proves uniqueness.

open as a page

A hand-written validator and a written grammar disagree about one input string — how does exhibiting a derivation settle it?

level: seniorimportance: nice to knowfreq 26%

basics

~20 s

Writing out a derivation of the string from the start symbol proves it belongs to the language the grammar defines, so a validator that rejects it disagrees with the specification. Failing to find a derivation proves nothing by itself.

open as a page

Why are the languages a pushdown automaton accepts closed under union but not under intersection?

level: seniorimportance: nice to knowfreq 26%

basics

~20 s

Union needs only one decision at the start: a machine that guesses which of two machines to run accepts exactly their union. Intersection would need two stores at once, and a counterexample settles it - two languages whose intersection demands three equal blocks.

open as a page

What does converting a rule set to Chomsky normal form for a CYK-style cubic parser actually cost you?

level: seniorimportance: nice to knowfreq 26%

basics

~20 s

Every production must become two nonterminals or one terminal, so empty and unit productions go, long right-hand sides are split by invented nonterminals, the rule set grows, and the trees the parser returns no longer match the rules anyone authored.

open as a page