302 research outputs found

    Table driven prediction for recursive descent LL(k) parsers

    Get PDF
    Programming languages are typically described in BNF or some extension of BNF, and the process of converting these descriptions into parsers is performed by parser generators. Some of the parser generators that convert LL grammars into parsers construct them to use recursive descent that gives them context during execution. The context is provided by the execution stack as the parser descends into the grammar and this is what allows the full expressiveness of LL grammars. Table driven parsers can be generated instead but restrictions are placed on the LL grammars that can be accepted. The benefit of tables is that they facilitate a separation of syntax analysis and semantic code written by a language designer. They are also faster and they simplify language implementation and modification. This paper proposes the possibility of a hybrid system that makes decisions using tables but once decisions are made recursive descent is employed to maintain context. The benefits of each system are maintained, and the drawbacks are mitigated. Also discussed are the modifications made to an existing parser generator, oops (version 2), so that it accepts LL(k) grammars and builds parsers using this system as proof-of-concept

    Lily: A parser generator for LL(1) languages

    Get PDF
    This paper discusses the design and implementation of Lily, a language for generating LL(1) language parsers, originally designed by Dr. Thomas J. Sager of the University of Missouri--Rolla. A method for the automatic generation of parser tables is described which creates small, highly optimized tables, suitable for conversion to minimal perfect hash functions. An implementation of Lily is discussed with attention to design goals, implementation of parser table generation, and table optimization techniques. Proposals are made detailing possibilities for further augmentation of the system. Examples of Lily programs are given as well as a manual for the system

    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

    Operator precedence for data-dependent grammars

    Get PDF
    Constructing parsers based on declarative specification of operator precedence is a very old research topic, and there are various existing approaches. However, these approaches are either tied to a particular parsing technique, or cannot deal with all corner cases found in programming languages. In this paper we present an implementation of declarative specification of operator precedence for general parsing that (1) is independent of the underlying parsing algorithm, (2) does not require any grammar transformation that increases the size of the grammar, (3) preserves the shape of parse trees of the original, natural grammar, and (4) can deal with intricate cases of operator precedence found in functional programming languages such as OCaml. Our new approach to operator precedence is formulated using data-dependent grammars, which extend context-free grammars with arbitrary computation, variable binding and constraints. We implemented our approach using Iguana, a data-dependent parsing framework, and evaluated it by parsing Java and OCaml source files. The results show that our approach is practical for parsing programming languages with complicated operator precedence rules

    Practical LR Parser Generation

    Full text link
    Parsing is a fundamental building block in modern compilers, and for industrial programming languages, it is a surprisingly involved task. There are known approaches to generate parsers automatically, but the prevailing consensus is that automatic parser generation is not practical for real programming languages: LR/LALR parsers are considered to be far too restrictive in the grammars they support, and LR parsers are often considered too inefficient in practice. As a result, virtually all modern languages use recursive-descent parsers written by hand, a lengthy and error-prone process that dramatically increases the barrier to new programming language development. In this work we demonstrate that, contrary to the prevailing consensus, we can have the best of both worlds: for a very general, practical class of grammars -- a strict superset of Knuth's canonical LR -- we can generate parsers automatically, and the resulting parser code, as well as the generation procedure itself, is highly efficient. This advance relies on several new ideas, including novel automata optimization procedures; a new grammar transformation ("CPS"); per-symbol attributes; recursive-descent actions; and an extension of canonical LR parsing, which we refer to as XLR, which endows shift/reduce parsers with the power of bounded nondeterministic choice. With these ingredients, we can automatically generate efficient parsers for virtually all programming languages that are intuitively easy to parse -- a claim we support experimentally, by implementing the new algorithms in a new software tool called langcc, and running them on syntax specifications for Golang 1.17.8 and Python 3.9.12. The tool handles both languages automatically, and the generated code, when run on standard codebases, is 1.2x faster than the corresponding hand-written parser for Golang, and 4.3x faster than the CPython parser, respectively

    A New Approach to LL and LR Parsing

    Get PDF
    Cílem této práce je vytvořit nový efektivní způsob syntaktické analýzy propojením LL a LR přístupů. Pro demonstrační účely je zhotoven nový programovací jazyk podle vzoru programovacího jazyka PHP. Tento jazyk je rozdělen na části, kde pro každou část je použita ta nejvhodnejší ze zmíněných metod. Jednotlivé metody jsou zde podrobněji popsané v kontextu dvou typů přístupů. Jedním z nich je syntaktická analýza shora dolů a tím druhým opačná verze, syntaktická analýza zdola nahoru. Pro každou separovanou část je vytvořen samostatný syntaktický analyzátor. Táto práce poskytuje kompletní teoretický základ k sestrojení všech zde použitých syntaktických analyzátorů a rozkladových tabulek. Nakonec jsou sestrojené analyzátory společne propojeny, což je úspěšné zakončení praktické demonstrace naší metody. V závěru jsou diskutovány dosažené výsledky práce jako efektivnejší druh syntaktické analýzy, modularita přístupu a podobně. Je zde také diskutovaná použitelnost navržené metody za účelem zefektivnení vývoje a rychlosti překladu. Jako poslední jsou uvedeny náměty pro další výzkum v této oblasti.The aim of this thesis is to create a new effective parsing method via connection of LL and LR approaches. For demonstration purpose is made a new programming language according to the pattern of PHP. The language is separated into the sections and for constituent sections is chosen the most appropriate from the mentioned methods. For every section is created its own syntax analyser. The thesis provides a complete theoretical basis to construct every syntax analyser that has been used here. Finally, the syntax analysers are connected together and new method is practically presented. In conclusion, contributions of this work are discussed, such as the faster parser or the improved development. It also discusses usability of the designed method and suggestions for the next possible research in this area.

    A survey of compiler development aids

    Get PDF
    A theoretical background was established for the compilation process by dividing it into five phases and explaining the concepts and algorithms that underpin each. The five selected phases were lexical analysis, syntax analysis, semantic analysis, optimization, and code generation. Graph theoretical optimization techniques were presented, and approaches to code generation were described for both one-pass and multipass compilation environments. Following the initial tutorial sections, more than 20 tools that were developed to aid in the process of writing compilers were surveyed. Eight of the more recent compiler development aids were selected for special attention - SIMCMP/STAGE2, LANG-PAK, COGENT, XPL, AED, CWIC, LIS, and JOCIT. The impact of compiler development aids were assessed some of their shortcomings and some of the areas of research currently in progress were inspected

    Apt Compiler Toolkit User Manual

    Get PDF
    The Apt Compiler Toolkit was designed to address the need for structured, efficient, portable, and capable tools to prototype language translators and compilers. In the current release of the toolkit tools are available for the generation of scanners, parsers, and data structures. A robust library of functions is supplied with the toolkit which includes support for the scanner, the parser, abstract data types (which are commonly used in language translators/compilers), and string functions
    corecore