Files
harbour-core/harbour/samples/cccppc/mparser.prg
1999-11-09 01:37:27 +00:00

1994 lines
62 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* $Id$
*/
//*******************************************************************
// mparser.prg: A mparser oszt ly implement ci¢ja.
// 1999, Csisz r Levente
// A sorokban a makr¢kat (define, command, xcommand, translate,
// xtranslate) helyettes¡ti.
// A PARSER-t“l ”r”k”l.
// A nv s a sor (lparser) elemz“  ltal ksz¡tett tokeneket v r az
// inputr¢l. <20>ltal ban a hparser ut n van.
/*
Algoritmus:
Olvas az inputj r¢l addig, am¡g el nem d”nti, hogy
helyettes¡teni kell vagy nem. Ha igen, akkor a helyettes¡ts
eredmnyt visszarakja az inputj ra, ha pedig nem
kellett helyettes¡teni, akkor azt kirakja az outputra.
Ezekut n mindig nil-t ad olvas sra.
*/
// #define DEBUG
//*******************************************************************
#include "debug.ch"
//*******************************************************************
#include "objgen.ch"
//*******************************************************************
#define _STRICT_PARENT_
#include "token.och"
#include "tokenst.och"
#include "edefdict.och"
#include "defdict.och"
#include "extrdict.och"
#include "xtrdict.och"
#include "reader.och"
#include "mmarker.och"
#include "tbuffer.och"
// #include "prtree.och"
#include "maltrset.och"
#include "rsmmarkr.och"
// #include "prserr.och"
//*******************************************************************
#include "cr_lf.ch"
#include "ctoken.ch"
// #include "prserr.ch"
//*******************************************************************
// ™sszehasonl¡tja a (tkId, tkStr)-t egy karaterrel.
#define eqTkChar(tkId,tkStr,aChar) ((tkId)==TKID_CHAR .and.;
(tkStr)==(aChar))
//*******************************************************************
// Megnzi, hogy, ha a token TKID_CHAR, akkor a tkStr benne van-e
// az aString-ben.
#define eqTkInCharList(tkId,tkStr,aString) ((tkId)==TKID_CHAR .and.;
(tkStr)$(aString))
#define PVT_IDX 1
#define PVT_NAME 2
//*******************************************************************
#define _MPARSER_PRG_
#define _IMPLEMENT_ONEW_
#include "mparser.och"
//*******************************************************************
// implement oinit(inputReader,name,defdict,errorStream)
implement oinit(inputReader,name,errorStream)
super:oinit(inputReader,name,errorStream)
// this:errorItem:=nil
// this:defdict:=defdict
return this
//*******************************************************************
implement startMakroBuf(item)
if (item==nil)
this:makroBuf:={}
else
this:makroBuf:={item}
endif
return nil
//*******************************************************************
implement rdsMakroBuf()
local w
w:=this:rds()
if (this:item!=nil)
aadd(this:makroBuf,this:item)
endif
return w
//*******************************************************************
implement unrdsMakroBuf(n)
local w,m
w:=this:unrds(n)
m:=len(this:makroBuf)-w
asize(this:makroBuf,if(m>0,m,0))
return w
//*******************************************************************
implement readItem()
outerr("MPARSER.o:readItem(): Ez a mvelet nem h¡vhat¢!",crlf())
return super:readItem()
#ifdef OLD
local w,tkId,tkStr
/*
Olvas a puffer-be:
- ha nv, s az szerepel a define sz¢t rban, akkor
akkor ind¡t egy define elemz“t.
Ez az elemz“ elmenti a parserBuffer-t, majd elvgzi
a define objektum elemzst.
*/
while(nil==(w:=this:getParserBuffer()) .and.;
nil!=(w:=super:readInput()) .and.;
TOKEN.w:id==TKID_NEV)
this:item:=w
// Ez itt nem j”het ki!
outerr("mparser: readItem",crlf())
this:putParserBuffer(w)
this:parseFun()
end while
return w
#endif
//*******************************************************************
implement parseFun(edefdict)
/*
Ez vgzi a tnyleges elemzst.
A this:item-t elemzi, sz<73>ksg esetn mg olvashat.
Elemezi az inputon a <nv>'('<param1>,...')' paramtereket.
Az edefdict-nek a <nv>-hez tartoz¢ makr¢ defin¡ci¢nak kell
lennie.
Ret: {sikeres,itemLista}
Ha sikeres volt, akkor a sikeres==.t., s az itemLista a csere
eredmnye.
Ha nem volt sikeres, akkor a sikeres==.f., s az itemLista a
beolvasott (el“reolvasott) itemek list ja.
A parserBufferben csak egy token lehet, ami az item-ben is
van.
*/
// Mj.: Elemzskor elfogadja az <20>res paramtereket is, ezeket csak a
// helyettes¡tskor szrj<72>k ki. Ez azrt van ¡gy, mert <20>res
// paramter £gy is lehet <20>res, hogy maga a token lista csupa
// <20>res tokenb“l  ll.
local state,tkId,tkStr,ujsor
local tList,i
local success,params,currentParam
local parentStack
#define STF_START "start"
#define STF_EXPR "expr"
#define STF_PARENT "parent"
tkId:=TOKEN.(this:item):id
tkStr:=TOKEN.(this:item):str
if (EDEFDICT.edefdict:params==nil)
// Paramterek nincsenek.
// Ez csak egy <nv> -> <token1>,... t¡pus£ helyettes¡ts.
this:unputParserBuffer()
return {.t.,EDEFDICT.edefdict:change()}
endif
// Most elemezz<7A>k a '('<param1>,...')' -t.
parentStack:={} // Itt vannak a z r¢jelek.
state:=STF_START
success:=.f.
this:rds()
while(this:item!=nil)
tkId:=TOKEN.(this:item):id
tkStr:=TOKEN.(this:item):str
ujsor:=tkId==TKID_UJSOR .or.;
tkId==TKID_BOS .or. tkId==TKID_EOS .or.;
(tkId==TKID_CHAR .and. tkStr==";")
if (state==STF_START)
if (tkId==TKID_URES)
// Maradunk
// state:=state
elseif (tkId==TKID_CHAR .and. tkStr=="(")
// Kezd“dik az elemzs.
currentParam:={}
params:={}
state:=STF_EXPR
else
// Vge. Ide tartozik a sorvgjel is.
exit
endif
elseif (state==STF_EXPR)
if (tkId==TKID_UJSOR .or.;
tkId==TKID_BOS .or. tkId==TKID_EOS .or.;
(tkId==TKID_CHAR .and. tkStr==";"))
// Vge.
exit
elseif (tkId==TKID_URES)
// Maradunk
// state:=state
aadd(currentParam,this:item)
elseif (tkId==TKID_CHAR .and. tkStr==")")
// Vge a paramter list nak.
aadd(params,currentParam)
success:=.t.
exit
elseif (tkId==TKID_CHAR .and. tkStr==",")
// —j paramter kezd“dik.
aadd(params,currentParam)
currentParam:={}
state:=STF_EXPR
elseif (tkId==TKID_CHAR .and.;
(tkStr=="(" .or. tkStr=="{" .or. tkStr=="["))
// El kell menni a k”vetkez“ csuk¢ig, k”zben figyelni,
// hogy rendesen z r¢jelezve van-e.
aadd(currentParam,this:item)
aadd(parentStack,thisclass:getCloseParent(tkStr))
state:=STF_PARENT
else
// Ez a paramterhez tartozik.
aadd(currentParam,this:item)
endif
elseif (state==STF_PARENT)
if (ujsor)
// Vge.
exit
elseif (tkId==TKID_URES)
// Maradunk
// state:=state
aadd(currentParam,this:item)
elseif (tkId==TKID_CHAR .and.;
(tkStr=="(" .or. tkStr=="{" .or. tkStr=="["))
// El kell menni a k”vetkez“ csuk¢ig, k”zben figyelni,
// hogy rendesen z r¢jelezve van-e.
aadd(currentParam,this:item)
aadd(parentStack,thisclass:getCloseParent(tkStr))
// Maradunk
elseif (tkId==TKID_CHAR .and. tkStr==alast(parentStack))
aadd(currentParam,this:item)
asize(parentStack,len(parentStack)-1)
if (len(parentStack)==0)
state:=STF_EXPR
endif
elseif (tkId==TKID_NEV)
aadd(currentParam,this:item)
else
// Ez a paramterhez tartozik.
aadd(currentParam,this:item)
endif
else
? "MPARSER:parseFun(): Ismeretlen  llapot: ",state
errorlevel(1)
quit
endif
this:rds()
end while
if (success .and.;
len(params)==1 .and.;
0==ascan(params[1],{|x| !TOKEN.x:id==TKID_URES}))
asize(params,0)
endif
if (success .and. len(params)==len(EDEFDICT.edefdict:params))
// Siker<65>lt az elemzs, most meg kell csin lni a csert.
for i:=1 to len(params)
params[i]:=thisclass:trimTokenList(params[i])
if (empty(params[i]))
return {.f.,this:arrayParserBuffer()}
endif
end for
#ifdef DEBUG
outerr(crlf())
outerr("define change: ",EDEFDICT.edefdict:printStr(),crlf())
for i:=1 to len(params)
outerr("params[",i,"]: ")
aeval(params[i],{|t| outerr(TOKEN.t:getStr())})
outerr(crlf())
end for
#endif
return {.t.,EDEFDICT.edefdict:change(params)}
endif
// Nem siker<65>lt az elemzs.
return {.f.,this:arrayParserBuffer()}
//*******************************************************************
// implement printDefDict()
// return DEFDICT.(this:defdict):printStr()
//*******************************************************************
cimplement getCloseParent(aChar)
// Ha az aChar egy nyit¢ z r¢jel, akkor a a csuk¢ p rj t adja,
// egybknt nil-t.
if (aChar=="(")
return ")"
elseif (aChar=="{")
return "}"
elseif (aChar=="[")
return "]"
endif
return nil
//*******************************************************************
cimplement trimTokenList(tList)
// A tList elejr“l s vgr“l elt vol¡tja az <20>res tokeneket.
// Ret: a tList.
local i
while(!empty(tList))
if (TOKEN.(tList[1]):id!=TKID_URES)
exit
endif
adel(tList,1)
asize(tList,len(tList)-1)
end while
for i:=len(tList) to 1 step -1
if (TOKEN.(tList[i]):id!=TKID_URES)
asize(tList,i)
exit
endif
end for
return tList
//*******************************************************************
cimplement parse(item,inputReader,name,defdict,edefdict,xtrdict,mi,errorStream,ujsor,trPrsAlg)
/*
Itt az item csak TOKEN lehet vagy nil.
Az inputReader-nek kell ind¡tania az £j elemz“ket.
Az algoritmus:
Megnzi a define sz¢t rban, ha megvan, akkor ind¡t egy
elemz“t r , ha az sikeres, akkor visszatr, ha nem sikeres, akkor
visszateszi a beolvasott token sort az inputra, elkezdi ind¡tani
r  az xtranslate makr¢kat.
Egy xtranslate makr¢ ind¡t sa:
- Ind¡tja a makr¢t, ha sikeres, akkor visszatr, ha nem,
akkor a token sort visszateszi az inputra.
A maxim lis hossz£s g£ tokensort meg kell “rizni, s
azt adni teljes sikertelensg esetn.
M sik lehet“sg, hogy ravaszkodunk: beiktatunk egy  tmeneti
puffert az inputunk el (ez az mcontrol!), s
azt adjuk sikertelensg esetn.
*/
// Nem teljesen korrekt, mert az elemz“t minden alkalommal legy rtja.
local othis,w,match,xtrList,xcmList
local i,j
if (nil==item)
return {item}
endif
match:={.f.,{item}}
// if (TOKEN.item:id==TKID_NEV .and.;
// nil!=(edefdict:=DEFDICT.(defdict):atKey(TOKEN.item:str)))
if (edefdict!=nil)
othis:=class:onew(inputReader,name,defdict,xtrdict,errorStream)
othis:item:=item
othis:putParserBuffer(item)
match:=othis:parseFun(edefdict)
// Az othis inputj ra visszatett tokeneket itt ki kellene venni!
// Persze most ilyen nem lehet, mert ebb“l az objektumb¢l senki
// sem olvas.
if (match[1])
// Az illeszs sikeres volt.
return match
endif
endif
// #define XTR_SEQ
if (trPrsAlg==TRPRA_SEQ)
// Szekvenci lis illeszts.
xtrList:=XTRDICT.xtrdict:getExtrList(item)
if (ujsor)
xcmList:=XTRDICT.xtrdict:getExtrList(item,.t.)
xtrList:=aconcatenate(xcmList,xtrList)
//xtrList:=aconcatenate(xtrList,xcmList)
endif
// H tulr¢l el“re haladunk.
for i:=len(xtrList) to 1 step -1
// Az els“ maga az item, ezrt azt nem kell visszatenni.
for j:=len(match[2]) to 2 step -1
READER.inputReader:unread(match[2][j])
end for
othis:=class:onew(inputReader,name,defdict,xtrdict,errorStream)
othis:item:=item
othis:putParserBuffer(item)
match:=othis:parseXtr(xtrList[i])
// Az othis inputj ra visszatett tokeneket itt ki kellene venni!
// Persze most ilyen nem lehet, mert ebb“l az objektumb¢l senki
// sem olvas.
if (match[1])
// Az illeszs sikeres volt.
return match
endif
end for
elseif (mi[1]!=0 .or. mi[2]!=0)
// Fa bej r sos illeszts.
// El“sz”r az xtranslate-eket illesztj<74>k.
for j:=len(match[2]) to 2 step -1
READER.inputReader:unread(match[2][j])
end for
if (mi[1]!=0)
othis:=class:onew(inputReader,name,defdict,xtrdict,errorStream)
othis:item:=item
othis:putParserBuffer(item)
match:=othis:parseXtrTree(XTRDICT.xtrdict:trdictTree,mi[1],.f.)
// Az othis inputj ra visszatett tokeneket itt ki kellene venni!
// Persze most ilyen nem lehet, mert ebb“l az objektumb¢l senki
// sem olvas.
if (match[1])
// Az illeszs sikeres volt.
return match
endif
endif
if (ujsor .and. mi[2]!=0)
// Azut n az xcommand-okat.
for j:=len(match[2]) to 2 step -1
READER.inputReader:unread(match[2][j])
end for
othis:=class:onew(inputReader,name,defdict,xtrdict,errorStream)
othis:item:=item
othis:putParserBuffer(item)
match:=othis:parseXtrTree(XTRDICT.xtrdict:cmdictTree,mi[2],.t.)
// Az othis inputj ra visszatett tokeneket itt ki kellene venni!
// Persze most ilyen nem lehet, mert ebb“l az objektumb¢l senki
// sem olvas.
if (match[1])
// Az illeszs sikeres volt.
return match
endif
endif
// else
// for j:=len(match[2]) to 2 step -1
// READER.inputReader:unread(match[2][j])
// end for
endif
return match
//*******************************************************************
static function nextLeftToken(o)
// Az o ¡gy nz ki: {iLeft,leftTokenlist}
// Az iLeft mindig a beolvasand¢ra mutat
local t
while(o[1]<=len(o[2]))
t:=o[2][o[1]]
o[1]++
if (TOKEN.t:id!=TKID_URES)
return t
endif
end while
return nil
//*******************************************************************
static function addMatchParam(paramValues,idx,name,tokenList)
if (paramValues[1]==PVT_IDX)
if (len(paramValues[2])<idx)
asize(paramValues[2],idx)
endif
if (paramValues[2][idx]==nil)
paramValues[2][idx]:={tokenList}
else
aadd(paramValues[2][idx],tokenList)
endif
else
aadd(paramValues[2],{name,tokenList})
endif
return nil
//*******************************************************************
implement parseTokenList(leftTokenList,cmd4,paramValues,toEOL)
/*
Ez vgzi a tnyleges elemzst. Az input folyamot megpr¢b lja
illeszteni a leftTokeList-re.
A this:item-t elemzi, sz<73>ksg esetn mg olvashat.
Amikor h¡vjuk, akkor a parserBuffer-ben csak a this:item-nek szabad
lennie.
Ha a toEOL nem <20>res, akkor csak akkor sikeres az illeszts, ha
a sor vgig ment.
Ha a cmd4 nem <20>res, akkor a neveket 4 hossz£ra v gva hasonl¡tja
”ssze.
Ret: 0: Ha nem siker<65>lt az illeszts.
Ekkor a parserBuffer-ben vannak a beolvasott tokenek.
1: Ha siker<65>lt az illeszts, de nem ment el“re. (Pl. egy <20>res
alternat¡va.
2: Ha siker<65>lt az illeszts s el“re is ment.
*/
/*
Megy<67>nk vgig az extrdict bal oldal n s:
- Ha normal token (nem match token s nem maltrset), akkor
annak illeszkednie kell, ha nem, akkor nem illeszkedett
jelzssel visszatr.
- Ha match token, akkor arra ind¡tunk egy k<>l”n match
token elemz“t. Ez az elemz“ megkapja a k”vetkez“ tokent.
*/
// #define STX_START "START"
#ifdef OLD
local tkId,tkStr,ujsor
local tList,i
local oLeftTList, leftToken, leftTkId, leftTkStr
local match
local w
local nUres//, utNemUresItem
oLeftTList:={1,leftTokenList}
// state:=STX_START
// tokenList:={}
if (nil==(leftToken:=nextLeftToken(oLeftTList)))
// šres ==> Nem illeszkedik semmire.
return .f.
endif
nUres:=0
// utNemUresItem:=this:item
while(this:item!=nil)
leftTkId:=TOKEN.leftToken:id
leftTkStr:=TOKEN.leftToken:str
tkId:=TOKEN.(this:item):id
tkStr:=TOKEN.(this:item):str
ujsor:=tkId==TKID_UJSOR .or.;
tkId==TKID_BOS .or. tkId==TKID_EOS .or.;
(tkId==TKID_CHAR .and. tkStr==";")
if (tkId==TKID_URES)
// Maradunk
// aadd(tokenList,this:item)
nUres++
elseif (ujsor)
// Vge.
// Illeszkedett, ha a leftToken egy alternat¡va, mert r  az
// <20>res is illeszkedik, nem illeszkedett, ha nem az.
// Ha illeszkedett, akkor a vgr“l az £jsort s az <20>reseket
// vissza kell tenni az inputra.
if (leftTkId==TKID_MALTERSET)
this:unrds(nUres+1)
// this:item:=utNemUresItem
// Itt nem kell a toEOL-t vizsg lni.
return .t.
endif
exit
else
if (leftTkId==TKID_MALTERSET)
this:mleftXMRToken(leftToken,cmd4,paramValues,nUres)
match:=.t.
this:makroBuf:=nil
elseif (leftTkId==TKID_REGULAR_MATCH_MARKER)
match:=this:mleftXRMMToken(leftToken,cmd4)
elseif (leftTkId==TKID_WILD_MATCH_MARKER)
match:=this:mleftXWMToken(leftToken)
elseif (leftTkId==TKID_EXT_EXPR_MATCH_MARKER)
match:=this:mleftXEEMToken(leftToken)
elseif (leftTkId==TKID_LIST_MATCH_MARKER)
match:=this:mleftXLMToken(leftToken,cmd4)
elseif (leftTkId==TKID_RESTRICTED_MATCH_MARKER)
match:=this:mleftXRSMMToken(leftToken,cmd4)
else
// Egyb illeszkeds.
match:=this:mleftXNToken(leftToken,cmd4)
this:makroBuf:=nil
endif
nUres:=0
if (!match)
// Az illeszts nem siker<65>lt ==> Vge.
exit
endif
// Az illeszts siker<65>lt, az eredmny a tokenList-ben van,
// megy<67>nk tov bb.
if (this:makroBuf!=nil)
addMatchParam(paramValues,;
MMARKER.leftToken:mNum,;
MMARKER.leftToken:getName(),;
this:makroBuf)
endif
leftToken:=nextLeftToken(oLeftTList)
endif
if (nil==leftToken)
// Vgig rt<72>nk a tokenlist n.
// Ha a toEOL nem <20>res, akkor meg kell nzni, hogy a sor
// vgn vagyunk-e vagy a sor vgig csak <20>resek vannak-e.
if (!empty(toEOL))
this:rds()
while(this:item!=nil)
tkId:=TOKEN.(this:item):id
tkStr:=TOKEN.(this:item):str
ujsor:=tkId==TKID_UJSOR .or.;
tkId==TKID_BOS .or. tkId==TKID_EOS .or.;
(tkId==TKID_CHAR .and. tkStr==";")
if (tkId==TKID_URES)
// Megy<67>nk tov bb.
nUres++
elseif (ujsor)
this:unrds(nUres+1)
return .t.
else
return .f.
endif
this:rds()
end while
endif
return .t.
endif
this:rds()
end while
return .f.
#endif
local oLeftTList,leftToken,retVal,gone
oLeftTList:={1,leftTokenList}
if (nil==(leftToken:=nextLeftToken(oLeftTList)))
// šres ==> Nem illeszkedik semmire.
return 0
endif
gone:=.f.
while(0!=(retVal:=matchLeftToken(this,leftToken,cmd4,paramValues,toEOL)))
if (retVal==2)
gone:=.t.
endif
if (nil==(leftToken:=nextLeftToken(oLeftTList)))
if (nilLeftToken(this,toEOL))
return if(gone,2,1)
endif
// Nem illeszkedett.
return 0
endif
this:rds()
end while
// Az illeszts nem siker<65>lt.
return 0
//*******************************************************************
static function nilLeftToken(this,toEOL)
// Akkor kell h¡vni, amikor a leftToken nil
local tkId,tkStr,ujsor,nUres
nUres:=0
// Vgig rt<72>nk a tokenlist n.
// Ha a toEOL nem <20>res, akkor meg kell nzni, hogy a sor
// vgn vagyunk-e vagy a sor vgig csak <20>resek vannak-e.
if (!empty(toEOL))
this:rds()
while(this:item!=nil)
tkId:=TOKEN.(this:item):id
tkStr:=TOKEN.(this:item):str
ujsor:=tkId==TKID_UJSOR .or.;
tkId==TKID_BOS .or. tkId==TKID_EOS .or.;
(tkId==TKID_CHAR .and. tkStr==";")
if (tkId==TKID_URES)
// Megy<67>nk tov bb.
nUres++
elseif (ujsor)
this:unrds(nUres+1)
return .t.
else
// Az illeszts nem siker<65>lt.
return .f.
endif
this:rds()
end while
endif
return .t.
//*******************************************************************
static function matchLeftToken(this,leftToken,cmd4,paramValues,toEOL)
// Illeszt egy matchToken-t az inputra.
// A leftToken-nek nem nil-nek kell lennie.
// Ret: 0: Ha nem siker<65>lt az illeszts.
// Ekkor a parserBuffer-ben vannak a beolvasott tokenek.
//
// 1: Ha siker<65>lt az illeszts, de nem ment el“re. (Pl. egy <20>res
// alternat¡va.
//
// 2: Ha siker<65>lt az illeszts s el“re is ment.
local tkId,tkStr,ujsor
local tList,i
local oLeftTList, leftTkId, leftTkStr
local match
local w
local nUres
local gone:=.t.
nUres:=0
while(this:item!=nil)
leftTkId:=TOKEN.leftToken:id
leftTkStr:=TOKEN.leftToken:str
tkId:=TOKEN.(this:item):id
tkStr:=TOKEN.(this:item):str
ujsor:=tkId==TKID_UJSOR .or.;
tkId==TKID_BOS .or. tkId==TKID_EOS .or.;
(tkId==TKID_CHAR .and. tkStr==";")
if (tkId==TKID_URES)
// Maradunk
// aadd(tokenList,this:item)
nUres++
elseif (ujsor)
// Vge.
// Illeszkedett, ha a leftToken egy alternat¡va, mert r  az
// <20>res is illeszkedik, nem illeszkedett, ha nem az.
// Ha illeszkedett, akkor a vgr“l az £jsort s az <20>reseket
// vissza kell tenni az inputra.
if (leftTkId==TKID_MALTERSET)
this:unrds(nUres+1)
// this:item:=utNemUresItem
// Itt nem kell a toEOL-t vizsg lni.
// Illeszkedik, de nem ment el“re.
return 1
endif
// Az illeszts nem siker<65>lt.
return 0 //exit
else
if (leftTkId==TKID_MALTERSET)
gone:=this:mleftXMRToken(leftToken,cmd4,paramValues,nUres)
match:=.t.
this:makroBuf:=nil
elseif (leftTkId==TKID_REGULAR_MATCH_MARKER)
match:=this:mleftXRMMToken(leftToken,cmd4)
elseif (leftTkId==TKID_WILD_MATCH_MARKER)
match:=this:mleftXWMToken(leftToken)
elseif (leftTkId==TKID_EXT_EXPR_MATCH_MARKER)
match:=this:mleftXEEMToken(leftToken)
elseif (leftTkId==TKID_LIST_MATCH_MARKER)
match:=this:mleftXLMToken(leftToken,cmd4)
elseif (leftTkId==TKID_RESTRICTED_MATCH_MARKER)
match:=this:mleftXRSMMToken(leftToken,cmd4)
else
// Egyb illeszkeds.
match:=this:mleftXNToken(leftToken,cmd4)
this:makroBuf:=nil
endif
nUres:=0
if (!match)
// Az illeszts nem siker<65>lt ==> Vge.
return 0 // exit
endif
// Az illeszts siker<65>lt, az eredmny a tokenList-ben van,
// megy<67>nk tov bb.
if (this:makroBuf!=nil)
addMatchParam(paramValues,;
MMARKER.leftToken:mNum,;
MMARKER.leftToken:getName(),;
this:makroBuf)
endif
// Tov bb.
return if(gone,2,1)
// leftToken:=nextLeftToken(oLeftTList)
endif
this:rds()
end while
// Egy olyan sor, aminek nincs sorvgjele.
if (leftTkId==TKID_MALTERSET)
this:unrds(nUres+1)
// this:item:=utNemUresItem
// Itt nem kell a toEOL-t vizsg lni.
// Illeszkedik, de nem ment el“re.
return 1
endif
// Az illeszts nem siker<65>lt.
return 0 //exit
//*******************************************************************
static function markParamValues(paramValues)
local mark,i
mark:=array(len(paramValues[2]))
for i:=1 to len(paramValues[2])
if (paramValues[2][i]!=nil)
mark[i]:=len(paramValues[2][i])
endif
end for
return mark
//*******************************************************************
static function restoreParamValues(paramValues,mark)
local i
for i:=1 to len(mark)
if (mark[i]==nil)
paramValues[2][i]:=nil
else
asize(paramValues[2][i],mark[i])
endif
end for
for i:=len(mark)+1 to len(paramValues[2])
paramValues[2][i]:=nil
endfor
return nil
//*******************************************************************
function parseDictTree(this,dictTree,cmd4,paramValues,toEOL,mi)
/*
Elemez egy dictTree-t. Vgigpr¢b lja a fa minden  g t.
Elvgzi a helyettes¡tst ¡s, hogy folytathassa az elemzst, ha
a helyettes¡ts nem vgezhet“ el.
Ha az mi meg van adva, akkor az mi index node-t¢l indul.
tree:=nodeList
node:={token,nodeList[,extrDict]}
nodeList:={node1,...}
Ret: nil, ha nem siker<65>lt illeszteni, vagy nem lehetett
helyettes¡teni.
tokenList: A helyettes¡ts eredmnye, ha siker<65>lt illeszteni
s siker<65>lt helyettes¡teni.
*/
local l,item,markParamValues
local i//,retVal
local extrDict,befejezheto
local mL,mItem,mMarkParamValues
local resultTkList
l:=TBUFFER.(this:parserBuffer):bItemNumber()
item:=this:item
// Megy<67>nk a node-okon a legfels“ szinten, ha tal lunk
// illeszkedst, akkor a fa tov bbi rszt is illesztj<74>k, ha
// nem, akkor visszalp<E2809A>nk.
markParamValues:=markParamValues(paramValues)
for i:=if(empty(mi),1,mi) to len(dictTree)
if (0!=(/*retVal:=*/matchLeftToken(this,dictTree[i][1],cmd4,paramValues,toEOL)))
// Illeszkedett
// Megnzz<7A>k, hogy lehet-e tov bb menni.
befejezheto:=len(dictTree[i])>=3 .and. dictTree[i][3]!=nil
if (len(dictTree[i][2])>0)
// Megy<67>nk lefel a f ban ezen a node-on.
if (befejezheto)
mL:=TBUFFER.(this:parserBuffer):bItemNumber()
mItem:=this:item
mMarkParamValues:=markParamValues(paramValues)
endif
this:rds()
if (nil!=(resultTkList:=parseDictTree(this,dictTree[i][2],cmd4,paramValues,toEOL)))
// Siker<65>lt.
return resultTkList
endif
if (befejezheto)
// Vissza kell lpni.
this:unrds(TBUFFER.(this:parserBuffer):bItemNumber()-mL)
this:item:=mItem
restoreParamValues(paramValues,mMarkParamValues)
endif
endif
// Megnzz<7A>k, hogy itt be lehet-e fejezni.
if (befejezheto)
// Be lehet fejezni!
if (nilLeftToken(this,toEOL))
extrDict:=dictTree[i][3]
asize(paramValues[2],EXTRDICT.extrdict:numMatchMarkers)
if (nil!=(resultTkList:=EXTRDICT.extrdict:change(paramValues[2])))
return resultTkList
endif
// Nem siker<65>lt az elemzs.
endif
// Vissza kell lpni.
endif
this:unrds(TBUFFER.(this:parserBuffer):bItemNumber()-l)
this:item:=item
restoreParamValues(paramValues,markParamValues)
// Nem siker<65>lt.
// elseif (retVal)
// // Siker<65>lt.
// // Ide nem j”het!
// outerr("parseDictTree: retVal==.t.: Ide nem j”het!",newline())
// this:unrds(TBUFFER.(this:parserBuffer):bItemNumber()-l)
// this:item:=item
// restoreParamValues(paramValues,markParamValues)
// return nil
else
// Itt vissza kell lpni, s £jra pr¢b lkozni.
this:unrds(TBUFFER.(this:parserBuffer):bItemNumber()-l)
this:item:=item
restoreParamValues(paramValues,markParamValues)
endif
end while
// A befejezst itt nem kell nzni, mert a legfels“ szinten
// nem lehet befejezni (az az <20>res szab ly lenne), az als¢bb
// szinteken pedig a h¡v¢ nzi.
return nil
//*******************************************************************
implement parseXtr(extrdict)
/*
Ez vgzi a tnyleges elemzst.
A this:item-t elemzi, sz<73>ksg esetn mg olvashat.
Elemezi az inputon az extrdict tokenjeit.
Ret: {sikeres,itemLista}
Ha sikeres volt, akkor a sikeres==.t., s az itemLista a csere
eredmnye.
Ha nem volt sikeres, akkor a sikeres==.f., s az itemLista a
beolvasott (el“reolvasott) itemek list ja.
A parserBufferben csak egy token lehet, ami az item-ben is
van.
*/
local paramValues,w
#ifdef DEBUG
local i
#endif
paramValues:={PVT_IDX,array(EXTRDICT.extrdict:numMatchMarkers)}
if (0!=this:parseTokenList(EXTRDICT.extrdict:leftSide,;
EXTRDICT.extrdict:cmdType==XTRTYPE_COMMAND .or.;
EXTRDICT.extrdict:cmdType==XTRTYPE_TRANSLATE,;
paramValues,;
EXTRDICT.extrdict:cmdType==XTRTYPE_XCOMMAND .or.;
EXTRDICT.extrdict:cmdType==XTRTYPE_COMMAND))
// Siker<65>lt az elemzs, most meg kell csin lni a csert.
#ifdef DEBUG
outerr(crlf())
outerr("xtranslate change: ",EXTRDICT.extrdict:printStr(),crlf())
// for i:=1 to len(tokenList)
// outerr("left[",i,"]: ",TOKEN.tokenList[i]:getStr(),crlf())
// end for
#endif
if (nil!=(w:=EXTRDICT.extrdict:change(paramValues[2])))
return {.t.,w}
endif
endif
// Nem siker<65>lt az elemzs.
return {.f.,this:arrayParserBuffer()}
//*******************************************************************
implement parseXtrTree(trdictTree,mi,toEOL)
/*
Ez vgzi a tnyleges elemzst.
A this:item-t elemzi, sz<73>ksg esetn mg olvashat.
Elemezi az inputon az extrdict tokenjeit.
Az mi index node-t¢l indul.
Ret: {sikeres,itemLista}
Ha sikeres volt, akkor a sikeres==.t., s az itemLista a csere
eredmnye.
Ha nem volt sikeres, akkor a sikeres==.f., s az itemLista a
beolvasott (el“reolvasott) itemek list ja.
A parserBufferben csak egy token lehet, ami az item-ben is
van.
*/
local paramValues,w//,extrDict
#ifdef DEBUG
local i
#endif
paramValues:={PVT_IDX,{}}
if (nil!=(w:=parseDictTree(this,trdictTree,;
.f.,;
paramValues,;
toEOL,mi)))
// Siker<65>lt az elemzs, a csert a parserDict()-nek kell
// csin lnia, hogy tov bb folytathassa az elemzst, ha
// a helyettes¡tst nem lehet elvgezni.
#ifdef OLD
asize(paramValues[2],EXTRDICT.extrdict:numMatchMarkers)
#ifdef DEBUG
outerr(crlf())
outerr("xtranslate change: ",EXTRDICT.extrdict:printStr(),crlf())
// for i:=1 to len(tokenList)
// outerr("left[",i,"]: ",TOKEN.tokenList[i]:getStr(),crlf())
// end for
#endif
if (nil!=(w:=EXTRDICT.extrdict:change(paramValues[2])))
return {.t.,w}
endif
#endif
return {.t.,w}
endif
// Nem siker<65>lt az elemzs.
return {.f.,this:arrayParserBuffer()}
//*******************************************************************
function isMatchNToken(tkId,tkStr,mTkId,mTkStr,cmd4)
// Egy norm l token illeszkedi-e egy norm l (bal oldalon lv“)
// tokenre.
// Mj.: A tk s az mTk nem cserlhet“ fel egym ssal!
if (tkId==TKID_NEV)
return mTkId==TKID_NEV .and. compareWNames(tkStr,mTkStr,cmd4)
elseif (tkId==TKID_STRING)
return mTkId==TKID_STRING .and. compareWNames(tkStr,mTkStr,cmd4)
endif
return tkId==mTkId .and. tkStr==mTkStr
//*******************************************************************
implement mleftXNToken(leftToken,cmd4)
/*
Match left xtranslate normal token.
Norm l token (nem match s nem malterset) elemz“.
A this:item-ben lev“ tokent vizsg lja, mg olvashat.
Ha az illeszts sikertelen, akkor a plusz beolvasott tokeneket
visszateszi az inputra s a this:item-et vissza ll¡tja.
*/
local tkId, tkStr
tkId:=TOKEN.(this:item):id
tkStr:=TOKEN.(this:item):str
if (isMatchNToken(tkId,tkStr,;
TOKEN.leftToken:id,TOKEN.leftToken:str,;
TOKEN.leftToken:eqType/*cmd4*/))
return .t.
endif
return .f.
//*******************************************************************
static function connectParamValues(paramValues,wParamValues)
local i
if (paramValues[1]==PVT_IDX)
if (len(paramValues[2])<len(wParamValues[2]))
asize(paramValues[2],len(wParamValues[2]))
endif
for i:=1 to len(wParamValues[2])
if (wParamValues[2][i]!=nil)
if (paramValues[2][i]==nil)
paramValues[2][i]:=wParamValues[2][i]
else
aappend(paramValues[2][i],wParamValues[2][i])
endif
endif
end for
else
aappend(paramValues[2],wParamValues[2])
endif
return nil
//*******************************************************************
implement mleftXMRToken(leftToken,cmd4,paramValues,nUres)
// MALTERSET
/*
Az algoritmus:
Megy<67>nk az alternat¡v kon, s megpr¢b ljuk illeszteni.
Ha nem siker<65>lt, vissza az inputra a beolvasott tokeneket,
s vessz<73>k a k”vetkez“t.
Ha siker<65>lt, akkor el“r“l kezdj<64>k vgignzni az alternat¡v kat.
Mj.: Ez v ltozhat
Ha az alternat¡v k egyike sem illeszkedett, akkor tov bbmegy<67>nk.
Mj.: Az illeszts mindig sikeres, mert az <20>res is benne van.
a lehet“sgek k”z”tt, csak ilyenkor az olvasott
tokent vissza kell tenni az inputra.
*/
local oldParserBuffer
local item,i,leftTokenList
local wParamValues
local gone,iGone
gone:=.f.
oldParserBuffer:=this:parserBuffer
this:unrds()
this:parserBuffer:=C.TBUFFER:onew()
this:rds()
item:=this:item
leftTokenList:=MALTRSET.leftToken:alterset
i:=1
while(i<=len(leftTokenList))
if (paramValues[1]==PVT_IDX)
wParamValues:={paramValues[1],array(len(paramValues[2]))}
else
wParamValues:={paramValues[1],{}}
endif
if (2==(iGone:=this:parseTokenList(leftTokenList[i],cmd4,wParamValues)))
// Siker<65>lt illeszteni.
// A mostani parserBuffer-t hozz  kell adni a rgihez.
TBUFFER.oldParserBuffer:appendBuffer(this:parserBuffer)
// A paramtereket hozz  kell adni a rgihez.
connectParamValues(paramValues,wParamValues)
// —jra vgignzz<7A>k a list t.
this:parserBuffer:=C.TBUFFER:onew()
this:rds()
item:=this:item
i:=1
nUres:=0
gone:=.t.
else
// A mostani parserBuffert pedig el kell dobni (a tartalm t
// visszatenni az inputra), a item-et pedig vissza kell
//  ll¡tani.
this:unrds(TBUFFER.(this:parserBuffer):bItemNumber()-1)
this:item:=item
i++
endif
end while
// Nem lehet tov bb menni, de az illeszts azrt sikeres!
this:unrds()
this:parserBuffer:=oldParserBuffer
// A buffer vgn lev“ <space>-kat vissza kell rakni az
// inputra.
this:unrds(nUres)
return gone
//*******************************************************************
static function compareWNames(name,trName,cmd4)
// A name (ami az elemzend“ sorban van) illeszkedik-e a translate
// bal oldal n lev“ token-re.
// Sajnos nem ngy hosszan, hanem minimum 4 hosszan kell hasonl¡tani,
// s nem mindegy, hogy mi illeszkedik mire.
// Ez kell!!!
if (len(name)>len(trName))
return .f.
endif
if (empty(cmd4) .or. len(name)<4)
return lower(name)==lower(trName)
endif
// Mj.: Ez lnyegben egy '=' (”sszehasonl¡t s), de az '='
// obsoleted.
return (lower(name)==lower(left(trName,len(name))))
//*******************************************************************
static function matchLookForward(tkId,tkStr,forwTkId,forwTkStr,forwT,cmd4)
if (forwTkId==TKID_RESTRICTED_MATCH_MARKER)
// A spec nem nz el“re ebben az esetben, ezrt ez nem kell.
#ifdef OLD
// Sajnos ez egyenl“re nem j¢, mert a wordList-ben tokeneknek
// kellene lennie, hogy a stringeket k<>l”n kezelhess<73>k,
// ezenk¡vl az <20>reseknl meg kellene  llni, etc.
// De ez egyenl“re nincs kitesztelve.
// Ezrt egyenl“re a stringeket kihagyjuk.
if (tkId==TKID_NEV .or.;
tkId==TKID_SZAMTOMB .or.;
;//tkId==TKID_STRING .or.;
tkId==TKID_CHAR)
return 0!=ascan(RSMMARKR.forwT:wordList,;
{|x| compareWNames(tkStr,x,RSMMARKR.forwT:eqType/*cmd4*/)})
endif
#endif
return .f.
elseif (forwTkId==TKID_NEV .or. forwTkID==TKID_STRING)
// A neveket s a stringeket 'case insensitive' m¢don kell
// ”sszehasonl¡tani.
return tkId==forwTkId .and. compareWNames(tkStr,forwTkStr,RSMMARKR.forwT:eqType/*cmd4*/)
endif
// Itt mg lehetnek csavar sok pl. a sz mokat rtk<E2809A>k szerint,
// vagy a stringeket £gy, hogy nem sz m¡t mivel hat rolt k etc.
return tkId==forwTkId .and. tkStr==forwTkStr
//*******************************************************************
implement mleftXRMMToken(leftToken,cmd4)
/*
Regular Match marker.
Addig megy, am¡g egy kifejezs tart, vagy el nem ri a
leftToken:nextToken-t.
Sajnos a specifik ci¢ nem k”vetkezetes:
Pl: Ez nem egy kifejezs: 'a*+b', ez viszont igen: 'a*(+b)'
A cmd4 az el“renzshez kell.
*/
local state
#define STXRMM_START "start"
#define STXRMM_PARENT "parent"
local tkId,tkStr,ujsor
local parentStack
// local iForwRead
local clfBuf,clfNumBuf,elvalaszt
local clf
local endToken,endTkId,endTkStr
this:startMakrobuf(this:item)
clfBuf:={}
clfNumBuf:={}
// iForwRead:=1
// Itt ki kell szrni az '='-t, mert azzal kifejezs nem kezd“dhet.
// Kihaszn ljuk, hogy this:item £jsor s <20>res nem lehet.
if (TOKEN.(this:item):id==TKID_CHAR .and.;
TOKEN.(this:item):classify=='=')
// Vajon itt kell unrds()?
this:unrdsMakroBuf()
return .f.
endif
endToken:=MMARKER.leftToken:nextToken
if (MMARKER.leftToken:nextToken!=nil)
endTkId:=TOKEN.(MMARKER.leftToken:nextToken):id
endTkStr:=TOKEN.(MMARKER.leftToken:nextToken):str
else
endTkId:=nil
endTkStr:=nil
endif
elvalaszt:=nil
state:=STXRMM_START
while(this:item!=nil)
tkId:=TOKEN.(this:item):id
tkStr:=TOKEN.(this:item):str
ujsor:=tkId==TKID_UJSOR .or.;
tkId==TKID_BOS .or. tkId==TKID_EOS .or.;
(tkId==TKID_CHAR .and. tkStr==";")
PDEBUG(outerr("mleftXRMMToken: ","state: ",state, "tkId: ",tkId, "tkStr: ", tkStr,crlf()))
if (state==STXRMM_START)
if (ujsor)
// Vge!
exit
elseif (matchLookForward(tkId,tkStr,endTkId,endTkStr,endToken,cmd4))
// elseif (tkId==endTkId .and. tkStr==endTkStr)
// Ez itt problm s, mert neveknl, vagy stringeknl nem
// tudjuk, hogyan kell az ”sszehasonl¡t st csin lni.
// (case sensitive, neveknl ngy karakter hosszan is
// lehet (translate,command)
// Vge!
// Mj.: Nem biztos, hogy j¢ a clBuf-beli visszalpseket
// kezelni kellene
exit
elseif (eqTkInCharList(tkId,tkStr,','))
// Vge!
exit
elseif (eqTkInCharList(tkId,tkStr,')}]'))
// Vge!
exit
elseif (tkId==TKID_URES)
// Maradunk.
elseif (eqTkInCharList(tkId,tkStr,'({['))
// El“sz”r megnzz<7A>k, hogy j”het-e itt z r¢jel.
aadd(clfBuf,TKCL_PARENT)
// Amikor kij”n a z r¢jelb“l, ide be fogja ¡rni a helyes
// sz mot.
aadd(clfNumBuf,len(this:makroBuf))
if (nil!=(elvalaszt:=exprChk(clfBuf)))
// Nem j”het.
exit
endif
state:=STXRMM_PARENT
parentStack:={thisclass:getCloseParent(tkStr)}
elseif (nil!=(clf:=TOKEN.(this:item):classify))
// Hozz vessz<73>k a clfBuf-hoz, s megnzz<7A>k, hogy
// j”het-e.
if (clf=='++' .and. len(clfBuf)>0 .and. atail(clfBuf)=='++')
clfNumBuf[len(clfNumBuf)]:=len(this:makroBuf)
else
aadd(clfBuf,clf)
aadd(clfNumBuf,len(this:makroBuf))
if (nil!=(elvalaszt:=exprChk(clfBuf)))
// Nem j”het.
// Az elvalaszt-n l van a kifejezshat r.
exit
endif
endif
else
// Ide nem j”het<65>nk, egyenl“re elengedj<64>k, b rmi is van
// itt.
endif
elseif (state==STXRMM_PARENT)
// Mj.: A clfNumBuf vgn a makr¢buf hossz t azrt kell
// vezetni, hogy az <20>res helyeket a vgn le tudjuk
// v gni.
if (ujsor)
// Vge!
exit
elseif (tkId==TKID_URES)
// Maradunk.
elseif (eqTkInCharList(tkId,tkStr,'({['))
aadd(parentStack,thisclass:getCloseParent(tkStr))
clfNumBuf[len(clfNumBuf)]:=len(this:makroBuf)
elseif (eqTkInCharList(tkId,tkStr,')}]'))
// Ha nem illeszkedik a stack-re, akkor nem vessz<73>k
// figyelembe, ha illeszkedik, akkor a stack-r“l
// levessz<73>k a legfels“ elemet.
clfNumBuf[len(clfNumBuf)]:=len(this:makroBuf)
if (atail(parentStack)==tkStr)
adrop(parentStack)
if (empty(parentStack))
state:=STXRMM_START
endif
endif
else
// B rmi m s, folytat¢dik az elemzs.
clfNumBuf[len(clfNumBuf)]:=len(this:makroBuf)
endif
else
? "MPARSER:mleftXRMMToken(): Ismeretlen  llapot: ",state
errorlevel(1)
quit
endif
this:rdsMakroBuf()
// iForwRead++
end while
if (elvalaszt==nil)
// Sor vge, vessz“, etc.
// Ha a clfBuf nem <20>res, akkor az utols¢ra lp<E2809A>nk vissza, ha
// <20>res, nem illeszkedett!
if (len(clfBuf)==0)
this:unrdsMakroBuf(len(this:makroBuf))
return .f.
endif
// Mg meg kell nzni, hogy van-e kifejezshat r, £gy, hogy
// nem lehet folytatni.
aadd(clfBuf,"newline")
aadd(clfNumBuf,len(this:makroBuf))
if (nil==(elvalaszt:=exprChk(clfBuf)))
elvalaszt:=len(clfBuf)-1
endif
endif
// Ilyenkor az clfNumBuf[elv laszt] azt mondja meg, hogy hova
// kell visszalpn<70>nk. Ennyi tokennek kell maradnia a
// makroBuf-ban.
this:unrdsMakroBuf(len(this:makroBuf)-clfnumBuf[elvalaszt])
// aappend(tokenList,this:makroBuf)
return !empty(this:makroBuf)
//*******************************************************************
#ifdef OLD
// Ez egsz j¢l mk”dik, de sokat elront.
// implement mleftXRMMToken(leftToken,tokenList)
// /*
// Regular Match marker.
// Addig megy, am¡g egy kifejezs tart, vagy el nem ri a
// leftToken-ben megadott lez r¢ tokent.
// Sajnos a specifik ci¢ nem k”vetkezetes:
// Pl: Ez nem egy kifejezs: 'a*+b', ez viszont igen: 'a*(+b)'
//
// */
//
// /*
// A kifejezs elemzs a k”vetkez“kppen megy:
//
// Az elemek:
// <Kifejezs token>: olyan token, ami meg llja a helyt ”n ll¢
// kifejezsknt.
// <El“revetett un ris oper tor>:
// '&','++','--','+','-','@','.not.','!'
// <H travetett un ris oper tor>:
// '--','++'
// <bin ris oper tor>:
// '$','%','*','**','^','+','-','->','.and.','.or.',
// '/',':',':=',
// '<','<=','<>','!=','#','=','==','>','>='
//
// Speci lis dolgok:
// <sz m>['.'[<sz m>]]
//
//
// Helyettes¡tsek:
// '.not.' -> '!'
// '**' -> '^'
//
// Megjegyzsek:
//
// - A <sz m>.and. kifejezsben az els“ '.' a .and.-hoz
// tartozik, mert a .and. foglalt nv. Ugyanez vonatkozik
// a '.or.','.not.','.t.','.f.'-re. A kis s a nagybetket
// nem k<>l”nb”zteti meg.
//
// - A kt '&' jel ugyan£gy megjegyzs, mint a '//'
//
// - Egy oper tornak tekinti a k”vetkez“ tokenek tetsz.
// kombin ci¢j t:
//
// '&','++','--','@','$','->','.and.','.or.','.not.','!',':=',
// '<','<=','<>','!=','#','=','==','>','>=','.'
//
// Mj.: A fenti oper torokat un ris oper tornak tekinti.
//
//
// Mj2.: A fentiek k”z<E2809D>l a k”vetkez“k maradtak ki:
// '+','-','*','**','^','/','%'
//
// - Speci lisan kezelt tokenek:
// '+': Csak bin ris lehet, el“jel nem lehet.
// '-': Bin ris s el“jel lehet.
// '*','**', '^', '/','%': csak bin ris oper torok lehetnek.
// Mj.: A '*','/'-nek van egy speci lis esete l sd 'Speci lis
// esetek'.
//
// - Speci lis esetek:
// <b rmi> '*' '/' <nv> : Ezt elfogadja egy kifejezsnek, de
// pl.; a '*' '/' '*' '/'-t m r nem.
// Mj.: A <nv> helyn nem  llhat semmit m s, mg £j sor sem!
//
// - Az illesztst s az xtranslate elemzst is tokenesen
// csin lja (argh...) Pl.: ez a kt xtranslate parancs k<>l”nb”zik
// egym st¢l:
//
// #xtranslate HUHU <a> := <b> => let(@<a>,<b>)
// #xtranslate HUHU <a> : = <b> => let(@<a>,<b>)
//
// Mj.: A m sodikat el sem fogadja 'hi nyz¢ =>' hibajelzssel.
//
//
//
// Lehetsges, hogy a kifejezshat rok oldal r¢l jobban meg lehet fogni
// a dolgot:
//
// <bin ris oper tor>:='*'|'**'|'^'|'/'|'%'
//
// <Z r¢jelezett kifejezs>: '()', '{}','[]' k”z”tt lev“ tetsz karakter
// sorozat. Az z r¢jeleken bel<65>l soha nincs
// kifejezshat r.
//
// <p r nlk<6C>li csuk¢ z r¢jel>: ')', '}',']' karater, amihez nincs
// megfelel“ nyit¢ z r¢jel.
//
// Ekkor a kifejezs hat rok:
//
// <sz m vagy nv> <kifejezshat r> <sz m vagy nv>
// '+' <kifejezshat r> <<3C>res> '+'
// '+' <kifejezshat r> <bin ris oper tor>
// '-' <kifejezshat r> <<3C>res> '+'
// '-' <kifejezshat r> <bin ris oper tor>
// '-' <kifejezshat r> <<3C>res> '-' <<3C>res> '-'
// <Z r¢jelezett kifejezs> <kifejezshat r> <nv vagy sz m>
// <kifejezshat r> <p r nlk<6C>li z r¢jel>
// <bin ris oper tor> <kifejezshat r> <bin ris oper tor>
// Kivtel: '*' '/' <nv> // Itt nincs kifejezs hat r.
// <bin ris oper tor> <kifejezshat r> '+'
// <bin ris oper tor> <kifejezshat r> <nem '-',<sz m>,<nv>,<nyit¢ z r¢jel>.>
// <kifejezshat r> ','
//
// Speci lis esetek:
//
//
// '~': Ezt t”rli (?)
// '`': Ezt string hat rol¢nak (") tekinti.
// '.','|': Ezeket nem tekinti hat rol¢nak.
// '&&': Ez egysoros megjegyzs, olyan, mint a '//'
//
// B rmilyen egyb esetben nincs kifejezs hat r.
//
// */
//
// local state
//
// #define isTkIdNevSzam(tkId) ((tkId)==TKID_NEV .or.;
// (tkid)==TKID_SZAMTOMB)
//
// #define isTkIdLiteral(tkId) (isTkIdNevSzam(tkId) .or.;
// (tkid)==TKID_STRING)
//
// #define isTkClassify(tkId,token,clsfy) ((tkId)==TKID_CHAR .and.;
// TOKEN.(token):classify==(clsfy))
//
// #define STXRMM_XSTART "xstart"
// #define STXRMM_START "start"
// #define STXRMM_LITERAL "literal"
// #define STXRMM_PLUS "plus"
// #define STXRMM_MINUS "minus"
// #define STXRMM_MINUS2 "minus2"
// #define STXRMM_PARENT "parent"
// #define STXRMM_CSILLAG "csillag"
// #define STXRMM_CSILLAGPER "csillagper"
// #define STXRMM_BINARY "binary"
//
// local tkId,tkStr,ujsor
// local parentStack
// local iForwRead
// local clfBuf
//
// iForwRead:=1
//
// this:startMakrobuf(this:item)
// state:=STXRMM_XSTART
// clfBuf:={}
//
// while(this:item!=nil)
// tkId:=TOKEN.(this:item):id
// tkStr:=TOKEN.(this:item):str
// ujsor:=tkId==TKID_UJSOR .or.;
// tkId==TKID_BOS .or. tkId==TKID_EOS .or.;
// (tkId==TKID_CHAR .and. tkStr==";")
//
// PDEBUG(outerr("state: ",state, "tkId: ",tkId, "tkStr: ", tkStr,crlf()))
// if (state==STXRMM_XSTART)
// if (ujsor)
// // Vge!
// exit
// elseif (tkId==TKID_URES)
// // Maradunk.
// elseif (isTkClassify(tkId,this:item,'='))
// // Vge!
// exit
// else
// iForwRead:=0
// this:unrdsMakroBuf()
// state:=STXRMM_START
// endif
// elseif (state==STXRMM_START)
// if (ujsor)
// // Vge!
// exit
// elseif (tkId==TKID_URES)
// // Maradunk.
// elseif (isTkIdLiteral(tkId))
// iForwRead:=0
// state:=STXRMM_LITERAL
// elseif (eqTkInCharList(tkId,tkStr,'({['))
// iForwRead:=0
// state:=STXRMM_PARENT
// parentStack:={thisclass:getCloseParent(tkStr)}
// elseif (eqTkInCharList(tkId,tkStr,')}]'))
// // Vge (!)
// exit
// elseif (eqTkChar(tkId,tkStr,','))
// // Vge (!)
// exit
// elseif (isTkClassify(tkId,this:item,'!'))
// // Ezut n soha nincs kifejezs hat r.
// iForwRead:=0
// // Maradunk.
// elseif (isTkClassify(tkId,this:item,'@'))
// // Ezut n soha nincs kifejezs hat r.
// iForwRead:=0
// // Maradunk.
// elseif (isTkClassify(tkId,this:item,'%'))
// // Hasonl¢ a '/'-hez s a '*'-hoz, de nincs kivtel.
// // Ut na j”het: '&', '- nev', '- sz m', 'nev','szam',
// // 'z r¢jel', '.t.'
// iForwRead:=0
// // state:=STXRMM_PERCENT
// state:=STXRMM_BINARY
// elseif (isTkClassify(tkId,this:item,'^'))
// // Hasonl¢ a '/'-hez s a '*'-hoz, de nincs kivtel.
// // Ut na j”het: '&', '- nev', '- sz m', 'nev','szam',
// // 'z r¢jel', '.t.'
// iForwRead:=0
// // state:=STXRMM_POW
// state:=STXRMM_BINARY
// elseif (isTkClassify(tkId,this:item,'&'))
// // Mindent elfogad.
// iForwRead:=0
// elseif (eqTkChar(tkId,tkStr,'*'))
// // A '*' '/' <name> speci lis eset kezelse.
// iForwRead:=0
// state:=STXRMM_CSILLAG
// PDEBUG(outerr("start->csillag"+crlf()))
// elseif (eqTkChar(tkId,tkStr,'-'))
// iForwRead:=0
// state:=STXRMM_MINUS
// elseif (eqTkChar(tkId,tkStr,'+'))
// iForwRead:=0
// state:=STXRMM_PLUS
// elseif (isTkClassify(tkId,this:item,'='))
// // Mivel nem ez az els“ karakter, b rmit el lehet
// // fogadni.
// iForwRead:=0
// // Maradunk.
// /*
// elseif (isTkClassify(tkId,this:item,'/'))
// elseif (isTkClassify(tkId,this:item,'++'))
// elseif (tkId==TKID_NEV)
// elseif (tkId==TKID_SZAMTOMB)
// elseif (tkId==TKID_STRING)
// */
// else
// // B rmi m s, maradunk.
// iForwRead:=0
// endif
// elseif (state==STXRMM_LITERAL)
// if (ujsor)
// // Vge!
// exit
// elseif (tkId==TKID_URES)
// // Maradunk.
// elseif (isTkIdLiteral(tkId))
// // Vge
// exit
// else
// // B rmi m s: £jra fel kell dolgozni.
// iForwRead--
// this:unrdsMakroBuf()
// state:=STXRMM_START
// endif
// elseif (state==STXRMM_PLUS)
// if (ujsor)
// // Vge!
// exit
// elseif (tkId==TKID_URES)
// // Maradunk.
// elseif (eqTkChar(tkId,tkStr,'+'))
// // Vge.
// exit
// elseif (thisclass:isTkBinaryOp(tkId,tkStr))
// // *, **, ^,/,%
// // Vge.
// exit
// else
// // B rmi m s: £jra fel kell
// // dolgozni.
// iForwRead--
// this:unrdsMakroBuf()
// state:=STXRMM_START
// endif
// elseif (state==STXRMM_MINUS)
// if (ujsor)
// // Vge!
// exit
// elseif (tkId==TKID_URES)
// // Maradunk.
// elseif (eqTkChar(tkId,tkStr,'+'))
// // Vge.
// exit
// elseif (thisclass:isTkBinaryOp(tkId,tkStr))
// // *, **, ^,/,%
// // Vge.
// exit
// elseif (eqTkChar(tkId,tkStr,'-'))
// state:=STXRMM_MINUS2
// else
// // B rmi m s: £jra fel kell dolgozni.
// iForwRead--
// this:unrdsMakroBuf()
// state:=STXRMM_START
// endif
// elseif (state==STXRMM_MINUS2)
// if (ujsor)
// // Vge!
// exit
// elseif (tkId==TKID_URES)
// // Maradunk.
// elseif (isTkIdNevSzam(tkId)) // A string itt nem j¢!
// // Elmegy.
// iForwRead:=0
// state:=STXRMM_LITERAL
// else
// // B rmi m s: kifejezshat r az els“ minusz ut n!
// exit
// endif
// elseif (state==STXRMM_PARENT)
// if (ujsor)
// // Vge!
// exit
// elseif (tkId==TKID_URES)
// // Maradunk.
// elseif (eqTkInCharList(tkId,tkStr,'({['))
// iForwRead:=0
// aadd(parentStack,thisclass:getCloseParent(tkStr))
// elseif (eqTkInCharList(tkId,tkStr,')}]'))
// // Ha nem illeszkedik a stack-re, akkor nem vessz<73>k
// // figyelembe, ha illeszkedik, akkor a stack-r“l
// // levessz<73>k a legfels“ elemet.
// iForwRead:=0
// if (atail(parentStack)==tkStr)
// adrop(parentStack)
// if (empty(parentStack))
// state:=STXRMM_START
// endif
// endif
// else
// // B rmi m s, folytat¢dik az elemzs.
// iForwRead:=0
// endif
// elseif (state==STXRMM_CSILLAG)
// if (ujsor)
// // Vge!
// exit
// elseif (tkId==TKID_URES)
// // Maradunk.
// elseif (eqTkChar(tkId,tkStr,'/'))
// state:=STXRMM_CSILLAGPER
// PDEBUG(outerr("csillag->csillagper"+crlf()))
// else
// // Az aktu lis item-et a binaris oper torok elemz“jvel
// // kell elemeztetni.
// iForwRead--
// this:unrdsMakroBuf()
// state:=STXRMM_BINARY
// endif
// elseif (state==STXRMM_CSILLAGPER)
// if (ujsor)
// // Vge!
// exit
// elseif (tkId==TKID_URES)
// // Maradunk.
// elseif (tkId==TKID_NEV)
// // Ok. Elker<65>lt<6C>k a kifejezshat rt.
// // Gyors¡tunk, egyb“l a liter lhoz megy<67>nk.
// iForwRead:=0
// state:=STXRMM_LITERAL
// PDEBUG(outerr("csillagper->literal"+crlf()))
// else
// // A '*' s a '/' k”z”tt van a kifejezshat r.
// exit
// endif
// elseif (state==STXRMM_BINARY)
// if (ujsor)
// // Vge!
// exit
// elseif (tkId==TKID_URES)
// // Maradunk.
// elseif (tkId==TKID_NEV)
// // Ok. Elker<65>lt<6C>k a kifejezshat rt.
// iForwRead:=0
// state:=STXRMM_LITERAL
// else
// // A '*' s a '/' k”z”tt van a kifejezshat r.
// exit
// endif
// else
// ? "MPARSER:mleftXRMMToken(): Ismeretlen  llapot: ",state
// errorlevel(1)
// quit
// endif
// this:rdsMakroBuf()
// iForwRead++
// end while
//
// this:unrdsMakroBuf(iForwRead)
// aappend(tokenList,this:makroBuf)
//
// return !empty(this:makroBuf)
#endif
//*******************************************************************
implement mleftXWMToken(leftToken)
/*
Wild matchmarker.
Egy '()' k”z z rt sorozat, vagy a leghosszabb space mentes
sorozat.
Mj.: Ha '('-al kezd“dik, s nincs lez rva, akkor is '()'-nek veszi.
Mj2.: A t”bbi z r¢jelet nem veszi figyelembe.
Mj3.: Nem nz el“re.
*/
local tkId,tkStr,ujsor
this:startMakrobuf(this:item)
while(this:item!=nil)
tkId:=TOKEN.(this:item):id
tkStr:=TOKEN.(this:item):str
ujsor:=tkId==TKID_UJSOR .or.;
tkId==TKID_BOS .or. tkId==TKID_EOS .or.;
(tkId==TKID_CHAR .and. tkStr==";")
PDEBUG(outerr("mleftXWMToken: "+"tkId: ",tkId, "tkStr: ", tkStr,crlf()))
if (ujsor)
// Vge!
this:unrdsMakroBuf()
exit
endif
this:rdsMakroBuf()
end while
return !empty(this:makroBuf)
//*******************************************************************
implement mleftXEEMToken(leftToken)
/*
Extended Expression match marker.
Egy '()' k”z z rt sorozat, vagy a leghosszabb space mentes
sorozat.
Mj.: Ha '('-al kezd“dik, s nincs lez rva, akkor is '()'-nek veszi.
Mj2.: A t”bbi z r¢jelet nem veszi figyelembe.
Mj3.: Nem nz el“re.
*/
local state
#define STXEEM_START "start"
#define STXEEM_PARENT "parent"
#define STXEEM_SOROZAT "sorozat"
local tkId,tkStr,ujsor
local numParent
this:startMakrobuf(this:item)
state:=STXEEM_START
while(this:item!=nil)
tkId:=TOKEN.(this:item):id
tkStr:=TOKEN.(this:item):str
ujsor:=tkId==TKID_UJSOR .or.;
tkId==TKID_BOS .or. tkId==TKID_EOS .or.;
(tkId==TKID_CHAR .and. tkStr==";")
PDEBUG(outerr("mleftXEEMToken: ","state: ",state, "tkId: ",tkId, "tkStr: ", tkStr,crlf()))
if (state==STXEEM_START)
if (ujsor)
// Vge!
this:unrdsMakroBuf()
exit
elseif (tkId==TKID_URES)
// Lenyeli
elseif (eqTkInCharList(tkId,tkStr,'('))
// Z r¢jelezett m¢d.
numParent:=1
state:=STXEEM_PARENT
else
// Space nlk<6C>li sorozat m¢d
state:=STXEEM_SOROZAT
endif
elseif (state==STXEEM_PARENT)
if (ujsor)
// Vge!
this:unrdsMakroBuf()
exit
elseif (eqTkInCharList(tkId,tkStr,'('))
numParent++
elseif (eqTkInCharList(tkId,tkStr,')'))
numParent--
if (numParent<=0)
exit
endif
else
// B rmi m s, folytat¢dik az elemzs.
// Ebben benne van az <20>res is.
endif
elseif (state==STXEEM_SOROZAT)
if (ujsor)
// Vge!
this:unrdsMakroBuf()
exit
elseif (tkId==TKID_URES)
// Vge!
this:unrdsMakroBuf()
exit
else
// B rmi m s, folytat¢dik az elemzs.
endif
else
? "MPARSER:mleftXEEMToken(): Ismeretlen  llapot: ",state
errorlevel(1)
quit
endif
this:rdsMakroBuf()
end while
return !empty(this:makroBuf)
//*******************************************************************
implement mleftXLMToken(leftToken,cmd4)
// List match marker
// Az <20>res paramtert (,,) megengedi.
local params:={}
local iForwRead
local tkId,tkStr,ujsor
this:mleftXRMMToken(leftToken,cmd4)
this:rds()
aadd(params,this:makroBuf)
iForwRead:=1
while(this:item!=nil)
tkId:=TOKEN.(this:item):id
tkStr:=TOKEN.(this:item):str
ujsor:=tkId==TKID_UJSOR .or.;
tkId==TKID_BOS .or. tkId==TKID_EOS .or.;
(tkId==TKID_CHAR .and. tkStr==";")
if (ujsor)
// Vge!
exit
elseif (tkId==TKID_URES)
// Maradunk.
elseif (eqTkChar(tkId,tkStr,','))
this:rds()
if (this:mleftXRMMToken(leftToken,cmd4))
aadd(params,this:makroBuf)
else
aadd(params,{})
endif
iForwRead:=0
else
// B rmi m s, vge.
exit
endif
iForwRead++
this:rds()
end while
this:unrds(iForwRead)
if (len(params)==1 .and. len(params[1])==0)
return .f.
endif
this:makroBuf:=params
return .t.
//*******************************************************************
implement mleftXRSMMToken(leftToken,cmd4)
/*
Restricted match marker.
Csan nevekre, sz mokra s karakterekre illeszt<7A>nk.
*/
local tkId, tkStr,wl,i
this:startMakrobuf(this:item)
tkId:=TOKEN.(this:item):id
tkStr:=TOKEN.(this:item):str
if !(tkId==TKID_NEV .or.;
tkId==TKID_SZAMTOMB .or.;
;//tkId==TKID_STRING .or.;
tkId==TKID_CHAR)
return .f.
endif
wl:=RSMMARKR.leftToken:wordList
if (empty(wl))
return .f.
endif
for i:=1 to len(wl)
if (empty(wl[i]))
this:unrdsMakrobuf()
return .t.
endif
if (compareWNames(tkStr,wl[i],TOKEN.leftToken:eqType/*cmd4*/))
return .t.
endif
end for
return .f.
//*******************************************************************
/*
cimplement isTkBinaryOp(tkId,tkStr)
// Ez a nem tokeniz lt v ltozat.
if (!tkId==TKID_CHAR)
return .f.
endif
return tkStr$"*^/%"
*/
//*******************************************************************