|
oldguy2 Wizard
Joined: 17 Jun 2006 Posts: 1201
|
Posted: Mon Jul 21, 2008 9:39 am
[2.32-33] Triggers in stringlist variables |
Can we no longer place a bunch of triggers in a stringlist variable? It's no longer working in 2.32. I keep getting an error that says error parsing command and error in trigger pattern. It states there are unmatched braces, but there isn't.
Also let me say wow. I haven't been here in ages. I can't believe you are already on 2.32. |
|
Last edited by oldguy2 on Sat Jul 26, 2008 2:28 am; edited 2 times in total |
|
|
|
Tech GURU
Joined: 18 Oct 2000 Posts: 2733 Location: Atlanta, USA
|
Posted: Mon Jul 21, 2008 2:59 pm |
Hmmm, that worked for me.
Can you post your trigger pattern and your stringlist variable?
(BTW Welcome back. 2.32 has got lots of goodness in it.) |
|
_________________ Asati di tempari! |
|
|
|
oldguy2 Wizard
Joined: 17 Jun 2006 Posts: 1201
|
Posted: Thu Jul 24, 2008 9:17 am |
Well I had no problem in 2.18. However, Cmud is now just mangling my triggers that are in stringlists if I use any kind of grouping.
Example:
Code: |
Error in trigger pattern:
^(?: With a sweeping kick of his leg, a Mhun bodyguard trips you up and sends you tumbling to the ground\.|With a roar of rage, a [\w ]+ leaps at you, knocking you to the ground, raking h(?:is|wild )?centaur (?:colt |Uttering a low growl, Scylina, Queen of the wildcats leaps on you, cutting you and knocking you to the ground\.|Using his mass to his advantage, a giant toad rushes at you, taking you tumbling|Suddenly ducking, Naggamantex |
It took parts of triggers and stuck them in other parts anywhere there was grouping.
Normally that first trigger is this.
An? (?:elder |wild )?centaur (?:colt |priestess )?thrusts h(?:is|er) spear deep into your belly, thrusting the tip and twisting with h(?:is|er) strong arms\. Quickly s?he pulls the spear |
|
|
|
oldguy2 Wizard
Joined: 17 Jun 2006 Posts: 1201
|
Posted: Thu Jul 24, 2008 9:18 am |
Well every time I try and post I keep getting bad response from server. So it double posted. Sorry.
More example from that list.
Code: |
Geh'shya, the Black Dragon's tail suddenly whips around to knock into everyone|er) strong arms\. Quickly s?he pulls the spear|er) spear deep into your belly, thrusting the tip and twisting with h(?:is|er) sharp teeth\.|er) claws over your skin and ripping chunks of flesh from you with h(?:is|Ducking behind his shield, a dwarf sentry charges you, knocking you to the |
No wonder nothing is working. |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Thu Jul 24, 2008 5:02 pm |
We need to see the actual trigger. Go into the Settings Editor and right-click on the trigger in the Tree view and select Copy. Then come to the forum and do a Paste and put [CODE] tags around it.
There is currently a problem in v2.33 handing %%function calls within a trigger pattern, so maybe that is it. |
|
|
|
oldguy2 Wizard
Joined: 17 Jun 2006 Posts: 1201
|
Posted: Thu Jul 24, 2008 5:13 pm |
Tech wrote: |
Hmmm, that worked for me.
Can you post your trigger pattern and your stringlist variable?
(BTW Welcome back. 2.32 has got lots of goodness in it.) |
I can't get them to work period if there is a group.
Take these two triggers placed in a stringlist variable for example in a new session.
There (?:may be|is) a bug with this\.
(?:Yes|No) there (?:is not|is) bugs\.
I know they aren't great examples, but they are pretty simple.
Well this is what CMUD sees when you click on the test trigger pattern.
^(There (?:is|No) there (?:is not|may be) a bug with this\.|may be) a bug with this\.|is) bugs\.|(?:Yes)
See how it just totally mangled and switched everything around into something completely different? I've always been able to do this before with Regex. Now it is impossible. What happened? |
|
|
|
oldguy2 Wizard
Joined: 17 Jun 2006 Posts: 1201
|
Posted: Thu Jul 24, 2008 5:14 pm |
Zugg wrote: |
We need to see the actual trigger. Go into the Settings Editor and right-click on the trigger in the Tree view and select Copy. Then come to the forum and do a Paste and put [CODE] tags around it.
There is currently a problem in v2.33 handing %%function calls within a trigger pattern, so maybe that is it. |
See my above post of a test I just did in a new session.
Code: |
<?xml version="1.0" encoding="ISO-8859-1" ?>
<cmud>
<var name="testtrig" type="StringList" copy="yes">"There (?:is|may be) a bug with this\."|"(?:Yes|No) there (?:is not|is) bugs\."</var>
</cmud> |
By the way, I am in 2.33 now. It didn't work in 2.32 either. |
|
|
|
oldguy2 Wizard
Joined: 17 Jun 2006 Posts: 1201
|
|
|
|
Toxic Adept
Joined: 27 May 2008 Posts: 299
|
Posted: Thu Jul 24, 2008 6:44 pm |
Yes, this is probably related to that bug and I believe Zugg is already checking into it.
|
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Thu Jul 24, 2008 7:44 pm |
You still haven't posted your actual TRIGGER XML. The post above shows the @testtrig VARIABLE, but I don't see the XML for your TRIGGER anywhere. I need the trigger XML to test this here.
|
|
|
|
oldguy2 Wizard
Joined: 17 Jun 2006 Posts: 1201
|
Posted: Thu Jul 24, 2008 8:20 pm |
Code: |
<?xml version="1.0" encoding="ISO-8859-1" ?>
<cmud>
<trigger priority="10" regex="true" copy="yes">
<pattern>^(?:@testtrig)</pattern>
<value>#say Test worked</value>
</trigger>
</cmud> |
|
|
|
|
oldguy2 Wizard
Joined: 17 Jun 2006 Posts: 1201
|
Posted: Fri Jul 25, 2008 2:57 pm |
So is it the same issue or something else?
|
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Fri Jul 25, 2008 5:31 pm |
I have no idea how this got so broken. I have reproduced the problem. Even if I just put a simple text value into the @testtrig variable this still doesn't work properly, and I have no idea why. But it's on the bug list. Sorry I don't have a work around. It looks like I'm going to need to stop working on the mapper *again* and go back and figure out why all of these bugs in the trigger stuff have suddenly appeared. Sigh. Not going to get any new release until next week though, sorry.
|
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Fri Jul 25, 2008 5:51 pm |
OK, I don't know what's going on. Now when I tested simple text it works fine. So I don't know why I couldn't get a simple string list to work 5 minutes ago.
Anyway, I narrowed down this problem to the | characters within the @testtrig variable. When the trigger tries to sort the string list and create the regular expression pattern, these embedded | characters seem to be confusing it. Other wildcards seem to work, but not embedded (?:a|b) syntax.
This is on the bug list, but is no longer an "emergency" fix priority. |
|
|
|
Toxic Adept
Joined: 27 May 2008 Posts: 299
|
Posted: Fri Jul 25, 2008 7:10 pm |
What about the fixes/issues for %%string() %%dbkeys() syntax for string list var's? If It isnt an emergency fix anymore then is there a work around to allow the trigger to convert to regex properly... Because currently its simply not working at all correctly.
|
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Fri Jul 25, 2008 7:50 pm |
That's still on the bug list too, but it's not an "emergency" so you'll have to wait till next week.
Keep in mind that the ability to use wildcards in a {} list in a trigger is a relatively new feature. So it's not something that effects the majority of users. |
|
|
|
Toxic Adept
Joined: 27 May 2008 Posts: 299
|
Posted: Fri Jul 25, 2008 7:56 pm |
While we are on the topic... Does the %% syntax go for all functions used in trigger patterns? For instance If I wanted to use {%%char|%%db(@Char_Info,Name)} or would it be a single %? And Im saying directly in the trigger pattern... not calling from a string list... So this...
#TR {^{%%char|%%db(@Char_Info,Name)}$} |
|
|
|
oldguy2 Wizard
Joined: 17 Jun 2006 Posts: 1201
|
Posted: Sat Jul 26, 2008 1:54 am |
Well I am not worried. I'm not even playing any muds right now. I just dropped by and saw the latest version and thought I would goof around in Cmud a bit. You are doing a great job as always trying to continually improve the product.
I realize it is getting confused with the pipe character. However, isn't the problem really with the parenthesis forming the non-capturing groups? Meaning it's not looking at them at all within the subgroups and just seeing the pipe characters. Therefore, it is splitting up the the entire stringlist everywhere it sees a pipe, even if it is inside parenthesis (non-capture group) and making it as if it were a different part of the overall non-capture group of triggers. I could write the same trigger non-capture group on the line itself and it is able to understand the regex and works just fine.
Example:
Code: |
^(?:There (?:is|may be) a bug with this\.|(?:Yes|No) there (?:is not|is) bugs\.) |
Since the (?: and ) indicate the start and end of a non-capture group, it shouldn't look at that | pipe within the group inside the actual individual trigger as being part of the overall trigger group. I apologize if I am being confusing and not making any sense. In other words, it is not deciphering the regex correctly when the trigger is inside a stringlist variable because it is just ignoring the characters "(?: and )" and just seeing the "or" pipe character. So it goes straight to the pipe and breaks that into another part of the overall trigger non-capture group.
So it breaks that trigger group above down like this:
(?:
There (?:is
or
may be) a bug with this\.
or
(?:Yes
or
No) there (?:is not
or
is) bugs\.
)
Then rearranges the overall group and ends up with this:
Code: |
^(?:There (?:is|No) there (?:is not|may be) a bug with this\.|may be) a bug with this\.|is) bugs\.|(?:Yes) |
So really it isn't ignoring the pipes because it is breaking it at every single pipe it encounters when it shouldn't, it just is ignoring the parenthesis which form the groups. Yet it only does it in a stringlist variable.
I could be wrong of course. However, when you said "these embedded | characters seem to be confusing it", I think it's because it isn't reading the groups correctly and ignoring the parenthesis which form the groups. Otherwise, it wouldn't break at the pipe inside of the embedded group right? Maybe I am just repeating what you said in the first place. I don't know. lol It's just not reading regex non-capture/capture groups correctly at all if the triggers are within a stringlist. It's only reading the pipe characters. It is reading the regex correctly in the actual trigger pattern though. |
|
Last edited by oldguy2 on Sat Jul 26, 2008 1:03 pm; edited 1 time in total |
|
|
|
oldguy2 Wizard
Joined: 17 Jun 2006 Posts: 1201
|
Posted: Sat Jul 26, 2008 2:12 am |
Hmm interestingly enough it is completely ignoring the \ escape character for "\|" or if you put the pipe inside brackets like "[|]". It still reads the pipe and comes out like as follows.
^(?:] won't work\.|This [|This is a test\.)
and
^(?:This \|This is a test\.| won't work\.)
The two triggers used were actually this.
This is a test\.
This \| won't work\.
also
This [|] won't work\.
So again it's just flat out ignoring regex except for the | character, but only when there is a pipe involved for some reason does it ignore the other special characters. |
|
|
|
Zhiroc Adept
Joined: 04 Feb 2005 Posts: 246
|
Posted: Sat Jul 26, 2008 6:09 pm |
Zugg wrote: |
When the trigger tries to sort the string list and create the regular expression pattern, |
Are all stringlists sorted for the RE? Even the ones not marked as sorted? If so, this can cause unexpected results.
One thing to remember is that RE engines, from what I know, are "eager". Thus, they match as soon as they can. With alternation, this means that the order of the elements can matter. Many times, this doesn't come up, but it can. So if someone has a non-sorted stringlist "setting|set", it is important to not sort that back to "set|setting" for the RE. In the first case, when presented with the string "setting", it will match it in full (barring any further parts of the RE that might fail and thus cause a backtrack). In the second case, "setting" would just match the "set" part. |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Mon Jul 28, 2008 4:48 pm |
Yes, string lists are *always* sorted in reverse order for PCRE. This was also done in zMUD. This is done so that patterns like:
(?:a|aab|aaab)
work properly. It's very important that the *longest* pattern in a {a|b|c...} or (?:a|b|c...) list comes first, otherwise there will be problems with the regex matching stuff that you don't want. zMUD/CMUD accomplish this by reverse sorting the string list. So this sorting has always been done...nothing new. It's just that this is bugged when the list contains nested | characters. |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Mon Jul 28, 2008 9:36 pm |
The problem with | in a string list should be fixed in v2.34
|
|
|
|
Zhiroc Adept
Joined: 04 Feb 2005 Posts: 246
|
Posted: Tue Jul 29, 2008 3:22 pm |
Zugg wrote: |
Yes, string lists are *always* sorted in reverse order for PCRE. This was also done in zMUD. This is done so that patterns like:
(?:a|aab|aaab)
work properly. It's very important that the *longest* pattern in a {a|b|c...} or (?:a|b|c...) list comes first, otherwise there will be problems with the regex matching stuff that you don't want. zMUD/CMUD accomplish this by reverse sorting the string list. So this sorting has always been done...nothing new. It's just that this is bugged when the list contains nested | characters. |
I'm not sure what you mean by "work properly".
By regex rules, alternations are supposed to be "eager", like I said earlier. Each alternative is tried in turn, and it advances to the next only if backtracking is done. That means if I write an RE like "(set|setting)" and match it against "setting", the correct result is that $1 == "set". If I wanted $1 == "setting", I have to write the RE as "(setting|set)". Alternations are not supposed to pick the longest result, unlike wildcards.
This can be confirmed using perl.
Now, in both zMUD and CMUD, if I write a trigger with the static pattern "(set|setting)", both get it right. Matching against "setting" using the test feature, it shows %1 == "set".
And even in zMUD, if I do #VAR tmp {set|setting}, then make a trigger with the pattern "(@tmp)", if I match it against "setting", it also shows that %1 == "set".
It is only in CMUD where if I do the same, that it shows me that %1 == "setting". However, if you create the variable using the PE, and leave its type as "Autotype", you get %1 == "set", perhaps because it is being treated as a string.
IMHO, the correct behavior is that using a stringlist in an RE alternation should result in what the regex rules state when viewing the variables contents using #SH @var. No rearrangement or sorting should be done (unless the stringlist is sorted, of course). The author may need the order to be significant.
There is a workaround to this. It seems that using "(%%string(@tmp))" removes this behavior in CMUD. But I still believe that there's no need to sort the stringlist in the first place, and that it is, in fact, incorrect to do so. |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Tue Jul 29, 2008 4:35 pm |
In addition to being "easer", patterns are also supposed to be "greedy". In the example that you gave:
Code: |
#VAR tmp {set|setting}
#TRIGGER {test ({@tmp})} {#show "fired:" %1}
#SHOW "test setting" |
zMUD and CMUD both show "setting". This is actually what you *want* to happen on a MUD. Typically you use the {@friends} syntax in a trigger to color or match a list of friends names. For example, you might have #VAR Friends {Sam|Samuel}. And if the MUD displays "Samuel tells you hello", then obviously you want the entire "Samuel" to be colored, and not just the "Sam" part of it.
Because most people do not understand nor care about the way Regular Expressions work, both zMUD and CMUD sort any string list within {} in reverse order. So when converted to a regular expression, the above trigger pattern is changed to "test (?:setting|set)" so that the longest string from the MUD will be properly matched. Because this is what people *want* it to do.
Now, the difference between CMUD and zMUD is that in CMUD, the string list variable is also sorted when *not* within {}. So yes, in your example of just (@tmp) it will also be converted to (setting|set) regardless of the order you have set in the string list. zMUD did not sort the string list unless it was within the {} subpattern. This caused people problems when they tried to use Regular Expression syntax instead of zScript syntax. By always sorting a string list (or database variable) in reverse regardless of whether it is within {}, CMUD is more consistent than zMUD was.
As you mentioned, the correct way to get around this "feature" is to use %%string to convert the string list into a regular string. A regular string is *not* sorted when used in a pattern. Using %%string gives the author a way to preserve the order of the string list in case that is significant. Anyone who understands regular expressions well enough to want to preserve the order can certainly learn to use %%string.
However, because the vast majority of players just "want it to work", that is why CMUD normally does the sorting for you. 99% of the time you *want* it to match the longest match and don't care about the order of values in the string list. Especially since so many other features of string lists in CMUD are faster when you use the #SORT command to sort the string list. People don't want their patterns to be screwed up just because they used #SORT to improve the speed of their string lists.
In summary, CMUD is working the way MUD players expect it to. |
|
|
|
Zhiroc Adept
Joined: 04 Feb 2005 Posts: 246
|
Posted: Tue Jul 29, 2008 5:32 pm |
I was talking about REGEX triggers. Try your example after converting to a regex in zMUD, and you see: fired: "set"
zScript triggers can act in a "simple" way. But I think that REGEX's should act like perl or any other RE engine. The RE rules are standards (de-facto, I think). The default syntax in an RE should try to match these rules (granted, variables in RE engines are not exactly standard, but I think it should be consistent: #SH @var should show the exact string passed into the RE).
Part of this is consistency. If I start with a static pattern of "(set|setting)" I would expect it to act the same as "(@tmp)" if I convert it.
I also just noticed an inconsistency with %subregex():
Code: |
#VAR tmp {set|setting}
#SH %subregex("setting", (@tmp), "XXX") |
So sorting means that REGEX triggers act differently than the RE in %subregex() |
|
|
|
|
|