LLlex.c 2.9 KB

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