haskell - Parsec parser failed on many1 and manyTill combinators -
i have faced unclear behavior of parsec parsers, want parsre strings same
> <cdid> 1 > <mol weight> 270.2369 > <formula> c15h10o5 > <log_er_rba> -0.36 > <activity> 1
i wrote parser
parseproperties = skipmany1 newline char '>' >> spaces >> char '<' propname <- many1 (noneof ">") char '>' newline propvalue <- many1 (noneof "\n") return (propname,propvalue)
this parser excellently parse 1 item, , able parse several:
parsetest (count 5 parseproperties) "\n> <cdid>\n1\n\n> <mol weight>\n270.2369\n\n> <formula>\nc15h10o5\n\n> <log_er_rba>\n-0.36\n\n> <activity>\n1\n\n"
results
[("cdid","1"),("mol weight","270.2369"),("formula","c15h10o5"),("log_er_rba","-0.36"),("activity","1")]
nevertheless found no ways parse random numbers of properties. if try
parsetest (many1 parseproperties) "\n> <cdid>\n1\n\n> <mol weight>\n270.2369\n\n> <formula>\nc15h10o5\n\n> <log_er_rba>\n-0.36\n\n> <activity>\n1\n\n"
or
parsetest (manytill parseproperties (try eof)) "\n> <cdid>\n1\n\n> <mol weight>\n270.2369\n\n> <formula>\nc15h10o5\n\n> <log_er_rba>\n-0.36\n\n> <activity>\n1\n\n"
parser failed
parse error @ (line 17, column 1): unexpected end of input expecting new-line or ">"
but, if use anychar parser, not failed.
parsetest (manytill anychar (try eof)) "\n> <cdid>\n1\n\n> <mol weight>\n270.2369\n\n> <formula>\nc15h10o5\n\n> <log_er_rba>\n-0.36\n\n> <activity>\n1\n\n" "\n> <cdid>\n1\n\n> <mol weight>\n270.2369\n\n> <formula>\nc15h10o5\n\n> <log_er_rba>\n-0.36\n\n> <activity>\n1\n\n"
the parseproperties
parser executed many times in example until eof
encountered. problem parseproperties
not consume trailing whitespace in example, after parsing last tag, remaining string "\n\n"
, not trigger termination condition, since not end of input. causes parseproperties
attempted again, consumes whitespace fails when trying eat '>'
.
try modifying parsetest
following
test = "\n> <cdid>\n1\n\n> <mol weight>\n270.2369\n\n> <formula>\nc15h10o5\n\n> <log_er_rba>\n-0.36\n\n> <activity>\n1\n\n" parsetest (manytill parseproperties $ try (skipmany newline >> eof)) test
this trys stripping preceding whitespace before checking if @ end of input.
Comments
Post a Comment