diff options
Diffstat (limited to 'prolog/parser.py')
-rw-r--r-- | prolog/parser.py | 94 |
1 files changed, 56 insertions, 38 deletions
diff --git a/prolog/parser.py b/prolog/parser.py index 599ecd1..4efc07c 100644 --- a/prolog/parser.py +++ b/prolog/parser.py @@ -21,18 +21,19 @@ from .util import Token # PARSER precedence = ( - ('nonassoc', 'FROM', 'FROMDCG'), - ('right', 'PIPE'), - ('right', 'IMPLIES'), - ('right', 'NOT'), - ('nonassoc', 'EQU', 'NEQU', 'EQ', 'NEQ', 'UNIV', 'IS', 'EQA', 'NEQA', 'LT', 'LE', 'GT', 'GE', 'LTL', 'LEL', 'GTL', 'GEL', 'IN', 'INS', 'THROUGH', 'EQFD', 'NEQFD', 'LTFD', 'LEFD', 'GTFD', 'GEFD'), - ('left', 'PLUS', 'MINUS'), - ('left', 'STAR', 'DIV', 'IDIV', 'MOD'), - ('nonassoc', 'POW'), - ('nonassoc', 'UINTEGER', 'UREAL'), - ('nonassoc', 'NAME', 'VARIABLE', 'STRING'), - ('nonassoc', 'PERIOD'), - ('nonassoc', 'LBRACKET', 'RBRACKET', 'LPAREN', 'RPAREN', 'COMMA', 'SEMI', 'LBRACE', 'RBRACE') + ('nonassoc', 'FROM', 'FROMDCG'), # 1200 + ('right', 'PIPE'), # 1105 + ('right', 'SEMI'), # 1100 + ('right', 'IMPLIES', 'SOFTCUT'), # 1050 + ('right', 'COMMA'), # 1000 + ('right', 'NOT'), # 900 + ('nonassoc', 'EQU', 'NEQU', 'EQV', 'NEQV', 'EQ', 'NEQ', 'UNIV', 'IS', 'EQA', 'NEQA', 'LT', 'LE', 'GT', 'GE', 'LTL', 'LEL', 'GTL', 'GEL', 'IN', 'INS', 'FDEQ', 'FDNEQ', 'FDLT', 'FDLE', 'FDGT', 'FDGE'), # 700 + ('left', 'PLUS', 'MINUS', 'AND', 'FDUNION'), # 500 + ('nonassoc', 'THROUGH'), # 450 + ('left', 'SHIFTLEFT', 'SHIFTRIGHT', 'STAR', 'SLASH', 'SLASH2', 'DIV', 'MOD', 'RDIV', 'REM', 'XOR'), # 400 + ('right', 'POW'), # 200 + ('nonassoc', 'POWSTAR'), # 200 + ('right', 'UPLUS', 'UMINUS', 'NEG'), # 200 ) def token_start(p, n): @@ -90,7 +91,8 @@ def p_if_single(p): 'if : and' p[0] = p[1] def p_if_and(p): - 'if : and IMPLIES if' + '''if : and IMPLIES if + | and SOFTCUT if''' p[0] = make_tree('if', [p[1], p[3]], p[1].start, p[3].end) def p_and_single(p): @@ -149,90 +151,106 @@ def p_term_brace(p): def p_term_operator_infix(p): '''term : term PLUS term | term MINUS term + | term AND term | term STAR term | term POW term + | term POWSTAR term + | term SLASH term + | term SLASH2 term | term DIV term - | term IDIV term | term MOD term - + | term RDIV term + | term REM term + | term XOR term + | term SHIFTLEFT term + | term SHIFTRIGHT term | term EQU term | term NEQU term + | term EQV term + | term NEQV term | term EQ term | term NEQ term | term UNIV term | term IS term - | term EQA term | term NEQA term | term LT term | term LE term | term GT term | term GE term - | term LTL term | term LEL term | term GTL term | term GEL term - | term PIPE term | term THROUGH term | term IN term | term INS term - | term EQFD term - | term NEQFD term - | term LTFD term - | term LEFD term - | term GTFD term - | term GEFD term''' - p[0] = make_tree('binop', [p[1], make_token(p, 2), p[3]], p[1].start, p[3].end) + | term FDEQ term + | term FDNEQ term + | term FDLT term + | term FDLE term + | term FDGT term + | term FDGE term + | term FDUNION term''' + start, end = p[1].start, p[3].end + p[0] = make_tree('binop', [p[1], make_token(p, 2), p[3]], start, end) # binary expressions in functional notation, e.g. “+(1,2)” def p_term_operator_prefix(p): '''term : PLUS LPAREN term COMMA term RPAREN | MINUS LPAREN term COMMA term RPAREN + | AND LPAREN term COMMA term RPAREN | STAR LPAREN term COMMA term RPAREN | POW LPAREN term COMMA term RPAREN + | POWSTAR LPAREN term COMMA term RPAREN + | SLASH LPAREN term COMMA term RPAREN + | SLASH2 LPAREN term COMMA term RPAREN | DIV LPAREN term COMMA term RPAREN - | IDIV LPAREN term COMMA term RPAREN | MOD LPAREN term COMMA term RPAREN - + | RDIV LPAREN term COMMA term RPAREN + | REM LPAREN term COMMA term RPAREN + | XOR LPAREN term COMMA term RPAREN + | SHIFTLEFT LPAREN term COMMA term RPAREN + | SHIFTRIGHT LPAREN term COMMA term RPAREN | EQU LPAREN term COMMA term RPAREN | NEQU LPAREN term COMMA term RPAREN + | EQV LPAREN term COMMA term RPAREN + | NEQV LPAREN term COMMA term RPAREN | EQ LPAREN term COMMA term RPAREN | NEQ LPAREN term COMMA term RPAREN | UNIV LPAREN term COMMA term RPAREN | IS LPAREN term COMMA term RPAREN - | EQA LPAREN term COMMA term RPAREN | NEQA LPAREN term COMMA term RPAREN | LT LPAREN term COMMA term RPAREN | LE LPAREN term COMMA term RPAREN | GT LPAREN term COMMA term RPAREN | GE LPAREN term COMMA term RPAREN - | LTL LPAREN term COMMA term RPAREN | LEL LPAREN term COMMA term RPAREN | GTL LPAREN term COMMA term RPAREN | GEL LPAREN term COMMA term RPAREN - | PIPE LPAREN term COMMA term RPAREN | THROUGH LPAREN term COMMA term RPAREN | IN LPAREN term COMMA term RPAREN | INS LPAREN term COMMA term RPAREN - | EQFD LPAREN term COMMA term RPAREN - | NEQFD LPAREN term COMMA term RPAREN - | LTFD LPAREN term COMMA term RPAREN - | LEFD LPAREN term COMMA term RPAREN - | GTFD LPAREN term COMMA term RPAREN - | GEFD LPAREN term COMMA term RPAREN''' + | FDEQ LPAREN term COMMA term RPAREN + | FDNEQ LPAREN term COMMA term RPAREN + | FDLT LPAREN term COMMA term RPAREN + | FDLE LPAREN term COMMA term RPAREN + | FDGT LPAREN term COMMA term RPAREN + | FDGE LPAREN term COMMA term RPAREN + | FDUNION LPAREN term COMMA term RPAREN''' start, end = token_start(p, 1), token_end(p, 6) p[0] = make_tree('binop', [p[3], make_token(p, 1), p[5]], start, end) # unary operators def p_term_operator_unary(p): '''term : NOT term - | MINUS term - | PLUS term''' + | MINUS term %prec UMINUS + | PLUS term %prec UPLUS + | NEG term''' # shift/reduce conflict for MINUS and PLUS with p_term_operator_prefix above: # ply prefers shifting and will resolve +(2,2) to the binary expression “2+2” # instead of the unary “+ (2,2)” (this behavior is what we want) |