Skip to content
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

possible changes to documentation #52

Open
ynotlayabout opened this issue Jun 3, 2014 · 0 comments
Open

possible changes to documentation #52

ynotlayabout opened this issue Jun 3, 2014 · 0 comments

Comments

@ynotlayabout
Copy link

note: you have to read this in plaintext because there's some markup going on that is eating special characters

In learning parsley, I had trouble understanding what was going on. And after some help from dash on IRC, a light bulb went on and I think I have an explanation of the various components in parsley which may help others come up to speed.

In a variant of BNF, a parsley rule is of the form:

= [:data_name] [[: data_name]]* [-> ( )

The first simple magic is every pattern, when matched, yields a value. That value is either discarded, or if followed by a colon and a data name (i.e. a Python legal symbol), the returned value is placed into the data name.

The second simple magic is that after the arrow ('->') you can have a Python expression surrounded by parentheses. Each data name defined prior to this expression can be used as part of the expression. It's the way you transfer the values determined by the pattern matching into expression so you can do whatever calculation you want.

The third simple magic is that the result of the expression at the end of the statement is assigned to the name at the start of the statement. You can retrieve this value by treating the name as a method call (explanation TBD)

Now the next part gave me that "ah ha" moment. Do you remember the tale about the Hindu woman in a remote village who was asked about her view of a creation myth. Well, in this case, it's Python expressions all the way down.

Every pattern if it's not a terminal pattern (i.e. constant strings, characters, or predefined patterns) refers to another pattern. And that pattern either returns a value or refers to another pattern. And so on… All the way down.

To be quite frank, if I had explained to me like this, I'm not sure I would've understood it right first but I don't think I would've gotten quite often the weeds as far as I had.

---- sketchy rewrite of the tutorial beginning ----
forget everything you know about parsing and regular expressions. Parsley does many things similar to regular expressions and other parsers but you will learn faster if you start with a clean slate.

Let's start with a simple parsley grammar:

X = 'a' ('b' | 'c') 'd'+ 'e'"

X is defined as any string that contains the letter a followed by 'b' or 'c' followed by at least one 'd' which is followed by a single 'e'. Yes, very similar to regular expressions but get those regex out of your mind please.

Each one of the elements of this expression is considered a terminal node. This means once you match, there is no other patterns to search for. the string that matches this pattern is returned as the value of 'X'. Example of expression with a non-terminal mode is a rewrite of the above:

X = 'a' Y 'd'+ 'e'"
Y = ('b' | 'c')

in this case, Y is a non-terminal node because it contains additional information that can match against the input data.

(clarification request: if we get a match, it yields the string we match?)
all of this pattern matching is pretty common and I just know you're thinking about regular expressions. Here's where we start to deviate into something really nice. Going back to the original expression, let's say we want to do something based on whether we match the 'b' or the 'c'. in that case, we want to preserve the state of that match and we do that by assigning a variable to that match.

X = 'a' ('b' | 'c'):v1 'd'+ 'e'"

In this case, we assigned the results of the match of 'b' or 'c' to the variable 'v1'. doing something with that result is also just as easy.

X = 'a' ('b' | 'c'):v1 'd'+ 'e'" -> (print v1)

I think of the '->' arrow as 'yields' as in matching the pattern on the left yields the result of evaluating the right.

.... and it continues on. at this point I'd explain how you get either a single element or lists.

anyway, that's my idea of how to make this more accessible. Corrections, feedback is welcome and if you're willing to wait halfway to the death of the universe, I'll be glad to contribute documentation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant