home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / lifeos2.zip / LIFE-1.02 / TESTS / LF / PREPARSE.LF < prev    next >
Text File  |  1996-06-04  |  13KB  |  569 lines

  1. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2. %                                                                             %
  3. % Translating grammars into LIFE                                              %
  4. %                                                                             %
  5. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6.  
  7. op( 1000, xfy, comma) ?
  8. op( 1200, xfy, -->) ?
  9. non_strict(-->) ?
  10.  
  11. my_project(A,B) -> B.A.
  12.  
  13.  
  14. (Lhs --> Rhs) :- R = compileRule( Lhs, Rhs), assert(R), fail ; succeed.
  15.  
  16. %
  17. % compileRule: translates the grammar rules into clauses
  18. %
  19.  
  20. non_strict(compileRule) ?
  21. compileRule( Lhs, Rhs) -> 
  22.     (compileSymbols( Lhs, false, false, Xs, Ys, _) :- 
  23.          compileSeq( Rhs, true,  false, Xs, Ys, _)).
  24.  
  25. %
  26. % compileSeq is used to translate a sequence of symbols of the grammar into a
  27. % sequence of literals.
  28. %
  29.  
  30. compileSeq( Symbols, FoldOk, InDisj, Xs, Ys, NewFoldOk) -> 
  31.     cond( Symbols :== @,
  32.           `varSymbol( Symbols, 0 => Xs, rest => Ys) 
  33.       | NewFoldOk = FoldOk,
  34.           compileSymbols( Symbols, FoldOk, InDisj, Xs, Ys, NewFoldOk)).
  35.  
  36. %
  37. % compileSymbols is used to translate non-variable symbols.
  38. %
  39.  
  40. % conjunction
  41.   compileSymbols( ( Symb, Autres), FoldOk, InDisj, Xs, Ys, NewFoldOk) ->
  42.     compileSeq( Symb,   FoldOk,      InDisj, Xs, Ys1, InterFoldOk) comma 
  43.         compileSeq( Autres, InterFoldOk, InDisj, Ys1, Ys, NewFoldOk).
  44.  
  45. % disjunction
  46.   compileSymbols( ( List1 ; List2), FoldOk, _, Xs, Ys, NewFoldOk) -> 
  47.     X | Z = compileSeq( List1, FoldOk, true, Xs, Ys, InterFoldOk1),
  48.             T = compileSeq( List2, FoldOk, true, Xs, Ys, InterFoldOk2),
  49.             NewFoldOk = InterFoldOk1 and InterFoldOk2,
  50.         X = `( Z ; T ), 
  51.         ! .
  52.                                    
  53. % terminals
  54.   compileSymbols( Terms: list, true, false, Xs, Ys, NewFoldOk) -> 
  55.     succeed | Xs = termSequence(Terms, Ys), NewFoldOk = true.
  56.   compileSymbols( Terms: list, FoldOk, _, Xs, Ys, NewFoldOk) -> 
  57.     Xs = termSequence(Terms, Ys) | NewFoldOk = FoldOk.
  58.  
  59. % cut
  60.   compileSymbols( !, FoldOk, false, Xs, Ys, NewFoldOk) -> 
  61.     ! | NewFoldOk = false, Xs = Ys.  
  62.   compileSymbols( !, FoldOk, true, Xs, Ys, NewFoldOk) -> 
  63.     Xs = Ys, ! | NewFoldOk = false.
  64.  
  65. % insertion of code
  66.  
  67.   compileSymbols( Term: #, FoldOk, false, Xs, Ys, NewFoldOk)  -> 
  68.     transLifeCode( Term) | Xs = Ys, NewFoldOk = false.
  69.   compileSymbols( Term: #, FoldOk, true, Xs, Ys, NewFoldOk)  -> 
  70.     Xs = Ys, transLifeCode( Term) | NewFoldOk = false.
  71.  
  72.  
  73. % non-terminals
  74.   compileSymbols(NonTerm, FoldOk, _, Xs, Ys, NewFoldOk)    -> 
  75.     NonTerm  | NonTerm = @( 0 => Xs, rest => Ys), NewFoldOk = FoldOk.
  76.  
  77.  
  78. %
  79. % Inserting Life code
  80. %
  81.  
  82. transLifeCode( L) -> transList( feats(L)).
  83.  
  84. feats(L) -> map( my_project( 2 => L), features(L)).
  85.  
  86. transList( []) ->  succeed.
  87. transList( [A|B]) -> A comma transList( B).
  88.  
  89. %
  90. % handling terminals
  91. %
  92.  
  93. termSequence( [], Ys)     -> Ys.
  94. termSequence( [T|Ts], Ys) -> [T|termSequence( Ts, Ys)].
  95.  
  96. %
  97. % This definition is used at run-time to evaluate variable symbols
  98. %
  99.  
  100. varSymbol( X:list, 0 => Xs, rest => Ys) -> 
  101.     Xs = termSequence( X, Ys). 
  102. varSymbol( X, 0 => Xs, rest => Ys) -> 
  103.     X | X = @( 0 => Xs, rest => Ys).
  104.  
  105.  
  106. %
  107. % getting rid of unnecessary succeed statements
  108. %
  109.  
  110. succeed comma A -> A .
  111. A comma succeed -> A .
  112. A comma B -> A , B.
  113.  
  114. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  115. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  116. setq(list_of_words,[]) ?
  117.  
  118. readf( File ) -> 
  119.     L 
  120.     |   ( open_in(File,S),
  121.       read_all(L1),
  122.       setq(list_of_words,L1),
  123.       close(S),
  124.       fail ;
  125.       L = list_of_words ).
  126.       
  127.  
  128. read_all( L) :-
  129.         get(X),
  130.         cond( X :=< end_of_file , 
  131.               L=[] ,
  132.               (read_all(Y), L = [X|Y])).
  133.  
  134. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  135. %
  136. % TOKENIZER FOR LIFE
  137. %
  138. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  139. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  140. %
  141. % tokenize(File,L) reads in the file F, and returns the list of tokens
  142. % encountered. No  error message is given in the present implementation.
  143. %
  144. % the tokens are of the following types:
  145. %    - variable(X) where X is the name of the variable;
  146. %    - construct(X) represents a constructor X. 
  147. %      The type of a constructor is a subsort of construct: numb, chaine, or
  148. %      atom. An atom may be a simple_atom or a quoted_atom. 
  149. %      X is usually a string, except in numb(X), where X is the actual value.
  150. %    - any syntactic object like "[" or "?"
  151. %
  152. %
  153. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  154. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  155. %
  156. % Types: those definitions are not useful here, but in the parser.
  157. %
  158. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  159.  
  160. simple_atom <| atom.
  161. quoted_atom <| atom.
  162.  
  163. atom <| construct.
  164. numb <| construct.
  165. chaine <| construct.
  166.  
  167. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  168. %
  169. % Program
  170. %
  171. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  172.  
  173.  
  174. tokenize(File,L) :- 
  175.         W = readf(File),
  176.     tokens(L,0 => W, rest => []).
  177.  
  178.  
  179. tokens(T) --> 
  180.     void_chars,
  181.     (
  182.         token(L),!,
  183.         tokens(Ls), 
  184.         #( T = [L|Ls]);
  185.         #( T = [])
  186.     )?
  187.  
  188.  
  189.  
  190. void_chars -->                                     % space, tab, return
  191.     [X],
  192.     #( X =:= 9 or X =:= 32 or X =:= 10, !), 
  193.     void_chars ?   
  194. void_chars -->                                     % commentaires
  195.     [37],!, 
  196.     comment_chars, 
  197.     void_chars ?
  198. void_chars --> [] ?
  199.  
  200. comment_chars --> [10], ! ?                     % un commentaire s'arrete avec
  201.                         % return.
  202. comment_chars --> [X], comment_chars ?
  203.  
  204.  
  205. token( 0 => []) :- !, fail.
  206. token(_A,rest => Rest,0 => _C) :-
  207.         realToken(_A,rest => Rest,0 => _C).
  208.     
  209.  
  210. realToken(T,rest => R,0 => W:[A|B]) ->
  211.     cond( A >= 48 and A =< 57,
  212.               ( 
  213.           number(N,0 => W,rest => R),
  214.           T = numb(N)
  215.           ),
  216.           cond( A >= 65 and A=< 90,
  217.                 (
  218.             variable(V, 0 => W,rest => R),
  219.             T = variable(V)
  220.             ),
  221.             cond( A >= 97 and A =< 122,
  222.                   ( 
  223.                   non_quoted_atom(SA,0 => W,rest => R),
  224.                   T = simple_atom(SA)
  225.               ),
  226.               str2psi(strcon("token",int2str(A)))
  227.                  & @(T,0 => W,rest  => R)))).
  228.  
  229. %
  230. %
  231. % variables
  232. %
  233.  
  234. token95( variable(X)) -->                        % _...
  235.     [_],
  236.     simple_atom_cars(Y), 
  237.     #((Y = "", ! ); X = strcon("_",Y)) ?                  
  238.  
  239. variable(X) -->                                  % M...
  240.     [Y], 
  241.     simple_atom_cars(Z), 
  242.     #( X = strcon(charac(Y),Z)) ?
  243.  
  244.  
  245. %
  246. %
  247. % syntactic objects
  248. %
  249. %
  250.  
  251. token40( "(") --> [_] ?
  252. token41( ")") --> [_] ?
  253. token44( ",") --> [_] ?
  254. token46( ".") --> [_] ?
  255. token59( ";") --> [_] ?
  256. token63( "?") --> [_] ?
  257. token91( "[") --> [_] ?
  258. token93( "]") --> [_] ?
  259. token123( "{") --> [_] ?
  260. token124( "|") --> [_] ?
  261. token125( "}") --> [_] ?
  262.  
  263. %
  264. %
  265. % constructors
  266. %
  267. %
  268.  
  269. %
  270. % @
  271. %
  272.  
  273. token64( simple_atom("@")) --> [_] ?
  274.  
  275. %
  276. % quote
  277. %
  278.  
  279. token96( simple_atom("`"),0 => [_|Rest],rest => Rest).
  280.  
  281. %
  282. % simple atoms
  283. %             
  284.  
  285. non_quoted_atom(X) --> 
  286.     [Y], 
  287.     simple_atom_cars(Z), 
  288.     #( X = strcon(charac(Y),Z)) ?
  289.  
  290. simple_atom_cars(Z) --> 
  291.     simple_atom_car(X), !,
  292.     simple_atom_cars(Y), 
  293.     #( Z = strcon(X,Y)) ?
  294. simple_atom_cars("") --> [] ?
  295.  
  296. simple_atom_car(X) --> 
  297.     [Y],  
  298.     #(    Y >= 48 and Y =< 57    % chiffre
  299.            or Y >= 65 and Y =< 90    % majuscule
  300.            or Y =:= 95               % underscore
  301.            or Y >= 97 and Y =< 122,  % minuscule
  302.        X = charac(Y))?
  303.  
  304. %
  305. % quoted atoms
  306. %
  307.  
  308. token39( quoted_atom(X)) --> 
  309.     [_],
  310.         quoted_atom_end(X) ?
  311.  
  312. quoted_atom_end(X) --> 
  313.     [39], !,
  314.     ( [39], !,quoted_atom_end(Y), X = strcon("'",Y) ; 
  315.           # ( X = "" )) ?
  316. quoted_atom_end(X) --> 
  317.     quoted_atom_car(Y),
  318.     quoted_atom_end(Z),
  319.     #(  X = strcon(Y,Z)) ?
  320.  
  321. quoted_atom_car(Y) -->
  322.     [X], #( Y = charac(X) ) ?
  323.  
  324.  
  325. %
  326. % Numbers
  327. %
  328.  
  329. number(X) --> 
  330.     digits(V1),
  331.     ( [46], digits(V2,length => L2), !;
  332.           #( V2 = 0, L2= 0) ),
  333.     ( [101], !,exponent(E) ;
  334.       #(E = 0) ),
  335.     #( X = (V1 + V2 * 10^(-L2)) * 10^(E)) ?
  336.  
  337. digits(V, length=>L) --> 
  338.     digit( V1), 
  339.     ( digits(V2, length=>L2),!,
  340.       #( L = L2+1, V = V1*10^L2 + V2) ;
  341.           #( V = V1, L = 1)) ?
  342.  
  343. sign(-1) --> [45],! ?
  344. sign(1)  --> [43],! ?
  345. sign(1)  --> [] ?
  346.  
  347. exponent(V) --> sign(S), digits(V1), #(V = S*V1) ?
  348.  
  349. digit(N)    --> [48+N], #(N =< 9 and N >= 0)  ?
  350.  
  351.  
  352. %
  353. % Strings
  354. %
  355.  
  356. token34(chaine(X)) --> 
  357.     [_],
  358.         car_chaine_end(X) ?
  359.  
  360. car_chaine_end(X) --> 
  361.     [34], !,
  362.     ( [34], !,car_chaine_end(Y), #(X = strcon("""",Y)) ; 
  363.           # ( X = "" )) ?
  364. car_chaine_end(X) --> 
  365.     car_chaine_car(Y),
  366.     car_chaine_end(Z),
  367.     #(  X = strcon(Y,Z)) ?
  368.  
  369. car_chaine_car(Y) -->
  370.     [X], #( Y = charac(X) ) ?
  371.  
  372.  
  373. %
  374. % op_atoms
  375. %
  376. op_atom_car(X) -->
  377.     [Y],
  378.     #( cond( Y >= 33,
  379.              cond(    Y =< 38 and Y =\= 34 or Y =:= 42 
  380.                    or Y =:= 43 or Y =:= 45 or Y =:= 47,
  381.                3 => cond( Y >= 58,
  382.                           cond( Y =< 62,
  383.                             Y =\= 59,
  384.                     Y =:= 92 or Y =:= 94 or Y=:= 126),
  385.                   fail)),
  386.              fail),
  387.            X = charac(Y)) ?
  388.  
  389. op_atom_cars(X) --> 
  390.     op_atom_car(Y),!, 
  391.     op_atom_cars(Z),
  392.     #(  X = strcon(Y,Z)) ?
  393. op_atom_cars("") -->
  394.     [] ?
  395.  
  396.  
  397. token33( simple_atom(X)) --> 
  398.     [_],
  399.     op_atom_cars(Z),
  400.     #(  X = strcon("!",Z)) ?
  401. token35( simple_atom(X)) --> 
  402.     [_],
  403.     op_atom_cars(Z),
  404.     #(  X = strcon("#",Z)) ?
  405. token36( simple_atom(X)) --> 
  406.     [_],
  407.     op_atom_cars(Z),
  408.     #(  X = strcon("$",Z)) ?
  409. token37( simple_atom(X)) --> 
  410.     [_],
  411.     op_atom_cars(Z),
  412.     #(  X = strcon("%",Z)) ?
  413. token38( simple_atom(X)) --> 
  414.     [_],
  415.     op_atom_cars(Z),
  416.     #(  X = strcon("&",Z)) ?
  417. token42( simple_atom(X)) --> 
  418.     [_],
  419.     op_atom_cars(Z),
  420.     #(  X = strcon("*",Z)) ?
  421. token43( simple_atom(X)) --> 
  422.     [_],
  423.     op_atom_cars(Z),
  424.     #(  X = strcon("+",Z)) ?
  425. token45( simple_atom(X)) --> 
  426.     [_],
  427.     op_atom_cars(Z),
  428.     #(  X = strcon("-",Z)) ?
  429. token47( simple_atom(X)) --> 
  430.     [_],
  431.     op_atom_cars(Z),
  432.     #(  X = strcon("/",Z)) ?
  433. token58( simple_atom(X)) --> 
  434.     [_],
  435.     op_atom_cars(Z),
  436.     #(  X = strcon(":",Z)) ?
  437. token60( simple_atom(X)) --> 
  438.     [_],
  439.     op_atom_cars(Z),
  440.     #(  X = strcon("<",Z)) ?
  441. token61( simple_atom(X)) --> 
  442.     [_],
  443.     op_atom_cars(Z),
  444.     #(  X = strcon("=",Z)) ?
  445. token62( simple_atom(X)) --> 
  446.     [_],
  447.     op_atom_cars(Z),
  448.     #(  X = strcon(">",Z)) ?
  449. token92( simple_atom(X)) --> 
  450.     [_],
  451.     op_atom_cars(Z),
  452.     #(  X = strcon("\",Z)) ?
  453. token94( simple_atom(X)) --> 
  454.     [_],
  455.     op_atom_cars(Z),
  456.     #(  X = strcon("^",Z)) ?
  457. token126( simple_atom(X)) --> 
  458.     [_],
  459.     op_atom_cars(Z),
  460.     #(  X = strcon("~",Z)) ?
  461.  
  462.  
  463. charac(Z) -> psi2str(chr(Z)) .
  464. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  465. %
  466. % GRAMMAR FOR ARITHMETIC EXPRESSIONS WITH DYNAMIC OPERATORS
  467. %
  468. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  469.  
  470.  
  471. %
  472. % list_express recognizes lists of expressions separated by dots
  473. %
  474.  
  475. list_express( list=>[A|B]) --> 
  476.     expr( tree => A, rest => L),
  477.     ["."], !,
  478.     list_express( list => B ) ?
  479.  
  480. list_express( list => []) --> ! ?
  481. list_express( list => [error]).
  482.     
  483. %
  484. % a term is a number or a variable (use the Life tokenizer)
  485. %
  486.  
  487.  
  488. term( tree => X) --> [numb(X)],!  ?
  489. term( tree => X) --> [variable(X)] ?
  490.  
  491. %
  492. % expressions
  493. %
  494.  
  495. expr( tree => Tree) --> ["("], !, expr( tree => Tree) , [")"] ?
  496. expr( max => Max, tree => Tree)    -->
  497.     start_expr( M, max => Max, tree => T),
  498.     end_expr( M, max => Max, left => T, tree => Tree) ?
  499.  
  500.  
  501. start_expr( 0, tree => T) --> term( tree => T), ! ?
  502. start_expr( M, max => Max, tree => Tree) -->
  503.     oper( prefix, M, Name, right_strict => S),
  504.     #(M =< Max),!,
  505.     expr( max => preced(S,M), tree => T),
  506.     #( Tree = Name&@(T) ) ?
  507.  
  508. end_expr( MLeft, max => Max, left => L, tree => T)  --> 
  509.     sub_expr( M, Mleft, max => Max, left => L, tree => T1),!,
  510.     end_expr( M, max => Max, left => T1, tree => T) ?
  511. end_expr( left => T, tree => T) --> [] ?
  512.  
  513. sub_expr(M, Mleft, max => Max, left => L, tree => Tree) --> 
  514.     oper( Type, M, Name, left_strict => LS, right_strict => RS),
  515.     #( M =< Max,
  516.        Mleft =< preced(LS,M)),
  517.     (
  518.         #( Type = postfix,!,
  519.            Tree = Name&@(L) )
  520.     ;
  521.         #( Type = infix),
  522.         expr( max => preced(RS,M), tree => R),
  523.         #( Tree = Name&@(L,R)) 
  524.     )?
  525.  
  526.  
  527. %
  528. % operators: any Life operator may be used
  529. %
  530.  
  531. oper( Type, P, Name, 
  532.       left_strict => LS, 
  533.       right_strict => RS) -->
  534.     [atom(Name)],
  535.     # (
  536.          op_member(ops,Precedence,T,Name),
  537.          P = Precedence,
  538.          cond( T :== xfx,
  539.                ( LS = true, RS = true, Type = infix),
  540.          cond( T :== xfy,
  541.                ( LS = true, RS = false,  Type = infix),         
  542.          cond( T :== yfx,
  543.                ( LS = false,  RS = true, Type = infix),
  544.              cond( T :== fx,
  545.                ( RS = true,  Type = prefix),
  546.          cond( T :== fy,,
  547.                ( RS = false, Type = prefix), 
  548.          cond( T :== xf,
  549.                ( LS = true,  Type = postfix),
  550.          cond( T :== yf,,
  551.                ( LS = false, Type = postfix))))))))
  552.           ) ?
  553.  
  554. preced(true,M) -> M-1.
  555. preced(false,M) -> M.
  556.  
  557. op_member([op(P1,T1,Oper)|OOps],Precedence,Type,Name) :-
  558.     (
  559.         Name = psi2str(`Oper), Precedence = P1, Type = T1;
  560.         op_member(OOps, Precedence,Type,Name)
  561.     ).
  562.  
  563.     
  564.  
  565.  
  566.  
  567.  
  568.