//
// A grammar example taken from Appel's book:
//   Modern Compiler Design and Implementation in ML
//

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

//
// How to compile:
//   atscc -o grammar_example_3_12 \
//     grammar_example_3_12.dats grammar.sats grammar.dats
//

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

staload "grammar.sats"

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

local

#define K 0

in

val a = symbol_make_string_int ("a", K+0)
val c = symbol_make_string_int ("c", K+1)
val d = symbol_make_string_int ("d", K+2)

val theTermLst = $lst (a, c, d)

end // end of [local]

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

local

#define K 256

in

val X = symbol_make_string_int ("X", K+0)
val Y = symbol_make_string_int ("Y", K+1)
val Z = symbol_make_string_int ("Z", K+2)

val theNontermLst = $lst (X, Y, Z)

end // end of [local]

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

val rule_X_1 = RULE ("rule_X_1", X, alpha) where {
  val alpha = array0_make_arrsz $arrsz {symbol_t} (Y)
} // end of [val]

val rule_X_2 = RULE ("rule_X_2", X, alpha) where {
  val alpha = array0_make_arrsz $arrsz {symbol_t} (a)
} // end of [val]

val rule_Y_1 = RULE ("rule_Y_1", Y, alpha) where {
  val alpha = array0_make_arrsz $arrsz {symbol_t} ()
} // end of [val]

val rule_Y_2 = RULE ("rule_Y_2", Y, alpha) where {
  val alpha = array0_make_arrsz $arrsz {symbol_t} (c)
} // end of [val]

val rule_Z_1 = RULE ("rule_Z_1", Z, alpha) where {
  val alpha = array0_make_arrsz $arrsz {symbol_t} (d)
} // end of [val]

val rule_Z_2 = RULE ("rule_Z_2", Z, alpha) where {
  val alpha = array0_make_arrsz $arrsz {symbol_t} (X, Y, Z)
} // end of [val]

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

val grammar_3_12 = '{
  termlst= theTermLst, nontermlst= theNontermLst, rules= rules
} where {
  val rules = $lst (
    rule_X_1, rule_X_2
  , rule_Y_1, rule_Y_2
  , rule_Z_1, rule_Z_2
  )
} // end of [val]

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

dynload "grammar.dats"

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

implement main () = let
  val () = print "The rules of the Grammar 3.12 are given as follows:\n"
  val () = print_grammar (grammar_3_12)
  val () = compute_nullable_first_follow_tables (grammar_3_12)
in
  print_nullable_first_follow_tables (grammar_3_12)
end // end of [main]

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

(* end of [grammar_example_3_12.dats] *)