SpecialTopic bug with adv3Lite

I found this on adv3Lite 1.5, but I checked last night and it appears the issue is still present in the latest code in GitHub.

My WIP uses several QueryTopic instances for NPC dialog, and I was having trouble creating matchPattern’s with regular expressions. After a bit of debugging, I found two problems:

The main issue is with the regular expression that SpecialTopic uses to determine if a matchPattern string is a regular expression (turtles all the way down!):

rex = static new RexPattern('<langle|rangle|star|dollar|vbar|percent|carat>')

It should be “caret,” not “carat,” which was throwing off the entire search pattern. With this bug, it appears all my regex matchPattern’s were being processed as Mentionable vocabulary strings (which, surprisingly, worked okay in a lot of situations, but not perfectly).

My patch is to replace the above with this:

// Fix: "caret" instead of "carat", add parentheses
rex = static new RexPattern('<langle|rangle|star|dollar|vbar|percent|caret|lparen|rparen>')

I added parentheses to the search pattern because they’re used for groupings in regex (and rarely, if ever, used in a vocab string).

This led to being tripped up by a second issue with TopicEntry:

/* 
 *   If they don't want an exact case match, convert the
 *   original topic text to lower case 
 */
if (!matchExactCase)
    txt = txt.toLower();

/* if the regular expression matches, we match */
if (rexMatch(matchPattern, txt) != nil)
    return matchScore + scoreBoost;

This works okay unless the regular expression is upper- or mixed-case, e.g.:

+ QueryTopic 'where' 'is (Fourth|Forth|4th) (Street|St.)'
  "<q>Go around the corner,</q> he says.  <q>It's between Third and Fifth Street.</q>"
;

Converting the user’s text to lowercase doesn’t help here, because the regex pattern defaults to case-sensitive. I could have gone through my code and adjusted all my existing patterns, but it seems to me that matchExactCase should not require the coder to understand this. So, I made this change:

/*
 * Fix: Use regex's case handling rather than case-folding the input text, otherwise
 * matchPattern is treated as case-sensitive no matter what.
 */
local caseHandling = matchExactCase ? '<Case>' : '<NoCase>';

/* if the regular expression matches, we match */
if (rexMatch('<<caseHandling>><<matchPattern>>', txt) != nil)
    return matchScore + scoreBoost;

I’m not super-excited about string-hacking regular expressions, but the above seems pretty inoffensive.

@Eric_Eve Don’t know if these changes are how you would solve the problem, so I didn’t submit a patch and am reporting it here instead. Definitely think the first problem needs attention, and feel strongly about the second.

3 Likes

Glad to know you’re still actively working in TADS!

3 Likes

Thanks for reporting this and for the suggested fixes. I’ll take a closer look at it all and incorporate your fixes (unless I can devise a better one) into the next update.

3 Likes