Reference manual

# Chapter 5 Reference manual

## 5.1 Lexical syntax of Frown

⟨To do: that of Haskell including comments.⟩
⟨To do: Literate grammar file (Bird tracks)⟩.

## 5.2 Syntax of Frown

Grammar file.

`> file : many "not special",`
`> "%{",`
`> many decl;`
`> "}%",`
`> many "not special";`

Note that `"not special"` matches every token except the special curly braces `"%{"` and `"}%"`.
Declaration.

`> decl : terminals;`
`> | nonterminals;`
`> | fixity;`
`> | signature;`
`> | productions;`

Terminal declaration.

`> terminals : "Terminal", "=", sepBy term "|", ";";`
`>`
`> term : opt "*", assoc, terminal;`
`> | opt "*", assoc, literal, "=", terminal;` -- deprecated
`> | opt "*", assoc, terminal, "as", literal;`
`> | opt "*", assoc, "guard", haskell, "as", literal;`
`>`
`> assoc : ;`
`> | "left", Numeral``;`
`> | "right", Numeral``;`
`> | "nonassoc", Numeral``;`

Nonterminal declaration.

`> nonterminals : "Nonterminal", "=", sepBy nonterm "|", ";";`
`>`
`> nonterm : opt "*", nonterminal;`

Fixity declaration.

`> fixity : "left", Numeral``, terminal, ";";`
`> | "right", Numeral``, terminal, ";";`
`> | "nonassoc", Numeral``, terminal, ";";`

Type signature.

`> signature : "::", nonterminal, premise, ";";` -- deprecated
`> | nonterminal, premise, ";";`
`> | "::", "*", nonterminal, ";";` -- deprecated
`> | "*", nonterminal, ";";`
`>`
`> premise : ;`
`> | "<-", sepBy1 nonterminal ",";`

Productions.

`> productions : nonterminal, ":", sepBy symbol ",", ";", alts;`
`>`
`> alts : ;`
`> | attributes, "|", sepBy symbol ",", ";", alts;`
`>`
`> symbol : "insert", terminal;`
`> | "delete", terminal;`
`> | "prec", terminal;`
`> | terminal;`
`> | nonterminal;`

Nonterminal symbols (`expr0` is a variant of `expr` lacking the embedded Haskell production).

`> nonterminal : expr0, attributes;`
`>`
`> expr0 : Varid``, many aexpr0;`
`>`
`> aexpr0 : Varid``;`
`> | Conid``;`
`> | literal;`
`> | "(", sepBy expr ",", ")";`
`> | "[", sepBy expr ",", "]";`
`>`
`> expr : aexpr;`
`> | Varid``, many1 aexpr;`
`> | Conid``, many1 aexpr;`
`>`
`> aexpr : Varid``;`
`> | Conid``;`
`> | literal;`
`> | "(", sepBy expr ",", ")";`
`> | "[", sepBy expr ",", "]";`
`> | haskell;` -- embedded Haskell``

Terminal symbols.

`> terminal : pat;`
`> | literal, haskell, attributes;` -- shortcut
`>`
`> pat : apat;`
`> | Conid``, many1 apat;`
`>`
`> apat : Conid``;`
`> | literal;` -- either literal or shortcut
`> | "(", sepBy pat ",", ")";`
`> | "[", sepBy pat ",", "]";`
`> | haskell;`
`>`
`> literal : String``;`
`> | Numeral``;`
`> | Char``;`

Embedded Haskell (types, patterns, and expressions).

`> attributes : ;`
`> | haskell, attributes;`
`>`
`> haskell : "{", many hs, "}";`
`>`
`> hs : "not brace";`
`> | "{", many hs, "}";`

Note that `"not brace"` matches every token except the curly braces `"{"` and `"}"`.

## 5.3 Predefined schemes

Note that the predefined rules are left-recursive and `run' using constant stack space. Also note that we define rules for arity zero and arity one (the arity specifies the number of attributes/semantic values). The primed versions of the rules work on Hughes's efficient sequence type (a sequence of `a`'s is represented by a function of type `[a] -> [a]`).

### 5.3.1 Optional elements

Arity zero.

`> opt x <- x;`
`> opt x : ;`
`> | x;`

Arity one.

`> opt x {Maybe` `a} <- x {a};`
`> opt x {Nothing``} : ;`
`> {Just` `a} | x {a};`

### 5.3.2 Repetition of elements

Arity zero.

`> many x <- x;`
`> many x : ;`
`> | many x, x;`
`>`
`> many1 x <- x;`
`> many1 x : x, many x;`

Arity one.

`> many x {[a]} <- x {a};`
`> many x {s []} : many' x {s};`
`>`
`> many' x {[a] -> [a]} <- x {a};`
`> many' x {\ as -> as} : ;`
`> {\ as -> s (a : as)} | many' x {s}, x {a};`
`>`
`> many1 x {[a]} <- x {a};`
`> many1 x {a : as} : x {a}, many x {as};`

### 5.3.3 Repetition of elements separated by a second element

Arity zero.

`> sepBy x sep <- x, sep;`
`> sepBy x sep : ;`
`> | sepBy1 x sep;`
`>`
`> sepBy1 x sep <- x, sep;`
`> sepBy1 x sep : x;`
`> | sepBy1 x sep, sep, x;`

Arity one.

`> sepBy x sep {[a]} <- x {a}, sep;`
`> sepBy x sep {[]} : ;`
`> {as} | sepBy1 x sep {as};`
`>`
`> sepBy1 x sep {[a]} <- x {a}, sep;`
`> sepBy1 x sep {s []} : sepBy1' x sep {s};`
`>`
`> sepBy1' x sep {[a] -> [a]} <- x {a}, sep;`
`> sepBy1' x sep`
`> {\ as -> a : as} : x {a};`
`> {\ as -> s (a : as)} | sepBy1' x sep {s}, sep, x {a};`

TODO: also versions where `sep` has arity one.

### 5.3.4 Repetition of possibly empty elements separated by a second element

⟨To do: better name.⟩
Arity zero.

`> optSepBy x sep <- x, sep;`
`> optSepBy x sep : ;`
`> | x;`
`> | optSepBy x sep, sep;`
`> | optSepBy x sep, sep, x;`

Arity one.

`> optSepBy x sep {[a]} <- x {a}, sep;`
`> optSepBy x sep {s []} : optSepBy' x sep {s};`
`>`
`> optSepBy' x sep {[a] -> [a]} <- x {a}, sep;`
`> optSepBy' x sep`
`> {\ as -> as} : ;`
`> {\ as -> a : as} | x {a};`
`> {\ as -> s as} | optSepBy' x sep {s}, sep;`
`> {\ as -> s (a : as)} | optSepBy' x sep {s}, sep, x {a};`

## 5.4 Output formats

⟨To do: Used type names: `Result` and `Terminal`.⟩
⟨To do: Used function names: `frown`. For each start symbol a parser.⟩
The `code=standard` format is due to Doaitse Swierstra [1].
The `code=stackless` format is due to Ross Paterson [2].
The `code=gvstack` format is also due to Ross Paterson.

> `> module Paren` `where`
> `> import Result`
> `>`
> `>` {- frown :-( -}
> `>`
> `> data Stack``= Empty``| T_1` `State` `Stack`
> `>`
> `> data State``= S_1``| S_2``| S_3``| S_4``| S_5``| S_6`
> `>`
> `> data Nonterminal``= Paren`
> `>`
> `> paren tr = parse_1 tr Empty``>>= (\ Paren``-> return ())`
> `>`
> `> parse_1 ts st = reduce_2 ts S_1` `st`
> `>`
> `> parse_2 tr@[] st = parse_3 tr (T_1` `S_2` `st)`
> `> parse_2 ('('``: tr) st = parse_5 tr (T_1` `S_2` `st)`
> `> parse_2 ts st = frown ts`
> `>`
> `> parse_3 ts st = reduce_1 ts st`
> `>`
> `> parse_4 ('('``: tr) st = parse_5 tr (T_1` `S_4` `st)`
> `> parse_4 (')'``: tr) st = parse_6 tr (T_1` `S_4` `st)`
> `> parse_4 ts st = frown ts`
> `>`
> `> parse_5 ts st = reduce_2 ts S_5` `st`
> `>`
> `> parse_6 ts st = reduce_3 ts st`
> `>`
> `> reduce_1 ts (T_1` `_ (T_1` `s st)) = return Paren`
> `>`
> `> reduce_2 ts s st = goto_5 s ts (T_1` `s st)`
> `>`
> `> reduce_3 ts (T_1` `_ (T_1` `_ (T_1` `_ (T_1` `s st))))`
> `> = goto_5 s ts (T_1` `s st)`
> `>`
> `> goto_5 S_1``= parse_2`
> `> goto_5 S_5``= parse_4`
> `>`
> `>` {- )-: frown -}
> `>`
> `> frown _ = fail "syntax error"`

> Figure 5.1: `frown --code=compact Paren.g`.

> `> module Paren` `where`
> `> import Result`
> `>`
> `>` {- frown :-( -}
> `>`
> `> paren tr = state_1 (\ _ -> return ()) tr`
> `>`
> `> state_1 k_1_0 ts = let { goto_paren = state_2 k_1_0 (reduce_3 goto_paren) }`
> `> in reduce_2 goto_paren ts`
> `>`
> `> state_2 k_1_1 k_3_1 ts = case ts of { tr@[] -> state_3 k_1_1 tr;`
> `> '('``: tr -> state_5 k_3_1 tr;`
> `> _ -> frown ts }`
> `>`
> `> state_3 k_1_2 ts = k_1_2 ts`
> `>`
> `> state_4 k_3_1 k_3_3 ts = case ts of { '('``: tr -> state_5 k_3_1 tr;`
> `> ')'``: tr -> state_6 k_3_3 tr;`
> `> _ -> frown ts }`
> `>`
> `> state_5 k_3_2 ts = let { goto_paren = state_4 (reduce_3 goto_paren) k_3_2 }`
> `> in reduce_2 goto_paren ts`
> `>`
> `> state_6 k_3_4 ts = k_3_4 ts`
> `>`
> `> reduce_2 g ts = g ts`
> `>`
> `> reduce_3 g ts = g ts`
> `>`
> `>` {- )-: frown -}
> `>`
> `> frown _ = fail "syntax error"`

> Figure 5.2: `frown --code=stackless Paren.g`.

> `> module Paren` `where`
> `> import Result`
> `>`
> `>` {- frown :-( -}
> `>`
> `> data Nonterminal``= Paren'``| Paren`
> `>`
> `> type Parser``= [Terminal``] -> Result` `Nonterminal`
> `>`
> `> type VStack` `vs v = ((vs, Nonterminal``-> Parser``), v)`
> `>`
> `> paren tr = state_1 () tr >>= (\ Paren'``-> return ())`
> `>`
> `> state_1 :: vs -> Parser`
> `> state_1 = state action_1 goto_1`
> `> action_1 t = reduce_2`
> `> goto_1 Paren``= goto state_2 ()`
> `>`
> `>`
> `> state_2 :: VStack` `vs () -> Parser`
> `> state_2 = state action_2 undefined`
> `> action_2 t = case t of { '('``-> shift state_5 ();`
> `> '$'``-> shift state_3 ();`
> `> _ -> error }`
> `>`
> `> state_3 :: VStack``(VStack` `vs ()) () -> Parser`
> `> state_3 = state action_3 undefined`
> `> action_3 t = reduce_1`
> `>`
> `> state_4 :: VStack``(VStack``(VStack` `vs ()) ()) () -> Parser`
> `> state_4 = state action_4 undefined`
> `> action_4 t = case t of { '('``-> shift state_5 ();`
> `> ')'``-> shift state_6 ();`
> `> _ -> error }`
> `>`
> `> state_5 :: VStack``(VStack` `vs ()) () -> Parser`
> `> state_5 = state action_5 goto_5`
> `> action_5 t = reduce_2`
> `> goto_5 Paren``= goto state_4 ()`
> `>`
> `> state_6 :: VStack``(VStack``(VStack``(VStack` `vs ()) ()) ()) () -> Parser`
> `> state_6 = state action_6 undefined`
> `> action_6 t = reduce_3`
> `>`
> `>`
> `> reduce_1 (((((_, g), ()), _), ()), _) ts`
> `> = accept Paren'``ts`
> `>`
> `> reduce_2 (_, g) ts = g Paren` `ts`
> `>`
> `> reduce_3 (((((((((_, g), ()), _), ()), _), ()), _), ()), _) ts`
> `> = g Paren` `ts`
> `>`
> `> state action goto vs ts = let { gs = (vs, g); g v = goto v gs } in action (head ts) gs ts`
> `>`
> `> shift state v vs ts = state (vs, v) (tail ts)`
> `>`
> `> shift' state v vs ts = state (vs, v) ts`
> `>`
> `> accept v _ = return v`
> `>`
> `> goto state v vs = state (vs, v)`
> `>`
> `> error gs ts = frown ts`
> `>`
> `>` {- )-: frown -}
> `>`
> `> frown _ = fail "syntax error"`

> Figure 5.3: `frown --code=gvstack Paren.g` (requires an explicit EOF symbol).

## 5.5 Invocation and options

`Usage: frown [option ...] file.g ...`

`-b` or `--backtrack`
  generate a backtracking parser (see Sec. 3.2.5)
`-cc`, `-ccompact` or `--code=compact`
  (see Sec. 3.4.5 and 5.4)
`-cg`, `-cgvstack` or `--code=gvstack`
  (see Sec. 3.4.5 and 5.4)
`-cs`, `-cstackless` or `--code=stackless`
  (see Sec. 3.4.5 and 5.4)
`-cstandard` or `--code=standard`
  (see Sec. 3.4.5 and 5.4)
`--copying`
  display details of copying
`-d` or `--debug`
  emit debugging information (see Sec. 3.4.4)
`-e` or `--expected`
  pass a list of expected terminals to ``frown`' (see Sec. 3.3.3)
`-g` or `--ghc`
  use GHC extensions (see Sec. 3.4.5)
`-h`, `-?` or `--help`
`-i` or `--info`
  put additional information into generated file (see Sec. 3.4.4)
`-k[nat]` or `--lookahead[=nat]`
  use k tokens of look-ahead (see Sec. 3.4.3)
`-l` or `--lexer`
  use a monadic lexer (`get :: M` `Terminal`) (see Sec. 3.3.1)
`-n` or `--noinline`
  generate `NOINLINE` pragmas (see Sec. 3.4.5)
`-O` or `--optimize`
  optimize parser (see Sec. 3.4.5)
`-p[nat]` or `--pagewidth[=nat]`
  use the specified pagewidth for pretty printing (see Sec. 3.4.4)
`--prefix[=string]`
  use prefix for Frown-generated variables (see Sec. 3.4.4)
`-sm`, `-smono` or `--signature=mono`
  add monomorphic type signatures (see Sec. 3.4.5)
`-sp`, `-spoly` or `--signature=poly`
  add polymorphic type signatures (see Sec. 3.4.5)
`--suffix[=string]`
  use suffix for frown generated variables (see Sec. 3.4.4)
`-t` or `--trace`
  insert calls to tracing routines (``shift`', ``reduce`' and ``accept`') (see Sec. 3.4.4)
`-v` or `--verbose`
  be verbose
`--version`
  print version information
`--warranty`
  display details of warranty