//
// For parsing context-free grammars
//

//
// Author: Hongwei Xi (hwxi AT cs DOT bu DOT edu)
// Time: February, 2009
//

(* ****** ****** *)

abstype symbol_t

fun symbol_make_string (name: string): symbol_t
fun symbol_make_string_int {n:pos} (name: string n, ind: int): symbol_t

fun symbol_index_get (_: symbol_t): int

fun symbol_is_term (_: symbol_t): bool
fun symbol_is_nonterm (_: symbol_t): bool

fun eq_symbol_symbol (_: symbol_t, _: symbol_t): bool
overload = with eq_symbol_symbol 

fun compare_symbol_symbol (_: symbol_t, _: symbol_t): Sgn
overload compare with compare_symbol_symbol 

fun print_symbol (_: symbol_t): void
fun print_symbol_list (_: List symbol_t): void

(* ****** ****** *)

abstype symbolset_t
val symbolset_nil : symbolset_t
fun symbolset_sing (x: symbol_t): symbolset_t
fun symbolset_ismem (xs: symbolset_t, x: symbol_t): bool
fun symbolset_add_flag (xs: symbolset_t, x: symbol_t, flag: &int): symbolset_t
fun symbolset_union_flag (xs: symbolset_t, ys: symbolset_t, flag: &int): symbolset_t

fun print_symbolset (_: symbolset_t): void

(* ****** ****** *)

fun symbol_is_nullable (sym: symbol_t): bool
fun symbol_isnot_nullable (sym: symbol_t): bool
fun symbol_nullable_set (sym: symbol_t, v: bool): void

fun symbol_FIRSTSET_get (sym: symbol_t): symbolset_t
fun symbol_FIRSTSET_set (sym: symbol_t, v: symbolset_t): void

fun symbol_FOLLOWSET_get (sym: symbol_t): symbolset_t
fun symbol_FOLLOWSET_set (x: symbol_t, v: symbolset_t): void

(* ****** ****** *)

datatype rule = RULE of (string(*name*), symbol_t, array0 (symbol_t))

fun print_rule (r: rule): void

(* ****** ****** *)

typedef grammar = '{
  termlst= List symbol_t (*terminals*)
, nontermlst= List symbol_t (*nonterminals*)
, rules= List rule
} // end of [grammar]

fun print_grammar (G: grammar): void
fun print_nullable_first_follow_tables (G: grammar): void

fun compute_nullable_first_follow_tables (G: grammar): void

(* ****** ****** *)

datatype partree =
  | PTnode of (string(*name*), symbol_t, List partree)
  | PTleaf of symbol_t

(* ****** ****** *)

(* end of [grammar.sats] *)