tl_main.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. /***** tl_spin: tl_main.c *****/
  10. /* Copyright (c) 1995-2003 by Lucent Technologies, Bell Laboratories. */
  11. /* All Rights Reserved. This software is for educational purposes only. */
  12. /* No guarantee whatsoever is expressed or implied by the distribution of */
  13. /* this code. Permission is given to distribute this code provided that */
  14. /* this introductory message is not removed and no monies are exchanged. */
  15. /* Software written by Gerard J. Holzmann. For tool documentation see: */
  16. /* http://spinroot.com/ */
  17. /* Send all bug-reports and/or questions to: bugs@spinroot.com */
  18. /* Based on the translation algorithm by Gerth, Peled, Vardi, and Wolper, */
  19. /* presented at the PSTV Conference, held in 1995, Warsaw, Poland 1995. */
  20. #include "tl.h"
  21. extern FILE *tl_out;
  22. int newstates = 0; /* debugging only */
  23. int tl_errs = 0;
  24. int tl_verbose = 0;
  25. int tl_terse = 0;
  26. int tl_clutter = 0;
  27. int state_cnt = 0;
  28. unsigned long All_Mem = 0;
  29. char *claim_name;
  30. static char uform[4096];
  31. static int hasuform=0, cnt=0;
  32. extern void cache_stats(void);
  33. extern void a_stats(void);
  34. int
  35. tl_Getchar(void)
  36. {
  37. if (cnt < hasuform)
  38. return uform[cnt++];
  39. cnt++;
  40. return -1;
  41. }
  42. int
  43. tl_peek(int n)
  44. {
  45. if (cnt+n < hasuform)
  46. { return uform[cnt+n];
  47. }
  48. return -1;
  49. }
  50. void
  51. tl_balanced(void)
  52. { int i;
  53. int k = 0;
  54. for (i = 0; i < hasuform; i++)
  55. { if (uform[i] == '(')
  56. { k++;
  57. } else if (uform[i] == ')')
  58. { k--;
  59. } }
  60. if (k != 0)
  61. { tl_errs++;
  62. tl_yyerror("parentheses not balanced");
  63. }
  64. }
  65. void
  66. put_uform(void)
  67. {
  68. fprintf(tl_out, "%s", uform);
  69. }
  70. void
  71. tl_UnGetchar(void)
  72. {
  73. if (cnt > 0) cnt--;
  74. }
  75. static void
  76. tl_stats(void)
  77. { extern int Stack_mx;
  78. printf("total memory used: %9ld\n", All_Mem);
  79. printf("largest stack sze: %9d\n", Stack_mx);
  80. cache_stats();
  81. a_stats();
  82. }
  83. int
  84. tl_main(int argc, char *argv[])
  85. { int i;
  86. extern int /* verbose, */ xspin;
  87. tl_verbose = 0; /* was: tl_verbose = verbose; */
  88. tl_clutter = 1-xspin; /* use -X -f to turn off uncluttering */
  89. newstates = 0;
  90. state_cnt = 0;
  91. tl_errs = 0;
  92. tl_terse = 0;
  93. All_Mem = 0;
  94. memset(uform, 0, sizeof(uform));
  95. hasuform=0;
  96. cnt=0;
  97. claim_name = (char *) 0;
  98. ini_buchi();
  99. ini_cache();
  100. ini_rewrt();
  101. ini_trans();
  102. while (argc > 1 && argv[1][0] == '-')
  103. {
  104. switch (argv[1][1]) {
  105. case 'd': newstates = 1; /* debugging mode */
  106. break;
  107. case 'f': argc--; argv++;
  108. for (i = 0; argv[1][i]; i++)
  109. { if (argv[1][i] == '\t'
  110. || argv[1][i] == '\"'
  111. || argv[1][i] == '\n')
  112. argv[1][i] = ' ';
  113. }
  114. strcpy(uform, argv[1]);
  115. hasuform = (int) strlen(uform);
  116. break;
  117. case 'v': tl_verbose++;
  118. break;
  119. case 'n': tl_terse = 1;
  120. break;
  121. case 'c': argc--; argv++;
  122. claim_name = (char *) emalloc(strlen(argv[1])+1);
  123. strcpy(claim_name, argv[1]);
  124. break;
  125. default : printf("spin -f: saw '-%c'\n", argv[1][1]);
  126. goto nogood;
  127. }
  128. argc--; argv++;
  129. }
  130. if (hasuform == 0)
  131. {
  132. nogood: printf("usage:\tspin [-v] [-n] -f formula\n");
  133. printf(" -v verbose translation\n");
  134. printf(" -n normalize tl formula and exit\n");
  135. exit(1);
  136. }
  137. tl_balanced();
  138. if (tl_errs == 0)
  139. tl_parse();
  140. if (tl_verbose) tl_stats();
  141. return tl_errs;
  142. }
  143. #define Binop(a) \
  144. fprintf(tl_out, "("); \
  145. dump(n->lft); \
  146. fprintf(tl_out, a); \
  147. dump(n->rgt); \
  148. fprintf(tl_out, ")")
  149. void
  150. dump(Node *n)
  151. {
  152. if (!n) return;
  153. switch(n->ntyp) {
  154. case OR: Binop(" || "); break;
  155. case AND: Binop(" && "); break;
  156. case U_OPER: Binop(" U "); break;
  157. case V_OPER: Binop(" V "); break;
  158. #ifdef NXT
  159. case NEXT:
  160. fprintf(tl_out, "X");
  161. fprintf(tl_out, " (");
  162. dump(n->lft);
  163. fprintf(tl_out, ")");
  164. break;
  165. #endif
  166. case NOT:
  167. fprintf(tl_out, "!");
  168. fprintf(tl_out, " (");
  169. dump(n->lft);
  170. fprintf(tl_out, ")");
  171. break;
  172. case FALSE:
  173. fprintf(tl_out, "false");
  174. break;
  175. case TRUE:
  176. fprintf(tl_out, "true");
  177. break;
  178. case PREDICATE:
  179. fprintf(tl_out, "(%s)", n->sym->name);
  180. break;
  181. case -1:
  182. fprintf(tl_out, " D ");
  183. break;
  184. default:
  185. printf("Unknown token: ");
  186. tl_explain(n->ntyp);
  187. break;
  188. }
  189. }
  190. void
  191. tl_explain(int n)
  192. {
  193. switch (n) {
  194. case ALWAYS: printf("[]"); break;
  195. case EVENTUALLY: printf("<>"); break;
  196. case IMPLIES: printf("->"); break;
  197. case EQUIV: printf("<->"); break;
  198. case PREDICATE: printf("predicate"); break;
  199. case OR: printf("||"); break;
  200. case AND: printf("&&"); break;
  201. case NOT: printf("!"); break;
  202. case U_OPER: printf("U"); break;
  203. case V_OPER: printf("V"); break;
  204. #ifdef NXT
  205. case NEXT: printf("X"); break;
  206. #endif
  207. case TRUE: printf("true"); break;
  208. case FALSE: printf("false"); break;
  209. case ';': printf("end of formula"); break;
  210. default: printf("%c", n); break;
  211. }
  212. }
  213. static void
  214. tl_non_fatal(char *s1, char *s2)
  215. { extern int tl_yychar;
  216. int i;
  217. printf("tl_spin: ");
  218. if (s2)
  219. printf(s1, s2);
  220. else
  221. printf(s1);
  222. if (tl_yychar != -1 && tl_yychar != 0)
  223. { printf(", saw '");
  224. tl_explain(tl_yychar);
  225. printf("'");
  226. }
  227. printf("\ntl_spin: %s\n---------", uform);
  228. for (i = 0; i < cnt; i++)
  229. printf("-");
  230. printf("^\n");
  231. fflush(stdout);
  232. tl_errs++;
  233. }
  234. void
  235. tl_yyerror(char *s1)
  236. {
  237. Fatal(s1, (char *) 0);
  238. }
  239. void
  240. Fatal(char *s1, char *s2)
  241. {
  242. tl_non_fatal(s1, s2);
  243. /* tl_stats(); */
  244. exit(1);
  245. }