LLlex.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /* $Id$ */
  2. /*
  3. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  4. * See the copyright notice in the ACK home directory, in the file "Copyright".
  5. */
  6. /* L L l e x . c
  7. *
  8. * Very simple lexical analyzer.
  9. * Also contains LLmessage().
  10. */
  11. # include <ctype.h>
  12. # include <stdio.h>
  13. # include "tunable.h"
  14. # include "token.h"
  15. # include "Lpars.h"
  16. # include "main.h"
  17. struct token dot; /* current token */
  18. static struct token aside; /* to put currrent token aside, when a token
  19. * is inserted
  20. */
  21. int newline, lineno; /* To keep track of linenumbers */
  22. extern FILE *input; /* file descriptor of machine table */
  23. int LLlex()
  24. {
  25. int c;
  26. if (aside.t_tokno) { /* A token was pushed aside, return it now */
  27. dot = aside;
  28. aside.t_tokno = 0;
  29. return dot.t_tokno;
  30. }
  31. if (newline) { /* delayed increment of lineno, needed to give
  32. * correct line numbers in error messages
  33. */
  34. lineno++;
  35. newline = 0;
  36. }
  37. c = getc(input);
  38. while (c == '/') { /* Could be a comment */
  39. if ((c = getc(input)) == '*') {
  40. /* Yes, it is a comment */
  41. int l;
  42. l = lineno;
  43. do {
  44. do {
  45. if (c == '\n') lineno++;
  46. c = getc(input);
  47. } while (c != '*' && c != EOF);
  48. if (c != EOF) c = getc(input);
  49. } while (c != '/' && c != EOF);
  50. if (c == EOF) {
  51. c = lineno;
  52. lineno = l;
  53. error("Unterminated comment");
  54. lineno = c;
  55. c = EOF;
  56. }
  57. else c = getc(input);
  58. }
  59. else {
  60. ungetc(c, input);
  61. c = '/';
  62. break;
  63. }
  64. }
  65. dot.t_tokno = c;
  66. dot.t_attrib = c;
  67. if (isupper(c) || islower(c) || c == '_') {
  68. dot.t_tokno = LETTER;
  69. return LETTER;
  70. }
  71. if (isdigit(c)) {
  72. dot.t_tokno = DIGIT;
  73. return DIGIT;
  74. }
  75. switch(c) {
  76. case line_term :
  77. dot.t_tokno = LINE_TERMINATOR;
  78. return LINE_TERMINATOR;
  79. case operand_sep :
  80. dot.t_tokno = OPERAND_SEPARATOR;
  81. return OPERAND_SEPARATOR;
  82. case instruction_sep :
  83. dot.t_tokno = INSTRUCTION_SEPARATOR;
  84. return INSTRUCTION_SEPARATOR;
  85. case '-' :
  86. c = getc(input);
  87. if (c == '>') {
  88. dot.t_tokno = PATTERN_SEPARATOR;
  89. return PATTERN_SEPARATOR;
  90. }
  91. ungetc(c,input);
  92. dot.t_tokno = OTHER;
  93. return OTHER;
  94. case open_bracket :
  95. dot.t_tokno = OPEN_BRACKET;
  96. return OPEN_BRACKET;
  97. case close_bracket :
  98. dot.t_tokno = CLOSE_BRACKET;
  99. return CLOSE_BRACKET;
  100. case '\n' :
  101. newline = 1;
  102. /* Fall through */
  103. case ' ' :
  104. case '\t' :
  105. dot.t_tokno = SPACE;
  106. return SPACE;
  107. case '%' :
  108. case EOF :
  109. return c;
  110. default :
  111. /* Let the C-compiler find out what is illegal! */
  112. dot.t_tokno = OTHER;
  113. return OTHER;
  114. }
  115. }
  116. void LLmessage(int d)
  117. {
  118. static int savlineno;
  119. if (savlineno != lineno) {
  120. /* Only an error message if on another line number */
  121. savlineno = lineno;
  122. error("Syntax error");
  123. }
  124. if (d > 0) {
  125. /* "d" is the token to be inserted.
  126. * This is the place to put the current token aside and
  127. * give the inserted token an attribute ... but who cares
  128. */
  129. aside = dot;
  130. }
  131. }