diff options
author | David Beazley <dave@dabeaz.com> | 2019-11-24 17:59:03 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-11-24 17:59:03 -0600 |
commit | f6d78006324079bfe824422b9a21dc91811ecfa2 (patch) | |
tree | 7f85b26028fca2c29e382496783c916e948a7b7a | |
parent | f45aa4e7aadfedbb48142cd8bab18c7cf6622d2e (diff) | |
parent | aa2d0bda9c4fb742eaf460f91c19125480499385 (diff) | |
download | ply-f6d78006324079bfe824422b9a21dc91811ecfa2.tar.gz |
Merge pull request #158 from hugovk/patch-1
README: Remove code formatting to make links clickable, add Python formatting to code
-rw-r--r-- | README.md | 227 |
1 files changed, 116 insertions, 111 deletions
@@ -75,14 +75,18 @@ within the 'ply' directory which may also be used as a Python package. To use PLY, simply copy the 'ply' directory to your project and import lex and yacc from the associated 'ply' package. For example: - from .ply import lex - from .ply import yacc +```python +from .ply import lex +from .ply import yacc +``` Alternatively, you can copy just the files lex.py and yacc.py individually and use them as modules however you see fit. For example: - import lex - import yacc +```python +import lex +import yacc +``` PLY has no third-party dependencies. @@ -105,7 +109,7 @@ Resources ========= More information about PLY can be obtained on the PLY webpage at: - http://www.dabeaz.com/ply +* http://www.dabeaz.com/ply For a detailed overview of parsing theory, consult the excellent book "Compilers : Principles, Techniques, and Tools" by Aho, Sethi, and @@ -114,11 +118,11 @@ may also be useful. The GitHub page for PLY can be found at: - https://github.com/dabeaz/ply +* https://github.com/dabeaz/ply An old and inactive discussion group for PLY is found at: - http://groups.google.com/group/ply-hack +* http://groups.google.com/group/ply-hack Acknowledgments =============== @@ -145,110 +149,111 @@ Example Here is a simple example showing a PLY implementation of a calculator with variables. - # ----------------------------------------------------------------------------- - # calc.py - # - # A simple calculator with variables. - # ----------------------------------------------------------------------------- - - tokens = ( - 'NAME','NUMBER', - 'PLUS','MINUS','TIMES','DIVIDE','EQUALS', - 'LPAREN','RPAREN', - ) - - # Tokens - - t_PLUS = r'\+' - t_MINUS = r'-' - t_TIMES = r'\*' - t_DIVIDE = r'/' - t_EQUALS = r'=' - t_LPAREN = r'\(' - t_RPAREN = r'\)' - t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*' - - def t_NUMBER(t): - r'\d+' - t.value = int(t.value) - return t - - # Ignored characters - t_ignore = " \t" - - def t_newline(t): - r'\n+' - t.lexer.lineno += t.value.count("\n") - - def t_error(t): - print("Illegal character '%s'" % t.value[0]) - t.lexer.skip(1) - - # Build the lexer - import ply.lex as lex - lex.lex() - - # Precedence rules for the arithmetic operators - precedence = ( - ('left','PLUS','MINUS'), - ('left','TIMES','DIVIDE'), - ('right','UMINUS'), - ) - - # dictionary of names (for storing variables) - names = { } - - def p_statement_assign(p): - 'statement : NAME EQUALS expression' - names[p[1]] = p[3] - - def p_statement_expr(p): - 'statement : expression' - print(p[1]) - - def p_expression_binop(p): - '''expression : expression PLUS expression - | expression MINUS expression - | expression TIMES expression - | expression DIVIDE expression''' - if p[2] == '+' : p[0] = p[1] + p[3] - elif p[2] == '-': p[0] = p[1] - p[3] - elif p[2] == '*': p[0] = p[1] * p[3] - elif p[2] == '/': p[0] = p[1] / p[3] - - def p_expression_uminus(p): - 'expression : MINUS expression %prec UMINUS' - p[0] = -p[2] - - def p_expression_group(p): - 'expression : LPAREN expression RPAREN' - p[0] = p[2] - - def p_expression_number(p): - 'expression : NUMBER' - p[0] = p[1] - - def p_expression_name(p): - 'expression : NAME' - try: - p[0] = names[p[1]] - except LookupError: - print("Undefined name '%s'" % p[1]) - p[0] = 0 - - def p_error(p): - print("Syntax error at '%s'" % p.value) - - import ply.yacc as yacc - yacc.yacc() - - while True: - try: - s = raw_input('calc > ') # use input() on Python 3 - except EOFError: - break - yacc.parse(s) - +```python +# ----------------------------------------------------------------------------- +# calc.py +# +# A simple calculator with variables. +# ----------------------------------------------------------------------------- + +tokens = ( + 'NAME','NUMBER', + 'PLUS','MINUS','TIMES','DIVIDE','EQUALS', + 'LPAREN','RPAREN', + ) + +# Tokens + +t_PLUS = r'\+' +t_MINUS = r'-' +t_TIMES = r'\*' +t_DIVIDE = r'/' +t_EQUALS = r'=' +t_LPAREN = r'\(' +t_RPAREN = r'\)' +t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*' + +def t_NUMBER(t): + r'\d+' + t.value = int(t.value) + return t + +# Ignored characters +t_ignore = " \t" + +def t_newline(t): + r'\n+' + t.lexer.lineno += t.value.count("\n") + +def t_error(t): + print("Illegal character '%s'" % t.value[0]) + t.lexer.skip(1) + +# Build the lexer +import ply.lex as lex +lex.lex() + +# Precedence rules for the arithmetic operators +precedence = ( + ('left','PLUS','MINUS'), + ('left','TIMES','DIVIDE'), + ('right','UMINUS'), + ) + +# dictionary of names (for storing variables) +names = { } + +def p_statement_assign(p): + 'statement : NAME EQUALS expression' + names[p[1]] = p[3] + +def p_statement_expr(p): + 'statement : expression' + print(p[1]) + +def p_expression_binop(p): + '''expression : expression PLUS expression + | expression MINUS expression + | expression TIMES expression + | expression DIVIDE expression''' + if p[2] == '+' : p[0] = p[1] + p[3] + elif p[2] == '-': p[0] = p[1] - p[3] + elif p[2] == '*': p[0] = p[1] * p[3] + elif p[2] == '/': p[0] = p[1] / p[3] + +def p_expression_uminus(p): + 'expression : MINUS expression %prec UMINUS' + p[0] = -p[2] + +def p_expression_group(p): + 'expression : LPAREN expression RPAREN' + p[0] = p[2] + +def p_expression_number(p): + 'expression : NUMBER' + p[0] = p[1] + +def p_expression_name(p): + 'expression : NAME' + try: + p[0] = names[p[1]] + except LookupError: + print("Undefined name '%s'" % p[1]) + p[0] = 0 + +def p_error(p): + print("Syntax error at '%s'" % p.value) + +import ply.yacc as yacc +yacc.yacc() + +while True: + try: + s = raw_input('calc > ') # use input() on Python 3 + except EOFError: + break + yacc.parse(s) +``` Bug Reports and Patches ======================= |