This preview shows pages 1–3. Sign up to view the full content.
This preview has intentionally blurred sections. Sign up to view the full version.
View Full Document
Unformatted text preview: 168 Declarative Programming Techniques read then I in I={Id S2 Sn} read(I) write then E in E={Expr S2 Sn} write(E) elseif {IsIdent T} then E S3 in S2= ´ := ´ S3 E={Expr S3 Sn} assign(T E) else S1=Sn raise error(S1) end end end The onetoken lookahead is put in T . With a case statement, the correct branch of the Stat grammar rule is found. Statement sequences (surrounded by begin – end ) are parsed by the procedure Sequence . This is a generic procedure that also handles comparison sequences, expression sequences, and term sequences. It is written as follows: fun {Sequence NonTerm Sep S1 Sn} X1 S2 T S3 in X1={NonTerm S1 S2} S2=TS3 if {Sep T} then X2 in X2={Sequence NonTerm Sep S3 Sn} T(X1 X2) % Dynamic record creation else S2=Sn X1 end end This takes two input functions, NonTerm , which is passed any nonterminal, and Sep , which detects the separator symbol in a sequence. Comparisons, expressions, and terms are parsed as follows with Sequence : fun {Comp S1 Sn} {Sequence Expr COP S1 Sn} end fun {Expr S1 Sn} {Sequence Term EOP S1 Sn} end fun {Term S1 Sn} {Sequence Fact TOP S1 Sn} end Each of these three functions has its corresponding function for detecting sepa rators: fun {COP Y} Y== ´ < ´ orelse Y== ´ > ´ orelse Y== ´ =< ´ orelse Y== ´ >= ´ orelse Y== ´ == ´ orelse Y== ´ != ´ Copyright c 20013 by P. Van Roy and S. Haridi. All rights reserved. 3.5 Time and space efficiency 169 end fun {EOP Y} Y== ´ + ´ orelse Y== ´ ´ end fun {TOP Y} Y== ´ * ´ orelse Y== ´ / ´ end Finally, factors and identifiers are parsed as follows: fun {Fact S1 Sn} TS2=S1 in if {IsInt T} orelse {IsIdent T} then S2=Sn T else E S2 S3 in S1= ´ ( ´ S2 E={Expr S2 S3} S3= ´ ) ´ Sn E end end fun {Id S1 Sn} X in S1=XSn true ={IsIdent X} X end fun {IsIdent X} {IsAtom X} end Integers are represented as builtin integer values and detected using the builtin IsInt function. This parsing technique works for grammars where onetoken lookahead is enough. Some grammars, called ambiguous grammars, require to look at more than one token to decide which grammar rule is needed. A simple way to parse them is with nondeterministic choice, as explained in Chapter 9. 3.5 Time and space efficiency Declarative programming is still programming; even though it has strong math ematical properties it still results in real programs that run on real computers. Therefore, it is important to think about computational efficiency. There are two parts to efficiency: execution time (e.g., in seconds) and memory usage (e.g., in bytes). We will show how to calculate both of these. 3.5.1 Execution time Using the kernel language and its semantics, we can calculate the execution time up to a constant factor . For example, for a mergesort algorithm we will be able to say that the execution time is proportional to n log n , given an input list of length n . The asymptotic time complexity of an algorithm is the tightest upper bound on its execution time as a function of the input size, up to a constant...
View
Full
Document
 Spring '11

Click to edit the document details