From 2f5e40a4607b15ef17190d43fe6da24bc65c035b Mon Sep 17 00:00:00 2001 From: David Beazley Date: Wed, 14 Sep 2016 15:27:54 -0500 Subject: [PATCH] Doc update --- README.md | 2 +- docs/index.rst | 170 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 164 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index d1c51fe..886255a 100644 --- a/README.md +++ b/README.md @@ -177,7 +177,7 @@ expressions and store variables: Documentation ============= -Further documentation can be found in the docs directory. +Further documentation can be found at https://sly.readthedocs.io/en/latest Resources ========= diff --git a/docs/index.rst b/docs/index.rst index d80a619..63c8405 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -3,20 +3,176 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -Welcome to sly's documentation! -=============================== +SLY (Sly Lex Yacc) +================== + +THIS IS A WORK IN PROGRESS. NO OFFICIAL RELEASE HAS BEEN MADE. +USE AT YOUR OWN RISK. + +Requirements +============ + +SLY requires the use of Python 3.5 or greater. Older versions +of Python are not supported. + +Overview +======== + +SLY is a 100% Python implementation of the lex and yacc tools +commonly used to write parsers and compilers. Parsing is +based on the same LALR(1) algorithm used by many yacc tools. +Here are a few notable features: + + - SLY provides *very* extensive error reporting and diagnostic + information to assist in parser construction. The original + implementation was developed for instructional purposes. As + a result, the system tries to identify the most common types + of errors made by novice users. + + - SLY provides full support for empty productions, error recovery, + precedence specifiers, and moderately ambiguous grammars. + + - SLY uses various Python metaprogramming features to specify + lexers and parsers. There are no generated files or extra + steps involved. You simply write Python code and run it. + + - SLY can be used to build parsers for "real" programming languages. + Although it is not ultra-fast due to its Python implementation, + SLY can be used to parse grammars consisting of several hundred + rules (as might be found for a language like C). + +SLY originates from the PLY project (http://www.dabeaz.com/ply/index.html). +However, it's been modernized a bit. In fact, don't expect any code +previously written for PLY to work. That said, most of the things +that were possible in PLY are also possible in SLY. + +An Example +========== + +SLY is probably best illustrated by an example. Here's what it +looks like to write a parser that can evaluate simple arithmetic +expressions and store variables:: + + # ----------------------------------------------------------------------------- + # calc.py + # ----------------------------------------------------------------------------- + + from sly import Lexer, Parser + + class CalcLexer(Lexer): + tokens = { + 'NAME', 'NUMBER', + } + ignore = ' \t' + literals = { '=', '+', '-', '*', '/', '(', ')' } + + # Tokens + NAME = r'[a-zA-Z_][a-zA-Z0-9_]*' + + @_(r'\d+') + def NUMBER(self, t): + t.value = int(t.value) + return t + + @_(r'\n+') + def newline(self, t): + self.lineno += t.value.count('\n') + + def error(self, value): + print("Illegal character '%s'" % value[0]) + self.index += 1 + + class CalcParser(Parser): + tokens = CalcLexer.tokens + + precedence = ( + ('left', '+', '-'), + ('left', '*', '/'), + ('right', 'UMINUS'), + ) + + def __init__(self): + self.names = { } + + @_('NAME "=" expr') + def statement(self, p): + self.names[p.NAME] = p.expr + + @_('expr') + def statement(self, p): + print(p.expr) + + @_('expr "+" expr') + def expr(self, p): + return p.expr0 + p.expr1 + + @_('expr "-" expr') + def expr(self, p): + return p.expr0 - p.expr1 + + @_('expr "*" expr') + def expr(self, p): + return p.expr0 * p.expr1 + + @_('expr "/" expr') + def expr(self, p): + return p.expr0 / p.expr1 + + @_('"-" expr %prec UMINUS') + def expr(self, p): + return -p.expr + + @_('"(" expr ")"') + def expr(self, p): + return p.expr + + @_('NUMBER') + def expr(self, p): + return p.NUMBER + + @_('NAME') + def expr(self, p): + try: + return self.names[p.NAME] + except LookupError: + print("Undefined name '%s'" % p.NAME) + return 0 + + if __name__ == '__main__': + lexer = CalcLexer() + parser = CalcParser() + while True: + try: + text = input('calc > ') + except EOFError: + break + if text: + parser.parse(lexer.tokenize(text)) + + +More Documentation +================== Contents: .. toctree:: :maxdepth: 2 + sly +Resources +========= -Indices and tables -================== +For a detailed overview of parsing theory, consult the excellent +book "Compilers : Principles, Techniques, and Tools" by Aho, Sethi, and +Ullman. The topics found in "Lex & Yacc" by Levine, Mason, and Brown +may also be useful. -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` +The GitHub page for SLY can be found at: + + https://github.com/dabeaz/sly + +Please direct bug reports and pull requests to the GitHub page. +To contact me directly, send email to dave@dabeaz.com or contact +me on Twitter (@dabeaz).