LLlex.c 2.9 KB

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