Originally I wanted the parser to be dead simple, the idea being that it would really only accept the usual mathematical expressions +.-,/,*,() what have you, dice rolls and function calls. The function calls would just be passed along to the macro engine that would find and call the bit of javascript that they were mapped to (think similar to how user defined functions in MT macros work now).
Then Joe had some requirements that he wanted the parser to meet for an updated DiceTool, and things went from simple to complex and messy and stuff.
The idea of the expressions and dice and function calls have remained the same, but a lot more has been added to the parser. So below are the details of the parser currently. I am hoping people will look over them and tell me if its all too complex or something seems too strange, or I am missing something that really needs to be there, or any other general comments. Keep in mind the parser only deals with the text that is within the [ ], so if your button contains "He swings at the dragon with his sword doing [4d6] damage" it would only be interested in the 4d6 part.
So on with the details (except for a few small bugs this is all currently working) but only XdY, dY rolls (with modifiers, see later) have been coded at the moment.
The parser uses an updated version of antlr (for anyone who cares)
Better support for unicode so a much larger character set should work
Both " and ' can be used to enclose strings.
Obviously addition, subtraction, division, and multiplication are supported (+,-,/,*)
% is the remainder operator (it performs a remainder as it does in Java not a mod like C)
^ Exponent, (e.g.) 2^3 = 8.
Supports long (integer), floating point, string, and list, dictionary (maps string to value), "result" data types.
Results are basically a value + information about how that value was derived.
Variables are prefixed with $ and properties are prefixed with @ so there are no chance of setting
the wrong thing (unlike now how a property overrides a variable)
examples
$dex = @dex
1d6 + @dexMod
Statements are separated with a ';', eg $toHit = 1d20; $damage = 2d6 + @strMod
?$var prompts for a value and places it in the var variable. It also supports prompt with a description in the form
?$str:"Enter your strength"
Dice rolls look the same as the previous version 2d5 or d5 etc, but as the parser is now aware of what makes a dice roll (rather than the string replace before going to the parser that used to happen) it can now support modifiers. There are currently the following modifiers
! return details of the individual rolls in both the detailed results and the normal results.
!s return details of the individual rolls in the detailed results and a sum in the normal results.
The detailed result is generally the string to be displayed, the normal result is generally the value to be used in calculations (or passed to function or assigned to variable/property)
An example, say you were rollong three dice (of six sides), and you roll 4, 2, and 5.
3d6 the detailed result would be the string "11", the normal result would be the integer 11
3d6! the detailed result would be the string "4, 2, 5" and the normal result would be the list [4, 2, 5]
3d6!s the detailed result would be the string "4, 2, 5" and the normal result would be the integer 11
These same flags would work for other roll formats too (where it makes sense).
Functions are passed off to the relevant Java or JavaScript code. I will post more information about this in a day or two when its not so late at night
Repeat groups.
There are 2 types of repeat groups, repeat and return a sum [] and repeat and return individual values {}, what ever is in the brackets is evaluated multiple times, they take the form.
x[expr] / x{expr} where x is an integer which is the amount of times to repeat
$x[expr] / $x{expr} where x is a variable that containes the amount of times to repeat
@x[expr] / @x{expr} where x is a property that containes the amount of times to repeat
?[expr] / ?{expr} prompt for the number of times to repeat.
?"message"[expr] / ?"message"{expr} prompt with a message for the number of times to repeat.
[expr] / {expr} is the same as 1[expr] / 1{expr} potential uses described later.
Some examples
4[2] = the integer 8
4{2} = the list [2, 2, 2, 2]
Advanced stuff you may never need...
To support the case where DiceTool needs to add a value within a [ ] repeat group but still be able to obtain the different values you can use the & operator. (See labels for how this works).
The parser supports labeling values, this is probably something that is going to be more useful in DiceTool than anywhere else. To label a value you use the syntax |label| expr
for example
|label 1| 3d6 will set the value of "label 1" label to the result of the dice roll (for the first index).
|label 2| (3d6 +2) will set the value of "label 2" label to the result of the dice roll plus 2(for the first index).
|label 3| 2[d6] will set the value of "label 3" label to the result of the dice rolls added together for the first index.
If a label appears within a repeat group then it will have multiple indicies with values, for example
2[|label 4| d6] will assign the first d6 result to the first index, and the second result to the second for "label 4"
Labels also allow you to record the values when & is used in a repeat group
$var = 3[|label 5| (d6 & 2)], for example. $var would be set to the sum of rolling a d6 and adding 2 to it 3 times, where the "label 5" would have 3 values, each of them would be a list with the result of the d6 roll and the number 2.
so it might look like
"label 5"(0) = [4, 2]
"label 5"(0) = [2, 2]
"label 5"(0) = [5, 2]
in which case $var would be set to 17.
+,-,* and strings or lists.
+ works as an append to a string where it just convers the other argument to a string and concatenates it, for lists it adds the value to the end of the list.
- for strings is only valid if both arguments are a string, in which case it removes all occurrences of the second string from the first. eg. "there is a great big red dragon on a great pile of treasure" - "great" = "there is a big red dragon on a pile of treasure"
- for lists is only value if both arguments are lists in which case it does the minus set operation, [1,2,3,4,4,5,6] - [1,4] = [2,3,5,6].
* is valid for a string and an integer, and repeats the string multiple times, so 10 * "-" = "----------".