Hi,Randall!
1)
In patterns.hhf in endOneOrMorePat macro i saw this line:
  mov( pat.ar( prevOpEBP ), pat.onePatEBP )
i think this must be
  mov(pat.ar(prevOpEBP), pat.oneOrMorePatEBP); ?
2)
When using pat.oneOrMorePat and matched string has several matching for this sub pattern
endmatch macro doesn't restore original ebp.

Example:
static
  test_str: string := "#include(""w.hhf"") #include(""inc.hhf"")";
endstatic;

begin patterns;
pat.match(test_str);
pat.oneOrMorePat;
pat.matchToiStr("#include");
pat.upToChar('(');
pat.oneChar('(');
pat.upToChar('"');
pat.oneChar('"');
pat.upToChar('"');
pat.endOneOrMorePat;
  pat.if_failure
  pat.endmatch;
and here ebp points to activation record of some pattern matching function not main program.

3)
Macros like pat.oneOrMorePat havily use ebp register.
How it is supposed to access local variables inside
oneOrMorePat -- endOneOrMorePat block?
Posted on 2005-11-02 15:08:27 by Elohim Meth

Hi,Randall!
1)
In patterns.hhf in endOneOrMorePat macro i saw this line:
  mov( pat.ar( prevOpEBP ), pat.onePatEBP )
i think this must be
  mov(pat.ar(prevOpEBP), pat.oneOrMorePatEBP); ?


Yep. Cut and paste (from onePat) strikes again! Just missed this when I cut and pasted onePat to create oneOrMorePat.


2)
When using pat.oneOrMorePat and matched string has several matching for this sub pattern
endmatch macro doesn't restore original ebp.

Example:
static
  test_str: string := "#include(""w.hhf"") #include(""inc.hhf"")";
endstatic;

begin patterns;
pat.match(test_str);
pat.oneOrMorePat;
pat.matchToiStr("#include");
pat.upToChar('(');
pat.oneChar('(');
pat.upToChar('"');
pat.oneChar('"');
pat.upToChar('"');
pat.endOneOrMorePat;
  pat.if_failure
  pat.endmatch;
and here ebp points to activation record of some pattern matching function not main program.

Yes, I can see how the problem in (1) can cause this.



3)
Macros like pat.oneOrMorePat havily use ebp register.
How it is supposed to access local variables inside
oneOrMorePat -- endOneOrMorePat block?

The pattern matching code *really* messes with the stack. Whenever one of the pattern matching functions returns, it does not clean up the activation record created on the stack for that function. This is done to support backtracking between the match/endmatch macro invocations. Basically, whenever backtracking occurs, the code unwinds the stack back to the last function that needs to do backtracking. When a match succeeds (or completely fails) and you hit the endmatch macro, *then* the code unwinds all the stuff left on the stack by all the pattern matching code. Playing games with EBP is exactly how this is achieved. For this reason, you do *not* want to bail out of the middle of a match/endmatch sequence via a JMP or other mechanism (well, exceptions are okay, as they unwind the stack too).
Cheers,
Randy Hyde
Posted on 2005-11-03 16:17:15 by rhyde
Thanks for reply, Randall!

Yes, I can see how the problem in (1) can cause this.


Yes it can cause this, when pattern fails matching the string, but in my example pattern matching succeeded
and doesn't even execute this line. I corrected this line in patterns.hhf and problem still exists.
As far as i can understand algorithm the cause of this problem is several match occurences in string.
oneOrMorePat macro creates activation record for each matching occurence and
endOneOrMorePat macro on successful matching restores ebp from FailToSave.ebpSave and its
correct for backtracking, but endmatch macro didn't know about this activation records and didn't
even touch ebp register. As a result after endmatch ebp points to activation record of last
pattern matching function inside oneOrMorePat - endOneOrMorePat block that supports backtracking.

The pattern matching code *really* messes with the stack. Whenever one of the pattern matching functions returns, it does not clean up the activation record created on the stack for that function. This is done to support backtracking between the match/endmatch macro invocations. Basically, whenever backtracking occurs, the code unwinds the stack back to the last function that needs to do backtracking. When a match succeeds (or completely fails) and you hit the endmatch macro, *then* the code unwinds all the stuff left on the stack by all the pattern matching code. Playing games with EBP is exactly how this is achieved. For this reason, you do *not* want to bail out of the middle of a match/endmatch sequence via a JMP or other mechanism (well, exceptions are okay, as they unwind the stack too).


Yes, i understand that pattern matching functions messes with the stack. But...they not mess ebp (well ... only inside themselves).
As far as i can see in between calls to pattern matching ebp is preserved. But using one of pat.pattern macros messes ebp.
One of main purposes of pattern matching is to extract matches, but where to store the result of pat.extract?
Ebx, esi and edi are internally used in matching functions, ebp is messed so local variables are not available.
And also when using pattern matching inside some procedure how to pass parameters of this procedure to matching function if ebp is messed?
Posted on 2005-11-04 05:17:37 by Elohim Meth