167 research outputs found

    Design, Implementation, Use, and Evaluation of Ox: An Attribute- Grammar Compiling System based on Yacc, Lex, and C

    Get PDF
    Ox generalizes the function of Yacc in the way that attribute grammars generalize context-free grammars. Ordinary Yacc and Lex specifications may be augmented with definitions of synthesized and inherited attributes written in C syntax. From these specifications, Ox generates a program that builds and decorates attributed parse trees. Ox accepts a most general class of attribute grammars. The user may specify postdecoration traversals for easy ordering of side effects such as code generation. Ox handles the tedious and error-prone details of writing code for parse-tree management, so its use eases problems of security and maintainability associated with that aspect of translator development. The translators generated by Ox use internal memory management that is often much faster than the common technique of calling malloc once for each parse-tree node. Ox is a Yacc/Lex/C preprocessor, and is designed to bring attribute grammars closer to the mainstream of Unix-based language development. Ox inherits all of the familiar syntax and semantics of Yacc, Lex, and C. It is relatively easy to convert programs between Ox code and pure Yacc/Lex/C code. Ox has been used to build a compiler for a small (eighty grammar rules) block-structured imperative programming language. This paper considers Ox\u27s design, implementation, and use, evaluates the performance of Ox-generated evaluators, and makes recommendations for improvements in Ox

    The formal power of one-visit attribute grammars

    Get PDF
    An attribute grammar is one-visit if the attributes can be evaluated by walking through the derivation tree in such a way that each subtree is visited at most once. One-visit (1V) attribute grammars are compared with one-pass left-to-right (L) attribute grammars and with attribute grammars having only one synthesized attribute (1S).\ud \ud Every 1S attribute grammar can be made one-visit. One-visit attribute grammars are simply permutations of L attribute grammars; thus the classes of output sets of 1V and L attribute grammars coincide, and similarly for 1S and L-1S attribute grammars. In case all attribute values are trees, the translation realized by a 1V attribute grammar is the composition of the translation realized by a 1S attribute grammar with a deterministic top-down tree transduction, and vice versa; thus, using a result of Duske e.a., the class of output languages of 1V (or L) attribute grammars is the image of the class of IO macro tree languages under all deterministic top-down tree transductions

    Simple multi-visit attribute grammars

    Get PDF
    An attribute grammar is simple multi-visit if each attribute of a nonterminal has a fixed visit-number associated with it such that, during attribute evaluation, the attributes of a node which have visit-number j are computed at the jth visit to the node. An attribute grammar is l-ordered if for each nonterminal a linear order of its attributes exists such that the attributes of a node can always be evaluated in that order (cf. the work of Kastens).\ud \ud An attribute grammar is simple multi-visit if and only if it is l-ordered. Every noncircular attribute grammar can be transformed into an equivalent simple multi-visit attribute grammar which uses the same semantic operations.\ud \ud For a given distribution of visit-numbers over the attributes, it can be decided in polynomial time whether the attributes can be evaluated according to these visit-numbers. The problem whether an attribute grammar is simple multi-visit is NP-complete

    User Manual for Ox: An Attribute-Grammar Compiling System based on Yacc, Lex, and C

    Get PDF
    Ox generalizes the function of Yacc in the way that attribute grammars generalize context-free grammars. Ordinary Yacc and Lex specifications may be augmented with definitions of synthesized and inherited attributes written in C syntax. From these specifications, Ox generates a program that builds and decorates attributed parse trees. Ox accepts a most general class of attribute grammars. The user may specify postdecoration traversals for easy ordering of side effects such as code generation. Ox handles the tedious and error-prone details of writing code for parse-tree management, so its use eases problems of security and maintainability associated with that aspect of translator development. The translators generated by Ox use internal memory management that is often much faster than the common technique of calling malloc once for each parse-tree node. Ox is a Yacc/Lex/C preprocessor, and is designed to bring attribute grammars closer to the mainstream of Unix-based language development. Ox inherits all of the familiar syntax and semantics of Yacc, Lex, and C. It is relatively easy to convert programs between Ox code and pure Yacc/Lex/C code. Ox has been used to build a compiler for a small (eighty grammar rules) block-structured imperative programming language. This document is the main reference for using Ox

    Reliably composable language extensions

    Get PDF
    University of Minnesota Ph.D. dissertation. May 2017. Major: Computer Science. Advisor: Eric Van Wyk. 1 computer file (PDF); x, 300 pages.Many programming tasks are dramatically simpler when an appropriate domain-specific language can be used to accomplish them. These languages offer a variety of potential advantages, including programming at a higher level of abstraction, custom analyses specific to the problem domain, and the ability to generate very efficient code. But they also suffer many disadvantages as a result of their implementation techniques. Fully separate languages (such as YACC, or SQL) are quite flexible, but these are distinct monolithic entities and thus we are unable to draw on the features of several in combination to accomplish a single task. That is, we cannot compose their domain-specific features. "Embedded" DSLs (such as parsing combinators) accomplish something like a different language, but are actually implemented simply as libraries within a flexible host language. This approach allows different libraries to be imported and used together, enabling composition, but it is limited in analysis and translation capabilities by the host language they are embedded within. A promising combination of these two approaches is to allow a host language to be directly extended with new features (syntactic and semantic.) However, while there are plausible ways to attempt to compose language extensions, they can easily fail, making this approach unreliable. Previous methods of assuring reliable composition impose onerous restrictions, such as throwing out entirely the ability to introduce new analysis. This thesis introduces reliably composable language extensions as a technique for the implementation of DSLs. This technique preserves most of the advantages of both separate and "embedded" DSLs. Unlike many prior approaches to language extension, this technique ensures composition of multiple language extensions will succeed, and preserves strong properties about the behavior of the resulting composed compiler. We define an analysis on language extensions that guarantees the composition of several extensions will be well-defined, and we further define a set of testable properties that ensure the resulting compiler will behave as expected, along with a principle that assigns "blame" for bugs that may ultimately appear as a result of composition. Finally, to concretely compare our approach to our original goals for reliably composable language extension, we use these techniques to develop an extensible C compiler front-end, together with several example composable language extensions

    Generating incremental attribute evaluators

    Get PDF
    In onze maatschappij wordt tegenwoordig veel met software, dat wil zeggen com- puterprogramma's, gewerkt. Denk daarbij niet alleen aan tekstverwerkers, maar ook aan software in geldautomaten, videorecorders en het administratiesysteem van de scus. Software moet geschreven worden. Programmeurs schrijven software in zoge- heten hogere programmeertalen, waarvan Pascal, C, Basic, Cobol en Fortran de bekenste zijn. Zulke programmeertalen nemen tijdrovende, saaie en administratieve taken verbonden aan het programmeren, uit handen. Echter, computers \begrijpen" hogere programmeertalen niet, zij moeten ge?n- strueerd worden in een zogeheten machinetaal. Om een hogere programmeertaal naar machinetaal te vertalen zijn er speciale computerprogramma's in omloop, zogeheten compilers. Met andere woorden, compilers vormen een vitale schakel in het productieproces van software. Een compiler zet een zogeheten bronprogramma, geschreven in een specieke hogere programmeertaal, om naar een zogeheten doel programma in een specieke machinetaal. Men spreek dan bijvoorbeeld ook van een \Pascal compiler voor een DOS computer". De kwaliteit van het doelprogramma is niet alleen afhankelijk van de kwaliteit van het bronprogramma, maar ook van de kwaliteit van de gebruikte compiler. Compilers zijn grote, ingewikkelde programma's, die ook geschreven moeten worden. Dit proces wordt ondersteund door compiler-generatoren. Tijdens mijn?192 Samenvatting boter melk 30 10 2,50 1,25 item aantal prijs a b c d 1 23 4 b2 b3 x c2 c3 x b4+c4 b2+c2 boter melk 30 10 2,50 1,25 25,00 52,50 item aantal prijs a b c d 1 23 4 40 77,50 a. Invoer b. Uitvoer Figuur 2. Een rekenblad voor de melkboer vierjarig onderzoek heb ik een compiler-generator gemaakt. Een compiler-generator is een computerprogramma dat, na invoer van een minutieuze beschrijving van een hogere programmeertaal en de gewenste machinetaal, een compiler voor die programmeertaal genereert. De voordelen van een compiler-generator zijn legio. Elke verbetering aan de generator heeft tot gevolg dat elke gegenereerde compiler verbetert. Bovendien worden de produktiekosten en de produktietijd verbonden aan het maken van een compiler, aanzienlijk verminderd. Immers, in plaats van een compiler voor een hogere programmeertaal hoeft alleen nog maar een beschrijving van die hogere programmeertaal geschreven te worden. Een student informatica kan in een paar maanden tijd een compiler genereren, terwijl een groep beroeps programmeurs daar eerder vele maanden tot jaren mee bezig is. Incrementele berekeningen De kracht van de compilers gegenereert door dedoor mij ontwikkelde generator is voornamelijk gelegen in het feit dat ze incrementeel zijn. Dat betekent dat na een kleine verandering in het bronprogramma, de compiler de corresponderende veran- deringen in het doelprogramma aanbrengt|dit in tegenstelling tot het simpelweg vertalen van het gehele (gewijzigde) bronprogramma. Dit laatste zou veel meer tijd zou kosten. Wat een incrementele berekening is wordt elegant ge?llustreerd aan de hand van een compiler-verwante toepassing: een rekenblad of spreadsheet. Een rekenblad bestaat uit cellen in een rechthoekig patroon, zie Figuur 2a. Elke cel wordt aangeduid met een letter-cijfer combinatie. Zo wordt de cel links-boven aangeduid met a1. Een cel kan tekst, getallen of formules bevatten: cel a1 bevat de tekst `item', cel b2 bevat het getal 10 en cel b4 bevat de formule b2 b3. Een rekenblad-evaluator berekent de waarde van de cellen waar formules in staan. Dus, na invoer van het rekenblad in Figuur 2a wordt de uitvoer van Figuur 2b geproduceerd. Stel dat we een verandering aanbrengen in het rekenblad; we voeren een zogeheten edit-operatie uit. We verlagen het getal in cel b2 van 10 naar 9, zie?Informele inleiding 193 boter melk 30 2,50 1,25 item aantal prijs a b c d 1 23 4 b2 b3 x c2 c3 x b4+c4 b2+c2 9 boter melk 30 2,50 1,25 52,50 item aantal prijs a b c d 1 23 4 9 22,50 75,00 39 a. Wijziging in de invoer b. Zuinige herberekening Figuur 3. Wijziging aan een rekenblad Figuur 3a. De rekenblad-evaluator zou alle cellen met formules opnieuw kunnen uitrekenen. Een incrementele evaluator berekent alleen de grijze cellen in Figuur 3b. In dit geval spaart dat de berekening van cel c4 uit. Het is overigens niet eenvoudig om in te zien welke cellen herberekend moeten worden. Om dat te bepalen stelt de rekenblad-evaluator een zogeheten graaf op die de cel-afhankelijkheden weergeeft. Een knoop in de graaf representeert een cel. Er loopt een pijl van knoop b2 naar knoopb4 omdat de formule van cel b4 refereert aan cel b2. Zo'n pijl impliceert dat cel b4 na celb2 uitgerekend moet worden. Bij een incrementele evaluatie moet elke cel wiens knoop in de graaf een opvolger is van b2, herberekend worden, tenzij veranderingen eerder uitdoven. Als voorbeeld van dat laatste, beschouwen we de volgende verandering: de prijs van boter gaat naar 0,25 en de hoeveelheid boter naar 100. In dat geval blijft de waarde van cel b4 25,00 zodat d4 niet herberekend hoeft te worden. Grafen spelen b3 b2 c2 c3 c4 d2 b4 d4 bij incrementele berekeningen een belangrijke rol. Ze komen dan ook veelvuldig in dit proefschrift voor. Compilers worden ook vaak toegepast op slechts weinig veranderde invoer. Hoe vaak wordt een computerprogramma niet gecompileerd om er vervolgens achter te komen dat er een kleine fout in staat? Het is daarom jammer dat er nog zo weinig i:=1 had natuurlijk i:=0 moeten zijn. incrementele compilers zijn. Taal-specieke editors Een editor is een computerprogramma waarmee gegevens in een computer in- gevoerd kunnen worden. Bovendien kunnen met een editor bestaande gegevens gewijzigd worden. Meestal verstaat men onder een editor een algemeen programma waarmee gegevens voor uiteenlopende applicaties (toepassings programma's zoals compilers, rekenbladen, tekstverwerkers) ingevoerd kunnen worden. Een applicatie-specieke editor is een invoer-en-wijzig programma dat \kennis" heeft van een applicatie. Alle huis-tuin-en-keuken applicaties zoals tekstverwerkers L a T E X is geen huis-tuin- en-keuken applicatie. en rekenbladen zijn uitgerust met applicatie-specieke editors. Het grootste voor- deel van zulke editors is dat ze de gebruiker kunnen sturen: er kan geen al te grote onzin in worden gevoerd.?194 Samenvatting Compilers zouden ook uitgerust kunnen worden met een brontaal-specieke editor. Dat is met name interessant als er een incrementele compiler beschikbaar is die tijdens het intypen van het bronprogramma voortdurend het bijbehorende doelprogramma berekend. Zulke systemen zouden de arbeidsproduktiviteit van programmeurs enorm verhogen. Immers, fouten in het bronprogramma worden direct als zodanig herkend door het system, en meegedeeld aan de gebruiker. Het grootste voordeel is echter dat de editor \ondervraagd" kan worden over bepaalde kenmerken van het bronprogramma. Voor ingewijden: als de editor constateert dat i:=1 incorrect is omdat i niet gedeclareerd is kan het een menu aanbieden met alle integer variabelen in de huidige scoop en een optie om de declaratie i:integer toe te voegen aan de declaraties. Kort overzicht Dit proefschrift beschrijft de generatie van incrementele compilers, met name als onderdeel van een taal-specieke \language based" editor. Omdat we uitgaan van een taal-specieke editor, kunnen we het ontleed- traject (lexical scanning en parsing ) overslaan: de editor onderhoudt een boom- representatie van het ingevoerde programma. Dat betekent dat compileren niets De titel: Generating incremental attribute evaluators. anders is dan het attribueren van de boom; de compiler is een (incrementele) attribute evaluator. Het formalisme waarmee we bomen en attributen beschrijven is het attribuut grammatica formalisme. We geven twee methodes om incrementele attribuut evaluatoren te construeren. De eerste methode is een bestaande: visit-sequences sturen boom decoratie. De tweede methode is nieuw: visit-sequences worden afgebeeld op visit-functies die gecached worden om incrementeel gedrag te verkrijgen. Een complicatie bij deze aanpak vormen zogeheten intra-visit-dependencies. Om dat probleem op te lossen worden bindingen ge?ntroduceerd. Visit-functies zijn functies zonder zij-eecten. Dit opent de mogelijkheid tot allerhanden optimalizaties. Aan de orde komen splitting, elimination, unication, folding, normalization en untyping. We bespreken hoe visit-sequences berekend worden aan de hand van een gram- matica. We wijzigen Kastens' ordered scheduling op twee vlakken. Om te beginnen voeren we dat grafen in (in stap 4) waardoor een grotere klasse van gramatica's geaccepteerd wordt. Ten tweede voeren we een nieuw orderings algorithme in (chained scheduling ) dat visit-sequences berekent die beter geschikt zijn voor omzetting naar visit-functies. Een groot deel van het onderzoek heeft zich toegespitst op de haalbaarheid van een functionele aanpak: we hebben een generator geschreven. De gegenereerde evaluatoren zijn eenvoudig, elegant en robuust. Bovenal zijn ze snel. De generator is onder andere gebruikt om een deel van zichzelf te genereren

    Symbol–Relation Grammars: A Formalism for Graphical Languages

    Get PDF
    AbstractA common approach to the formal description of pictorial and visual languages makes use of formal grammars and rewriting mechanisms. The present paper is concerned with the formalism of Symbol–Relation Grammars (SR grammars, for short). Each sentence in an SR language is composed of a set of symbol occurrences representing visual elementary objects, which are related through a set of binary relational items. The main feature of SR grammars is the uniform way they use context-free productions to rewrite symbol occurrences as well as relation items. The clearness and uniformity of the derivation process for SR grammars allow the extension of well-established techniques of syntactic and semantic analysis to the case of SR grammars. The paper provides an accurate analysis of the derivation mechanism and the expressive power of the SR formalism. This is necessary to fully exploit the capabilities of the model. The most meaningful features of SR grammars as well as their generative power are compared with those of well-known graph grammar families. In spite of their structural simplicity, variations of SR grammars have a generative power comparable with that of expressive classes of graph grammars, such as the edNCE and the N-edNCE classes

    The productivity of polymorphic stream equations and the composition of circular traversals

    Get PDF
    This thesis has two independent parts concerned with different aspects of laziness in functional programs. The first part is a theoretical study of productivity for very restricted stream programs. In the second part we define a programming abstraction over a recursive pattern for defining circular traversals modularly. Productivity is in general undecidable. By restricting ourselves to mutually recursive polymorphic stream equations having only three basic operations, namely "head", "tail", and "cons", we aim to prove interesting properties about productivity. Still undecidable for this restricted class of programs, productivity of polymorphic stream functions is equivalent to the totality of their indexing function, which characterise their behaviour in terms of operations on indices. We prove that our equations generate all possible polymorphic stream functions, and therefore their indexing functions are all the computable functions, whose totality problem is indeed undecidable. We then further restrict our language by reducing the numbers of equations and parameters, but despite those constraints the equations retain their expressiveness. In the end we establish that even two non-mutually recursive equations on unary stream functions are undecidable with complexity Π20Π_2^0. However, the productivity of a single unary equation is decidable. Circular traversals have been used in the eighties as an optimisation to combine multiple traversals in a single traversal. In particular they provide more opportunities for applying deforestation techniques since it is the case that an intermediate datastructure can only be eliminated if it is consumed only once. Another use of circular programs is in the implementation of attribute grammars in lazy functional languages. There is a systematic transformation to define a circular traversal equivalent to multiple traversals. Programming with this technique is not modular since the individual traversals are merged together. Some tools exist to transform programs automatically and attribute grammars have been suggested as a way to describe the circular traversals modularly. Going to the root of the problem, we identify a recursive pattern that allows us to define circular programs modularly in a functional style. We give two successive implementations, the first one is based on algebras and has limited scope: not all circular traversals can be defined this way. We show that the recursive scheme underlying attribute grammars computation rules is essential to combine circular programs. We implement a generic recursive operation on a novel attribute grammar abstraction, using containers as a parametric generic representation of recursive datatypes. The abstraction makes attribute grammars first-class objects. Such a strongly typed implementation is novel and make it possible to implement a high level embedded language for defining attribute grammars, with many interesting new features promoting modularity

    Functional programming, program transformations and compiler construction

    Get PDF
    Dit proefschrift handelt over het ontwerp van de compilergenerator Elegant. Een compiler generator is een computer programma dat vanuit een speci??catie een compiler kan genereren. Een compiler is een computer programma dat een gestructureerde invoertekst kan vertalen in een uitvoertekst. Een compiler generator is zelf een compiler welke de speci??catie vertaalt in de programmatekst van de gegenereerde compiler. Dit heeft het mogelijk gemaakt om Elegant met zichzelf te genereren. Van een compilergenerator wordt verlangd dat deze een krachtig speci??catie formalisme vertaalt in een eÆci??ent programma, een eis waar Elegant aan voldoet. Een compiler bestaat uit een aantal onderdelen, te weten een scanner, een parser, een attribuutevaluator, een optimalisator en een codegenerator. Deze onderdelen kunnen door het Elegant systeem geneneerd worden, ieder uit een aparte speci??catie, met uitzondering van de parser en attribuutevaluator, welke gezamenlijk worden beschreven in de vorm van een zogenaamde attribuutgrammatica. De scanner wordt gegenereerd met behulp van een scannergenerator en heeft tot taak de invoertekst te splitsen in een rij symbolen. Deze rij symbolen kan vervolgens ontleed worden door een parser. Daarna berekent de attribuutevaluator eigenschappen van de invoertekst in de vorm van zogenaamde attributen. De attributenwaarden vormen een datastructuur. De vorm van deze datastructuur wordt gede??nieerd met behulp van typeringsregels in de Elegant programmeertaal. De optimalisator en codegenerator voeren operaties op deze datastructuur uit welke eveneens beschreven worden in de Elegant programmeertaal. Dit proefschrift beschrijft de invloed die functionele programmeertalen hebben gehad op het ontwerp van Elegant. Functionele talen zijn programmeertalen met als belangrijkste eigenschap dat functies een centrale rol vervullen. Functies kunnen worden samengesteld tot nieuwe functies, ze kunnen worden doorgegeven aan functies en worden opgeleverd als functieresultaat. Daarnaast staan functionele talen niet toe dat de waarde van een variable wordt gewijzigd, het zogenaamde nevene??ect, in tegenstelling tot imperatieve talen die zo'n nevene??ect wel toestaan. Deze laatste beperking maakt het mogelijk om met behulp van algebra??ische regels een functioneel programma te herschrijven in een ander functioneel programma met dezelfde betekenis. Dit herschrijfproces wordt ook wel progammatransformatie genoemd. De invloed van functionele talen op Elegant omvat: ?? Het beschrijven van ontleedalgorithmen als functionele programma's. Traditioneel worden ontleedalgorithmen beschreven met behulp van de theorie van stapelautomaten. In hoofdstuk 3 wordt aangetoond dat deze theorie niet nodig is. Met behulp van programmatransformaties zijn vele uit de literauur bekende ontleedalgorithmen af te leiden en worden ook nieuwe ontleedalgorithmen gevonden. Deze aanpak maakt het bovendien mogelijk om de vele verschillende ontleedalgorithmen met elkaar te combineren. ?? De evaluatie van attributen volgens de regels van een attribuutgrammatica blijkt eveneens goed te kunnen worden beschreven met behulp van functionele talen. Traditioneel bouwt een ontleedalgorithme tijdens het ontleden een zogenaamde ontleedboom op. Deze ontleedboom beschrijft de structuur van de invoertekst. Daarna wordt deze ontleedboom geanalyseerd en worden eigenschappen ervan in de vorm van attributen berekend. In hoofdstuk 4 van het proefschrift wordt aangetoond dat het niet nodig is de ontleedboom te construeren. In plaats daarvan is het mogelijk om tijdens het ontleden functies die attributen kunnen berekenen samen te stellen tot nieuwe functies. Uiteindelijk wordt er zo ??e??en functie geconstrueerd voor een gehele invoertekst. Deze functie wordt vervolgens gebruikt om de attribuutwaarden te berekenen. Voor de uitvoering van deze functie is het noodzakelijk gebruik te maken van zogenaamde "luie evaluatie". Dit is een mechanisme dat attribuutwaarden slechts dan berekent wanneer deze werkelijk noodzakelijk zijn. Dit verklaart de naam Elegant, welke een acroniem is voor "Exploiting Lazy Evaluation for the Grammar Attributes of Non- Terminals". ?? Scanners worden traditioneel gespeci??ceerd met behulp van zogenaamde reguliere expressies. Deze reguliere expressies kunnen worden afgebeeld op een eindige automaat. Met behulp van deze automaat kan de invoertekst worden geanalyseerd en gesplitst in symbolen. In hoofdstuk 5 wordt uiteengezet hoe functionele talen het mogelijk maken om scanneralgorithmen te construeren zonder gebruik te maken van automatentheorie. Door een reguliere expressie af te beelden op een functie en de functies voor de onderdelen van samengestelde reguliere expressies samen te stellen tot nieuwe functies kan een scannerfunctie geconstrueerd worden. Door gebruik te maken van programmatransformaties kan deze scanner deterministisch worden gemaakt en minimaal worden gehouden. ?? Het typeringssysteem van Elegant wordt beschreven in hoodstuk 6 en vormt een combinatie van systemen die in functionele en imperatieve talen worden gevonden. Functionele typeringssystemen omvatten typen welke bestaan uit een aantal varianten. Elk van deze varianten bestaat uit een aantal waarden. Bij een dergelijk typeringssysteem wordt een functie gede??ni??eerd door middel van een aantal deeelfuncties. Elke deelfunctie kan met behulp van zogenaamde patronen beschrijven voor welke van de varianten hij gede??ni??eerd is. Het blijkt dat imperatieve typesystemen welke subtypering mogelijk maken een generalisatie zijn van functionele typesystemen. In deze generalisatie kan een patroon worden opgevat als een subtype en een deelfunctie als een parti??ele functie. Het Elegant typesystemen maakt deze vorm van typering en functiebeschrijving mogelijk. Bij toepassing van een functie wordt de bijbehorende deelfunctie geselecteerd door de patronen te passen met de waarden van de actuele functieargumenten. In dit proefschrift wordt een eÆci??ent algorithme voor dit patroonpassen met behulp van programmatransformaties afgeleid uit de de??nitie van patronen. Het Elegant typeringssystemen bevat ook typen voor de modellering van luie evaluatie. De aanwezigheid van nevene??ekten maakt het mogelijk om drie verschillende luie typen te onderscheiden, welke verschillen in de wijze waarop de waarde van een lui object stabiliseert. ?? In hoofdstuk 7 wordt aangetoond dat de regels uit een attribuutgrammatica ook kunnen worden gebruikt om eigenschappen van een datastructuur te berekenen in plaats van eigenschappen van een invoertekst. Elegant biedt de mogelijkheid om zulke attribuutregels te gebruiken voor dit doel. ?? In hoofdstuk 8 tenslotte worden de Elegant programmeertaal en de eÆci??entie van de Elegant vertaler en door Elegant gegenereerde vertalers ge??evalueerd. Het blijkt dat de imperatieve Elegant programmeertaal dankzij abstractie mechanismen uit functionele talen een zeer rijke en krachtige taal is. Daarnaast zijn zowel Elegant zelf als de door Elegant gegenereerde vertalers van hoge eÆci??entie en blijken geschikt voor het maken van compilers voor professionele toepassingen
    • …
    corecore