PageRenderTime 58ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/core/third_parties/fparser.m

http://brainstream.googlecode.com/
MATLAB | 1289 lines | 1035 code | 68 blank | 186 comment | 1 complexity | 70c6d7c29e9a265e05402f9918109558 MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, LGPL-2.0, GPL-3.0, GPL-2.0, LGPL-2.1, LGPL-3.0, BSD-2-Clause
  1. % PAR = FPARSER('M-file',['OPT',...,'OPT',...])
  2. % PAR = FPARSER('command_line','-c',['OPT',...,'OPT',...])
  3. %
  4. % to parse a M-file or command line
  5. % and list tokens and constructs
  6. % - functions/keywords
  7. % - variables/constants
  8. % - struct field assignments
  9. %
  10. % OPT option flags/arguments
  11. % -c : input is a command-line
  12. % -d : show results at run-time
  13. %
  14. % PAR output struct with fields
  15. % .tmpl lexical engine templates
  16. % .file file name
  17. % .buff file contents
  18. % .skel file contents after removal of
  19. % var class tokens
  20. % .res RESULTS [show at run-time: <-d>]
  21. % .nline nr of lines
  22. % .linx indices eol/lnr
  23. % .nent nr of tokens found
  24. % .nmtok nr of FUNCTIONS found
  25. % .mtok list of FUNCTIONS
  26. % .nvtok nr of VARIABLES found
  27. % .vtok list of VARIABLES
  28. % .nstok nr of STRUCT.FIELD assignments
  29. % .stok list of STRUCT.FIELD assignments
  30. %
  31. % contents of sorted token list cells
  32. % .mtok {'token' 'source' name_len nr_used inx_lst lin_lst}
  33. % .vtok {'token' 'type' name_len nr_used inx_lst lin_lst}
  34. % .stok {'token' 'contructor' name_len line_nr inx_lst lin_lst}
  35. %
  36. % contents of <inx_lst>s
  37. % nr_used indices
  38. % [beg1 ... begN = buffer offset beg
  39. % end1 ... endN] = buffer offset end
  40. % into par.buff where tokenX was found
  41. % contents of <lin_lst>s
  42. % nr_used indices
  43. % [lnr1 ... lnrN = line number
  44. % beg1 ... begN = line offset beg
  45. % end1 ... endN] = line offset end
  46. % of the file contents where tokenX was found
  47. %
  48. % USAGE EXAMPLE
  49. % see accompanying html-file <fpatdemo.html>
  50. % this option is not implemented in final version!
  51. % mod: modify default templates [def: par.tmpl]
  52. % '[xyz]' : do NOT delete characters <x><y><z>
  53. % '{xyz}' : delete additional characters <x><y><z>
  54. % created:
  55. % us 10-Jun-2001 / project <alias>
  56. % modified:
  57. % us 12-Dec-2005 09:26:17 / CSSM/TMW
  58. function olst=fparser(varargin)
  59. mod=[];
  60. mode=0;
  61. lst=ini_lst(varargin{:});
  62. if nargout
  63. olst=lst;
  64. end
  65. if nargin < 1 | isempty(varargin{1})
  66. help(mfilename);
  67. return;
  68. end
  69. var=varargin{1};
  70. % command line
  71. if nargin > 1 & lst.par.opt.cflg
  72. lst.file='command line';
  73. lst.type='string';
  74. mode=1;
  75. var=[var char(10)];
  76. % m-file
  77. else
  78. lst.file=var;
  79. lst.type='file';
  80. mode=1;
  81. [fp,msg]=fopen(var,'rt');
  82. if fp > 0
  83. var=fread(fp,'uchar');
  84. fclose(fp);
  85. var=char(var).';
  86. else
  87. % disp(sprintf('fparser> cannot open <%s>',var));
  88. % disp(sprintf('.......> %s',msg));
  89. return;
  90. end
  91. end
  92. % build empty output parameter struct
  93. lst.buff=var;
  94. lst.skel=var;
  95. lst.res='no tokens';
  96. linx=[0 find(var==10)];
  97. lst.nline=length(linx)-mode;
  98. lst.linx=[linx; 1:lst.nline+1];
  99. lst.linx(end,end)=nan;
  100. lst.nent=0;
  101. lst.nmtok=0; % functions
  102. lst.mtok={};
  103. lst.mtxt=[];
  104. lst.nvtok=0; % variables
  105. lst.vtok={};
  106. lst.vtxt=[];
  107. lst.nstok=0; % struct assignments
  108. lst.stok={};
  109. lst.stxt=[];
  110. %--------------------------------------------------------------------------------
  111. % templates
  112. % - special characters
  113. % tmpls='@._';
  114. % - unconditional:
  115. % tmpl1='=+-*/^''[](){},.:;\~!#$%&|<>?"`';
  116. tmpl1='=+-*/^''[](){},:;\~!#$%&|<>?"`';
  117. % - space both | right | surrounded by chars
  118. tmpl2='@';
  119. % - space both | left
  120. tmpl3='0123456789';
  121. iinc=[];
  122. idel=[];
  123. if nargin > 1 & ~isempty(mod)
  124. ib=strfind(mod,'[');
  125. if ~isempty(ib)
  126. ie=strfind(mod,']');
  127. if ~isempty(ie)
  128. iinc=mod(ib+1:ie-1);
  129. end
  130. end
  131. ib=strfind(mod,'{');
  132. if ~isempty(ib)
  133. ie=strfind(mod,'}');
  134. if ~isempty(ie)
  135. idel=mod(ib+1:ie-1);
  136. end
  137. end
  138. %D disp(sprintf('inc: <%s>',iinc));
  139. %D disp(sprintf('del: <%s>',idel));
  140. for i=1:length(iinc)
  141. tmpl1(find(iinc(i)==tmpl1))='';
  142. tmpl2(find(iinc(i)==tmpl2))='';
  143. tmpl3(find(iinc(i)==tmpl3))='';
  144. end
  145. tmpl1=[tmpl1 idel];
  146. end
  147. dflg=1;
  148. if nargin > 2
  149. lst.par.opt.dflg=1;
  150. end
  151. % tmpl3=[tmpl3 tmpl3];
  152. vari=var;
  153. lst.tmpl.tmpl1=tmpl1;
  154. lst.tmpl.cused=setdiff(char(32:128),tmpl1);
  155. lst.tmpl.tmpl2=tmpl2;
  156. lst.tmpl.tmpl3=tmpl3;
  157. lst.tmpl.inc=iinc;
  158. lst.tmpl.del=idel;
  159. %--------------------------------------------------------------------------------
  160. % MAIN LEXICAL ENGINE
  161. %--------------------------------------------------------------------------------
  162. %D disp('***** special constructs *****');
  163. [lst,var,sok]=get_stri(lst,var);
  164. [lst,var,sok]=get_comm(lst,var,'%',10);
  165. [lst,var,sok]=get_stru(lst,var,'.',tmpl1);
  166. var=[' ' var ' '];
  167. %--------------------------------------------------------------------------------
  168. %D disp('***** punctuations *****');
  169. for i=1:length(tmpl1)
  170. var=strrep(var,tmpl1(i),' ');
  171. %D disp(var)
  172. end
  173. for i=1:length(tmpl2)
  174. ix=strfind(var,tmpl2(i));
  175. if ~isempty(ix)
  176. % space both
  177. iy=find(var(ix+1)==' ' & var(ix-1)==' ');
  178. var(ix(iy))=' ';
  179. % char both | left
  180. iy=[...
  181. find((var(ix+1)~=' ' & var(ix-1)~=' ') | ...
  182. (var(ix-1)~=' '))...
  183. ];
  184. if ~isempty(iy)
  185. ixo=ix;
  186. iyo=iy;
  187. ix=ix(iy); % -1
  188. var(ix)=' '; % '|'
  189. nc=0;
  190. % erode ->
  191. while iy
  192. nc=nc+1;
  193. iy=find(var(ix+nc)~=' ');
  194. var(ix(iy)+nc)=' ';
  195. ix=ix(iy);
  196. end
  197. ix=ixo;
  198. iy=iyo;
  199. nc=0;
  200. % erode <-
  201. while iy
  202. nc=nc+1;
  203. iy=find(var(ix-nc)~=' ');
  204. var(ix(iy)-nc)=' ';
  205. ix=ix(iy);
  206. end
  207. end
  208. end
  209. % disp(var);
  210. end
  211. %--------------------------------------------------------------------------------
  212. %D disp('***** numbers *****')
  213. % must use an eroding process!
  214. vart=var;
  215. while true
  216. for i=1:length(tmpl3)
  217. ix=find(var==tmpl3(i));
  218. if ~isempty(ix)
  219. % space left
  220. iy=find(isspace(var(ix-1)));
  221. var(ix(iy))=' ';
  222. % space both
  223. iy=find(isspace(var(ix+1)) & isspace(var(ix-1)));
  224. var(ix(iy))=' ';
  225. end
  226. %D disp(var);
  227. end
  228. if isequal(var,vart)
  229. break;
  230. end
  231. vart=var;
  232. end
  233. %--------------------------------------------------------------------------------
  234. %D disp('***** tokens *****')
  235. tok={};
  236. emp={};
  237. tc={};
  238. var=var(2:end-1);
  239. b=var;
  240. trep=0;
  241. tnew=0;
  242. tent=0;
  243. [tc,b,tcp]=astrtok(b);
  244. tent=size(tc,1);
  245. tc=unique(tc);
  246. ix=xor(cellfun('isempty',tc),1);
  247. tc=tc(ix);
  248. for cc=1:size(tc,1)
  249. a=tc{cc};
  250. %D disp(sprintf('%s: searching',a));
  251. if (~isempty(tok) & ~isempty(strmatch(a,tok(:,1),'exact'))) | ...
  252. (~isempty(emp) & ~isempty(strmatch(a,emp(:,1),'exact')))
  253. trep=trep+1;
  254. %D disp(sprintf('repeat token %5d:%5d/%5d <%s>',trep,tnew,trep+tnew,a));
  255. continue;
  256. end
  257. tnew=tnew+1;
  258. w=[]; % keep this!
  259. if ~isempty(w)
  260. emp=[emp;{a w.class length(a)}];
  261. else
  262. p=evalin('base',sprintf('which(''%s'')',a));
  263. if strcmp(p,'variable')
  264. p=[];
  265. end
  266. if ~isempty(p)
  267. if iskeyword(a)
  268. p='keyword';
  269. end
  270. %D disp(sprintf('%s: PATH <%s>',a,p));
  271. tok=[tok;{a p length(a)}];
  272. else
  273. if a(1)=='@' & length(a) > 1
  274. emp=[emp;{a class(eval(a)) length(a)}];
  275. else
  276. emp=[emp;{a class(a) length(a)}];
  277. end
  278. end
  279. end % token not in tables
  280. end
  281. varo=var;
  282. if ~isempty(emp)
  283. ix=strmatch('@',emp(:,1));
  284. if ~isempty(ix)
  285. tlen=[size(tok,1)+1:size(tok,1)+length(ix)];
  286. tok(tlen,:)=emp(ix,:);
  287. emp(ix,:)=[];
  288. end
  289. if ~isempty(tok)
  290. [dum,ix]=unique(tok(:,1));
  291. tok=tok(ix,:);
  292. end
  293. [var,tcp,tok]=fill_pattern(var,tcp,tok,'+');
  294. [dum,ix]=unique(emp(:,1));
  295. if ~isempty(emp)
  296. emp=emp(ix,:);
  297. [var,tcp,emp]=fill_pattern(var,tcp,emp,'-');
  298. ix=strfind(var,'-');
  299. if ~isempty(ix)
  300. var=varo;
  301. var(ix)=' ';
  302. end
  303. else
  304. var=varo;
  305. end
  306. elseif ~isempty(tok)
  307. [dum,ix]=unique(tok(:,1));
  308. tok=tok(ix,:);
  309. [dum,tcp,tok]=fill_pattern(var,tcp,tok,'+');
  310. end
  311. %--------------------------------------------------------------------------------
  312. lst=set_var(lst,var,tok,emp,sok);
  313. lst=set_stru(lst);
  314. lst=show_ent(lst);
  315. if nargout
  316. olst=lst;
  317. end
  318. if lst.par.opt.dflg
  319. disp(lst.res);
  320. end
  321. return;
  322. %--------------------------------------------------------------------------------
  323. function [var,tcp,tmpl]=fill_pattern(var,tcp,tmpl,pat)
  324. [ts,tx]=sort([tmpl{:,3}]);
  325. tmpl=tmpl(tx,:);
  326. for i=size(tmpl,1):-1:1 % reverse search!
  327. s=tmpl{i,1};
  328. %D disp(sprintf('%s: CLR <%s>',var,s));
  329. six=strmatch(s,tcp.u(:,1),'exact');
  330. ix=tcp.u{six,end};
  331. tmpl{i,4}=size(ix,2);
  332. tmpl{i,5}=ix;
  333. var=astrrepx(var,pat,ix);
  334. %D disp(sprintf('%s: DONE <%s>',var,s));
  335. end
  336. return;
  337. %--------------------------------------------------------------------------------
  338. function [lst,tok,var]=set_var(lst,buf,tok,var,sok)
  339. if ~isempty(sok)
  340. sokt=sok;
  341. for i=1:size(sok,1)
  342. n=sok{i,1};
  343. o=n;
  344. nnew=1;
  345. nlen=0;
  346. if n(1) == '.'
  347. nnew=0;
  348. else
  349. ix=find(n=='.');
  350. n=n(1:ix-1);
  351. n=get_bracket(n);
  352. if isstruct(n)
  353. n=n.s;
  354. end
  355. nlen=length(n)+1;
  356. o=o(ix:end);
  357. ix=find(n=='|');
  358. if ~isempty(ix)
  359. n=n(1:ix(1)-1);
  360. end
  361. end
  362. if nnew
  363. if ~isempty(var)
  364. ix=strcmp(var(:,1),n);
  365. end
  366. if ~isempty(find(ix))
  367. p=sok{i,6};
  368. var{ix,4}=size(var{ix,5},2);
  369. var{ix,5}=[var{ix,5} p];
  370. else
  371. sok{i,1}=n;
  372. sok{i,2}='struct';
  373. sok{i,4}=length(n);
  374. var=[var;sok(i,[1 3:6])];
  375. end
  376. end
  377. end
  378. sok=sokt;
  379. end
  380. if ~isempty(tok)
  381. [dum,ix]=sort(tok(:,1));
  382. tok=tok(ix,:);
  383. tok=get_line(lst,tok);
  384. end
  385. if ~isempty(var)
  386. [dum,ix]=sort(var(:,1));
  387. var=var(ix,:);
  388. var=get_line(lst,var);
  389. end
  390. if ~isempty(sok)
  391. [dum,ix]=sort(sok(:,1));
  392. sok=sok(ix,:);
  393. sok=sok(:,[1 3:6]);
  394. sok=get_line(lst,sok);
  395. end
  396. lst.skel=buf;
  397. lst.nmtok=size(tok,1);
  398. lst.mtok=tok;
  399. lst.nvtok=size(var,1);
  400. lst.vtok=var;
  401. lst.nstok=size(sok,1);
  402. lst.stok=sok;
  403. lst.nent=lst.nmtok+lst.nvtok+lst.nstok;
  404. return;
  405. %--------------------------------------------------------------------------------
  406. function tok=get_line(lst,tok)
  407. if isempty(lst.linx)
  408. return;
  409. end
  410. for i=1:size(tok,1)
  411. p=tok{i,5};
  412. l=ones(3,size(p,2));
  413. for j=1:tok{i,4}
  414. ix=find(lst.linx(1,:)>=p(1,j));
  415. if ~isempty(ix)
  416. l(:,j)=[lst.linx(2,ix(1)-1);
  417. [p(:,j)-lst.linx(1,ix(1)-1)]];
  418. end
  419. end
  420. tok{i,6}=l;
  421. end
  422. return
  423. %--------------------------------------------------------------------------------
  424. function lst=show_ent(lst)
  425. % created:
  426. % us 30-Aug-2003 / CSSM/TMW <aparser>/<fparser>
  427. lst.res=[];
  428. lst.mtxt=[];
  429. lst.vtxt=[];
  430. lst.stxt=[];
  431. if ~lst.nent
  432. lst.res=sprintf('fparser> no tokens in <%s>',lst.file);
  433. else
  434. ml=[[lst.mtok{:,3}],[lst.vtok{:,3}],[lst.stok{:,3}]];
  435. ml=max([ml 20])+2;
  436. ml=max(ml,20);
  437. del={repmat('-',1,ml+7)};
  438. fm1=sprintf('%%-%d.%ds> %%5d',ml,ml);
  439. fm2=sprintf('%%%dd',ml-12);
  440. txt=[];
  441. txt=[txt;{sprintf(['functions/keywords ' fm2],lst.nmtok)}];
  442. txt=[txt;del];
  443. for i=1:size(lst.mtok,1)
  444. tmp=sprintf(fm1,lst.mtok{i,1},lst.mtok{i,4});
  445. tmp=[tmp ' ' sprintf('%s',lst.mtok{i,2})];
  446. txt=[txt;{tmp}];
  447. end
  448. mtxt=[txt;del];
  449. txt=[];
  450. txt=[txt;{sprintf(['variables/constants' fm2],lst.nvtok)}];
  451. txt=[txt;del];
  452. for i=1:size(lst.vtok,1)
  453. txt=[txt;{sprintf(fm1,lst.vtok{i,1},lst.vtok{i,4})}];
  454. end
  455. vtxt=[txt;del];
  456. txt=[];
  457. txt=[txt;{sprintf(['struct.field assmnt' fm2],lst.nstok)}];
  458. txt=[txt;del];
  459. for i=1:size(lst.stok,1)
  460. tok=lst.stok{i,1};
  461. tok=tok(~isspace(tok));
  462. tmp=sprintf(fm1,tok,lst.stok{i,4});
  463. tmp=[tmp ' ' sprintf('%s',lst.stok{i,2})];
  464. txt=[txt;{tmp}];
  465. end
  466. txt=[txt;del];
  467. stxt=txt;
  468. lst.res=char([mtxt;vtxt;stxt]);
  469. lst.mtxt=char(mtxt);
  470. lst.vtxt=char(vtxt);
  471. lst.stxt=char(stxt);
  472. end
  473. return;
  474. %--------------------------------------------------------------------------------
  475. function [lst,varo,stok]=get_stru(lst,var,tmpl,tmpl1)
  476. varo=var;
  477. stok={};
  478. % do not parse <structures>: <o=aparser(string,'{.}',...)>
  479. if find(tmpl1==tmpl)
  480. return;
  481. end
  482. if strfind(var,tmpl)
  483. [lst,b]=get_struct(lst,var);
  484. varo=b.s;
  485. stok=b.v;
  486. end
  487. return;
  488. %--------------------------------------------------------------------------------
  489. function lst=set_stru(lst)
  490. if ~lst.nent
  491. return;
  492. end
  493. atok=[lst.mtok;lst.vtok];
  494. if isempty(atok)
  495. return;
  496. end
  497. itok=[atok{:,5}];
  498. for i=1:size(lst.stok,1)
  499. p=lst.stok{i,5};
  500. ix=find(lst.linx(1,:)-p(1)<0);
  501. if ~isempty(ix)
  502. lst.stok{i,4}=ix(end);
  503. end
  504. tok=lst.stok{i,1};
  505. if tok(1) == '.'
  506. pix=itok(2,:)<p(1);
  507. jtok=itok(:,pix);
  508. [a,b]=sort(abs(jtok(2,:)-p(1)));
  509. bp=jtok(1,b(1));
  510. tok=lst.buff(bp:p(2));
  511. bx=1;
  512. while length(find(tok=='(')) < length(find(tok==')')) | ...
  513. length(find(tok=='{')) < length(find(tok=='}')) | ...
  514. length(find(tok=='[')) < length(find(tok==']'))
  515. bx=bx+1;
  516. bp=jtok(1,b(bx));
  517. tok=lst.buff(bp:p(2));
  518. end
  519. lst.stok{i,1}=tok;
  520. lst.stok{i,2}='';
  521. lst.stok{i,3}=length(tok);
  522. else
  523. lst.stok{i,2}='';
  524. end
  525. end
  526. if ~isempty(lst.stok)
  527. [dum,ix]=sort(lst.stok(:,1));
  528. lst.stok=lst.stok(ix,:);
  529. end
  530. return;
  531. %--------------------------------------------------------------------------------
  532. function [lst,varo,stok]=get_stri(lst,var)
  533. varo=var;
  534. stok={};
  535. [lst,b]=get_string(lst,var);
  536. varo=b.s;
  537. stok=b;
  538. return;
  539. %--------------------------------------------------------------------------------
  540. function [lst,varo,stok]=get_comm(lst,var,commdel,eoldel)
  541. varo=var;
  542. stok={};
  543. ib=find(var==commdel);
  544. if ~isempty(ib)
  545. ie=find(var==eoldel);
  546. for i=1:length(ib)
  547. ix=find(ie>=ib(i));
  548. varo(ib(i):ie(ix(1))-1)='%';
  549. end
  550. end
  551. return
  552. %--------------------------------------------------------------------------------
  553. %--------------------------------------------------------------------------------
  554. %--------------------------------------------------------------------------------
  555. % UTILITY FUNCTIONS ADDED FROM PROJECT <ALIAS>
  556. % modified for CSSM/TMW
  557. %--------------------------------------------------------------------------------
  558. %--------------------------------------------------------------------------------
  559. %--------------------------------------------------------------------------------
  560. function [lst,b]=get_string(lst,s,rtmpl,rr)
  561. magic='get_string';
  562. if isstruct(s)
  563. b=s;
  564. if isfield(s,'magic') & strcmp(getfield(s,'magic'),magic)
  565. if nargin < 4
  566. b.k=b.r;
  567. else
  568. b.k=rr;
  569. end
  570. for i=1:b.n
  571. nobj=sprintf(b.tmpl.mark,i);
  572. b.k=strrep(b.k,nobj,b.t{i}(2:end-1));
  573. end
  574. end
  575. return;
  576. end
  577. tmpl='''';
  578. btmpl=' ,;=({[';
  579. if nargin < 3
  580. rtmpl='|';
  581. end
  582. n=0;
  583. v={};
  584. t={};
  585. sl=length(s);
  586. b.magic=magic;
  587. b.n=0;
  588. b.s=s;
  589. b.c=s;
  590. b.k=[];
  591. b.r=s;
  592. b.t=t;
  593. b.v=v;
  594. b.tmpl.tmpl=tmpl;
  595. b.tmpl.rtmpl=rtmpl;
  596. b.tmpl.btmpl=btmpl;
  597. b.tmpl.mark='_S%-1dS_';
  598. if nargin < 1 | isempty(s)
  599. return;
  600. end
  601. % remove <inner> 'STRING's
  602. sori=s;
  603. while 1
  604. for i=2:ceil(sl/2)
  605. obr=repmat(tmpl,1,i);
  606. ix=strfind(s,obr);
  607. if ~isempty(ix)
  608. dix=[-1 diff(ix)];
  609. iy=ix(find(dix~=1));
  610. if ~isempty(iy)
  611. s=astrrepx(s,' ',[iy;iy+i-1]);
  612. end
  613. else
  614. break;
  615. end
  616. end
  617. if strcmp(s,sori)
  618. break;
  619. end
  620. sori=s;
  621. end
  622. % search 'STRING's
  623. rori=s;
  624. ix=strfind(s,tmpl);
  625. if ~isempty(ix)
  626. i=0;
  627. while i < length(ix)-1
  628. i=i+1;
  629. j=ix(i);
  630. hasdel=0;
  631. for k=btmpl
  632. if j==1 | s(j-1)==k | isspace(s(j-1))
  633. hasdel=1;
  634. break;
  635. end
  636. end
  637. if hasdel
  638. n=n+1;
  639. t=[t;{b.c(j:ix(i+1))}];
  640. v=[v;{b.c(j:ix(i+1)) j ix(i+1) ix(i+1)-j}];
  641. s(j+1:ix(i+1)-1)=rtmpl;
  642. rori(j+1:ix(i+1)-1)=char(0);
  643. i=i+1;
  644. end
  645. end
  646. end
  647. while 1
  648. ix=strfind(rori,[char(0) char(0)]);
  649. if isempty(ix)
  650. break;
  651. end
  652. rori(ix)='';
  653. end
  654. b.s=s;
  655. if n
  656. b.r=sprintf(strrep(rori,char(0),b.tmpl.mark),[1:n]);
  657. else
  658. b.r=rori;
  659. end
  660. b.n=n;
  661. b.t=t;
  662. b.v=v;
  663. return;
  664. %--------------------------------------------------------------------------------
  665. function [lst,b]=get_struct(lst,var,tmpl1)
  666. % we must deal with dynamic field assignments
  667. % valid field assignments
  668. % var.field var.field
  669. % var.(field).(field) var.(field).(field)
  670. % var.(field).field .field
  671. % var(...).field .field
  672. % var{...}.field .field
  673. magic='get_struct';
  674. tmpl='.';
  675. varo=var;
  676. it=0;
  677. tok={};
  678. stok={};
  679. b.magic=magic;
  680. b.n=0;
  681. b.s=var;
  682. b.c=var;
  683. b.t=tok;
  684. b.v=stok;
  685. if nargin < 2 | isempty(var)
  686. return;
  687. end
  688. vlen=length(var);
  689. if vlen == 1
  690. b.s=strrep(var,tmpl,'|');
  691. return;
  692. end
  693. % <aparser!>
  694. if nargin < 3
  695. tmpl1='=+-*/^''[](){},:;\~!#$%&|<>?"`';
  696. end
  697. tmpl2=tmpl1;
  698. for i='[](){}<>'
  699. tmpl2(tmpl2==i)='';
  700. end
  701. % mask off marker <|>
  702. var=strrep(var,'|',char(0));
  703. % mask off <continuation> <parent directory> constructs
  704. ix=find(var(1:end-1)=='.' & var(2:end)=='.');
  705. if ~isempty(ix)
  706. var=astrrepx(var,'|',ix);
  707. var=astrrepx(var,'|',ix+1);
  708. end
  709. vart=var;
  710. k=astrtok(var);
  711. for i=1:k.len
  712. if strfind(k.tb{i},'||')
  713. k.b(k.bos(i):k.eos(i))='|';
  714. end
  715. end
  716. var=k.b;
  717. var=strrep(var,char(0),'|');
  718. v=get_bracket(vart);
  719. var=v.s;
  720. if ~v.eflg
  721. var=astrrepx(var,'x',[v.eb;v.ee]);
  722. end
  723. for i=tmpl2
  724. var(vart==i)=i;
  725. end
  726. if ~v.eflg
  727. var(v.eb)='(';
  728. var(v.ee)=')';
  729. end
  730. var(vart==tmpl)=tmpl;
  731. % mask off dynamic field assignments
  732. ix=find(var==tmpl);
  733. for j=1:length(ix)
  734. px=ix(j);
  735. k=1;
  736. while px+k<vlen & isspace(var(px+k))
  737. k=k+1;
  738. end
  739. if var(px+k) == '('
  740. var(px+k)='X';
  741. while px+k<vlen & find(var(px+k)~=')')
  742. k=k+1;
  743. end
  744. var(px+k)='Y';
  745. end
  746. end
  747. for j=1:length(ix)
  748. % char both
  749. pref=0;
  750. suff=0;
  751. px=ix(j);
  752. k=1;
  753. while px+k<vlen & isspace(var(px+k))
  754. k=k+1;
  755. end
  756. if isletter(var(px+k)) | var(px+k) == tmpl
  757. suff=px+k;
  758. end
  759. px=ix(j);
  760. k=1;
  761. while px-k>1 & isspace(var(px-k))
  762. k=k+1;
  763. end
  764. if px-k > 0
  765. if ischar(var(px-k)) % letter | number
  766. pref=px-k;
  767. end
  768. end
  769. %D disp(sprintf('%5d %5d %5d-%5d <%s> [%d]',j,px,pref,suff,var(pref:suff),isletter(var(pref))))
  770. % ... ok
  771. if pref & suff
  772. % search right
  773. while suff<=vlen & ~isspace(var(suff)) & isempty(find(var(suff)==tmpl1))
  774. suff=suff+1;
  775. end
  776. suff=suff-1;
  777. % search left
  778. while pref>0 & ~isspace(var(pref)) & isempty(find(var(pref)==tmpl1))
  779. pref=pref-1;
  780. end
  781. pref=pref+1;
  782. % unflag for STRICT RULE!
  783. % if ~isletter(var(pref)) &
  784. % pref=0;
  785. % else
  786. %D disp(sprintf('%5d %5d %5d-%5d <%s> [%d]',j,px,pref,suff,var(pref:suff),isletter(var(pref))))
  787. % end
  788. it=it+1;
  789. stok{it,1}=pref-1;
  790. stok{it,2}=suff-1;
  791. end
  792. end
  793. var=vart;
  794. if it
  795. varz=char(' '*ones(size(var)));
  796. for i=1:it
  797. varz=astrrepx(varz,'|',[stok{i,1:2}]'+1);
  798. end
  799. k=astrtok(varz);
  800. stok=cell(size(k,1),7);
  801. i=0;
  802. for j=1:k.len
  803. %D disp(sprintf('%5d %5d-%5d <%s>',j,k.bos(j),k.eos(j),var(k.bos(j):k.eos(j))));
  804. vk=var(k.bos(j));
  805. if isletter(vk) | vk(1)=='.' | vk == ' '
  806. tvar=strrep(var(k.bos(j):k.eos(j)),' ','');
  807. if isempty(strfind(tvar,'..'))
  808. i=i+1;
  809. tok{i}=tvar;
  810. st=var(k.bos(j):k.eos(j));
  811. while st(end) == '.' | st(end) == ')'
  812. st=st(1:end-1);
  813. end
  814. if length(find(st=='(')) > length(find(st==')'))
  815. st(end+1)=')';
  816. end
  817. st(isspace(st))='';
  818. stok{i,1}=st;
  819. stok{i,2}='';
  820. stok{i,3}='field';
  821. stok{i,4}=length(stok{i,1});
  822. stok{i,5}=1;
  823. stok{i,6}=[k.bos(j);k.eos(j)];
  824. end
  825. end
  826. end
  827. varo(varz=='|')='|';
  828. end
  829. if isempty(tok)
  830. stok={};
  831. end
  832. varo(varo==tmpl)='|';
  833. b.s=varo;
  834. b.n=size(stok,1);
  835. b.t=tok;
  836. b.v=stok;
  837. return;
  838. %--------------------------------------------------------------------------------
  839. function b=get_bracket(k,b,flg)
  840. magic='get_bracket';
  841. if nargin < 2 | isempty(b)
  842. b='()';
  843. end
  844. if ischar(b)
  845. br=b;
  846. clear b; % R14+!
  847. b.magic=magic;
  848. b.bron=br(1);
  849. b.brof=br(2);
  850. end
  851. b.s=k;
  852. b.c=k;
  853. b.err=[];
  854. if nargin < 1 | isempty(k)
  855. b.eflg=-4;
  856. b.err=['no ' b.bron '...' b.brof ' found'];
  857. return;
  858. end
  859. b.eflg=0;
  860. klen=length(k);
  861. sz=char('_'*ones(1,klen));
  862. kb=length(find(k==b.bron));
  863. ke=length(find(k==b.brof));
  864. if ~kb & ~ke
  865. b.eflg=-3;
  866. b.err=['no ' b.bron '...' b.brof ' found'];
  867. return;
  868. elseif kb > ke
  869. b.eflg=-2;
  870. elseif kb < ke
  871. b.eflg=-1;
  872. end
  873. dep=0;
  874. depm=0;
  875. deps=0;
  876. kb=[];
  877. ke=[];
  878. zd=zeros(size(k));
  879. zs=zd;
  880. for i=1:klen
  881. if k(i)==b.bron
  882. dep=dep+1;
  883. depm=max(dep,depm);
  884. zd(i)=dep;
  885. if dep == 1
  886. deps=deps+1;
  887. zs(i)=deps;
  888. end
  889. end
  890. if k(i)==b.brof
  891. zd(i)=-dep;
  892. dep=dep-1;
  893. if dep == 0
  894. zs(i)=-deps;
  895. end
  896. end
  897. end
  898. kb=[];
  899. ke=[];
  900. kf=[];
  901. for i=1:depm+1
  902. kb=[kb find(zd==i)];
  903. ke=[ke find(zd==-i)];
  904. kf=[kf i*ones(size(find(zd==i)))];
  905. end
  906. if b.eflg
  907. if isempty(kb)
  908. kb=ke;
  909. kf=1;
  910. elseif isempty(ke)
  911. ke=1;
  912. end
  913. kdlen=length(kb)-length(ke);
  914. if kdlen
  915. ke(end:end+kdlen)=repmat(ke(end),1,kdlen+1);
  916. end
  917. end
  918. [kbs,kis]=sort(kb);
  919. kes=ke(kis);
  920. g=ones(size(kf));
  921. ix=1:length(g);
  922. ix=ix(1:length(kes));
  923. for i=2:depm
  924. iy=find(diff(kes(ix))<0);
  925. g(ix(iy))=i;
  926. ix=ix(iy);
  927. end
  928. zz={};
  929. for i=1:depm
  930. z=sz;
  931. ix=find(g==i);
  932. for j=ix
  933. z(kbs(j):kes(j))=k(kbs(j):kes(j));
  934. end
  935. zz=[zz;{z}];
  936. end
  937. zz=[zz;{k}];
  938. b.bl=size(kbs,2);
  939. b.depth=depm+1;
  940. b.ib=kbs;
  941. b.ie=kes;
  942. b.id=g;
  943. b.epoch=deps;
  944. b.eb=find(zs>0);
  945. b.ee=find(zs<0);
  946. b.z=char(zz);
  947. b.zd=zd;
  948. b.zs=cumsum(zs);
  949. if b.eflg | (isempty(kbs) & isempty(kes))
  950. berr='?';
  951. b.err=sz;
  952. if b.eflg == -1
  953. berr='-';
  954. elseif b.eflg == -2
  955. berr='+';
  956. end
  957. if isempty(kbs) & isempty(kes)
  958. ks=sort(find(k==b.bron | k==b.brof));
  959. b.err(ks(1))=berr;
  960. elseif b.eflg == -2 % beg > end
  961. ix=find(b.zs==max(b.zs));
  962. b.err(ix(1))=berr;
  963. elseif b.eflg == -1 % end > beg
  964. ix=find(b.zs>0);
  965. iy=find(b.c==b.brof);
  966. ix=setdiff(iy,ix+1);
  967. b.err(ix(1))=berr;
  968. end
  969. else
  970. b.zs(b.ee)=[1:b.epoch];
  971. b.s=astrrepx(b.s,'|',[b.eb;b.ee]);
  972. end
  973. return;
  974. %--------------------------------------------------------------------------------
  975. function [tb,bb,tbp]=astrtok(bb,pat,cflag)
  976. % [tb,b,tpb] = astrtok(string[,delimiter,cflag)
  977. % created:
  978. % us 10-Aug-1996
  979. if nargin < 2 | isempty(pat)
  980. pat=' ';
  981. end
  982. if nargin < 3 | isempty(cflag)
  983. cflag=0;
  984. end
  985. b=bb;
  986. tb={};
  987. u={};
  988. bl=length(b);
  989. pl=min(length(pat),bl);
  990. len=0;
  991. bos=[];
  992. eos=[];
  993. los=[];
  994. if ~isempty(b)
  995. b(isspace(b))=' ';
  996. if cflag
  997. while 1
  998. ix=strfind(b,' ');
  999. if isempty(ix)
  1000. break;
  1001. end
  1002. b(ix)='';
  1003. end
  1004. b=deblank(b);
  1005. b(strfind(b,' '))='';
  1006. end
  1007. if ~isempty(b)
  1008. ix=strfind(b,pat);
  1009. bos=[-pl+1 ix]+pl;
  1010. los=diff([-pl+1 ix length(b)+pl])-pl;
  1011. eos=min(bos+los-1,length(b));
  1012. ix=find(eos>=bos);
  1013. bos=bos(ix);
  1014. eos=eos(ix);
  1015. los=los(ix);
  1016. len=length(bos);
  1017. if isempty(len)
  1018. len=0;
  1019. end
  1020. tb={};
  1021. tb=cell(len,1);
  1022. for i=1:len
  1023. tb(i)={b(bos(i):eos(i))};
  1024. end
  1025. [u,j,k]=unique(tb);
  1026. tt=cell(len,1);
  1027. for i=1:len
  1028. tt{i}=[bos(i) eos(i)];
  1029. end
  1030. for i=1:length(j);
  1031. tp=reshape([tt{k==i}],2,length(find(k==i)));
  1032. u(i,4)={tp};
  1033. end
  1034. end % ~isempty(len)
  1035. end % ~isempty(b)
  1036. tbp.tb=tb;
  1037. tbp.u=u;
  1038. tbp.b=bb;
  1039. tbp.bl=length(bb);
  1040. tbp.pat=pat;
  1041. tbp.pl=pl;
  1042. tbp.len=len;
  1043. tbp.bos=bos;
  1044. tbp.los=los;
  1045. tbp.eos=eos;
  1046. if nargout < 3
  1047. tb=tbp;
  1048. end
  1049. return;
  1050. %--------------------------------------------------------------------------------
  1051. function [so,sp]=astrrepx(s,pat,pix,opat)
  1052. % [s,sop] = astrrepx(str,npat,pix)
  1053. % [s,sop] = astrrepx(str,npat,oix,opat)
  1054. %
  1055. % indexed string replacement:
  1056. % str([inx11:inx12 inx21:inx22 ...])=npat
  1057. %
  1058. % str : input string: class <char> | <double>
  1059. % pat : replacing pattern: class <char> | <double>
  1060. %
  1061. % pix : index into <s>
  1062. % (2,N): [ beg1 beg2 ... begN
  1063. % end1 end2 ... endN ]
  1064. % (1,N): [ beg1 beg2 ... begN ]
  1065. % endX = computed from <pat>length
  1066. %
  1067. % oix : index into occurrencies of <opat> in <s>
  1068. % [] = all occurrencies
  1069. % [nr(s)] = occurrencies [nr1 nr2 ... nrN]
  1070. % nrX = <inf>
  1071. % = last occurrence
  1072. %
  1073. % sop : replacement parameters <struct>
  1074. %
  1075. % note:
  1076. % astrrepx only changes EXACT matches!
  1077. %
  1078. % examples:
  1079. % s = astrrepx(s,pat,pix)
  1080. % s = astrrepx(s,pat,oix,opat)
  1081. %
  1082. % s = astrrepx(s,pat,[1 4 10],opat)
  1083. % s = astrrepx(s,pat,[],opat)
  1084. % s = astrrepx(s,pat,[1 inf],opat)
  1085. % v='d|dd|ddd|dd|dddd|dddddd';
  1086. % created:
  1087. % us 20-Dec-1993
  1088. sp.pati=[];
  1089. sp.opat=[];
  1090. sp.pato=[];
  1091. sp.pixi=[];
  1092. sp.oixi=[];
  1093. sp.nr=[];
  1094. sp.nc=[];
  1095. sp.pix=[];
  1096. if nargin < 3
  1097. help astrrepx;
  1098. if nargout
  1099. so=[];
  1100. sp.msg='input parameters missing';
  1101. end
  1102. return;
  1103. end
  1104. %--------------------------------------------------------------------------------
  1105. so=s;
  1106. sp.pati=pat;
  1107. sp.msg='running ...';
  1108. if ~strcmp(class(s),class(pat))
  1109. disp(sprintf('astrrepx> cannot merge input classes <%s>:<%s>',class(s),class(pat)));
  1110. sp.msg='input classes do not match';
  1111. return;
  1112. end
  1113. if ~ischar(s)
  1114. [sp.nr,sp.nc]=size(s);
  1115. s=s(:)';
  1116. so=s;
  1117. end
  1118. %--------------------------------------------------------------------------------
  1119. if nargin > 3
  1120. pixi=pix;
  1121. sp.opat=opat;
  1122. sp.pixi=pixi;
  1123. pix=findstr(s,opat);
  1124. if isempty(pix)
  1125. sp.msg='pattern not found';
  1126. return;
  1127. end
  1128. pix=[pix;pix+length(opat)-1];
  1129. pixl=size(pix,2);
  1130. if isempty(pixi)
  1131. pixi=[1:pixl];
  1132. else
  1133. pixi=pixi(1,:);
  1134. pixi(isinf(pixi))=pixl;
  1135. pixi=unique(pixi(find(pixi>0 & pixi<=pixl)));
  1136. end
  1137. sp.opat=opat;
  1138. sp.oixi=pixi;
  1139. pix=pix(:,pixi);
  1140. % pattern must be <exact> !
  1141. pixex=find(pix(1,2:end)<=pix(2,1:end-1));
  1142. pix(:,[pixex pixex+1])=[];
  1143. if isempty(pix)
  1144. sp.msg='exact pattern match not found';
  1145. return;
  1146. end
  1147. end % nargin > 3
  1148. %--------------------------------------------------------------------------------
  1149. sp.pix=pix;
  1150. [nr,nc]=size(pix);
  1151. if nr == 1
  1152. pix=[pix;pix+length(pat)-1];
  1153. end
  1154. if 0
  1155. pixx=find(pix(2,:)>0 & pix(2,:)<=length(so));
  1156. pix=pix(:,pixx);
  1157. end
  1158. % pattern length must be <exact> !
  1159. if ischar(s)
  1160. rlen=length(pat);
  1161. plen=pix(2,1)-pix(1,1)+1;
  1162. % allow diff pix.length in case pat.length == 1!
  1163. if rlen == 1
  1164. nc=rlen;
  1165. plen=sum(pix(2,:)-pix(1,:)+1);
  1166. end
  1167. if plen < rlen
  1168. pat=pat(1:plen);
  1169. elseif plen > rlen
  1170. pat=(ones(ceil(plen/rlen),1)*pat)';
  1171. pat=pat(1:plen);
  1172. end
  1173. end % input class <char>
  1174. rpat=(ones(nc,1)*pat)';
  1175. pixe=pix(2,:)+1;
  1176. pixx=find(pixe<=length(so));
  1177. k1=zeros(size(so));
  1178. k2=k1;
  1179. k1(pix(1,:))=1;
  1180. k2(pixe(pixx))=-1;
  1181. a=logical(cumsum(k1+k2));
  1182. try
  1183. so(a)=rpat;
  1184. catch
  1185. disp('astrrepx> this should NOT happen!')
  1186. disp('astrrepx> please, contact <us@neurol.unizh.ch>');
  1187. keyboard
  1188. end
  1189. if ~ischar(so)
  1190. so=reshape(so,sp.nr,sp.nc);
  1191. else
  1192. pat=char(pat);
  1193. end
  1194. sp.pato=pat;
  1195. sp.pix=pix;
  1196. sp.msg='ok';
  1197. return;
  1198. %--------------------------------------------------------------------------------
  1199. function lst=ini_lst(varargin)
  1200. lst.magic='FPARSER';
  1201. lst.ver='12-Dec-2005 09:26:17';
  1202. lst.time=datestr(clock);
  1203. lst.par.mos=version;
  1204. lst.par.rel=sscanf(version('-release'),'%d');
  1205. lst.par.opt.cflg=0; % input: command line
  1206. lst.par.opt.dflg=0; % show res at run-time
  1207. lst.tmpl=[];
  1208. if nargin > 1
  1209. if strmatch('-c',varargin,'exact')
  1210. lst.par.opt.cflg=1;
  1211. end
  1212. if strmatch('-d',varargin,'exact')
  1213. lst.par.opt.dflg=1;
  1214. end
  1215. end
  1216. return;
  1217. %--------------------------------------------------------------------------------