Skip to content

fix Utilities/parser.jl on 0.7 #384

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,12 @@ os:
# - osx
julia:
- 0.6
# - nightly
- 0.7
notifications:
email: false
git:
depth: 99999999

## uncomment the following lines to allow failures on nightly julia
## (tests will run but not make your overall status red)
matrix:
allow_failures:
- julia: nightly

# Integration with JuMP-dev gitter channel
notifications:
webhooks:
Expand Down
93 changes: 56 additions & 37 deletions src/Utilities/parser.jl
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
using Base.Meta: isexpr


"""
A parser for a simple human-readable of an MOI model.
This should be thought of as a compact way to write small models
for tests, and not an exchange format.

variables: x, y, z
minobjective: 2x + 3y
con1: x + y <= 1
con2: [x,y] in Set

special labels: variables, minobjective, maxobjective
everything else denotes a constraint with a name
all constraints must be named
"x - y" does NOT currently parse, needs to be written as "x + -1.0*y"
"x^2" does NOT currently parse, needs to be written as "x*x"
"""
# A parser for a simple human-readable of an MOI model.
# This should be thought of as a compact way to write small models
# for tests, and not an exchange format.
#
# variables: x, y, z
# minobjective: 2x + 3y
# con1: x + y <= 1
# con2: [x,y] in Set
#
# special labels: variables, minobjective, maxobjective
# everything else denotes a constraint with a name
# all constraints must be named
# "x - y" does NOT currently parse, needs to be written as "x + -1.0*y"
# "x^2" does NOT currently parse, needs to be written as "x*x"

struct ParsedScalarAffineTerm
coefficient::Float64
Expand Down Expand Up @@ -151,23 +148,45 @@ function parsefunction(ex)
end

# see tests for examples
function separatelabel(ex)
if isexpr(ex, :(:))
return ex.args[1], ex.args[2]
elseif isexpr(ex, :tuple)
ex = copy(ex)
@assert isexpr(ex.args[1], :(:))
label = ex.args[1].args[1]
ex.args[1] = ex.args[1].args[2]
return label, ex
elseif isexpr(ex, :call)
ex = copy(ex)
@assert isexpr(ex.args[2], :(:))
label = ex.args[2].args[1]
ex.args[2] = ex.args[2].args[2]
return label, ex
else
error("Unrecognized expression $ex")
if VERSION > v"0.7-"
function separatelabel(ex)
if isexpr(ex, :call) && ex.args[1] == :(:)
return ex.args[2], ex.args[3]
elseif isexpr(ex, :tuple)
ex = copy(ex)
@assert isexpr(ex.args[1], :call) && ex.args[1].args[1] == :(:)
label = ex.args[1].args[2]
ex.args[1] = ex.args[1].args[3]
return label, ex
elseif isexpr(ex, :call)
ex = copy(ex)
@assert isexpr(ex.args[2], :call) && ex.args[2].args[1] == :(:)
label = ex.args[2].args[2]
ex.args[2] = ex.args[2].args[3]
return label, ex
else
error("Unrecognized expression $ex")
end
end
else
function separatelabel(ex)
if isexpr(ex, :(:))
return ex.args[1], ex.args[2]
elseif isexpr(ex, :tuple)
ex = copy(ex)
@assert isexpr(ex.args[1], :(:))
label = ex.args[1].args[1]
ex.args[1] = ex.args[1].args[2]
return label, ex
elseif isexpr(ex, :call)
ex = copy(ex)
@assert isexpr(ex.args[2], :(:))
label = ex.args[2].args[1]
ex.args[2] = ex.args[2].args[2]
return label, ex
else
error("Unrecognized expression $ex")
end
end
end

Expand All @@ -185,14 +204,14 @@ parsedtoMOI(model, s::Union{Float64, Int64}) = s
for typename in [:ParsedScalarAffineTerm,:ParsedScalarAffineFunction,:ParsedVectorAffineTerm,:ParsedVectorAffineFunction,
:ParsedScalarQuadraticTerm,:ParsedScalarQuadraticFunction,:ParsedVectorQuadraticTerm,:ParsedVectorQuadraticFunction,
:ParsedSingleVariable,:ParsedVectorOfVariables]
moiname = parse(replace(string(typename), "Parsed" => "MOI."))
moiname = Compat.Meta.parse(replace(string(typename), "Parsed" => "MOI."))
fields = fieldnames(eval(typename))
constructor = Expr(:call, moiname, [Expr(:call,:parsedtoMOI,:model,Expr(:.,:f,Base.Meta.quot(field))) for field in fields]...)
@eval parsedtoMOI(model, f::$typename) = $constructor
end

function loadfromstring!(model, s)
parsedlines = filter(ex -> ex != nothing,parse.(split(s,"\n")))
parsedlines = filter(ex -> ex != nothing, Compat.Meta.parse.(split(s,"\n")))

for line in parsedlines
label, ex = separatelabel(line)
Expand Down Expand Up @@ -221,7 +240,7 @@ function loadfromstring!(model, s)
f = parsedtoMOI(model, parsefunction(ex.args[2]))
if ex.args[1] == :in
# Could be safer here
set = eval(MOI, ex.args[3])
set = Compat.Core.eval(MOI, ex.args[3])
elseif ex.args[1] == :<=
set = MOI.LessThan(ex.args[3])
elseif ex.args[1] == :>=
Expand Down