fully fledged bracket counter
This commit is contained in:
parent
1a8fad9cb5
commit
54ecf83c40
|
@ -1,29 +1,29 @@
|
||||||
struct Parser{T}
|
mutable struct Parser{T}
|
||||||
tokens::T
|
tokens::T
|
||||||
substitutions::Dict{String, String}
|
substitutions::Dict{String, String}
|
||||||
records::Dict{String, Dict{String, String}}
|
records::Dict{String, Dict{String, String}}
|
||||||
line::Ref{Int}
|
line::Int
|
||||||
|
bracket_counter::Int
|
||||||
end
|
end
|
||||||
|
|
||||||
Base.eltype(p::Parser) = eltype(p.tokens)
|
Base.eltype(p::Parser) = eltype(p.tokens)
|
||||||
Base.one(p::Parser) = eltype(p)("")
|
Base.one(p::Parser) = eltype(p)("")
|
||||||
|
|
||||||
Parser(tokens::T, substitutions, records, line) where T =
|
Parser(tokens::T, substitutions, records, line, bracket_counter) where T =
|
||||||
Parser{T}(tokens, substitutions, records, line)
|
Parser{T}(tokens, substitutions, records, line, bracket_counter)
|
||||||
|
|
||||||
parse_text(text) = begin
|
Parser(tokens) = Parser(tokens, Dict{String, String}(), Dict{String, Dict{String, String}}(), 1, 0)
|
||||||
tokens = matchall(r"[^\s\"#{}@,=]+|\s+|\"|#|{|}|@|,|=", text)
|
|
||||||
Parser(tokens, Dict{String, String}(), Dict{String, String}(), Ref(1))
|
|
||||||
end
|
|
||||||
|
|
||||||
location(parser) = "on line $(parser.line.x)"
|
parse_text(text) = matchall(r"[^\s\"#{}@,=\\]+|\s+|\"|#|{|}|@|,|=|\\", text) |> Parser
|
||||||
|
|
||||||
|
location(parser) = "on line $(parser.line)"
|
||||||
|
|
||||||
next_token_default!(parser) =
|
next_token_default!(parser) =
|
||||||
if isempty(parser.tokens)
|
if isempty(parser.tokens)
|
||||||
one(parser)
|
one(parser)
|
||||||
else
|
else
|
||||||
result = shift!(parser.tokens)
|
result = shift!(parser.tokens)
|
||||||
parser.line.x = parser.line.x + count(x -> x == '\n', result)
|
parser.line = parser.line + count(x -> x == '\n', result)
|
||||||
if all(isspace, result)
|
if all(isspace, result)
|
||||||
eltype(parser)(" ")
|
eltype(parser)(" ")
|
||||||
else
|
else
|
||||||
|
@ -56,29 +56,34 @@ expect(parser, result, expectation) =
|
||||||
|
|
||||||
expect!(parser, expectation) = expect(parser, next_token!(parser, expectation), expectation)
|
expect!(parser, expectation) = expect(parser, next_token!(parser, expectation), expectation)
|
||||||
|
|
||||||
token_and_counter!(parser, bracket_counter = 1) = begin
|
token_and_counter!(parser, eol) = begin
|
||||||
token = next_token_with_space!(parser, "}")
|
token = next_token_with_space!(parser, eol)
|
||||||
if token == "{"
|
if token == "{"
|
||||||
bracket_counter += 1
|
parser.bracket_counter += 1
|
||||||
elseif token == "}"
|
elseif token == "}"
|
||||||
bracket_counter -= 1
|
parser.bracket_counter -= 1
|
||||||
|
end
|
||||||
|
if parser.bracket_counter < 0
|
||||||
|
error("} without corresponding { $(location(parser))")
|
||||||
|
else
|
||||||
|
token
|
||||||
end
|
end
|
||||||
token, bracket_counter
|
|
||||||
end
|
end
|
||||||
|
|
||||||
value!(parser, values = eltype(parser)[]) = begin
|
value!(parser, values = eltype(parser)[]) = begin
|
||||||
token = next_token!(parser)
|
token = next_token!(parser)
|
||||||
if token == "\""
|
if token == "\""
|
||||||
token = next_token_with_space!(parser, "\"")
|
token = token_and_counter!(parser, "\"")
|
||||||
while token != "\""
|
while !(token == "\"" && parser.bracket_counter == 0)
|
||||||
push!(values, token)
|
push!(values, token)
|
||||||
token = next_token_with_space!(parser, "\"")
|
token = token_and_counter!(parser, "\" or }")
|
||||||
end
|
end
|
||||||
elseif token == "{"
|
elseif token == "{"
|
||||||
token, counter = token_and_counter!(parser)
|
parser.bracket_counter += 1
|
||||||
while counter > 0
|
token = token_and_counter!(parser, "}")
|
||||||
|
while parser.bracket_counter > 0
|
||||||
push!(values, token)
|
push!(values, token)
|
||||||
token, counter = token_and_counter!(parser, counter)
|
token = token_and_counter!(parser, "}")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
push!(values, getkey(parser.substitutions, token, String(token) ) )
|
push!(values, getkey(parser.substitutions, token, String(token) ) )
|
||||||
|
@ -125,7 +130,7 @@ julia> preamble, result = parse_bibtex(""\"
|
||||||
@string{short = long}
|
@string{short = long}
|
||||||
@a{b,
|
@a{b,
|
||||||
c = {{c} c},
|
c = {{c} c},
|
||||||
d = "d d",
|
d = "d {"} d",
|
||||||
e = f # short
|
e = f # short
|
||||||
}
|
}
|
||||||
""\");
|
""\");
|
||||||
|
@ -140,7 +145,7 @@ julia> result["b"]["c"]
|
||||||
"{c} c"
|
"{c} c"
|
||||||
|
|
||||||
julia> result["b"]["d"]
|
julia> result["b"]["d"]
|
||||||
"d d"
|
"d {\\"} d"
|
||||||
|
|
||||||
julia> result["b"]["e"]
|
julia> result["b"]["e"]
|
||||||
"f short"
|
"f short"
|
||||||
|
|
Loading…
Reference in New Issue