Reference articles on history, science, culture and more
Encyclopedia

Simple precedence grammar

Context-free formal grammar

In computer science, a simple precedence grammar is a context-free formal grammar that can be parsed with a simple precedence parser. The concept was first created in 1964 by Claude Pair, and was later rediscovered, from ideas due to Robert Floyd, by Niklaus Wirth and Helmut Weber who published a paper, entitled EULER: a generalization of ALGOL, and its formal definition, published in 1966 in the Communications of the ACM.

01Formal definition

G = (N, Σ, P, S) is a simple precedence grammar if all the production rules in P comply with the following constraints:

02Simple precedence parser

A simple precedence parser is a type of bottom-up parser for context-free grammars that can be used only by simple precedence grammars.

The implementation of the parser is quite similar to the generic bottom-up parser. A stack is used to store a viable prefix of a sentential form from a rightmost derivation. The symbols ⋖, ≐ and ⋗ are used to identify the pivot, and to know when to Shift or when to Reduce.

Implementation

  • Compute the Wirth-Weber precedence relationship table for a grammar with initial symbol S.
  • Initialize a stack with the starting marker $.
  • Append an ending marker $ to the string being parsed (Input).
  • Until Stack equals "$ S" and Input equals "$"
    • Search the table for the relationship between Top(stack) and NextToken(Input)
    • if the relationship is ⋖ or ≐
      • Shift:
      • Push(Stack, relationship)
      • Push(Stack, NextToken(Input))
      • RemoveNextToken(Input)
    • if the relationship is ⋗
      • Reduce:
      • SearchProductionToReduce(Stack)
      • Remove the Pivot from the Stack
      • Search the table for the relationship between the nonterminal from the production and first symbol in the stack (Starting from top)
      • Push(Stack, relationship)
      • Push(Stack, Non terminal)

SearchProductionToReduce (Stack)

  • Find the topmost ⋖ in the stack; this and all the symbols above it are the Pivot.
  • Find the production of the grammar which has the Pivot as its right side.

Example

Given following language, which can parse arithmetic expressions with the multiplication and addition operations:

E --> E + T' | T' T' --> T T --> T * F | F F --> ( E' ) | num E' --> E

num is a terminal, and the lexer parse any integer as num; E represents an arithmetic expression, T is a term and F is a factor.

and the Parsing table:

EE'TT'F+*()num$
E
E'
T
T'
F
+
*
(
)
num
$
STACK PRECEDENCE INPUT ACTION
$ 2 * ( 1 + 3 )$ SHIFT
$ ⋖ 2 * ( 1 + 3 )$ REDUCE (F -> num)
$ ⋖ F * ( 1 + 3 )$ REDUCE (T -> F)
$ ⋖ T * ( 1 + 3 )$ SHIFT
$ ⋖ T ≐ * ( 1 + 3 )$ SHIFT
$ ⋖ T ≐ * ⋖ ( 1 + 3 )$ SHIFT
$ ⋖ T ≐ * ⋖ ( ⋖ 1 + 3 )$ REDUCE 4× (F -> num) (T -> F) (T' -> T) (E ->T ')
$ ⋖ T ≐ * ⋖ ( ⋖ E + 3 )$ SHIFT
$ ⋖ T ≐ * ⋖ ( ⋖ E ≐ + 3 )$ SHIFT
$ ⋖ T ≐ * ⋖ ( ⋖ E ≐ + < 3 )$ REDUCE 3× (F -> num) (T -> F) (T' -> T)
$ ⋖ T ≐ * ⋖ ( ⋖ E ≐ + ≐ T )$ REDUCE 2× (E -> E + T) (E' -> E)
$ ⋖ T ≐ * ⋖ ( ≐ E' )$ SHIFT
$ ⋖ T ≐ * ⋖ ( ≐ E' ≐ ) $ REDUCE (F -> ( E' ))
$ ⋖ T ≐ * ≐ F $ REDUCE (T -> T * F)
$ ⋖ T $ REDUCE 2× (T' -> T) (E -> T')
$ ⋖ E $ ACCEPT

03Wirth-Weber precedence relationship

In computer science, a Wirth-Weber relationship between a pair of symbols (V_{t}\cup V_{n}) is necessary to determine if a formal grammar is a simple precedence grammar. In such a case, the simple precedence parser can be used. The relationship is named after computer scientists Niklaus Wirth and Helmut Weber.

The goal is to identify when the viable prefixes have the pivot and must be reduced. A \gtrdot means that the pivot is found, a \lessdot means that a potential pivot is starting, and a \doteq means that a relationship remains in the same pivot.

Formal definition

G=\langle V_{n},V_{t},S,P\rangle
{\begin{aligned}X\doteq Y&\iff {\begin{cases}A\to \alpha XY\beta \in P\\A\in V_{n}\\\alpha ,\beta \in (V_{n}\cup V_{t})^{*}\\X,Y\in (V_{n}\cup V_{t})\end{cases}}\\X\lessdot Y&\iff {\begin{cases}A\to \alpha XB\beta \in P\\B\Rightarrow ^{+}Y\gamma \\A,B\in V_{n}\\\alpha ,\beta ,\gamma \in (V_{n}\cup V_{t})^{*}\\X,Y\in (V_{n}\cup V_{t})\end{cases}}\\X\gtrdot Y&\iff {\begin{cases}A\to \alpha BY\beta \in P\\B\Rightarrow ^{+}\gamma X\\Y\Rightarrow ^{*}a\delta \\A,B\in V_{n}\\\alpha ,\beta ,\gamma ,\delta \in (V_{n}\cup V_{t})^{*}\\X,Y\in (V_{n}\cup V_{t})\\a\in V_{t}\end{cases}}\end{aligned}}

Precedence relations computing algorithm

We will define three sets for a symbol:

{\begin{aligned}\mathrm {Head} ^{+}(X)&=\{Y\mid X\Rightarrow ^{+}Y\alpha \}\\\mathrm {Tail} ^{+}(X)&=\{Y\mid X\Rightarrow ^{+}\alpha Y\}\\\mathrm {Head} ^{*}(X)&=(\mathrm {Head} ^{+}(X)\cup \{X\})\cap V_{t}\end{aligned}}
Head*(X) is X if X is a terminal, and if X is a non-terminal, Head*(X) is the set with only the terminals belonging to Head+(X). This set is equivalent to First-set or Fi(X) described in LL parser.
Head+(X) and Tail+(X) are if X is a terminal.

The pseudocode for computing relations is:

  • RelationTable :=
  • For each production A\to \alpha \in P
    • For each two adjacent symbols X Y in α
      • add(RelationTable, X\doteq Y)
      • add(RelationTable, X\lessdot \mathrm {Head} ^{+}(Y))
      • add(RelationTable, \mathrm {Tail} ^{+}(X)\gtrdot \mathrm {Head} ^{*}(Y))
  • add(RelationTable, \$\lessdot \mathrm {Head} ^{+}(S)) where S is the initial non terminal of the grammar, and $ is a limit marker
  • add(RelationTable, \mathrm {Tail} ^{+}(S)\gtrdot \$) where S is the initial non terminal of the grammar, and $ is a limit marker
\lessdot and \gtrdot are used with sets instead of elements as they were defined, in this case you must add all the cartesian product between the sets/elements.

Example 1

S\to aSSb|c

  • Head+(a) =
  • Head+(S) = {a, c}
  • Head+(b) =
  • Head+(c) =
  • Tail+(a) =
  • Tail+(S) = {b, c}
  • Tail+(b) =
  • Tail+(c) =
  • Head*(a) = a
  • Head*(S) = {a, c}
  • Head*(b) = b
  • Head*(c) = c
  • S\to aSSb
    • a Next to S
      • a\doteq S
      • a\lessdot \mathrm {Head} ^{+}(S)
        • a\lessdot a
        • a\lessdot c
    • S Next to S
      • S\doteq S
      • S\lessdot \mathrm {Head} ^{+}(S)
        • S\lessdot a
        • S\lessdot c
      • \mathrm {Tail} ^{+}(S)\gtrdot \mathrm {Head} ^{*}(S)
        • b\gtrdot a
        • b\gtrdot c
        • c\gtrdot a
        • c\gtrdot c
    • S Next to b
      • S\doteq b
      • \mathrm {Tail} ^{+}(S)\gtrdot \mathrm {Head} ^{*}(b)
        • b\gtrdot b
        • c\gtrdot b
  • S\to c
    • there is only one symbol, so no relation is added.
precedence table
{\begin{array}{c|ccccc}&S&a&b&c&\$\\\hline S&\doteq &\lessdot &\doteq &\lessdot &\\a&\doteq &\lessdot &&\lessdot &\\b&&\gtrdot &\gtrdot &\gtrdot &\gtrdot \\c&&\gtrdot &\gtrdot &\gtrdot &\gtrdot \\\$&&\lessdot &&\lessdot &\end{array}}

Example 2

S\to a|aT|[S]

T\to b|bT

  • Head+( S ) = { a, [ }
  • Head+( a ) =
  • Head+( T ) = { b }
  • Head+( [ ) =
  • Head+( ] ) =
  • Head+( b ) =
  • Tail+( S ) = { a, T, ], b }
  • Tail+( a ) =
  • Tail+( T ) = { b, T }
  • Tail+( [ ) =
  • Tail+( ] ) =
  • Tail+( b ) =
  • Head*( S ) = { a, [ }
  • Head*( a ) = a
  • Head*( T ) = { b }
  • Head*( [ ) = [
  • Head*( ] ) = ]
  • Head*( b ) = b
  • S\to aT
    • a Next to T
      • a\doteq T
      • a\lessdot \mathrm {Head} ^{+}(T)
        • a\lessdot b
  • S\to [S]
    • [ Next to S
      • [\doteq S
      • [\lessdot \mathrm {Head} ^{+}(S)
        • [\lessdot a
        • [\lessdot [
    • S Next to ]
      • S\doteq ]
      • \mathrm {Tail} ^{+}(S)\gtrdot \mathrm {Head} ^{*}(])
        • a\gtrdot ]
        • T\gtrdot ]
        • ]\gtrdot ]
        • b\gtrdot ]
  • T\to bT
    • b Next to T
      • b\doteq T
      • b\lessdot \mathrm {Head} ^{+}(T)
        • b\lessdot b
precedence table
{\begin{array}{c|ccccccc}&S&T&a&b&[&]&\$\\\hline S&&&&&&\doteq &\doteq \\T&&&&&&\gtrdot &\gtrdot \\a&&\doteq &&\lessdot &&\gtrdot &\gtrdot \\b&&\doteq &&\lessdot &&\gtrdot &\gtrdot \\{\text{[}}&\doteq &&\lessdot &&\lessdot &&\\]&&&&&&\gtrdot &\gtrdot \\\$&\doteq &&\lessdot &&\lessdot &&\end{array}}
Watch videos about Simple precedence grammarExplainers and documentaries on YouTube (opens in a new tab)

Sources and credits

This article is adapted from the Wikipedia article Simple precedence grammar, written by its contributors and licensed under CC BY-SA 4.0. Fathomly has changed the layout, removed citation markers, navigation and maintenance notices, and adjusted punctuation. This adapted version is shared under the same license. For references, see the original article.

Fathomly is not affiliated with or endorsed by the Wikimedia Foundation. Spotted a problem? Tell us.