Comments (7)
EDIT: we don't need not
because apparently no one actually uses that, the gene logic is plain constructive.
from cobrexa.jl.
OK anyway, this is one possible parser:
import PikaParser as P
abstract type LogicalExpr end
struct AndExpr <: LogicalExpr
l::LogicalExpr
r::LogicalExpr
end
struct OrExpr <: LogicalExpr
l::LogicalExpr
r::LogicalExpr
end
struct NotExpr <: LogicalExpr
x::LogicalExpr
end
struct IdentExpr <: LogicalExpr
id::Symbol
end
isident(x::Char) = isletter(x) || isdigit(x) || x == '_' || x == '-' || x == ':' || x == '.'
noglue(x) = P.seq(x, P.not_followed_by(:identpart))
rules = Dict(
:identpart => P.satisfy(isident),
:space => P.many(P.satisfy(isspace)),
:id => noglue(:in_id => P.some(:identpart)),
:orop => P.first(P.tokens("||"), P.token('|'), noglue(P.tokens("OR")), noglue(P.tokens("or"))),
:andop => P.first(P.tokens("&&"), P.token('&'), noglue(P.tokens("AND")), noglue(P.tokens("and"))),
:notop => P.first(P.token('!'), noglue(P.tokens("NOT")), noglue(P.tokens("not"))),
:expr => P.seq(:space, :orexpr, :space),
:orexpr => P.first(
:or => P.seq(:andexpr, :space, :orop, :space, :orexpr),
:andexpr,
),
:andexpr => P.first(
:and => P.seq(:notexpr, :space, :andop, :space, :andexpr),
:notexpr,
),
:notexpr => P.first(:not => P.seq(:notop, :notexpr), :baseexpr),
:baseexpr => P.first(:id, :parenexpr => P.seq(P.token('('), :space, :orexpr, :space, P.token(')'))),
)
grmr = P.make_grammar([:expr], P.flatten(rules, Char))
input = " Mbar_A0384 and Mbar_A0385 and Mbar_A0389 and (Mbar_A0391 or Mbar_A0379) and (Mbar_A3102 or Mbar_A0386) and (Mbar_A0390 or Mbar_A0378) and Mbar_A0387 and Mbar_A0392 and (Mbar_A3101 or Mbar_A0388) "
s = P.parse(grmr, input)
m = P.find_match_at!(s, :expr, 1)
@assert s.matches[m].len == length(input) "match not found"
openfn(m,_) = m.rule == :expr ? Bool[0,1,0] :
m.rule == :parenexpr ? Bool[0,0,1,0,0] :
m.rule == :not ? Bool[0,1] :
m.rule in [:or, :and] ? Bool[1,0,0,0,1] :
m.rule in [:andexpr, :orexpr, :notexpr, :baseexpr] ? Bool[1] :
(false for _ in m.submatches)
foldfn(m,_,subvals) = m.rule == :id ? IdentExpr(Symbol(m.view)) :
m.rule == :not ? NotExpr(subvals[2]) :
m.rule == :and ? AndExpr(subvals[1], subvals[5]) :
m.rule == :or ? OrExpr(subvals[1], subvals[5]) :
m.rule == :parenexpr ? subvals[3] :
m.rule == :expr ? subvals[2] :
isempty(subvals) ? nothing : subvals[1]
grr = P.traverse_match(s, m, open = openfn, fold = foldfn)
Questions arise:
- Do we support negation? (in DNF, we'd need to have slightly more complicated clauses)
- How come we didn't need negation yet? is it just so uncommon in metabolic modeling?
from cobrexa.jl.
(the @assert
there will get simplified once I get time to implement this LCSB-BioCore/PikaParser.jl#15 )
from cobrexa.jl.
I just checked, this works! nice!
from cobrexa.jl.
Additional fun:
- Fruitfly GEM uses colons in gene names
- there may be unicode in gene names (but that's hopefully already handled by the parser above)
from cobrexa.jl.
also:
- square brackets
- dots
- matt
'
s gene
from cobrexa.jl.
this was addressed by #731
from cobrexa.jl.
Related Issues (20)
- Add support for ME models HOT 4
- Drop OSQP and use Clarabel instead for QPs HOT 4
- tINIT algorithm HOT 7
- Parse common attributes from notes HOT 3
- Collect package download information HOT 5
- .mat model not loading HOT 6
- Conversion from MATModel produces opaque errors if fields are missing HOT 3
- JSON model format incompatible with escher HOT 8
- Mapping through delimited IDs into inner models HOT 2
- `removeReaction!` etc. doesn't update all fields in a `CoreModel` HOT 1
- Pretty print model semantics HOT 2
- Check that function return types inferred in documentation make sense HOT 2
- `check_duplicate_reaction` does not consider reaction directionality HOT 2
- Implement Tables.jl interface for `ModelWithResult` HOT 1
- Document forwarding the `--project` exeflag with ClusterManagers HOT 1
- Warning when reaction is added with metabolites not yet in model HOT 2
- inconsistent parsing of subsystems HOT 9
- JUMP time limit HOT 5
- Genes not parsed if they have an "@" symbol HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cobrexa.jl.