| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554 |
- (* changes:
- 11-nov-92
- Now in m+ mode "AB""CD" is accespted as AB"CD value
- Earlier it were two values "AB" and "CD"
- mar-93
- Now MIF conditional definition is available.
- may-93
- Now TEX scaner is available.
- T+ defines LaTeX lexical rules
- and value of new "tex_lexics" boolean variable
- @+ defines (additionaly to T+) .sty - file mode of LaTeX,
- when @ characters are allowed in command names
- .TEX file have to be with 'P-U-p-A-T+'
- .STY file have to be with 'P-U-p-A-T+@+'
- *)
- {$DEFINE RAMSCAN}
- {$DEFINE SCANU}
- { Rigal integrated environment (c) 1991 Software house Riga }
- { }
- { }
- {$IFDEF SCANU}
- {$IFDEF MIF}
- Unit Scanmif;
- {$ELSE}
- Unit Scan;
- {$ENDIF}
- interface
- uses
- {$IFDEF WIN} tmemstrm,winprocs, {$ENDIF}
- define;
- { Separate scanner for input strings and output Rigal objects }
- {$IFDEF MIF}
- Procedure INITIALIZE_SCAN_VARIABLES_mif;
- Procedure Scaner_mif
- {$ELSE}
- Procedure INITIALIZE_SCAN_VARIABLES;
- Procedure Scaner
- {$ENDIF}
- {*****************************************}
- (mode_parm:integer;
- {1=from file,2=list of strings,3=absulute address,
- 4=stream memory handle }
- filename:string80;
- options_str:string80;
- var rez:a; { result; set to NULL if input is absent }
- var erlist_parm:a; { error number list; set to NULL if no errors }
- strlist:a; { list of atoms }
- segm,ofs:longint); { parts of absolute address }
- implementation
- uses defpage,nef,poutlexu,doutu;
- {$ELSE}
- #include "define.p"
- #include "defpage.inc"
- #include "nef2.inc"
- #include "outs.inc"
- #include "scan.inc"
- {$ENDIF}
- {VARIABLES}
- const maxline=255;
- type bigstring=
- {$IFDEF xSUN}
- varying array[127] of char;
- {$ELSE}
- array[1..maxline]of char ;
- {$ENDIF}
- var a1: a; { global variable for ONLY LOCAL use }
- {aa1 : aa ;} { --"-- }
- X : MPD; { --"-- }
- bl801 : bl80; { -- " -- }{ array[1..80] of char}
- k,kk:integer; { -"- }
- c1:char;
- saved_coord, { where current token began }
- coord_mark , { what was set by coordinate marker }
- line_byte_number , { number of totally read bytes till beginning
- of current line }
- last_mark_byte_number , { number of totally read bytes till
- last coordinate marker }
- old_line_length { length of the current line,
- used only for incrementation of "lyne_byte_number"}
- :word;
- DT:descriptortype; { type of last read token or control character }
- AADR:a; { A-space address of last read token }
- Linenumber:longint; { Current line number }
- Tokennumber:longint;{ Current token number }
- Errlist :a; { List of numbers of errors }
- Read_mode:integer; { 1,2,3 }
- PTR1 : PTR; { List pointer when read from list of atoms }
- {$IFDEF RAMSCAN}
- ABSPNT : Pointer;{ RAM pointer when read from RAM }
- {$ENDIF}
- inpfile : text;
- var
- c_lexics,
- pascal_lexics,
- sty_lexics,
- tex_lexics,
- row80_coord,
- byte_coord,
- mark_byte_coord,
- mark_only_coord,
- string_coord,
- char_coord,
- token_coord,
- collect_errors,
- screen_errors,
- to_uppercase,
- pascal_comment,
- c_comment,
- ada_comment,
- pascal_string,
- modula_string:boolean;
- const new_line_code=Chr(13); { Chr(0 is allowed too }
- endfile_code =Chr(26);
- var s:bigstring;
- { s_for_val:bigstring;} { added 17-FEB-92 }
- i:integer;
- type is_something=
- (is_control, is_letter, is_digit, is_underscore, is_printable,
- is_special, is_space , is_first_of_two);
- type pair=packed array[1..2]of char;
- var as:array[char]of is_something;
- isa : is_something;
- upcase_tab:array[char]of char;
- set_of_second_of_two:set of char;
- two_char_symbols_num:integer;
- two_char_symbols:array[1..30]of pair;
- b123 : record
- case integer of
- 1:(b1:char);
- 2:(b2:packed array[1..2]of char);
- 3:(b3:packed array[1..3]of char);
- end;
- var in_comment,in_string : boolean;
- var is_2quote : boolean; { if in_string then it is possible }
- var Str_constlen:longint;
- Str_const : string80; { array of char is allowed too }
- {===== SUN VERSION ===}
- {$IFDEF SUN}
- procedure inc{1}(var xxx:longint);
- begin xxx:=xxx+1; end;
- procedure inc{2}(var xxx:longint;yyy:longint);
- begin xxx:=xxx+yyy; end;
- procedure inc{3}(var xxx:integer);
- begin xxx:=xxx+1; end;
- procedure inc{4}(var xxx:integer;yyy:integer);
- begin xxx:=xxx+yyy; end;
- {$ENDIF}
- {=====}
- function CONT_CHAR_TO_DT(c:char):descriptortype;forward;
- function Getcoord:word;forward;
- procedure ER_LEX(er_number:integer);forward;
- {Procedure INITIALIZE_SCAN_VARIABLES;forward;}
- Procedure READ_FILE(var read_file_rez:a);forward;
- Function READ_ITEM(var pghead:a):a;forward; {NEW!}
- Procedure READLINE;forward;
- Procedure PutAtom(j:integer);forward;
- Procedure PutIt(dd:descriptortype;j:integer);forward;
- Procedure PutIdent(j:integer);forward;
- Procedure PutFloat(j:integer;digits_before_dot,digits_after_dot:integer);forward;
- Procedure PutNumber;forward;
- Procedure PutStr(dd:descriptortype);forward;
- {Procedure Scaner;forward;}
- Procedure SETLEXICS;forward;
- Procedure StrAdd(c:char);forward;
- Procedure StrBegin;forward;
- Procedure Token;forward;
- Function TAKE_DIGITS(var jj:integer):longint;forward;
- Function TAKE_LETTERS:integer;forward;
- { uses global string, received from Readline procedure,
- produces global attributes of new one token read.
- Some variables also should be initialized if by Initial_token
- procedure at the start of the WHOLE programm }
- { This procedure is oriented to Turbo Pascal language }
- { Procedure call graph follows :
- /self\
- USEPAS -> SCAN -> READFILE -> READITEM -> ADDEL.nef
- -> LCONC.nef ER_LEX
- -> SETOPTIONS GETS1.defpage
- -> FIRST.nef TOKEN
- -> ASSIGN.system POINTR.defpage
- -> RESET.system LCONC.nef
- -> READLINE
- TOKEN -> ER
- -> READ_LETTERS_OR_DIGITS
- -> READ_DIGITS
- -> STRBEGIN
- -> PUTNUMBER
- -> StrAdd -> ER
- -> PUTSTR -> PUTATM.defpage
- -> PutAtom ->\
- -> PUTFLOAT -> PUTIT -> PUTATM.defpage
- -> PUTIDENT ->/
- }
- function CONT_CHAR_TO_DT(c:char):descriptortype;
- {**********************************************}
- begin
- Cont_char_to_dt:=descriptortype(c);
- {$IFDEF MIF}
- if c='<' then cont_char_to_dt:=start_list;
- if c='>' then cont_char_to_dt:=end_list;
- {$ENDIF}
- end;
- function Getcoord:word;
- {***********************}
- begin
- if row80_coord then Getcoord:=i+Linenumber*80
- else
- if mark_only_coord then Getcoord:=coord_mark
- else
- if mark_byte_coord then
- Getcoord:=coord_mark+
- (line_byte_number+i-last_mark_byte_number)
- else
- if byte_coord then Getcoord:=line_byte_number+i
- else
- if string_coord then Getcoord:=Linenumber
- else
- if token_coord then Getcoord:=Tokennumber
- else
- Getcoord:=0;
- end;
- procedure ER_LEX(er_number:integer);
- {***********************************}
- var er_atom:a;co:word;erm:string80;
- begin
- co:=Getcoord;
- if collect_errors then begin
- Gets1(er_atom,x.sa);
- with x.snd^ do begin
- dtype:=number;
- cord:=co;
- val:=er_number;
- end;
- lconc(errlist {global} ,er_atom);
- end;
- if screen_errors then
- begin
- case er_number of
- 1 : erm:=' unexpected end of file before end of tree';
- 2 : erm:=' unexpected end of file within tree branch ';
- 3 : erm:=' unexpected end of file within tree ';
- 4 : erm:=' unexpected end of file before end of list ';
- 5 : erm:=' unexpected end of tree ';
- 6 : erm:=' unexpected end of list or another control character';
- 7 : erm:=' unexpected end of file in name ';
- 8 : erm:=' unexpected end of file in named object ';
- 9 : erm:=' unexpected control character ';
- 10 : erm:=' too long atom ( more than 80 bytes ) ';
- 11 : erm:=' end of string constant not found in the current line';
- 12 : erm:=' end of file before end of comment';
- 13 : erm:=' control character within comment ';
- 14 : erm:=' control character within string constant';
- end;
- writeln('Lexical error :',erm);
- writeln('Line=',linenumber,' column=',i);
- end;
- end;
- {$IFDEF MIF}
- Procedure INITIALIZE_SCAN_VARIABLES_mif;
- {$ELSE}
- Procedure INITIALIZE_SCAN_VARIABLES;
- {$ENDIF}
- {***********************************}
- var c:char;
- begin
- for c:=Chr(0) to Chr(255) do upcase_tab[c]:=c;
- for c:=Chr(97) to Chr(122) do upcase_tab[c]:=Chr(ord(c)-32);{ASCII}
- (* for c:=Chr(160) to Chr(175) do upcase_tab[c]:=Chr(ord(c)-32); *){Russian}
- (* for c:=Chr(224) to Chr(239) do upcase_tab[c]:=Chr(ord(c)-60);*){Russian}
- { German for Windows }
- upcase_tab[chr(228)]:=chr(196);
- upcase_tab[chr(246)]:=chr(214);
- upcase_tab[chr(252)]:=chr(220);
- for c:=Chr(0) to Chr(31) do as[c]:=is_control;
- for c:=Chr(128) to Chr(255) do as[c]:=is_letter; { Russian and pseudographics }
- for c:=Chr(32) to Chr(127) do as[c]:=is_printable; { not used actually }
- as[new_line_code]:=is_control;
- as[' ']:=is_space;
- as[Chr(9)] :=is_space;
- { these are allowed to be First letter of identifiers }
- for c:='A'to'Z' do as[c]:=is_letter;
- for c:='a'to'z' do as[c]:=is_letter;
- for c:='0'to'9' do as[c]:=is_digit;
- { allowed to be non-first letter of odentifier }
- as['_']:=is_underscore;
- { All the rest settings - see procedure SETLEXICS }
- end;
- Procedure READ_FILE(var read_file_rez:a);
- {******************************}
- { reads whole input, produces list of items }
- label 99;
- var head:a;
- begin read_file_rez:=NULL;
- repeat a1:=read_item(head);
- if (dt=start_tree)or(dt=end_tree)or(dt=start_list)or
- (dt=end_list)or(dt=name_obj) then begin ER_LEX(6);goto 99;end;
- if DT<>eof_desk then
- begin
- if head<>NULL then lconc(read_file_rez,head);
- lconc(read_file_rez,a1);
- end;
- until DT=eof_desk;
- 99: end;
- Function READ_ITEM(var pghead:a):a;
- {********************}
- label 99;
- var aadr1:a; result,temp_res,dum,head:a;
- begin
- READ_ITEM:=NULL; { default value for exits with errors }
- pghead:=NULL;
- result:=NULL;
- TOKEN;
- case DT of
- atom,idatom,tatom,fatom,keyword:
- begin gets1(result,x.sa);
- with x.sad^ do begin
- dtype:=DT; cord:=saved_coord;
- name := AADR;
- end
- end;
- number:
- begin gets1(result,x.sa);
- with x.snd^ do begin
- dtype:=DT; cord:=saved_coord;
- val:= AADR; { is set in TOKEN .. is_digit }
- end;
- end;
- dummy: result:=NULL;
- start_tree:
- begin result:=NULL;
- repeat
- TOKEN;
- aadr1:=AADR; { to save }
- if (DT=idatom)or(DT=atom)or(DT=tatom)or(DT=keyword)
- { What is allowed selector in scaner input ?
- Normally - idatom only, but here
- atom is allowed too - for experiment purposes }
- then
- begin
- a1:=Read_item(dum);
- if DT=end_list then begin ER_LEX(6); goto 99; end;
- if DT=eof_desk then begin ER_LEX(1);goto 99;end;
- Addel3(result,aadr1,a1);
- end
- else if DT<>end_tree then begin ER_LEX(2);goto 99;end;
- ;
- until (DT=end_tree)or(DT=eof_desk);
- if DT=eof_desk then begin ER_LEX(3);goto 99;end;
- DT:=complex_desk; { to ignore analysis in upper level of
- recursion }
- end;
- start_list :
- begin
- result:=NULL;
- {$IFDEF MIF}
- pghead:=READ_ITEM(dum);
- repeat
- a1:=read_item(head);
- if DT=eof_desk then begin ER_LEX(4);goto 99;end;
- if (DT<>end_list) then
- begin
- if head<>NULL then lconc(result,head);
- lconc(result,a1);
- end;
- until DT=end_list;
- {$ELSE}
- repeat
- a1:=read_item(dum);
- if DT=eof_desk then begin ER_LEX(4);goto 99;end;
- if (DT<>end_list) then lconc(result,a1);
- until DT=end_list;
- {$ENDIF}
- DT:=complex_desk;
- end;
- end_tree : begin ER_LEX(5); goto 99; end;
- end_list : begin end; {immodiately returns to the upper level}
- name_obj: begin
- temp_res:=read_item(dum);
- if DT=end_list then begin ER_LEX(6); goto 99; end;
- if DT=eof_desk then begin ER_LEX(7); goto 99; end;
- result :=read_item(dum);
- if DT=end_list then begin ER_LEX(6); goto 99; end;
- if DT=eof_desk then begin ER_LEX(8); goto 99; end;
- if result<>NULL then begin
- points(result,x.sa);
- if (x.smld^.dtype=listmain)or(x.smtd^.dtype=treemain)
- then x.smtd^.name:=temp_res;
- end;
- DT:=complex_desk;
- end;
- eof_desk:begin end; { returns to the upper level }
- {$IFDEF xSUN}
- OTHERWISE
- {$ELSE}
- ELSE
- {$ENDIF}
- begin ER_LEX(9);goto 99; end { impossible value }
- end; { case }
- read_item:=result;
- 99: end; { Procedure Read_item }
- Procedure READLINE;
- {***************************}
- { sets new values for "s" and "i" global variables }
- label 99;
- begin
- i:=1; { In any case, so; only here it is initialized.
- it is column number.
- Variable "s" is string only for speed purposes;
- It plays exactly as Packed array of char,
- never used as whole and the Length byte is never used }
- Linenumber:=linenumber+1;
- line_byte_number:=line_byte_number+old_line_length;
- case read_mode of
- 1:
- begin
- if eof(inpfile) then begin s[1]:=endfile_code;close(inpfile);end
- else
- begin
- {$IFDEF STRING_READ}
- readln(inpfile,s);s[length(s)+1]:=new_line_code;
- old_line_length:=length(s);
- {$ELSE}
- old_line_length:=0;
- while not(eoln(inpfile)) do
- begin
- inc(old_line_length);
- if old_line_length<maxline-1 then
- read(inpfile,s[old_line_length])
- else
- begin
- writeln(' FATAL ERROR: Line ',linenumber,' too long !');
- old_line_length:=0;
- readln;
- end;
- end;
- readln(inpfile);
- s[old_line_length+1]:=new_line_code;
- {$ENDIF}
- end;
- end;
- 2:
- begin
- if PTR1.nel=0 then begin s[1]:=endfile_code;goto 99;end;
- if PTR1.cel=0
- then begin
- s[1]:=new_line_code;
- old_line_length:=0;
- end
- else begin
- Pointr(PTR1.cel,X.sa);
- with x.sad^ do begin
- if (dtype=atom)or (dtype=idatom)or
- (dtype=fatom)or (dtype=tatom)or (dtype=keyword)
- then begin
- pointa(name,bl801,k);
- for kk:=1 to k do s[kk]:=bl801[kk];
- old_line_length:=k;
- s[k+1]:=new_line_code;
- end
- else
- begin
- s[1]:=new_line_code; { other objects are ignored }
- old_line_length:=0;
- end
- end; { with }
- end; { <>0 }
- NEXT(PTR1);
- end; {=2}
- 3:
- begin
- {$IFDEF RAMSCAN}
- k:=0;
- repeat c1:=char(Pointer(ABSPNT)^);
- write(':',ord(c1));
- inc{1}(longint(ABSPNT));
- inc{1}(k);
- s[k]:=c1;
- until (c1=new_line_code)or(k=126);
- if (k=126) then
- begin
- writeln('SCANNER DIRECT ACCESS WARNING !');
- s[127]:=new_line_code;
- end;
- old_line_length:=k;
- {$ENDIF}
- end;
- 4: begin
- {$IFDEF WIN}
- (* reads by-byte from global memory stream *)
- k:=0;
- while true do begin
- if k > maxline-1 then begin
- writeln(' FATAL ERROR: Line too long !');
- k:=0;
- readln;
- end;
- byte(c1):=SM^.readbyte;
- if c1=#13 then begin (* eoln symbol reached *)
- old_line_length:=k;
- (* this variable must refer to last symbol before eoln *)
- s[k+1]:=new_line_code;Exit;end;
- if c1=#26 then begin (* end of file reached *)
- old_line_length:=k;
- inc(k);
- s[k]:=endfile_code;
- SM^.Close;Dispose(SM,Done);Exit;end;
- if c1<>#10 then
- begin
- Inc(k);s[k]:=c1;
- {inc(byte(s[0]));} (* adds one character to string *)
- end;
- end;
- {$ENDIF}
- end;
- end; (* case *)
- 99:;
- end;
- Procedure PutAtom(j:integer);
- {***********************}
- begin
- PutIt(atom,j);
- end;
- Procedure PutIt(dd:descriptortype;j:integer);
- {***********************}
- begin
- if j>80 then begin DT:=Keyword;ER_LEX(10);j:=80; end else DT:=dd;
- putatm(s[i],j,AADR);
- saved_coord:=Getcoord;
- Tokennumber:=Tokennumber+1;
- end;
- Procedure PutIdent(j:integer);
- {***********************}
- begin
- PutIt(idatom,j);
- end;
- Procedure PutFloat(j:integer;digits_before_dot,digits_after_dot:integer);
- {***********************}
- var REA_VAL:real; ii:integer;
- floatstring:string;
- AR:array[1..sizeof(real)+2]of char;
- begin
- (* Val2(Copy(s,i,j),REA_VAL,ii ignored ); *)
- floatstring:='';
- for k:=1 to j do floatstring:=floatstring+s[i+k-1];
- system.Val(floatstring,REA_VAL,ii);
- if ii<>0 then
- begin
- if j>80 then j:=80;
- DT:=keyword; (* WRONG REAL CONSTANT *)
- putatm(s[i],j,aadr);
- end
- else
- begin
- ii:=sizeof(real)+2;
- for j:=1 to ii-2 do
- AR[j]:=REAL_CHAR(REA_VAL)[j];
- AR[ii-1]:=chr(digits_before_dot);
- AR[ii] :=chr(digits_after_dot);
- putatm(AR[1],ii,AADR);
- DT:=fatom;
- end;
- (* writeln(' BEF, AFT =',digits_before_dot,' ',digits_after_dot); *)
- saved_coord:=Getcoord;
- inc{1}(Tokennumber);
- end;
- Procedure PutNumber;
- {***********************}
- begin
- DT:=number;
- saved_coord:=Getcoord;
- inc{1}(Tokennumber);
- end;
- Procedure PutStr(dd:descriptortype);
- {***********************}
- var iii:integer;
- begin
- if dd=KEYWORD then begin
- writeln('Erroneous string is:');
- for iii:=1 to str_constlen do write(str_const[iii]);
- writeln;
- readln;
- end;
- if str_constlen>80 then
- begin
- str_constlen:=80;
- DT:=keyword; (* TOO LONG STRING CONSTANT *)
- end
- else
- DT:=dd;
- putatm(Str_const[1],Str_constlen, AADR);
- in_string:=false;
- Tokennumber:=Tokennumber+1;
- {$IFDEF MIF}
- if Str_constlen=0 then DT:=dummy;
- { String constants of 0 length are converted to NULL}
- {$ENDIF}
- end;
- { Normally this procedure uses parameter TATOM ;
- this procedure used with parameter KEYWORD only for Modula2
- or C-style string constants like 'x', -
- to show difference between 'x' and "x".
- Access via #_KEYWORD built_in rule is possible.
- When input use 'm+p-' !
- When output such tokens you should write
- IF #_KEYWORD($X) -> OUT <] @ '"' $X '"' ELSIF T-> OUT <] $X FI;
- }
- {$IFDEF MIF}
- Procedure Scaner_mif
- {$ELSE}
- Procedure Scaner
- {$ENDIF}
- {*****************************************}
- (mode_parm:integer;
- {1=from file,2=list of strings,3=absulute address}
- filename:string80;
- options_str:string80;
- var rez:a; { result; set to NULL if input is absent }
- var erlist_parm:a; { error number list; set to NULL if no errors }
- strlist:a; { list of atoms }
- segm,ofs:longint); { parts of absolute address }
- LABEL 1,99;
- {INNER FUNCTION}
- Function Setop(c:char):boolean;
- begin
- Setop:=false;
- {$IFDEF xSUN}
- k:=Index(options_str,c);
- {$ELSE}
- k:=Pos(c,options_str);
- {$ENDIF}
- if k<>0 then
- if options_str[k+1]<>'-' then Setop:=true;
- end;
- begin
- read_mode:=mode_parm ; { save for global use }
- rez:=NULL;
- erlist_parm:=NULL;
- ERRLIST { global }:=NULL;
- { INITIALIZES ALL OPTIONS }
- { DEFAULTS }
- options_str:=options_str+'D-C-P+p+m-U+S+O+s-t-L-A+R+Y-B-N-T-@-';
- { to every option su,me default value should be given,
- otherwise the flag remains uninitialized }
- {ERRORS}
- screen_errors :=Setop('S');
- collect_errors:=Setop('O');
- {COMMENTS}
- ada_comment :=Setop('D');
- c_comment :=Setop('C');
- pascal_comment:=Setop('P');
- {STRING CONSTANTS}
- pascal_string :=Setop('p');
- modula_string :=Setop('m');
- to_uppercase :=Setop('U');
- {COORDINATE}
- string_coord :=Setop('s');
- token_coord :=Setop('t');
- row80_coord :=Setop('R');
- byte_coord :=Setop('Y');
- mark_byte_coord:=Setop('B');
- mark_only_coord:=Setop('N');
- {LANGUAGE_SPECIFIC LEXICS}
- c_lexics :=Setop('L');
- pascal_lexics :=Setop('A');
- tex_lexics :=Setop('T');
- sty_lexics :=Setop('@');
- { INITIALIZES LANGUAGE-SPECIFIC SETTINGS }
- SETLEXICS;
- { INITIALIZES "SESSION" FLAGS (alf order)}
- coord_mark:=0;
- in_comment:=false;
- in_string :=false;
- is_2quote :=false;
- last_mark_byte_number:=0;
- line_byte_number:=0;
- linenumber:=0;
- old_line_length :=0;
- str_constlen:=0;
- tokennumber:=0;
- { INITIALIZES PHYSICAL LEVEL READING }
- case read_mode of
- 1: begin { READ FROM FILE }
- if not existfile(filename)then begin Rez:=0;goto 1;end;
- {$IFDEF xSUN}
- Reset(inpfile,filename);
- {$ELSE}
- Assign(inpfile,filename);
- Reset(inpfile);
- {$ENDIF}
- readline; { reads first line of file }
- end;
- 2:
- begin { READ FROM LIST }
- if strlist=NULL then begin Rez:=0; goto 99; end;
- First(strlist,PTR1); { sets global list-pointer PTR1 }
- if (PTR1.ptrtype<>ptrlist) or
- (PTR1.nel=0) then begin Rez:=0; goto 99; end;
- readline; { reads line from current list-pointer position }
- end;
- 3:
- begin { READ FROM MS-DOS RAM MEMORY }
- {$IFDEF RAMSCAN}
- { Normalizing memory address }
- { Is it necessary for Windows model ? }
- { segm:=segm+ofs div 16;
- ofs:=ofs mod 16; }
- ABSPNT:=system.Ptr(segm,ofs); { This place is DOS-dependent !!! }
- if char (ABSPNT^) <> new_line_code
- then begin Rez:=0; goto 99; end;
- ABSPNT:=Pointer(longint(ABSPNT)+1);
- readline;
- {$ENDIF}
- end;
- 4: begin
- {$IFDEF WIN}
- New(SM,Init);
- SM^.open(segm);
- if (SM^.GETSIZE>128000)or(SM^.GETSIZE<0) THEN
- begin
- MESSAGEBOX(0,'Wrong handle to LDT stream',nil,16);
- rez:=0; goto 99; end
- else if (SM^.GETSIZE=0) then
- begin
- MESSAGEBOX(0,'Empty LDT stream',nil,16);
- rez:=0; goto 99; end
- else
- begin
- readline;
- end;
- {$ENDIF}
- end;
- end; (* case *)
- READ_FILE(REZ); { Main call ... }
- erlist_parm:=ERRLIST {global} ;
- 1:;99:;
- end;{ procedure Scaner }
- Procedure SETLEXICS;
- {***********************}
- var j:integer;
- begin
- {$IFDEF MIF}
- as['<']:=is_control;
- as['>']:=is_control;
- Exit;
- {$ENDIF}
- if pascal_lexics then begin { changes in standard, necessary for Pascal}
- as['{']:=is_special;
- as['#']:=is_special;
- as['$']:=is_special;
- as['%']:=is_special;
- as['''']:=is_special;
- as['(']:=is_special;
- two_char_symbols[1]:=':=';
- two_char_symbols[2]:='<=';
- two_char_symbols[3]:='>=';
- two_char_symbols[4]:='**';
- two_char_symbols[5]:='..';
- two_char_symbols[6]:='<>';
- two_char_symbols_num:=6;
- set_of_second_of_two:=['=','*','.','>'];
- for j:=1 to two_char_symbols_num do
- as[two_char_symbols[j][1]]:=is_first_of_two;
- if modula_string then
- begin
- as['"']:=is_special;
- as['{']:=is_printable;
- end
- end
- else
- if c_lexics then begin
- as['_']:=is_letter;
- as['$']:=is_letter;
- two_char_symbols[1]:='->';
- two_char_symbols[2]:='++';
- two_char_symbols[3]:='--';
- two_char_symbols[4]:='>>';
- two_char_symbols[5]:='<<';
- two_char_symbols[6]:='==';
- two_char_symbols[7]:='+=';
- two_char_symbols[8]:='*=';
- two_char_symbols[9]:='-=';
- two_char_symbols[10]:='/=';
- two_char_symbols[11]:='%=';
- two_char_symbols[12]:='&=';
- two_char_symbols[13]:='^=';
- two_char_symbols[14]:='|=';
- two_char_symbols[15]:='!=';
- two_char_symbols_num:=15;
- set_of_second_of_two:=['>','+','-','<','='];
- for j:=1 to two_char_symbols_num do
- as[two_char_symbols[j][1]]:=is_first_of_two;
- as['<']:=is_special; { used to process <<= }
- as['>']:=is_special; { used to process >>= }
- as['/']:=is_special; { used to process /* }
- { otherwise isa:=is_first_of_two
- is assigned ! }
- as['''']:=is_special;
- as['"']:=is_special;
- end;
- if tex_lexics then begin
- as['!']:=is_special;
- as['"']:=is_special;
- as['#']:=is_special;
- as['$']:=is_special;
- as['%']:=is_special;
- as['&']:=is_special;
- as['/']:=is_special;
- as['{']:=is_special;
- as['}']:=is_special;
- as['(']:=is_special;
- as[')']:=is_special;
- as['[']:=is_special;
- as[']']:=is_special;
- as['=']:=is_special;
- as['?']:=is_special;
- as['\']:=is_special;
- as['`']:=is_special;
- as['^']:=is_special;
- as['~']:=is_special;
- as['*']:=is_special;
- as['<']:=is_special;
- as['>']:=is_special;
- as['|']:=is_special;
- as[';']:=is_special;
- as[',']:=is_special;
- as[':']:=is_special;
- as['.']:=is_special;
- as['-']:=is_special;
- as['_']:=is_special;
- as['''']:=is_special;
- if sty_lexics {It is the only place where sty_lexics is used}
- then as['@']:=is_letter
- else as['@']:=is_special;
- end;
- end;
- Procedure StrAdd(c:char); {Adds one character to string constant}
- {***********************}
- begin
- inc{1}(Str_constlen);
- if Str_constlen<=80 then Str_const[Str_constlen]:=c;
- end;
- Procedure StrBegin; {Initiates string constant}
- {******************}
- begin
- saved_coord:=GetCoord;
- { It will be used when PutStr works and TOKEN EXITs - in READ_ITEM}
- in_string:=true;
- Str_constlen:=0;
- end;
- Procedure Token; {Reads one token from the input stream}
- {********************}
- label 1,99;
- var J,i_saved:integer; { positions }
- var digits_before_dot,digits_after_dot:integer;
- begin
- { at beginning time
- "i" - is already set to character in string "s";
- array "as" is already initialized;
- coordinate mode "coord_mode" is already known;
- }
- with b123 do begin { variant record ,b1=b2[1]=b3[1]; b2[2]=b3[2] }
- 1: { we return to this label if token is not ready still }
- b1:=s[i];
- isa:=as[b1]; { type of this character }
- if isa=is_control
- then begin {1}
- if b1=new_line_code
- then
- begin
- Readline; { skips to next line, sets new "s" and "i" }
- if tex_lexics then begin DT:=dummy; goto 99;end; {NULL is returned at the end of line}
- if in_string then begin
- {$IFDEF MIF}
- writeln('s=[',s,'], constlen=',str_constlen,' i=',i,'b1=',b1);
- PutStr(ATOM); goto 99;
- {$ELSE}
- ER_LEX(11); PutStr(KEYWORD); goto 99;
- {$ENDIF}
- end;
- { ERROR= end of line appears in string constant }
- goto 1;
- end
- else
- if b1=endfile_code
- then
- begin
- if in_comment then ER_LEX(12);
- { ERROR = end of file appears in comment }
- DT:=eof_desk;
- goto 99;
- end
- else
- { others are CONTROL characters; }
- { they set "DT" field and then form Rigal list/tree structure }
- {$IFDEF MIF}
- if not in_string then
- {$ENDIF}
- begin{2}
- if in_comment then begin ER_LEX(13); in_comment:=false; end;
- { ERROR = control char in comment }
- if in_string then begin ER_LEX(14); PutStr(KEYWORD); goto 99;
- { will take control character next time }
- end;
- { ERROR = control char in string }
- DT:=Cont_char_to_dt(b1);
- I:=I+1;
- If (DT=set_coord)and(as[s[i]]=is_digit)
- { this control character sets coordinate to value given in input }
- then begin
- Coord_mark:=TAKE_DIGITS(J);
- Last_mark_byte_number:=line_byte_number+i;
- I:=I+J;
- goto 1; { DOES NOT RETURNS ! }
- end;
- goto 99;
- end; {2}
- {NEVER HERE}
- end; {1}
- { all the following executes AFTER check of is_control }
- {b3[1]:=s[i];} { this character }
- b3[2]:=s[i+1]; { next }
- b3[3]:=s[i+2]; { next }
- if in_comment { CHECK FOR END OF COMMENT }
- {THIS part never appears in MIF input, since there is no in_comment status}
- then begin {1}
- { we are in comment;
- here only comments that have some special end mark are processed }
- if pascal_comment then begin {2}
- if b1='}' then begin inc{3}(i); in_comment:=false; goto 1;end;
- if b2='*)' then begin inc{4}(i,2); in_comment:=false; goto 1; end;
- end {2}
- else
- if c_comment then begin {2}
- if b2='*/' then begin inc{4}(i,2); in_comment:=false; goto 1;end;
- end {2}
- ;
- inc{3}(i);
- goto 1;
- end;{1}
- {$IFDEF MIF}
- if in_string then begin{1}
- if b1='''' then begin
- if str_constlen=81 then begin
- {constant ends after special character or in 80 character}
- StrBegin;{sets str_constlen to 0}
- is_2quote:=false;
- end;
- PutStr(ATOM);
- {jncx}inc(i);
- goto 99;
- end
- {End if MIF constant}
- else
- {$IFDEF BBS}
- { BBS variant of processing:
- If \\ appears in MIF format, \ is included output atom;
- \> >
- \xd2 "
- \xd4 $B4
- \xd5 '
- If \letters
- then new IDENT-atom is created. It contains only 'letters', without \
- }
- if b1='\' then begin
- if b2[2]='\' then begin StrAdd(b2[2]);inc{jcnx2}(i,2);goto 1;end;
- if b2[2]='>' then begin StrAdd(b2[2]);inc{jcnx2}(i,2);goto 1;end;
- if (b2[2]='x')and(b3[3]='d')and(s[i+3]in['2','4','5']) then begin
- case s[i+3] of
- '2':StrAdd('"');
- '4':StrAdd('´');
- '5':StrAdd('''');
- end;
- inc{jcnx2}(i,4);goto 1;end;
- (* UNREGISTRED CONTROL SEQUENCE *)
- PutStr(ATOM);
- inc(i); (* symbol \ is ignored *)
- in_string:=true; str_constlen:=82; (* special value, normally impossible *)
- goto 99;
- end;
- {$ELSE}
- { LATEX variant of processing:
- If any of control characters appears then a separate IDATOM with such contents
- is created.
- If \x(N)(N)(space) then IDATOM with \x(N)(N) is created;
- If \t then IDATOM t
- \b b
- \n n
- \\ \\
- \> \>
- \(another letter) \(another letter)
- Empty MIF strings are coded as NULL
- After and before IDENTs additional NULLs can appear sometimes
- }
- if str_constlen=83 then{ special value for taking one character to next IDATOM }
- begin
- StrBegin;is_2quote:=false;
- StrAdd(b1); PutStr(IDATOM); inc(i);in_string:=true;
- str_constlen:=81; { go to next part of the constant} goto 99;end;
- if str_constlen=84 then{ special value for taking two characters to next IDATOM }
- begin
- StrBegin;is_2quote:=false;
- StrAdd(b1);StrAdd(b2[2]); PutStr(IDATOM); inc(i,2);in_string:=true;
- str_constlen:=81; { go to next part of the constant} goto 99;end;
- if str_constlen=85 then{ special value for taking 4 characters to next IDATOM,
- and ignoring one more after them }
- begin
- StrBegin;is_2quote:=false;
- StrAdd(b2[1]);StrAdd(b2[2]);StrAdd(b3[3]);StrAdd(s[i+3]); PutStr(IDATOM); inc(i,5);in_string:=true;
- str_constlen:=81; { go to next part of the constant} goto 99;end;
- if b1 in ['§','!','"','@','#','¤','$','%','&','/',
- '{','}','[',']','`','^','~','>','|','<','_','-','*',',']
- (* COMMA (last ,) added 6/6/95 *)
- then begin
- if str_constlen=81 then DT:=dummy else PutStr(ATOM);
- in_string:=true;str_constlen:=83;{ special value for taking one character to next IDATOM }
- goto 99;
- end;
- if b1='\' then begin
- if b2[2]='x' then begin
- if str_constlen=81 then DT:=dummy else PutStr(ATOM);
- in_string:=true;str_constlen:=85;{take 4 chars}goto 99;end;
- if (b2[2]in ['t','b','n']) then begin Inc(i);
- if str_constlen=81 then DT:=dummy else PutStr(ATOM);
- in_string:=true;str_constlen:=83;{take 1 char}goto 99;end;
- if str_constlen=81 then DT:=dummy else PutStr(ATOM);in_string:=true;str_constlen:=84;{take 2 chars}goto 99;
- end;
- {$ENDIF}
- if str_constlen<80 then
- begin StrAdd(b1); {jncx}inc(i); goto 1; end {Normal case}
- else
- if str_constlen=82 then begin
- (* ***
- StrBegin;is_2quote:=false;
- StrAdd(b3[1]);StrAdd(b3[2]);StrAdd(b3[3]);
- PutStr(IDATOM); special 3-character identifier
- *** *)
- J:=TAKE_LETTERS;
- PutIdent(J);
- in_string:=true;
- str_constlen:=81; (* special value, normally impossible;
- used for starting next part of the constant *)
- I:=I+J; (* *** *)
- goto 99;
- end
- else
- if str_constlen=80 then begin PutStr(ATOM);in_string:=true;{jnc}inc(str_constlen);
- {Becomes 81; no shift in input performed, ends part of constant}
- goto 99; end
- else
- if str_constlen=81 then begin
- {immediately afrer previous case; starts next part of constant}
- StrBegin;{sets str_constlen to 0}
- is_2quote:=false;
- {$IFDEF BBS}
- StrAdd(b1);
- {jncx}inc(i);
- {$ELSE}
- {$ENDIF}
- goto 1; end
- end;{1}
- if b1='`' then begin StrBegin;is_2quote:=false;{jncx}inc(i);goto 1;end;
- {Starts new MIF text constant}
- if b1='#' then begin Readline; goto 1; end; {MIF comment}
- {$ELSE}
- if in_string
- { CHECK FOR END OF STRING or SOMETHING SPECIAL IN STRING }
- then begin {1}
- if pascal_string then begin {2}
- if b1='''' then begin {3}
- if b2[2]='''' then begin StrAdd('''');
- inc{4}(i,2);
- goto 1;end
- { this allow to save '''' as '' }
- else begin Putstr(TATOM);inc{3}(i);goto 99;end;
- end {3}
- else begin {3}
- StrAdd(b1);
- inc{3}(i);
- goto 1;
- end {3}
- end; {2}
- if modula_string then begin {2}
- if is_2quote and (b1='"') then
- begin
- if b2[2]='"' then begin StrAdd('"');Inc{4}(i,2);goto 1;end
- else begin Putstr(TATOM);inc{3}(i);goto 99;end;
- end;
- if not(is_2quote) and (b1='''') then
- begin Putstr(KEYWORD);inc{3}(i);goto 99;end
- else begin {3}
- if b1='\' then
- begin
- StrAdd(b1);
- StrAdd(b2[2]);
- { this allows to save \? as ? even if \" appears}
- inc{4}(i,2);
- goto 1;
- end;
- StrAdd(b1);
- inc{3}(i);
- goto 1;
- end; {3}
- end {2}
- end ; {1}
- {$ENDIF}
- { all the following executes AFTER check for in_string & in_comment }
- if isa=is_special then begin{1}
- {THIS part never appears in MIF input, since there is no is_special}
- if pascal_comment then begin{2}
- if (b2='(*')
- then begin in_comment:=true;inc{4}(i,2);goto 1;end;
- if (b1='{')and(b2[2]<>'$')
- then begin in_comment:=true;inc{3}(i) ;goto 1;end;
- end{2}
- else
- if c_comment then begin{2}
- if b2='/*' then begin in_comment:=true;inc{4}(i,2);goto 1;end;
- end {2}
- else
- if ada_comment then begin {2}
- if b2='--' then begin Readline;goto 1; end;
- end {2}
- ;
- if pascal_string then begin {2}
- if b1='''' then begin StrBegin;is_2quote:=false;inc{3}(i);goto 1;end;
- end {2}
- else
- if modula_string then begin {2}
- if b1='''' then begin StrBegin;is_2quote:=false;inc{3}(i);goto 1;end;
- if b1='"' then begin StrBegin;is_2quote:=true;inc{3}(i);goto 1;end;
- end {2}
- ;
- if pascal_lexics then begin {2}
- { SPECIALLY TAKES TURBO PASCAL DIRECTIVE-COMMENTS }
- if (b2='{$') then begin {3}
- j:=0;
- repeat inc{3}(j);
- until (s[i+j]='}')or(as[s[i+j]]=is_control);
- if s[i+j]='}' then inc{3}(j);
- PutAtom(j);
- inc{4}(i,j);
- goto 99;
- end; {3}
- { ADDITIONAL SYMBOLS }
- if (b1='#')or(b1='$')or(b1='%')
- then begin {3}
- inc{3}(i);
- J:=TAKE_LETTERS; { starts from i-th position }
- i:=i-1;
- PutAtom(J+1); { takes token from i-th position }
- inc{4}(i,j+1);
- goto 99;
- end; {3}
- end{2}
- else
- if c_lexics then begin {2} { SYMBOLS= > < }
- { SPECIAL CASES FOR C LANGUAGE }
- if (b3='<<=')or(b3='>>=') then begin
- PutAtom(3); inc{4}(i,3); goto 99;
- end;
- isa:=is_first_of_two;
- { !! in C case <<, >>, >=, <= will be tested further
- in TWO_char_symbols section, hence we go to there
- using assignment to "ISA" }
- end {2}
- end; {1}
- if tex_lexics then begin{1}
- (********* DESCRIPTION OF TeX Lexics *********
- End_of_Line,(but not End_of_file) are NULL atom
- \letters is command , where letters are A-Z,a-z.
- @ is added to letters if we are in sty_lexics submode
- Recognizable by #IDENT rule
- \? is command , where ? is arbitrary.
- Recognizable by #_KEYWORD rule
- ? is command , where ? is one of special characters,
- (all visible except letters and digits)
- Recognizable by #_KEYWORD rule
- ' ' is command. Every space-separately.
- Recognizable as #ATOMs, not #IDATOM, not #_KEYWORD
- letters,digits,spaces that can form unlimited
- sequences.
- Recognizable as #ATOMs, not #IDATOM, not #_KEYWORD
- **********************************************)
- (* My comments: End_of_File is not NULL atom,
- because it is unclear how to stop main loop then.
- #XXX is not accepted as camment bacause of \verbatim
- environment *)
- if b1='\' then begin {2}
- if as[b2[2]]=is_letter then begin
- { Command like \def, or \d@f \@ in sty_lexics }
- j:=1;
- while as[s[i+j]]=is_letter do inc(j);
- { Non-loop condition: s[last_element]=' ', it is not a is_letter
- character }
- PutIT(IDATOM,j);
- inc{4}(i,j);
- goto 99;
- end
- else
- if b2[2]=new_line_code then
- (* THIS ADDITIONAL IF IS ADDED 4/5/1995 (!) *)
- begin
- PutIt(KEYWORD,1);
- inc{4}(i,1);
- goto 99;
- end
- else
- begin
- {Commands like \% \$ and so on; \@ if not sty_lexics }
- PutIt(KEYWORD,2);
- inc{4}(i,2);
- goto 99;
- end;
- end;{2}
- {My comment: \ is included in is_special, but it makes
- no any difference}
- if (isa=is_special) then begin PutIt(KEYWORD,1);inc{3}(i);goto 99;end;
- {Separate character like $ ( ) etc. }
- if b1=' ' then begin PutIt(ATOM ,1);inc{3}(i);goto 99;end;
- {All other characters}
- {all other characters simply form 80-byte atoms;
- end of line and end of file cannot be included to it;
- Tabulators are changed to spaces.}
- j:=0;
- while (as[s[i+j]]<>is_special)and(j<80)and
- (s[i+j]<>new_line_code)and(s[i+j]<>endfile_code)
- do begin
- if s[i+j]=#9 then s[i+j]:=' ';
- inc(j);
- end;
- PutIt(Atom,j);
- inc{4}(i,j);
- goto 99;
- end;{1}
- if isa=is_space then begin inc{3}(i); goto 1;end;
- if isa=is_letter then begin
- J:=TAKE_LETTERS;
- PutIdent(J);
- I:=I+J;
- goto 99;
- end;
- if isa=is_digit then begin {1}
- if c_lexics then begin {2}
- { ADDITIONAL SYMBOLS; HERE hex and octal numbers are saved as
- normal ATOMs }
- if (b1='0')
- then begin {3}
- inc{3}(i);
- J:=TAKE_LETTERS; { starts from i-th position }
- i:=i-1;
- PutAtom(J+1); { takes token from i-th position }
- inc{4}(i,j+1);
- goto 99;
- end; {3}
- end; {2}
- i_saved:=i; { remember starting position }
- AADR:=TAKE_DIGITS(J);
- digits_before_dot:=j;
- if (j<10)and
- ( ((s[i+j]='.')and(s[i+j+1]='.'))
- or
- (not(s[i+j]in['e','E','.'])) )
- then begin PutNumber;inc{4}(i,j);goto 99;end;
- inc{4}(i,j);
- if s[i]='.' then begin
- inc{3}(i);
- AADR:=TAKE_DIGITS(J);
- digits_after_dot:=j;
- inc{4}(i,j);
- end;
- if s[i] in ['e','E'] then
- begin
- digits_before_dot:=0;
- digits_after_dot:=0;
- inc{3}(i);
- if s[i] in ['+','-'] then inc{3}(i);
- AADR:=TAKE_DIGITS(J);
- inc{4}(i,j);
- end;
- J:=i-i_saved;
- i:=i_saved; { to set "i" to starting position }
- PutFloat(J,digits_before_dot,digits_after_dot);
- inc{4}(i,j);
- goto 99;
- end;{1}
- if isa=is_first_of_two then begin {1}
- if b2[2] in set_of_second_of_two then
- for j:=1 to two_char_symbols_num do
- if b2=two_char_symbols[j] then begin
- PutAtom(2);I:=I+2;goto 99;
- end
- end;{1}
- PutAtom(1);inc{3}(i);
- end; { with}
- 99:;
- end; { Procedure }
- Function TAKE_LETTERS:integer;
- {**************************************}
- label 99;
- { Reads only letters, digits and underscores.
- returns number of characters read }
- var JJ:integer; c:char;
- begin
- JJ:=0;
- while true do begin
- c:=s[i+jj];
- isa:=as[c];
- if (isa=is_letter)or(isa=is_digit)or(isa=is_underscore)
- then begin
- if to_uppercase then s[i+jj]:=upcase_tab[c];
- inc{3}(jj)
- end
- else begin
- TAKE_LETTERS:=jj;goto 99;
- end;
- end;
- 99:;
- end;
- Function TAKE_DIGITS(var jj:integer):longint;
- {************************************************}
- label 99;
- var summator:longint; c:char;
- begin
- JJ:=0; summator:=0;
- while true do begin
- c:=s[i+jj];
- if as[c]=is_digit then
- begin summator:=summator*10+ord(c)-ord('0');inc{3}(jj);end
- else begin TAKE_DIGITS:=summator;goto 99;end;
- end;
- 99:;
- end;
- (*begin*)
- { PRESS F8 when debugging ! }
- (*INITIALIZE_SCAN_VARIABLES;*)
|