Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
lervag committed Nov 21, 2024
1 parent 3f08da4 commit 505ba70
Show file tree
Hide file tree
Showing 5 changed files with 361 additions and 539 deletions.
246 changes: 246 additions & 0 deletions lua/vimtex/parser/comb2.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
-- VimTeX - LaTeX plugin for Vim
--
-- Maintainer: Karl Yngve Lervåg
-- Email: [email protected]
--

local pc = require "vimtex.parser.combinators"

---Create parser to match a specified character
---@param match string
---@return Parser
local function char(match)
---@param initial_state ParserState
---@return ParserState
local parser_fn = function(initial_state)
if initial_state.error then
return initial_state
end

if #initial_state.target < initial_state.index then
local new_state = pc.ParserState:new(
initial_state.target,
initial_state.index,
initial_state.result,
"char: unexpected end of input."
)

return new_state
end

local c = initial_state.target:sub(initial_state.index, initial_state.index)

if match == c then
local new_state =
pc.ParserState:new(initial_state.target, initial_state.index + 1, c)
return new_state
end

local new_state = pc.ParserState:new(
initial_state.target,
initial_state.index,
initial_state.result,
"char: unable to match '"
.. c
.. "' with required '"
.. match
.. "' at index "
.. initial_state.index
.. "."
)

return new_state
end

return pc.Parser:new(parser_fn)
end

local letter = pc.Parser:new(function(initial_state)
if initial_state.error then
return initial_state
end

if #initial_state.target < initial_state.index then
local new_state = pc.ParserState:new(
initial_state.target,
initial_state.index,
initial_state.result,
"letter: unexpected end of input."
)

return new_state
end

local c = initial_state.target:sub(initial_state.index, initial_state.index)
local b = string.byte(c)

if (b >= 65 and b <= 90) or (b >= 97 and b <= 122) then
local new_state =
pc.ParserState:new(initial_state.target, initial_state.index + 1, c)
return new_state
end

local new_state = pc.ParserState:new(
initial_state.target,
initial_state.index,
initial_state.result,
"letter: unable to match letter at index " .. initial_state.index .. "."
)

return new_state
end)

---Parser that puts current state to value and nothing more
local peek = pc.Parser:new(function(initial_state)
if initial_state.error then
return initial_state
end

if #initial_state.target < initial_state.index then
local new_state = pc.ParserState:new(
initial_state.target,
initial_state.index,
initial_state.result,
"letter: unexpected end of input."
)

return new_state
end

local c = initial_state.target:sub(initial_state.index, initial_state.index)
local new_state =
pc.ParserState:new(initial_state.target, initial_state.index, c)

return new_state
end)

local blank_space_char = pc.Parser:new(function(initial_state)
if initial_state.error then
return initial_state
end

if #initial_state.target < initial_state.index then
local new_state = pc.ParserState:new(
initial_state.target,
initial_state.index,
initial_state.result,
"blank_space: unexpected end of input."
)

return new_state
end

local c = initial_state.target:sub(initial_state.index, initial_state.index)
local b = string.byte(c)

if
c == "\n"
or c == "\t"
or c == "\r"
or c == " "
or b == 0xb
or b == 0xc
then
local new_state =
pc.ParserState:new(initial_state.target, initial_state.index + 1, c)
return new_state
end

local new_state = pc.ParserState:new(
initial_state.target,
initial_state.index,
initial_state.result,
"blank_space: unable to match blank space at index "
.. initial_state.index
.. "."
)

return new_state
end)

local eof = pc.Parser:new(function(initial_state)
if initial_state.error then
return initial_state
end

if #initial_state.target < initial_state.index then
local new_state = pc.ParserState:new(
initial_state.target,
initial_state.index,
initial_state.result
)

return new_state
end

local error_state = pc.ParserState:new(
initial_state.target,
initial_state.index,
initial_state.result,
"eof: Not end of file."
)

return error_state
end)

local digit = pc.Parser:new(function(initial_state)
if initial_state.error then
return initial_state
end

if #initial_state.target < initial_state.index then
local new_state = pc.ParserState:new(
initial_state.target,
initial_state.index,
initial_state.result,
"digit: unexpected end of input."
)

return new_state
end

local c = initial_state.target:sub(initial_state.index, initial_state.index)
local b = string.byte(c)

if b >= 48 and b <= 57 then
local new_state =
pc.ParserState:new(initial_state.target, initial_state.index + 1, c)
return new_state
end

local new_state = pc.ParserState:new(
initial_state.target,
initial_state.index,
initial_state.result,
"digit: unable to match digit at index " .. initial_state.index .. "."
)

return new_state
end)

---Create parser to match given string
---@param match string
---@return Parser
local function str(match)
local parsers = {}
for i = 1, #match do
parsers[#parsers + 1] = char(match:sub(i, i))
end

return pc.sequence_of(unpack(parsers)):map(table.concat)
end

local parsers = {}

parsers.blank_space_char = blank_space_char
parsers.char = char
parsers.digit = digit
parsers.digits = pc.many1(digit):map(table.concat)
parsers.eof = eof
parsers.letter = letter
parsers.letters = pc.many1(letter):map(table.concat)
parsers.optional_blank_space = pc.many(blank_space_char):map(table.concat)
parsers.peek = peek
parsers.str = str

return parsers
Loading

0 comments on commit 505ba70

Please sign in to comment.