Every story and comment from the Hacker News API, in a layout borrowed from 2001.
A comment on Regular, Recursive, Restricted.
Consider the 2 operators example near the end:
Expr = 'number' | '(' Expr ')' | Expr '+' Expr | Expr '*' Expr Expr != Expr '+' [Expr '+' Expr] | Expr '*' [Expr '*' Expr] | Expr '*' [Expr '+' Expr] | [Expr '+' Expr] '*' Expr
Expr!= | Expr '^' [Expr '+' Expr] | [Expr '+' Expr] '^' Expr
Expr!= | Expr '^' [Expr '*' Expr] | [Expr '*' Expr] '^' Expr
There is a simpler but less elegant technique to constrain associativity and precedence: different types used asymmetrically.
Expr_base = 'number' | '(' Expr ')' Expr_plus= Expr_plus '+' Expr_base | Expr_base Expr_mul= Expr_mul '*' Expr_plus| Expr_plus Expr_exp= Expr_mul '^' Expr_exp| Expr_mul Expr=Expr_exp
There are no comments on this comment yet.
Consider the 2 operators example near the end:
There are 1 exclusion per operator to enforce associativity (not problematic) and 2 exclusions (out of 4 trees containing both operators) to enforce precedence. These scale quadratically: if we add, say, exponentiation ('^') we need to add both and And so on.There is a simpler but less elegant technique to constrain associativity and precedence: different types used asymmetrically.
Expr_mul contains no '^', Expr_plus contains no '^' and no '*', Expr_base contains no operator at all.