From a0ce80ee73d4245f60ac642a1b0780dbc39edc45 Mon Sep 17 00:00:00 2001 From: KikooDX Date: Tue, 9 Jun 2020 10:24:09 +0200 Subject: [PATCH] Hello world of yacc (yay) --- lexer.py | 6 +- parser.out | 324 ++++++++++++++++++++++++++++++++++++++++++++++++++++ parser.py | 52 +++++++++ parsetab.py | 38 ++++++ 4 files changed, 418 insertions(+), 2 deletions(-) create mode 100644 parser.out create mode 100644 parser.py create mode 100644 parsetab.py diff --git a/lexer.py b/lexer.py index c695abe..cef2cfd 100644 --- a/lexer.py +++ b/lexer.py @@ -78,8 +78,10 @@ t_ignore_COMMENT = r'//.*' # A regex rule with some action code def t_NUMBER(t): - r'[+-]?[0-9]+\b' - t.value = int(t.value) + r'[+-]*[(0-9).]+\b' + t.value = t.value.replace("--", "") + t.value = t.value.replace("+", "") + t.value = float(t.value) return t # Strings diff --git a/parser.out b/parser.out new file mode 100644 index 0000000..b02ba47 --- /dev/null +++ b/parser.out @@ -0,0 +1,324 @@ +Created by PLY version 3.11 (http://www.dabeaz.com/ply) + +Unused terminals: + + ASSIGN + And + COMMA + DIVIDEASSIGN + DO + ELSE + FOR + GETKEY + GOTO + ID + IF + IFEND + ISEQUAL + LBL + LCURBRA + LIST + LOCATE + LPWHILE + LSQRBRA + MAT + MINUSASSIGN + MODULO + MODULOASSIGN + NEWLINE + NEXT + NOT + OR + PLUSASSIGN + RCURBRA + RSQRBRA + STEP + STR + STRING + THEN + TIMESASSIGN + TO + WHILE + WHILEEND + +Grammar + +Rule 0 S' -> expression +Rule 1 expression -> expression PLUS term +Rule 2 expression -> expression MINUS term +Rule 3 expression -> term +Rule 4 term -> term TIMES factor +Rule 5 term -> term DIVIDE factor +Rule 6 term -> factor +Rule 7 factor -> NUMBER +Rule 8 factor -> LPAREN expression RPAREN + +Terminals, with rules where they appear + +ASSIGN : +And : +COMMA : +DIVIDE : 5 +DIVIDEASSIGN : +DO : +ELSE : +FOR : +GETKEY : +GOTO : +ID : +IF : +IFEND : +ISEQUAL : +LBL : +LCURBRA : +LIST : +LOCATE : +LPAREN : 8 +LPWHILE : +LSQRBRA : +MAT : +MINUS : 2 +MINUSASSIGN : +MODULO : +MODULOASSIGN : +NEWLINE : +NEXT : +NOT : +NUMBER : 7 +OR : +PLUS : 1 +PLUSASSIGN : +RCURBRA : +RPAREN : 8 +RSQRBRA : +STEP : +STR : +STRING : +THEN : +TIMES : 4 +TIMESASSIGN : +TO : +WHILE : +WHILEEND : +error : + +Nonterminals, with rules where they appear + +expression : 1 2 8 0 +factor : 4 5 6 +term : 1 2 3 4 5 + +Parsing method: LALR + +state 0 + + (0) S' -> . expression + (1) expression -> . expression PLUS term + (2) expression -> . expression MINUS term + (3) expression -> . term + (4) term -> . term TIMES factor + (5) term -> . term DIVIDE factor + (6) term -> . factor + (7) factor -> . NUMBER + (8) factor -> . LPAREN expression RPAREN + + NUMBER shift and go to state 4 + LPAREN shift and go to state 5 + + expression shift and go to state 1 + term shift and go to state 2 + factor shift and go to state 3 + +state 1 + + (0) S' -> expression . + (1) expression -> expression . PLUS term + (2) expression -> expression . MINUS term + + PLUS shift and go to state 6 + MINUS shift and go to state 7 + + +state 2 + + (3) expression -> term . + (4) term -> term . TIMES factor + (5) term -> term . DIVIDE factor + + PLUS reduce using rule 3 (expression -> term .) + MINUS reduce using rule 3 (expression -> term .) + $end reduce using rule 3 (expression -> term .) + RPAREN reduce using rule 3 (expression -> term .) + TIMES shift and go to state 8 + DIVIDE shift and go to state 9 + + +state 3 + + (6) term -> factor . + + TIMES reduce using rule 6 (term -> factor .) + DIVIDE reduce using rule 6 (term -> factor .) + PLUS reduce using rule 6 (term -> factor .) + MINUS reduce using rule 6 (term -> factor .) + $end reduce using rule 6 (term -> factor .) + RPAREN reduce using rule 6 (term -> factor .) + + +state 4 + + (7) factor -> NUMBER . + + TIMES reduce using rule 7 (factor -> NUMBER .) + DIVIDE reduce using rule 7 (factor -> NUMBER .) + PLUS reduce using rule 7 (factor -> NUMBER .) + MINUS reduce using rule 7 (factor -> NUMBER .) + $end reduce using rule 7 (factor -> NUMBER .) + RPAREN reduce using rule 7 (factor -> NUMBER .) + + +state 5 + + (8) factor -> LPAREN . expression RPAREN + (1) expression -> . expression PLUS term + (2) expression -> . expression MINUS term + (3) expression -> . term + (4) term -> . term TIMES factor + (5) term -> . term DIVIDE factor + (6) term -> . factor + (7) factor -> . NUMBER + (8) factor -> . LPAREN expression RPAREN + + NUMBER shift and go to state 4 + LPAREN shift and go to state 5 + + expression shift and go to state 10 + term shift and go to state 2 + factor shift and go to state 3 + +state 6 + + (1) expression -> expression PLUS . term + (4) term -> . term TIMES factor + (5) term -> . term DIVIDE factor + (6) term -> . factor + (7) factor -> . NUMBER + (8) factor -> . LPAREN expression RPAREN + + NUMBER shift and go to state 4 + LPAREN shift and go to state 5 + + term shift and go to state 11 + factor shift and go to state 3 + +state 7 + + (2) expression -> expression MINUS . term + (4) term -> . term TIMES factor + (5) term -> . term DIVIDE factor + (6) term -> . factor + (7) factor -> . NUMBER + (8) factor -> . LPAREN expression RPAREN + + NUMBER shift and go to state 4 + LPAREN shift and go to state 5 + + term shift and go to state 12 + factor shift and go to state 3 + +state 8 + + (4) term -> term TIMES . factor + (7) factor -> . NUMBER + (8) factor -> . LPAREN expression RPAREN + + NUMBER shift and go to state 4 + LPAREN shift and go to state 5 + + factor shift and go to state 13 + +state 9 + + (5) term -> term DIVIDE . factor + (7) factor -> . NUMBER + (8) factor -> . LPAREN expression RPAREN + + NUMBER shift and go to state 4 + LPAREN shift and go to state 5 + + factor shift and go to state 14 + +state 10 + + (8) factor -> LPAREN expression . RPAREN + (1) expression -> expression . PLUS term + (2) expression -> expression . MINUS term + + RPAREN shift and go to state 15 + PLUS shift and go to state 6 + MINUS shift and go to state 7 + + +state 11 + + (1) expression -> expression PLUS term . + (4) term -> term . TIMES factor + (5) term -> term . DIVIDE factor + + PLUS reduce using rule 1 (expression -> expression PLUS term .) + MINUS reduce using rule 1 (expression -> expression PLUS term .) + $end reduce using rule 1 (expression -> expression PLUS term .) + RPAREN reduce using rule 1 (expression -> expression PLUS term .) + TIMES shift and go to state 8 + DIVIDE shift and go to state 9 + + +state 12 + + (2) expression -> expression MINUS term . + (4) term -> term . TIMES factor + (5) term -> term . DIVIDE factor + + PLUS reduce using rule 2 (expression -> expression MINUS term .) + MINUS reduce using rule 2 (expression -> expression MINUS term .) + $end reduce using rule 2 (expression -> expression MINUS term .) + RPAREN reduce using rule 2 (expression -> expression MINUS term .) + TIMES shift and go to state 8 + DIVIDE shift and go to state 9 + + +state 13 + + (4) term -> term TIMES factor . + + TIMES reduce using rule 4 (term -> term TIMES factor .) + DIVIDE reduce using rule 4 (term -> term TIMES factor .) + PLUS reduce using rule 4 (term -> term TIMES factor .) + MINUS reduce using rule 4 (term -> term TIMES factor .) + $end reduce using rule 4 (term -> term TIMES factor .) + RPAREN reduce using rule 4 (term -> term TIMES factor .) + + +state 14 + + (5) term -> term DIVIDE factor . + + TIMES reduce using rule 5 (term -> term DIVIDE factor .) + DIVIDE reduce using rule 5 (term -> term DIVIDE factor .) + PLUS reduce using rule 5 (term -> term DIVIDE factor .) + MINUS reduce using rule 5 (term -> term DIVIDE factor .) + $end reduce using rule 5 (term -> term DIVIDE factor .) + RPAREN reduce using rule 5 (term -> term DIVIDE factor .) + + +state 15 + + (8) factor -> LPAREN expression RPAREN . + + TIMES reduce using rule 8 (factor -> LPAREN expression RPAREN .) + DIVIDE reduce using rule 8 (factor -> LPAREN expression RPAREN .) + PLUS reduce using rule 8 (factor -> LPAREN expression RPAREN .) + MINUS reduce using rule 8 (factor -> LPAREN expression RPAREN .) + $end reduce using rule 8 (factor -> LPAREN expression RPAREN .) + RPAREN reduce using rule 8 (factor -> LPAREN expression RPAREN .) + diff --git a/parser.py b/parser.py new file mode 100644 index 0000000..94e1b2a --- /dev/null +++ b/parser.py @@ -0,0 +1,52 @@ +import ply.yacc as yacc + +# Get the token map from the lexer. This is required. +from lexer import tokens + +def p_expression_plus(p): + 'expression : expression PLUS term' + p[0] = p[1] + p[3] + +def p_expression_minus(p): + 'expression : expression MINUS term' + p[0] = p[1] - p[3] + +def p_expression_term(p): + 'expression : term' + p[0] = p[1] + +def p_term_times(p): + 'term : term TIMES factor' + p[0] = p[1] * p[3] + +def p_term_div(p): + 'term : term DIVIDE factor' + p[0] = p[1] / p[3] + +def p_term_factor(p): + 'term : factor' + p[0] = p[1] + +def p_factor_num(p): + 'factor : NUMBER' + p[0] = p[1] + +def p_factor_expr(p): + 'factor : LPAREN expression RPAREN' + p[0] = p[2] + +# Error rule for syntax errors +def p_error(p): + print("Syntax error in input!") + +# Build the parser +parser = yacc.yacc() + +while True: + try: + s = input('calc > ') + except EOFError: + break + if not s: continue + result = parser.parse(s) + print(result) diff --git a/parsetab.py b/parsetab.py new file mode 100644 index 0000000..c57f58f --- /dev/null +++ b/parsetab.py @@ -0,0 +1,38 @@ + +# parsetab.py +# This file is automatically generated. Do not edit. +# pylint: disable=W,C,R +_tabversion = '3.10' + +_lr_method = 'LALR' + +_lr_signature = 'ASSIGN And COMMA DIVIDE DIVIDEASSIGN DO ELSE FOR GETKEY GOTO ID IF IFEND ISEQUAL LBL LCURBRA LIST LOCATE LPAREN LPWHILE LSQRBRA MAT MINUS MINUSASSIGN MODULO MODULOASSIGN NEWLINE NEXT NOT NUMBER OR PLUS PLUSASSIGN RCURBRA RPAREN RSQRBRA STEP STR STRING THEN TIMES TIMESASSIGN TO WHILE WHILEENDexpression : expression PLUS termexpression : expression MINUS termexpression : termterm : term TIMES factorterm : term DIVIDE factorterm : factorfactor : NUMBERfactor : LPAREN expression RPAREN' + +_lr_action_items = {'NUMBER':([0,5,6,7,8,9,],[4,4,4,4,4,4,]),'LPAREN':([0,5,6,7,8,9,],[5,5,5,5,5,5,]),'$end':([1,2,3,4,11,12,13,14,15,],[0,-3,-6,-7,-1,-2,-4,-5,-8,]),'PLUS':([1,2,3,4,10,11,12,13,14,15,],[6,-3,-6,-7,6,-1,-2,-4,-5,-8,]),'MINUS':([1,2,3,4,10,11,12,13,14,15,],[7,-3,-6,-7,7,-1,-2,-4,-5,-8,]),'RPAREN':([2,3,4,10,11,12,13,14,15,],[-3,-6,-7,15,-1,-2,-4,-5,-8,]),'TIMES':([2,3,4,11,12,13,14,15,],[8,-6,-7,8,8,-4,-5,-8,]),'DIVIDE':([2,3,4,11,12,13,14,15,],[9,-6,-7,9,9,-4,-5,-8,]),} + +_lr_action = {} +for _k, _v in _lr_action_items.items(): + for _x,_y in zip(_v[0],_v[1]): + if not _x in _lr_action: _lr_action[_x] = {} + _lr_action[_x][_k] = _y +del _lr_action_items + +_lr_goto_items = {'expression':([0,5,],[1,10,]),'term':([0,5,6,7,],[2,2,11,12,]),'factor':([0,5,6,7,8,9,],[3,3,3,3,13,14,]),} + +_lr_goto = {} +for _k, _v in _lr_goto_items.items(): + for _x, _y in zip(_v[0], _v[1]): + if not _x in _lr_goto: _lr_goto[_x] = {} + _lr_goto[_x][_k] = _y +del _lr_goto_items +_lr_productions = [ + ("S' -> expression","S'",1,None,None,None), + ('expression -> expression PLUS term','expression',3,'p_expression_plus','parser.py',7), + ('expression -> expression MINUS term','expression',3,'p_expression_minus','parser.py',11), + ('expression -> term','expression',1,'p_expression_term','parser.py',15), + ('term -> term TIMES factor','term',3,'p_term_times','parser.py',19), + ('term -> term DIVIDE factor','term',3,'p_term_div','parser.py',23), + ('term -> factor','term',1,'p_term_factor','parser.py',27), + ('factor -> NUMBER','factor',1,'p_factor_num','parser.py',31), + ('factor -> LPAREN expression RPAREN','factor',3,'p_factor_expr','parser.py',35), +]