Lexer.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // Standard includes
  2. #include <cctype>
  3. #include <cstdio>
  4. // Local includes
  5. #include "Lexer.h"
  6. /// gettok - Return the next token from standard input.
  7. namespace lexer {
  8. std::string LexerObjects::IdentifierStr; // Filled in if tok_identifier
  9. double LexerObjects::NumVal;
  10. std::string getTokName(int Tok) {
  11. switch (Tok) {
  12. case tok_eof:
  13. return "eof";
  14. case tok_def:
  15. return "def";
  16. case tok_extern:
  17. return "extern";
  18. case tok_identifier:
  19. return "identifier";
  20. case tok_number:
  21. return "number";
  22. case tok_if:
  23. return "if";
  24. case tok_then:
  25. return "then";
  26. case tok_else:
  27. return "else";
  28. case tok_for:
  29. return "for";
  30. case tok_in:
  31. return "in";
  32. case tok_binary:
  33. return "binary";
  34. case tok_unary:
  35. return "unary";
  36. case tok_var:
  37. return "var";
  38. }
  39. return std::string(1, (char)Tok);
  40. }
  41. static int advance() {
  42. int LastChar = getchar();
  43. if (LastChar == '\n' || LastChar == '\r') {
  44. LexLoc.Line++;
  45. LexLoc.Col = 0;
  46. } else
  47. LexLoc.Col++;
  48. return LastChar;
  49. }
  50. int gettok() {
  51. static int LastChar = ' ';
  52. // Skip any whitespace.
  53. while (isspace(LastChar))
  54. LastChar = advance();
  55. if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
  56. LexerObjects::IdentifierStr = LastChar;
  57. while (isalnum((LastChar = getchar())))
  58. LexerObjects::IdentifierStr += LastChar;
  59. if (LexerObjects::IdentifierStr == "def")
  60. return tok_def;
  61. if (LexerObjects::IdentifierStr == "extern")
  62. return tok_extern;
  63. if (LexerObjects::IdentifierStr == "if")
  64. return tok_if;
  65. if (LexerObjects::IdentifierStr == "then")
  66. return tok_then;
  67. if (LexerObjects::IdentifierStr == "else")
  68. return tok_else;
  69. if (LexerObjects::IdentifierStr == "for")
  70. return tok_for;
  71. if (LexerObjects::IdentifierStr == "in")
  72. return tok_in;
  73. if (LexerObjects::IdentifierStr == "binary")
  74. return tok_binary;
  75. if (LexerObjects::IdentifierStr == "unary")
  76. return tok_unary;
  77. if (LexerObjects::IdentifierStr == "var")
  78. return tok_var;
  79. return tok_identifier;
  80. }
  81. if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+
  82. std::string NumStr;
  83. do {
  84. NumStr += LastChar;
  85. LastChar = advance();
  86. } while (isdigit(LastChar) || LastChar == '.');
  87. LexerObjects::NumVal = strtod(NumStr.c_str(), nullptr);
  88. return tok_number;
  89. }
  90. if (LastChar == '#') {
  91. // Comment until end of line.
  92. do
  93. LastChar = getchar();
  94. while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');
  95. if (LastChar != EOF)
  96. return gettok();
  97. }
  98. // Check for end of file. Don't eat the EOF.
  99. if (LastChar == EOF)
  100. return tok_eof;
  101. // Otherwise, just return the character as its ascii value.
  102. int ThisChar = LastChar;
  103. LastChar = getchar();
  104. return ThisChar;
  105. }
  106. }