You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

184 lines
4.8 KiB

  1. /***** ltl2ba : lex.c *****/
  2. /* Written by Denis Oddoux, LIAFA, France */
  3. /* Copyright (c) 2001 Denis Oddoux */
  4. /* Modified by Paul Gastin, LSV, France */
  5. /* Copyright (c) 2007 Paul Gastin */
  6. /* */
  7. /* This program is free software; you can redistribute it and/or modify */
  8. /* it under the terms of the GNU General Public License as published by */
  9. /* the Free Software Foundation; either version 2 of the License, or */
  10. /* (at your option) any later version. */
  11. /* */
  12. /* This program is distributed in the hope that it will be useful, */
  13. /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
  14. /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
  15. /* GNU General Public License for more details. */
  16. /* */
  17. /* You should have received a copy of the GNU General Public License */
  18. /* along with this program; if not, write to the Free Software */
  19. /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/
  20. /* */
  21. /* Based on the translation algorithm by Gastin and Oddoux, */
  22. /* presented at the 13th International Conference on Computer Aided */
  23. /* Verification, CAV 2001, Paris, France. */
  24. /* Proceedings - LNCS 2102, pp. 53-65 */
  25. /* */
  26. /* Send bug-reports and/or questions to Paul Gastin */
  27. /* http://www.lsv.ens-cachan.fr/~gastin */
  28. /* */
  29. /* Some of the code in this file was taken from the Spin software */
  30. /* Written by Gerard J. Holzmann, Bell Laboratories, U.S.A. */
  31. #include <stdlib.h>
  32. #include <ctype.h>
  33. #include "ltl2ba.h"
  34. static Symbol *symtab[Nhash+1];
  35. static int tl_lex(void);
  36. extern YYSTYPE tl_yylval;
  37. char yytext[2048];
  38. #define Token(y) tl_yylval = tl_nn(y,ZN,ZN); return y
  39. int
  40. isalnum_(int c)
  41. { return (isalnum(c) || c == '_');
  42. }
  43. int
  44. hash(char *s)
  45. { int h=0;
  46. while (*s)
  47. { h += *s++;
  48. h <<= 1;
  49. if (h&(Nhash+1))
  50. h |= 1;
  51. }
  52. return h&Nhash;
  53. }
  54. static void
  55. getword(int first, int (*tst)(int))
  56. { int i=0; char c;
  57. yytext[i++]= (char ) first;
  58. while (tst(c = tl_Getchar()))
  59. yytext[i++] = c;
  60. yytext[i] = '\0';
  61. tl_UnGetchar();
  62. }
  63. static int
  64. follow(int tok, int ifyes, int ifno)
  65. { int c;
  66. char buf[32];
  67. extern int tl_yychar;
  68. if ((c = tl_Getchar()) == tok)
  69. return ifyes;
  70. tl_UnGetchar();
  71. tl_yychar = c;
  72. sprintf(buf, "expected '%c'", tok);
  73. tl_yyerror(buf); /* no return from here */
  74. return ifno;
  75. }
  76. int
  77. tl_yylex(void)
  78. { int c = tl_lex();
  79. #if 0
  80. printf("c = %d\n", c);
  81. #endif
  82. return c;
  83. }
  84. static int
  85. tl_lex(void)
  86. { int c;
  87. do {
  88. c = tl_Getchar();
  89. yytext[0] = (char ) c;
  90. yytext[1] = '\0';
  91. if (c <= 0)
  92. { Token(';');
  93. }
  94. } while (c == ' '); /* '\t' is removed in tl_main.c */
  95. if (islower(c))
  96. { getword(c, isalnum_);
  97. if (strcmp("true", yytext) == 0)
  98. { Token(TRUE);
  99. }
  100. if (strcmp("false", yytext) == 0)
  101. { Token(FALSE);
  102. }
  103. tl_yylval = tl_nn(PREDICATE,ZN,ZN);
  104. tl_yylval->sym = tl_lookup(yytext);
  105. return PREDICATE;
  106. }
  107. if (c == '<')
  108. { c = tl_Getchar();
  109. if (c == '>')
  110. { Token(EVENTUALLY);
  111. }
  112. if (c != '-')
  113. { tl_UnGetchar();
  114. tl_yyerror("expected '<>' or '<->'");
  115. }
  116. c = tl_Getchar();
  117. if (c == '>')
  118. { Token(EQUIV);
  119. }
  120. tl_UnGetchar();
  121. tl_yyerror("expected '<->'");
  122. }
  123. switch (c) {
  124. case '/' : c = follow('\\', AND, '/'); break;
  125. case '\\': c = follow('/', OR, '\\'); break;
  126. case '&' : c = follow('&', AND, '&'); break;
  127. case '|' : c = follow('|', OR, '|'); break;
  128. case '[' : c = follow(']', ALWAYS, '['); break;
  129. case '-' : c = follow('>', IMPLIES, '-'); break;
  130. case '!' : c = NOT; break;
  131. case 'U' : c = U_OPER; break;
  132. case 'V' : c = V_OPER; break;
  133. #ifdef NXT
  134. case 'X' : c = NEXT; break;
  135. #endif
  136. default : break;
  137. }
  138. Token(c);
  139. }
  140. Symbol *
  141. tl_lookup(char *s)
  142. { Symbol *sp;
  143. int h = hash(s);
  144. for (sp = symtab[h]; sp; sp = sp->next)
  145. if (strcmp(sp->name, s) == 0)
  146. return sp;
  147. sp = (Symbol *) tl_emalloc(sizeof(Symbol));
  148. sp->name = (char *) tl_emalloc(strlen(s) + 1);
  149. strcpy(sp->name, s);
  150. sp->next = symtab[h];
  151. symtab[h] = sp;
  152. return sp;
  153. }
  154. Symbol *
  155. getsym(Symbol *s)
  156. { Symbol *n = (Symbol *) tl_emalloc(sizeof(Symbol));
  157. n->name = s->name;
  158. return n;
  159. }