Problem with Combine

Hi! I am trying lear Combine in order to write a parser for a markup language. The function below is defined in a module MUP (MarkupParser). When I run MUP.paragraph("one\ntwo"), the result should be “one” – the parser is supposed to consume input while the function given to take_while is true. Instead it returns [[]]. If I change the little parser to the line commented out and run it on the string "aaabbb", the value returned is ["aaa"]. Go figure! Is there something wrong with my Boolean function?

  def paragraph(input) do
     parser = take_while( fn(a) -> (?a != 97) end)
    # parser = take_while(fn ?a -> true; _ -> false end)
    Combine.parse(input, parser)
  end

I believe it is because of the question mark in the second line: (?a != 97) == (97 != 97), and thus the take_while will quit already at the first iteration. I think you meant (a != 97).

Exactly what Qqwy said. :slight_smile:

If you are curious, I made a PEG parser of my own (like combine) but mine holds more information, like row and column and the specific error if any issue parsing and its a little more efficient in about all ways, your paragraph in mine would be something like (untested):

def paragraph(input) do
  import MyParser # Assuming you named your parser this
  result = parse(input, chars(-?\n))
  result.result
end

Although normally you would want to put it in a parsing module, which the paragraph function could be in. For note, the result is a map, a few useful things in it is error, which is nil if no error else is an exception describing the error in detail including rule stack and all, result which has the parsed the result, and rest which contains the remaining unparsed output.

ExSpirit (Modeled after the C++ Boost Spirit library that I used to work on)

Thankou! Is your PEG parser written in Elixir? If so I’d like to take a look at it – on GitHub?

Thanks! I’ll try that as soon as I get back to work :slight_smile:

Looking at ExPirit now — thanks!

Entirely, mostly in macros, and yep, I forgot but I added the link at the bottom of my first post. ^.^;

Feel free to take a look at it! I had plans to add more functions over time (and indeed I have) but there is always room for more if you want to PR anything. I’m actively using it in a few little projects right now (I really like having row/column output information) so improvements are always welcome. :slight_smile:

The design is broken up into a few parts, first of all there is the base parser stuff, which is entirely generic, there are also sub-parsers, like for unicode binaries (the ‘Text’ parsers), and I have plans for other parsers, like for lists, or parsing binaries as non-text, etc… I also have eventual plans for a reverse parser (like Spirit.Karma) to take a structure and output it to text or whatever based on the same types of sets of rules used to parse it. :slight_smile:

EDIT: Elixir has a slight bug where setting variables has a tendency to ‘leak’ out of cases and if’s and such, so occasionally you get warnings from the compiler because of that, but I do not really have a good idea on how to fix that as Elixir does not seem to have any real scoping mechanism outside of functions… :frowning:

I do have an idea though (entirely dynamic variable generation), but eh… atom creation, even at compile-time… For now ignore those warnings unless you see an actual bug happen because of it (you should not). :slight_smile:

I downloaded ExSpirt from GitHub – all OK except for the first example:

  jxxmbp:ex_spirit carlson$ mix run examples/number_adder.exs
  ** (CompileError) examples/number_adder.exs:1: undefined function edefmodule/2
  (elixir) lib/code.ex:370: Code.require_file/2

I did run mix deps.get – is there something else I should do? I’ll play with this as time permits over the Easter vacation – might have some questions for you if you don’t mind. I am quite new to this PEG grammar business.

Wtf did I put that?! Should be just defmodule at the start of that file, that is the normal elixir defmodule, nothing special. Whoops… ^.^;

EDIT: Wait, I’m not able to find edefmodule anywhere in the source… Did you open and edit that file or something?

Certainly, I’ve been doing PEG for over 15 years now with multiple libraries written and know the tips and tricks well. :slight_smile:

Nope, I just downloaded it and ran it – but I will check. I do have an editor open so as to look at your source.

I will do a re-clone and run it just to be sure.

Cool, because it looks fine on github. :slight_smile:

It’s all OK – I don’t know what happened. Sorry!

And glad to find a PEG expert!! Yay!

1 Like

I have a thread on the forums somewhere that you can post in directly if you want, though opening new posts in the libraries help section is good too. :slight_smile: