I've been trying to make a parser for a (very) simple language that looks like this:
block{you are a cow too blkA{ but maybe not} and so is he} hear me moo blockZ{moooooo}
I can break it apart using regexes:
.*?[^ ]*?\\{
.*?\\}
which would essentially keep eating characters until it found something that matches [^ ]*?\\{ or \\}: the start or end of a block. My question is, if I want to do it using Scala's Parser Combinators, how do I do that? I currently have:
def expr: Parser[Any] = (block | text)+
def text = ".+?".r
def block = "[^ ]*?\\{".r ~ expr ~ "}"
but this doesn't work:
parsed: List(b, l, o, c, k, {, y, o, u, a, r, e, a, c, o, w, t, o, o, b, l, k, A, {, b, u, t, m, a, y, b, e, n, o, t, }, a, n, d, s, o, i, s, h, e, }, h, e, a, r, m, e, m, o, o)
It seems that the block parser is not firing, and so the text parser is being fired repeatedly. but when i remove the text parser:
def expr: Parser[Any] = (block)+
I get:
failure: string matching regex `[^ ]*?\{' expected but `y' found
block{you are a cow too blkA{ but maybe not} and so is he} hear me moo
^
So obviously the block parser does work, except not when the text parser is present. What's happening? and is there a "proper" way of doing this, for so basic a grammar?
EDIT: Changed the title, since it's not so much about the reluctance anymore as just solving the problem
EDIT: I now have this:
def expr: Parser[Any] = (block | text)+
def text = "[^\\}]".r
def block = "[^ ]*?\\{".r ~ expr ~ "}"
The logic behind this is that for each character, it tests whether or not it is the start of a block. If it isn't, it moves on to the next character. This gives me:
parsed: List(((block{~List(y, o, u, a, r, e, a, c, o, w, t, o, o, ((blkA{~List(b, u, t, m, a, y, b, e, n, o, t))~}), a, n, d, s, o, i, s, h, e))~}), h, e, a, r, m, e, m, o, o)
which is kind of correct. It is parsing the non-block characters one-by-one though, which is probably a performance problem (i think?). Is there any way to parse all those non-block characters at once and leave them in one big string?
The problem is that text is consuming all closing curly braces (}). It goes like this:
expr -> block -> expr -> text.+ (until all input is consumed)
At this point, it exits expr and tries to parse }, which does not exists, fails, and falls back to text on the first expr.
You can use log to see what's going on when you parse.
Related
I have 2 nodes where I want to move all the TO and FROM relationships to the second node.
//This works FROM
MATCH (c)<-[r:HAS]-(f {name: 'ball(a)'}), (t {name: 'ball(b)'})
WITH c, r, f, t
CALL apoc.refactor.from(r, t)
YIELD input, output
Return c
//AND this works TO
MATCH (c)-[r:HAS]->(f {name: 'ball(a)'}), (t {name: 'ball(b)'})
WITH c, r, f, t
CALL apoc.refactor.to(r, t)
YIELD input, output
Return c
//THIS DOES NOT WORK
MATCH (c)-[r:HAS]->(f {name: 'ball(a)'})-[r2:HAS]->(d), (t {name: 'ball(b)'})
WITH c, r, f, t, r2, d
CALL apoc.refactor.to(r, t)
CALL apoc.refactor.from(r2, t)
YIELD input, output
Return c
I get the ERROR: "Procedure call inside a query does not support naming results implicitly"
How can I refactor TO and FROM relations in one query?
Please try this:
MATCH (c)-[r:HAS]->(f {name: 'ball(a)'})-[r2:HAS]->(d), (t {name: 'ball(b)'})
WITH c, r, t, r2, d
CALL apoc.refactor.to(r, t)
YIELD input, output
WITH c, r2, t
CALL apoc.refactor.from(r2, t)
YIELD input, output
Return c
Line number 3 is a function that takes an input r, t and as a result returns input, output. Inside this return you do not have r2 and t, that's why you're receiving an error.
I am new to Haskell and I am having issues with syntax. What I want to do is given data and a tree of this datatype, find the path to the corresponding node in the tree. I believe my logic for the function is correct but I am not sure how to make it valid Haskell. I have tried changing tabs to spaces.
-- | Binary trees with nodes labeled by values of an arbitrary type.
data Tree a
= Node a (Tree a) (Tree a)
| End
deriving (Eq,Show)
-- | One step in a path, indicating whether to follow the left subtree (L)
-- or the right subtree (R).
data Step = L | R
deriving (Eq,Show)
-- | A path is a sequence of steps. Each node in a binary tree can be
-- identified by a path, indicating how to move down the tree starting
-- from the root.
type Path = [Step]
pathTo :: Eq a => a -> Tree a -> Maybe Path
pathTo a End = Nothing
pathTo a (Node b l r)
| a == b = Just []
| case (pathTo a l) of
Just p -> Just [L:p]
Nothing -> case (pathTo a r) of
Just p -> Just [R:p]
Nothing -> Nothing
This is the error:
parse error (possibly incorrect indentation or mismatched brackets)
The underlying problem here is that this does not look like a guard: a guard is an expression with type Bool, this determines if the guard "fires" or not. Here this is likely `otherwise:
pathTo :: Eq a => a -> Tree a -> Maybe Path
pathTo a End = Nothing
pathTo a (Node b l r)
| a == b = Just []
| otherwise = case (pathTo a l) of
Just p -> Just (L:p)
Nothing -> case (pathTo a r) of
Just p -> Just (R:p)
Nothing -> Nothing
This also revealed some extra mistakes: Just [L:p] is a Maybe [[Step]], you likely wanted to use Just (L:p), the same applies for Just [R:p].
You furthermore do not need to use nested cases, you can work with the Alternative typeclass:
import Control.Applicative((<|>))
pathTo :: Eq a => a -> Tree a -> Maybe Path
pathTo a End = Nothing
pathTo a (Node b l r)
| a == b = Just []
| otherwise = ((L:) <$> pathTo a l) <|> ((R:) <$> pathTo a r)
Here x <|> y will take x if it is a Just …, and y otherwise. We use (L:) <$> … to prepend the list wrapped in the Just data constructor, or return Nothing in case … is Nothing.
Can someone help me figure out what's wrong with my sorting algorithms. I get no errors but get stuck in some kind of infinite loop. The functions seem to work individually.
msort([])->
[];
msort(L)->
{L3, L4} = msplit(L, [],[]),
merge(msort(L3), msort(L4)).
msplit([], L1, L2)->
{L1, L2};
msplit([H|[]], L1, L2)->
msplit([], [H]++L1, L2);
msplit([H|[H2|T]], A, B)->
msplit(T, A++[H], B++[H2]).
merge(L, [])->L;
merge([], R)->R;
merge([H1|T1], [H2|T2])->
if H1 < H2
-> [H1|merge(T1, [H2|T2])];
true-> [H2|merge([H1|T1], T2)]
end.
qsort([])->[];
qsort([H|T])->
{A, B} =qsplit(T, H, [], []),
Small =qsort(A),
Large = qsort(B),
lists:append(Small,Large).
qsplit([], H, A, B)->
{A++[H], B};
qsplit([H|T], P, A, B)->
if H > P->
qsplit(T, P, A++[H], B);
true-> qsplit(T, P, A, B++[H])
end.
After some changes the code is working properly:
msort([]) ->
[];
msort([_] = L) ->
L;
msort(L)->
{L3, L4} = msplit(L, [],[]),
merge(msort(L3), msort(L4)).
msplit([], L1, L2)->
{L1, L2};
msplit([H|[]], L1, L2)->
msplit([], [H|L1], L2);
msplit([H|[H2|T]], A, B)->
msplit(T, [H|A], [H2|B]).
merge(L, [])->L;
merge([], R)->R;
merge([H1|T1], [H2|T2])->
if H1 < H2
-> [H1|merge(T1, [H2|T2])];
true-> [H2|merge([H1|T1], T2)]
end.
qsort([])->[];
qsort([_] = L)->L;
qsort([H|T])->
{A, B} =qsplit(T, H, [], []),
Large =qsort(A),
Small = qsort(B),
lists:append(Small,[H|Large]).
qsplit([], _, A, B)->
{A, B};
qsplit([H|T], P, A, B)->
if H > P->
qsplit(T, P, [H|A], B);
true-> qsplit(T, P, A, [H|B])
end.
If you call msort/1 with a list containing just one item [X] your msplit/1 will return {[X], []} where you call msort/1 with one item [X] and so on. You can fix it by adding msort/1 function clause:
msort([])->
[];
msort([_] = L) ->
L;
msort(L)->
...
A similar problem is in your qsort/1.
There are more problems in your code. You should replace all your A++[H] with [H] ++ A which is even better written as [H|A]. It has big impact to an efficiency of your code. You can use [H, H2 | T] instead of [H | [H2 | T]], it is nice syntactic sugar which helps readability.
I really hate asking this kind of question but I'm at the end of my wits here. I am writing an incremental parser but for some reason, just cannot figure out how to implement functor instance for it. Here's the code dump:
Input Data Type
Input is data type yielded by parser to the coroutine. It contains the current list of input chars being operated on by coroutine and end of line condition
data Input a = S [a] Bool deriving (Show)
instance Functor Input where
fmap g (S as x) = S (g <$> as) x
Output Data Type
Output is data type yielded by coroutine to Parser. It is either a Failed message, Done [b], or Partial ([a] -> Output a b), where [a] is the current buffer passed back to the parser
data Output a b = Fail String | Done [b] | Partial ([a] -> Output a b)
instance Functor (Output a) where
fmap _ (Fail s) = Fail s
fmap g (Done bs) = Done $ g <$> bs
fmap g (Partial f) = Partial $ \as -> g <$> f as
The Parser
The parser takes [a] and yields a buffer [a] to coroutine, which yields back Output a b
data ParserI a b = PP { runPi :: [a] -> (Input a -> Output a b) -> Output a b }
Functor Implementation
It seems like all I have to do is fmap the function g onto the coroutine, like follows:
instance Functor (ParserI a) where
fmap g p = PP $ \as k -> runPi p as (\xs -> fmap g $ k xs)
But it does not type check:
Couldn't match type `a1' with `b'
`a1' is a rigid type variable bound by
the type signature for
fmap :: (a1 -> b) -> ParserI a a1 -> ParserI a b
at Tests.hs:723:9
`b' is a rigid type variable bound by
the type signature for
fmap :: (a1 -> b) -> ParserI a a1 -> ParserI a b
at Tests.hs:723:9
Expected type: ParserI a b
Actual type: ParserI a a1
As Philip JF declared, it's not possible to have an instance Functor (ParserI a). The proof goes by variance of functors—any (mathematical) functor must, for each of its arguments, be either covariant or contravariant. Normal Haskell Functors are always covariant which is why
fmap :: (a -> b) -> (f a -> f b)`
Haskell Contravariant functors have the similar
contramap :: (b -> a) -> (f a -> f b)`
In your case, the b index in ParserI a b would have to be both covariant and contravariant. The quick way of figuring this out is to relate covariant positions to + and contravariant to - and build from some basic rules.
Covariant positions are function results, contravariant are function inputs. So a type mapping like type Func1 a b c = (a, b) -> c has a ~ -, b ~ -, and c ~ +. If you have functions in output positions, you multiply all of the argument variances by +1. If you have functions in input positions you multiply all the variances by -1. Thus
type Func2 a b c = a -> (b -> c)
has the same variances as Func1 but
type Func3 a b c = (a -> b) -> c
has a ~ 1, b ~ -1, and c ~ 1. Using these rules you can pretty quickly see that Output has variances like Output - + and then ParserI uses Output in both negative and positive positions, thus it can't be a straight up Functor.
But there are generalizations like Contravariant. The particular generalization of interest is Profunctor (or Difunctors which you see sometimes) which goes like so
class Profunctor f where
promap :: (a' -> a) -> (b -> b') -> (f a b -> f a' b')
the quintessential example of which being (->)
instance Profunctor (->) where
promap f g orig = g . orig . f
i.e. it "extends" the function both after (like a usual Functor) and before. Profunctors f are thus always mathematical functors of arity 2 with variance signature f - +.
So, by generalizing your ParserI slightly, letting there be an extra parameter to split the ouput types in half, we can make it a Profunctor.
data ParserIC a b b' = PP { runPi :: [a] -> (Input a -> Output a b) -> Output a b' }
instance Profunctor (ParserIC a) where
promap before after (PP pi) =
PP $ \as k -> fmap after $ pi as (fmap before . k)
and then you can wrap it up
type ParserI a b = ParserIC a b b
and provide a slightly less convenient mapping function over b
mapPi :: (c -> b) -> (b -> c) -> ParserI a b -> ParserI a c
mapPi = promap
which really drives home the burden of having the variances go both ways---you need to have bidirectional maps!
In Lisp, I can have:
(a b c d e f g)
which means
look up b, c, d, e, f, g
look up a; apply value of a to above
Then, I can also have:
`(a b c d e f g)
which is the equiv to
(list 'a 'b 'c 'd 'e 'f 'g)
Now, in lua, I can have:
[snipplet 1]
foo = {
Foo,
{Cat, cat},
{Dog, dog}
};
Which ends up most likely expanding into:
{ nil, { nil, nil}, {nil, nil}}
Whereas what I really want is something like:
[snipplet 2]
{ "Foo", {"Cat", "cat"}, {"Dog", "dog"}}
Is there some backquote-like method in lua?
I find [snipplet 1] to be more visually pleasing than [snipplet 2], but what I mean is snipplet 2.
Thanks!
There's no syntax for that but you can try this run-time solution:
setmetatable(_G,{__index=function (t,k) return k end})
This makes all undefined variables behave as if they contained strings with their names.
Consider a function that parses a string containing the Lisp syntax and constructs a table from that.