tokenizer.c 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "region.h"
  4. #include "stringport.h"
  5. #include "tokenizer.h"
  6. #include "variables.h"
  7. #include "reporting.h"
  8. char tok_buf[TOK_MAX];
  9. int token_end(int chr)
  10. {
  11. return chr == ' ' || chr == '\t' || chr == '\n' || chr == '#';
  12. }
  13. void skip_spaces(string_port *stream)
  14. {
  15. while (!port_eof(stream) && (port_peek(stream) == ' ' || port_peek(stream) == '\t'))
  16. port_getc(stream);
  17. }
  18. void skip_newline(string_port *stream)
  19. {
  20. skip_spaces(stream);
  21. if (port_peek(stream) == '\n')
  22. port_getc(stream);
  23. else
  24. return;
  25. }
  26. void skip_comment(string_port *stream)
  27. {
  28. while (!port_eof(stream) && port_getc(stream) != '\n');
  29. }
  30. int token(string_port *stream)
  31. {
  32. // TODO strings
  33. char *buf;
  34. int l;
  35. skip_spaces(stream);
  36. if (port_eof(stream) || port_peek(stream) == '\n')
  37. return -1;
  38. l = 0;
  39. buf = tok_buf;
  40. // WARNING: fpeek must be done before feof
  41. // otherwise it may not succeed
  42. while (!token_end(port_peek(stream)) && !port_eof(stream)) {
  43. buf[l] = port_getc(stream);
  44. if (buf[l] == '\\') {
  45. buf[l] = port_getc(stream);
  46. port_peek(stream);
  47. if (port_eof(stream))
  48. reporterr("end of file when interpreting \\");
  49. }
  50. l++;
  51. if (l >= TOK_MAX-1) {
  52. reporterr("Token too long!");
  53. exit(-1);
  54. }
  55. }
  56. buf[l] = '\0';
  57. if (port_peek(stream) == '#')
  58. skip_comment(stream);
  59. if (!l)
  60. return -1;
  61. return l;
  62. }
  63. char** read_tokens(region *r, string_port *f)
  64. {
  65. char **tokens;
  66. int i, t;
  67. i = 0;
  68. tokens = region_malloc(r, sizeof(char*)*MAX_TOKS_PER_LINE);
  69. while ((t = token(f)) != -1) {
  70. if (!(tokens[i] = expand_variables(r, tok_buf, t))) {
  71. return NULL;
  72. }
  73. i++;
  74. if (i >= MAX_TOKS_PER_LINE) {
  75. reporterr("Line too long!\n");
  76. exit(-1);
  77. }
  78. }
  79. tokens[i] = NULL;
  80. return tokens;
  81. }