tl_main.c 5.1 KB

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