text: # updated for FA 2012 grammar
  # thanks to github.com/thehodapp for the update
  T = [
  	"T_PROGRAM",
  	"T_ID",
  	"T_VAR",
  	"T_ARRAY",
  	"T_NUM",
  	"T_OF",
  	"T_INTEGER",
  	"T_REAL",
  	"T_FUNCTION",
  	"T_BEGIN",
  	"T_END",
  	"T_ASSIGNOP",
  	"T_IF",
  	"T_THEN",
  	"T_ELSE",
  	"T_WHILE",
  	"T_DO",
  	"T_RELOP",
  	"T_ADDOP",
  	"T_MULOP",
  	"T_NOT",
  	"T_LPAREN",
  	"T_RPAREN",
  	"T_SEMICOLON",
  	"T_PERIOD",
  	"T_COMMA",
  	"T_COLON",
  	"T_LBRACK",
  	"T_RBRACK",
  	"T_PLUS",
  	"T_MINUS",
  	"T_DOUBLEPERIOD",
  	"",
  ]
  
  V = [
  	"NT_PROGRAM",
  	"NT_DECLARATIONS",
  	"NT_TYPE",
  	"NT_STANDARD_TYPE",
  	"NT_SUBPROGRAM_DECLARATIONS",
  	"NT_SUBPROGRAM_DECLARATION",
  	"NT_SUBPROGRAM_HEAD",
  	"NT_ARGUMENTS",
  	"NT_PARAMETER_LIST",
  	"NT_COMPOUND_STATEMENT",
  	"NT_OPTIONAL_STATEMENTS",
  	"NT_STATEMENT_LIST",
  	"NT_STATEMENT",
  	"NT_VARIABLE",
  	"NT_EXPRESSION_LIST",
  	"NT_EXPRESSION",
  	"NT_SIMPLE_EXPRESSION",
  	"NT_TERM",
  	"NT_FACTOR",
  	"NT_SIGN"
  ]
  
  S = "NT_PROGRAM"
  
  P = [
  	("NT_PROGRAM", "T_PROGRAM T_ID T_LPAREN T_ID T_RPAREN T_SEMICOLON NT_DECLARATIONS NT_SUBPROGRAM_DECLARATIONS NT_COMPOUND_STATEMENT T_PERIOD".split()),
  	("NT_DECLARATIONS", "NT_DECLARATIONS T_VAR T_ID T_COLON NT_TYPE T_SEMICOLON".split()),
  	("NT_DECLARATIONS", [""]),
  	("NT_TYPE", ["NT_STANDARD_TYPE"]),
  	("NT_TYPE", "T_ARRAY T_LBRACK T_NUM T_DOUBLEPERIOD T_NUM T_RBRACK T_OF NT_STANDARD_TYPE".split()),
  	("NT_STANDARD_TYPE", ["T_INTEGER"]),
  	("NT_STANDARD_TYPE", ["T_REAL"]),
  	("NT_SUBPROGRAM_DECLARATIONS", "NT_SUBPROGRAM_DECLARATIONS NT_SUBPROGRAM_DECLARATION T_SEMICOLON".split()),
  	("NT_SUBPROGRAM_DECLARATIONS", [""]),
  	("NT_SUBPROGRAM_DECLARATION", "NT_SUBPROGRAM_HEAD NT_DECLARATIONS NT_SUBPROGRAM_DECLARATIONS NT_COMPOUND_STATEMENT".split()),
  	("NT_SUBPROGRAM_DECLARATION", "NT_SUBPROGRAM_HEAD NT_DECLARATIONS NT_COMPOUND_STATEMENT".split()),
  	("NT_SUBPROGRAM_HEAD", "T_FUNCTION T_ID NT_ARGUMENTS T_COLON NT_STANDARD_TYPE T_SEMICOLON".split()),
  	("NT_ARGUMENTS", "T_LPAREN NT_PARAMETER_LIST T_RPAREN".split()),
  	("NT_ARGUMENTS", [""]),
  	("NT_PARAMETER_LIST", "T_ID T_COLON NT_TYPE".split()), 
  	("NT_PARAMETER_LIST", "NT_PARAMETER_LIST T_SEMICOLON T_ID T_COLON NT_TYPE".split()),
  	("NT_COMPOUND_STATEMENT", "T_BEGIN NT_OPTIONAL_STATEMENTS T_END".split()),
  	("NT_OPTIONAL_STATEMENTS", "NT_STATEMENT_LIST".split()),
  	("NT_OPTIONAL_STATEMENTS", [""]),
  	("NT_STATEMENT_LIST", "NT_STATEMENT".split()),
  	("NT_STATEMENT_LIST", "NT_STATEMENT_LIST T_SEMICOLON NT_STATEMENT".split()),
  	("NT_STATEMENT", "NT_VARIABLE T_ASSIGNOP NT_EXPRESSION".split()),
  	("NT_STATEMENT", "NT_COMPOUND_STATEMENT".split()),
  	("NT_STATEMENT", "T_IF NT_EXPRESSION T_THEN NT_STATEMENT T_ELSE NT_STATEMENT".split()),
  	("NT_STATEMENT", "T_WHILE NT_EXPRESSION T_DO NT_STATEMENT".split()),
  	("NT_STATEMENT", "T_IF NT_EXPRESSION T_THEN NT_STATEMENT".split()),
  	("NT_VARIABLE", "T_ID".split()),
  	("NT_VARIABLE", "T_ID T_LBRACK NT_EXPRESSION T_RBRACK".split()),
  	("NT_EXPRESSION_LIST", "NT_EXPRESSION".split()),
  	("NT_EXPRESSION_LIST", "NT_EXPRESSION_LIST T_COMMA NT_EXPRESSION".split()),
  	("NT_EXPRESSION", "NT_SIMPLE_EXPRESSION".split()),
  	("NT_EXPRESSION", "NT_SIMPLE_EXPRESSION T_RELOP NT_SIMPLE_EXPRESSION".split()),
  	("NT_SIMPLE_EXPRESSION", "NT_TERM".split()),
  	("NT_SIMPLE_EXPRESSION", "NT_SIGN NT_TERM".split()),
  	("NT_SIMPLE_EXPRESSION", "NT_SIMPLE_EXPRESSION T_ADDOP NT_TERM".split()),
  	("NT_TERM", "NT_FACTOR".split()),
  	("NT_TERM", "NT_TERM T_MULOP NT_FACTOR".split()),
  	("NT_FACTOR", "T_ID".split()),
  	("NT_FACTOR", "T_ID T_LPAREN NT_EXPRESSION_LIST T_RPAREN".split()),
  	("NT_FACTOR", "T_NUM".split()),
  	("NT_FACTOR", "T_LPAREN NT_EXPRESSION T_RPAREN".split()),
  	("NT_FACTOR", "T_NOT NT_FACTOR".split()),
  	("NT_FACTOR", "T_ID T_LBRACK NT_EXPRESSION T_RBRACK".split()),
  	("NT_SIGN", ["T_PLUS"]),
  	("NT_SIGN", ["T_MINUS"])
  ]
  
  if S not in V:
  	print "S = %s not in V!" % S
  for lhs,rhs in P:
  	if lhs not in V:
  		print "'%s' not in V!" % lhs
  	for w in rhs:
  		if w not in T and w not in V:
  			print "'%s' not in T! (context: %s)" % (w, lhs)
  		if ' ' in w:
  			print "improperly split?"
  