Skip to content

Commit d214646

Browse files
authored
Merge pull request #143 from NougatBitz/master
Add better `getPosition` implementation
2 parents 5990884 + 86e80d0 commit d214646

File tree

1 file changed

+35
-6
lines changed

1 file changed

+35
-6
lines changed

src/prometheus/tokenizer.lua

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,8 @@ Tokenizer.EOF_TOKEN = {
4444
source = "<EOF>",
4545
}
4646

47-
local function getPosition(source, i)
48-
return source:sub(1, i):gsub("[^\n]", ""):len() + 1, i - source:sub(1, i):gsub("[^\r]", ""):len() + 1;
49-
end
50-
5147
local function token(self, startPos, kind, value)
52-
local line, linePos = getPosition(self.source, self.index);
48+
local line, linePos = self:getPosition(self.index);
5349
local annotations = self.annotations
5450
self.annotations = {};
5551
return {
@@ -65,14 +61,45 @@ local function token(self, startPos, kind, value)
6561
end
6662

6763
local function generateError(self, message)
68-
local line, linePos = getPosition(self.source, self.index);
64+
local line, linePos = self:getPosition(self.index);
6965
return "Lexing Error at Position " .. tostring(line) .. ":" .. tostring(linePos) .. ", " .. message;
7066
end
7167

7268
local function generateWarning(token, message)
7369
return "Warning at Position " .. tostring(token.line) .. ":" .. tostring(token.linePos) .. ", " .. message;
7470
end
7571

72+
function Tokenizer:getPosition(i)
73+
local column = self.columnMap[i]
74+
75+
if not column then --// `i` is bigger than self.length, this shouldnt happen, but it did. (Theres probably some error in the tokenizer, cant find it.)
76+
column = self.columnMap[#self.columnMap]
77+
end
78+
79+
return column.id, column.charMap[i]
80+
end
81+
82+
--// Prepare columnMap for getPosition
83+
function Tokenizer:prepareGetPosition()
84+
local columnMap, column = {}, { charMap = {}, id = 1, length = 0 }
85+
86+
for index = 1, self.length do
87+
local character = string.sub(self.source, index, index) -- NOTE_1: this could use table.clone to reduce amount of NEWTABLE (if that causes any performance issues)
88+
89+
local columnLength = column.length + 1
90+
column.length = columnLength
91+
column.charMap[index] = columnLength
92+
93+
if character == "\n" then
94+
column = { charMap = {}, id = column.id + 1, length = 0 } -- NOTE_1
95+
end
96+
97+
columnMap[index] = column
98+
end
99+
100+
self.columnMap = columnMap
101+
end
102+
76103
-- Constructor for Tokenizer
77104
function Tokenizer:new(settings)
78105
local luaVersion = (settings and (settings.luaVersion or settings.LuaVersion)) or LuaVersion.LuaU;
@@ -132,12 +159,14 @@ function Tokenizer:reset()
132159
self.length = 0;
133160
self.source = "";
134161
self.annotations = {};
162+
self.columnMap = {};
135163
end
136164

137165
-- Append String to this Tokenizer
138166
function Tokenizer:append(code)
139167
self.source = self.source .. code
140168
self.length = self.length + code:len();
169+
self:prepareGetPosition();
141170
end
142171

143172
-- Function to peek the n'th char in the source of the tokenizer

0 commit comments

Comments
 (0)