xiiregexbuilder
FPGA-Accelerated Regular Expression Matching Enginesrc/lexer.cpp (3317B)
1#include "lexer.h"
2#include <stdexcept>
3
4std::string tokenTypeToString(TokenType type) {
5 switch (type) {
6 case TokenType::LITERAL: return "LITERAL";
7 case TokenType::DOT: return "DOT";
8 case TokenType::STAR: return "STAR";
9 case TokenType::PLUS: return "PLUS";
10 case TokenType::QUESTION: return "QUESTION";
11 case TokenType::PIPE: return "PIPE";
12 case TokenType::LPAREN: return "LPAREN";
13 case TokenType::RPAREN: return "RPAREN";
14 case TokenType::LBRACKET: return "LBRACKET";
15 case TokenType::RBRACKET: return "RBRACKET";
16 case TokenType::END_OF_INPUT: return "END_OF_INPUT";
17 default: return "UNKNOWN";
18 }
19}
20
21Lexer::Lexer(const std::string& input, int lineNum)
22 : input(input), pos(0), line(lineNum), col(1) {}
23
24char Lexer::peek() const {
25 if (isAtEnd()) return '\0';
26 return input[pos];
27}
28
29char Lexer::advance() {
30 char current = input[pos++];
31 col++;
32 return current;
33}
34
35bool Lexer::isAtEnd() const {
36 return pos >= input.length();
37}
38
39std::vector<Token> Lexer::tokenize() {
40 std::vector<Token> tokens;
41
42 while (!isAtEnd()) {
43 char c = peek();
44 int currentCharCol = col;
45
46 switch (c) {
47 case '\\':
48 advance(); // consume '\'
49 if (isAtEnd()) throw std::runtime_error("Trailing backslash");
50 tokens.emplace_back(TokenType::LITERAL, advance(), line, currentCharCol);
51 break;
52 case '.':
53 tokens.emplace_back(TokenType::DOT, advance(), line, currentCharCol);
54 break;
55 case '*':
56 tokens.emplace_back(TokenType::STAR, advance(), line, currentCharCol);
57 break;
58 case '+':
59 tokens.emplace_back(TokenType::PLUS, advance(), line, currentCharCol);
60 break;
61 case '?':
62 tokens.emplace_back(TokenType::QUESTION, advance(), line, currentCharCol);
63 break;
64 case '|':
65 tokens.emplace_back(TokenType::PIPE, advance(), line, currentCharCol);
66 break;
67 case '(':
68 tokens.emplace_back(TokenType::LPAREN, advance(), line, currentCharCol);
69 break;
70 case ')':
71 tokens.emplace_back(TokenType::RPAREN, advance(), line, currentCharCol);
72 break;
73 case '[':
74 tokens.emplace_back(TokenType::LBRACKET, advance(), line, currentCharCol);
75 break;
76 case ']':
77 tokens.emplace_back(TokenType::RBRACKET, advance(), line, currentCharCol);
78 break;
79 default:
80 if (c >= 32 && c <= 126) {
81 tokens.emplace_back(TokenType::LITERAL, advance(), line, currentCharCol);
82 } else {
83 throw std::runtime_error("Invalid character at line " + std::to_string(line) +
84 ", column " + std::to_string(currentCharCol) + ": code " + std::to_string(static_cast<unsigned char>(c)));
85 }
86 break;
87 }
88 }
89
90 tokens.emplace_back(TokenType::END_OF_INPUT, '\0', line, col);
91 return tokens;
92}