nk 1.0.0
C++ Numerical Computing Runtime
Loading...
Searching...
No Matches
lexer.hpp
1#pragma once
2
3#include <string>
4#include <vector>
5
6namespace nk {
7
8enum class TokenType {
9 NUMBER,
10 IMAG_NUMBER,
11 STRING,
12 IDENTIFIER,
13 PLUS,
14 MINUS,
15 STAR,
16 SLASH,
17 BACKSLASH,
18 DOT_BACKSLASH,
19 CARET,
20 DOT_STAR,
21 DOT_SLASH,
22 DOT_CARET,
23 DOT_APOSTROPHE,
24 EQ,
25 NEQ,
26 LT,
27 GT,
28 LEQ,
29 GEQ,
30 AND,
31 OR,
32 TILDE,
33 AND_SHORT,
34 OR_SHORT,
35 ASSIGN,
36 LPAREN,
37 RPAREN,
38 LBRACKET,
39 RBRACKET,
40 LBRACE,
41 RBRACE,
42 COMMA,
43 SEMICOLON,
44 COLON,
45 DOT,
46 NEWLINE,
47 APOSTROPHE,
48 AT,
49 ELLIPSIS,
50 KW_IF,
51 KW_ELSEIF,
52 KW_ELSE,
53 KW_END,
54 KW_FOR,
55 KW_WHILE,
56 KW_BREAK,
57 KW_CONTINUE,
58 KW_RETURN,
59 KW_FUNCTION,
60 KW_TRUE,
61 KW_FALSE,
62 KW_SWITCH,
63 KW_CASE,
64 KW_OTHERWISE,
65 KW_TRY,
66 KW_CATCH,
67 KW_GLOBAL,
68 KW_PERSISTENT,
69 KW_CLASSDEF,
70 DQSTRING,
71 // `%` line comments and `%{ ... %}` block comments — emitted by
72 // the lexer so downstream consumers (tools, formatters, the
73 // script-graph IDE viewer) can position themselves precisely
74 // around them. The parser silently skips COMMENT tokens through
75 // its centralized advance() helper, so script-level grammar is
76 // unaffected.
77 COMMENT,
78 END_OF_INPUT
79};
80
81struct Token
82{
83 TokenType type = TokenType::END_OF_INPUT;
84 std::string value;
85 int line = 0;
86 int col = 0;
87};
88
89class Lexer
90{
91public:
92 explicit Lexer(const std::string &source);
93 std::vector<Token> tokenize();
94
95private:
96 std::string src_;
97 size_t pos_ = 0;
98 int line_ = 1;
99 int col_ = 1;
100 std::vector<Token> tokens_;
101 std::vector<char> bracketStack_;
102
103 char peek() const;
104 char peek(int offset) const;
105 char advance();
106
107 int bracketDepth() const;
108 bool inMatrixContext() const;
109 void pushBracket(char open);
110 void popBracket(char expected);
111
112 bool isAtLineStart() const;
113 bool isAtLineStart(size_t position) const;
114
115 void skipSpacesAndComments();
116 void skipBlockComment();
117 void addToken(TokenType type, const std::string &val, int line, int col);
118 bool isValueToken(TokenType t) const;
119 bool isTransposeContext() const;
120
121 void readNumber();
122 void validateUnderscores(size_t start, size_t end, int startLine, int startCol);
123 void readString(int startLine, int startCol);
124 void readDoubleQuotedString(int startLine, int startCol);
125 void readIdentifier();
126 bool readOperator();
127
128 void insertImplicitComma();
129
130 [[noreturn]] void error(const std::string &msg);
131 [[noreturn]] void error(const std::string &msg, int line, int col);
132
133 static bool isDigit(char c);
134 static bool isAlpha(char c);
135 static bool isAlnum(char c);
136 static bool isXDigit(char c);
137 static char closingFor(char open);
138};
139
140} // namespace nk