tl_main.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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. unsigned long All_Mem = 0;
  20. static char uform[4096];
  21. static int hasuform=0, cnt=0;
  22. extern void cache_stats(void);
  23. extern void a_stats(void);
  24. int
  25. tl_Getchar(void)
  26. {
  27. if (cnt < hasuform)
  28. return uform[cnt++];
  29. cnt++;
  30. return -1;
  31. }
  32. void
  33. tl_balanced(void)
  34. { int i;
  35. int k = 0;
  36. for (i = 0; i < hasuform; i++)
  37. { if (uform[i] == '(')
  38. { k++;
  39. } else if (uform[i] == ')')
  40. { k--;
  41. } }
  42. if (k != 0)
  43. { tl_errs++;
  44. tl_yyerror("parentheses not balanced");
  45. }
  46. }
  47. void
  48. put_uform(void)
  49. {
  50. fprintf(tl_out, "%s", uform);
  51. }
  52. void
  53. tl_UnGetchar(void)
  54. {
  55. if (cnt > 0) cnt--;
  56. }
  57. static void
  58. tl_stats(void)
  59. { extern int Stack_mx;
  60. printf("total memory used: %9ld\n", All_Mem);
  61. printf("largest stack sze: %9d\n", Stack_mx);
  62. cache_stats();
  63. a_stats();
  64. }
  65. int
  66. tl_main(int argc, char *argv[])
  67. { int i;
  68. extern int verbose, xspin;
  69. tl_verbose = verbose;
  70. tl_clutter = 1-xspin; /* use -X -f to turn off uncluttering */
  71. while (argc > 1 && argv[1][0] == '-')
  72. { switch (argv[1][1]) {
  73. case 'd': newstates = 1; /* debugging mode */
  74. break;
  75. case 'f': argc--; argv++;
  76. for (i = 0; i < argv[1][i]; i++)
  77. { if (argv[1][i] == '\t'
  78. || argv[1][i] == '\"'
  79. || argv[1][i] == '\n')
  80. argv[1][i] = ' ';
  81. }
  82. strcpy(uform, argv[1]);
  83. hasuform = (int) strlen(uform);
  84. break;
  85. case 'v': tl_verbose++;
  86. break;
  87. case 'n': tl_terse = 1;
  88. break;
  89. default : printf("spin -f: saw '-%c'\n", argv[1][1]);
  90. goto nogood;
  91. }
  92. argc--; argv++;
  93. }
  94. if (hasuform == 0)
  95. {
  96. nogood: printf("usage:\tspin [-v] [-n] -f formula\n");
  97. printf(" -v verbose translation\n");
  98. printf(" -n normalize tl formula and exit\n");
  99. exit(1);
  100. }
  101. tl_balanced();
  102. if (tl_errs == 0)
  103. tl_parse();
  104. if (tl_verbose) tl_stats();
  105. return tl_errs;
  106. }
  107. #define Binop(a) \
  108. fprintf(tl_out, "("); \
  109. dump(n->lft); \
  110. fprintf(tl_out, a); \
  111. dump(n->rgt); \
  112. fprintf(tl_out, ")")
  113. void
  114. dump(Node *n)
  115. {
  116. if (!n) return;
  117. switch(n->ntyp) {
  118. case OR: Binop(" || "); break;
  119. case AND: Binop(" && "); break;
  120. case U_OPER: Binop(" U "); break;
  121. case V_OPER: Binop(" V "); break;
  122. #ifdef NXT
  123. case NEXT:
  124. fprintf(tl_out, "X");
  125. fprintf(tl_out, " (");
  126. dump(n->lft);
  127. fprintf(tl_out, ")");
  128. break;
  129. #endif
  130. case NOT:
  131. fprintf(tl_out, "!");
  132. fprintf(tl_out, " (");
  133. dump(n->lft);
  134. fprintf(tl_out, ")");
  135. break;
  136. case FALSE:
  137. fprintf(tl_out, "false");
  138. break;
  139. case TRUE:
  140. fprintf(tl_out, "true");
  141. break;
  142. case PREDICATE:
  143. fprintf(tl_out, "(%s)", n->sym->name);
  144. break;
  145. case -1:
  146. fprintf(tl_out, " D ");
  147. break;
  148. default:
  149. printf("Unknown token: ");
  150. tl_explain(n->ntyp);
  151. break;
  152. }
  153. }
  154. void
  155. tl_explain(int n)
  156. {
  157. switch (n) {
  158. case ALWAYS: printf("[]"); break;
  159. case EVENTUALLY: printf("<>"); break;
  160. case IMPLIES: printf("->"); break;
  161. case EQUIV: printf("<->"); break;
  162. case PREDICATE: printf("predicate"); break;
  163. case OR: printf("||"); break;
  164. case AND: printf("&&"); break;
  165. case NOT: printf("!"); break;
  166. case U_OPER: printf("U"); break;
  167. case V_OPER: printf("V"); break;
  168. #ifdef NXT
  169. case NEXT: printf("X"); break;
  170. #endif
  171. case TRUE: printf("true"); break;
  172. case FALSE: printf("false"); break;
  173. case ';': printf("end of formula"); break;
  174. default: printf("%c", n); break;
  175. }
  176. }
  177. static void
  178. tl_non_fatal(char *s1, char *s2)
  179. { extern int tl_yychar;
  180. int i;
  181. printf("tl_spin: ");
  182. if (s2)
  183. printf(s1, s2);
  184. else
  185. printf(s1);
  186. if (tl_yychar != -1 && tl_yychar != 0)
  187. { printf(", saw '");
  188. tl_explain(tl_yychar);
  189. printf("'");
  190. }
  191. printf("\ntl_spin: %s\n---------", uform);
  192. for (i = 0; i < cnt; i++)
  193. printf("-");
  194. printf("^\n");
  195. fflush(stdout);
  196. tl_errs++;
  197. }
  198. void
  199. tl_yyerror(char *s1)
  200. {
  201. Fatal(s1, (char *) 0);
  202. }
  203. void
  204. Fatal(char *s1, char *s2)
  205. {
  206. tl_non_fatal(s1, s2);
  207. /* tl_stats(); */
  208. exit(1);
  209. }