Я новичок в StackOverflow и, в конце концов, задал этот вопрос после прочтения всего, что смог найти на Inte rnet о перехватах в LPeg. Я изучаю LPeg, и я успешно создал несколько программ, использующих захваты и подстановки текста, используя C и захваты Cs. Однако я понимаю, что все еще что-то ускользает от моего понимания, поскольку я не могу заставить следующую программу заменить таблицы и строки в таблицах.
Следующая программа показывает работу в процессе. Цель программы - прочитать файл, в котором хранится несколько таблиц, и извлечь отдельные таблицы, а также отдельные строки (в программе они называются TUPLES). Я включаю тестовый файл, чтобы проиллюстрировать проблему. Для любопытных, формат файла - это формат StarBase, разработанный Джоном Роллом.
local function mk_read_sbt ()
local lpeg = require'lpeg'
local C, Cs, Ct, P, S, match
= lpeg.C, lpeg.Cs, lpeg.Ct, lpeg.P, lpeg.S, lpeg.match
local EOF = P(-1)
local EOL = P'\n'
local FF = P'\f' -- In Linux with Emacs I use ^L in place of \f.
local SEP = P','
local SPC = P' '
local TABLEITEM = (1 - SPC - SEP - EOL - FF)
* (SPC^0 * (1 - SPC - SEP - EOL - FF))^0
local TABLEITEM0 = (SPC^0 * TABLEITEM * SPC^0)
+ SPC^0
local TABLETUPLE = C(TABLEITEM0 * (SEP * TABLEITEM0)^0) / "<%1>"
local TABLE = C((TABLETUPLE * EOL)^0 * TABLETUPLE^(-1)) / "[[%1]]\n"
local FILE = TABLE^-1 * (FF * TABLE^-1)^0 * EOF
return {file=function (t1) return match(Cs(FILE),t1) end,
tuple=function (t1) return match(TABLETUPLE,t1) end}
end
r1 = mk_read_sbt()
sbt1 = [[
id,name,diameter,height
--,----,--------,------
23,malus,0.153,2.20
54,acer,0.045,0.51
\f
id,cost
--,----
23,1.33
32,4.26
]]
I sh строк, которые будут выглядеть после подстановки,
>print(r1.tuple(sbt1))
<id,name,diameter,height>
К сожалению, это то, что я получаю, когда читаю весь файл, и отдельные строки не экранируются в скобках <>, как я ожидал. Подстановка применялась правильно к двум таблицам в файле, но подстановка TUPLE - нет.
>print(r1.file(sbt1))
[[id,name,diameter,height
--,----,--------,------
23,malus,0.153,2.20
54,acer,0.045,0.51
]]
[[
id,cost
--,----
23,1.33
32,4.26
]]
Проблема в том, что замены, похоже, относятся только к последнему уровню. Из того, что я прочитал, захват «C (...) / замена» должен накапливать все замены, сделанные в шаблоне, даже косвенно через другие правила, но это не так. Есть ли способ заставить накопления замещения на многих уровнях или это плоская система с потерями замещения с более низких уровней?
Спасибо за любые подсказки.
(Редактирование и очистка) Извините если это похоже на монолог, но я чувствую, что двигаюсь вперед, но мне хочется ехать в густом тумане. Поэтому следующий код работает, как я и ожидал, и похоже, что мне нужно каскадные захваты C вместо базовых c C захватов. Вот фрагмент кода, который работает нормально, и результат, который я получаю
local TABLETUPLE = C(TABLEITEM0 * (SEP * TABLEITEM0)^0) / "<%1>"
local TABLE = Cs((TABLETUPLE * EOL)^0 * TABLETUPLE^(-1)) / "[[%1]]\n"
local FILE = Cs(TABLE^-1 * (FF * TABLE^-1)^0 * EOF) / "FILE: %1"
return {file=function (t1) return match(FILE,t1) end,
tuple=function (t1) return match(TABLETUPLE,t1) end}
И ожидаемый результат,
>print(r1.file(sbt1))
FILE: [[<id,name,diameter,height>
<--,----,--------,------>
<23,malus,0.153,2.20>
<54,acer,0.045,0.51>
<>]]
[[<>
<id,cost>
<--,---->
<23,1.33>
<32,4.26>
<>]]
Так что, похоже, я ответил на свой вопрос: Использование Cs захватывает везде вместо использования простых C захватов. Тем не менее я все еще мог бы использовать некоторые подсказки в логике c за этим поведением.