Ich versuche, Lua 5.3 Strings zu parsen. Ich habe jedoch ein Problem festgestellt. Zum BeispielParsing Lua Strings, genauer gesagt Zeilenumbrüche
$ lua
Lua 5.3.4 Copyright (C) 1994-2017 Lua.org, PUC-Rio
> print(load('return "\\z \n\r \n\r \r\n \n \n \\x"', "@test"))
nil test:6: hexadecimal digit expected near '"\x"'
>
> print(load('return "\\z\n\r\n\r\r\n\n\n\\x"', "@test"))
nil test:6: hexadecimal digit expected near '"\x"'
Diese beiden Fehler in Zeile 6, und die Logik dahinter ist recht einfach: Zeilenumbrüche essen (\ r oder \ n), wenn sie von der aktuellen anders sind (ich glauben um eine genaue Beschreibung zu sein, wie der Lua Lexer funktioniert, aber ich kann falsch liegen).
Ich habe diesen Code, die es tun soll:
local ln = 1
local skip = false
local mode = 0
local prev
for at, crlf in eaten:gmatch('()[\r\n]') do
local last = eaten:sub(at-1, at-1)
if skip and prev == last and last ~= crlf then
skip = false
else
skip = true
ln = ln + 1
end
prev = crlf
end
, ob Zeilenumbrüche auf dem vorherigen Zeichen basierend zu essen entscheidet. Nun, von dem, was ich sagen kann, das sollte funktionieren, aber egal was ich tue es scheint nicht zu funktionieren. Andere Versuche haben es 5 Zeilen gemeldet, während dieser Bericht 9 (!) Meldet. Was fehlt mir hier? Ich betreibe dies auf Lua 5.2.4.
Dies ist Teil einer Routine \z
zum Parsen:
local function parse52(s)
local startChar = string.sub(s,1,1)
if startChar~="'" and startChar~='"' then
error("not a string", 0)
end
local c = 0
local ln = 1
local t = {}
local nj = 1
local eos = #s
local pat = "^(.-)([\\" .. startChar .. "\r\n])"
local mkerr = function(emsg, ...)
error(string.format('[%s]:%d: ' .. emsg, s, ln, ...), 0)
end
local lnj
repeat
lnj = nj
local i, j, part, k = string.find(s, pat, nj + 1, false)
if i then
c = c + 1
t[c] = part
if simpleEscapes[v] then
--[[ some code, some elseifs, some more code ]]
elseif v == "z" then
local eaten, np = s:match("^([\t\n\v\f\r ]*)%f[^\t\n\v\f\r ]()", nj+1)
local p=np
nj = p-1
--[[ the newline counting routine above ]]
--[[ some other elseifs ]]
end
else
nj = nil
end
until not nj
if s:sub(-1, -1) ~= startChar then
mkerr("unfinished string near <eof>")
end
return table.concat(t)
end
'crlf' ist immer 'nil' weil' appeared: gmatch ('() [\ r \ n]') 'gibt nur EINE Aufnahme zurück. Wahrscheinlich willst du, dass dein Muster '() ([\ r \ n])' 'ist? –
@EgorSriptunoff Das löst es, aber ich kann einen Kommentar nicht als Antwort akzeptieren. – SoniEx2
Ja, das ist ein berüchtigter Fehler der SO: Kommentare dürfen nicht akzeptiert werden, obwohl sie eine Antwort enthalten könnten :-) –