Dice Rolling Metalanguage

Apprentice
Posts: 12
Joined: 2008.09
Post: #16
I just noticed something thats kind of bothering me.

The syntax for the diceroller is not totally congruent.

i mean, when your friends usually call out... "roll 4d6" or "roll to hit, yeah dude is 1d20 plus modifiers" the concept at the core of the metalanguage is "XdY" which is the infix notation of a binary operator. Where "d" is the operator and X and Y are operands. Now, from that light. "d" ( which is the operation to roll the dice and "r" is just syntactic sugar, could be the other way around ). conflicts with the operator "dY" which is the one to Drop some results. But my main gripe is that there is a mix of infix, postfix, prefix, rpn and algebraic notations. I didn't notice before because most operators are Unary. but i think there should be some congruency in this. Any suggestions to improve the syntax?

Thanks,

Onedeveloper
Quote this message in a reply
Moderator
Posts: 680
Joined: 2002.11
Post: #17
You can actually just say that a roll is "4d6." If the syntax is correct, then the parser should be able to differentiate. You should never have a case where the expected behavior is ambiguous. In my parser, you should be able to simply separate numbers with whitespace.

I think I'll go test that, and maybe see if I can modify OSC's to do the same thing.

Edit: Well, that was easy. In mine, it was just a two-line change. New code: http://pastie.textmate.org/288691 - and the whitespace thing does work. There should be no ambiguous cases.

Would it help you if this was in C instead of Python, or is C not much better for you?

My web site - Games, music, Python stuff
Quote this message in a reply
Apprentice
Posts: 12
Joined: 2008.09
Post: #18
C would definitely be an improvement as the python dialects are very alien to me.
Quote this message in a reply
Member
Posts: 254
Joined: 2005.10
Post: #19
Python shouldn't be too hard from C if you know a few gotchas:

- One of the operations that you may see diordna use is someList[num:num]. This is a splice operation returns a subset of the list (from one index to another).

- 'return n, position' essentially returns a list of two elements

- def means define function

- lambda means an annonymous function (in c you would use function pointers) which just allows a function to be passed in a variable

I think everything else should be fairly self-explanitory but feel free to ask questions if it will help you understand the code.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #20
diordna Wrote:Edit 2: I just looked over OSC's code in detail, and it makes perfect sense, but I wish there were some comments in it so I could tell more easily which productions where which, since the method names are a bit cryptic, especially the first few in DiceParser.

sorry, using the syntax to enforce the type system since it's very simple. "n" stands for nil, "v" for vector, and "s" for scalar.

Quote:I also wish that productions could be collected in one place instead of scattered over lots of methods. Maybe I could write a YAML-SPARK bridge of some kind...

You can have multiple productions in one method, but then you (obviously) only have a single body for the function. I probably could get away with that here since there's only one kind of AST node...

Quote:Also, this map(), filter(), and reduce() business should technically be handled by list comprehensions to be 2.6-compatible. And there is a sum() function for integer lists, no need for a custom reduce() for the 'S' token.

Hmm, why would they remove the nice functional bits? Sad

Care to supply a patch?
Quote this message in a reply
Moderator
Posts: 680
Joined: 2002.11
Post: #21
OneSadCookie Wrote:Hmm, why would they remove the nice functional bits? Sad
They'll still be there, but I think they're being moved to itertools. Anyway, list comprehensions provide the same functionality with more Python-y syntax. A quick summary:
Code:
map(func, list) == [func(item) for item in list]
filter(func, list) == [item for item in list if func(item)]
reduce(func, list) == no real equivalent, I guess
The nice thing about list comprehensions is that you can do map() and filter() in the same pass. reduce() is a bit of a special case. You used it for adding integers, but there's already a built-in sum() function for that.

Quote:Care to supply a patch?
I might, but it would probably involve expanding most of your one-letter abbreviations for the sake of my sanity before I added any new functionality.

My web site - Games, music, Python stuff
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #22
I finally got around to doing this in C to figure out the details of flex & bison. It's horrible and vastly more verbose than the Python solution, as you might expect Smile

I also think that it should leak on parse error, but can't actually cause that to happen. Anyway, the memory management is generally horrible.

http://onesadcookie.com/~keith/dice.zip
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #23
... and Haskell using ParseC: http://onesadcookie.com/~keith/Dice.hs

As usual, Haskell wins for brevity, if not necessarily readability Wink

ParseC can't represent left-recursive grammars as this one naturally is (and I now realize, why the bison version doesn't leak memory on syntax error) so I had to restructure the grammar a little to make it work.
Quote this message in a reply
Post Reply