diff options
Diffstat (limited to 'l6/calc.py')
| -rw-r--r-- | l6/calc.py | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/l6/calc.py b/l6/calc.py new file mode 100644 index 0000000..ea4d2b3 --- /dev/null +++ b/l6/calc.py @@ -0,0 +1,187 @@ +# ---------------------------------------------------------------------------- +# Grammar for the Calc language +# ---------------------------------------------------------------------------- + +""" + +PROGRAM ::= '[' 'calc' ',' STATEMENTS ']' + +STATEMENTS ::= STATEMENT + | STATEMENT ',' STATEMENTS + +STATEMENT ::= ASSIGNMENT + | REPETITION + | SELECTION + | INPUT + | OUTPUT + +ASSIGNMENT ::= '[' 'set' ',' VARIABLE ',' EXPRESSION ']' + +REPETITION ::= '[' 'while' ',' CONDITION ',' STATEMENTS ']' + +SELECTION ::= '[' 'if' ',' CONDITION ',' STATEMENT ']' + | '[' 'if' ',' CONDITION ',' STATEMENT ',' STATEMENT ']' + +INPUT ::= '[' 'read' ',' VARIABLE ']' + +OUTPUT ::= '[' 'print' ',' VARIABLE ']' + +EXPRESSION ::= CONSTANT + | VARIABLE + | BINARYEXPR + +BINARYEXPR ::= '[' EXPRESSION ',' BINARYOPER ',' EXPRESSION ']' + +CONDITION ::= '[' EXPRESSION ',' CONDOPER ',' EXPRESSION ']' + +BINARYOPER ::= '+' | '-' | '*' | '/' + +CONDOPER ::= '<' | '>' | '=' + +VARIABEL ::= a Python string + +KONSTANT ::= a Python number + +""" + +# ---------------------------------------------------------------------------- +# Primitive functions for the Calc language constructs +# ---------------------------------------------------------------------------- + +# ----- PROGRAM ----- + +def isprogram(p): + return isinstance(p, list) and len(p) > 1 and p[0] == 'calc' + +def program_statements(p): + return p[1:] + +# ----- STATEMENTS ----- + +def isstatements(p): + isstmnt = lambda s: isassignment(s) or isrepetition(s) or isselection(s) \ + or isoutput(s) or isinput(s) + return isinstance(p, list) and p and all(map(isstmnt, p)) + +def first_statement(p): + return p[0] + +def rest_statements(p): + return p[1:] + +def empty_statements(p): + return not p + +# ----- STATEMENT ----- + +# No functions for statements in general. Instead, see the differenct +# types of statements: assignments, repetitions, selections, input +# and output. + +# ----- ASSIGNMENT ----- + +def isassignment(p): + return isinstance(p, list) and len(p) == 3 and p[0] == 'set' + +def assignment_variable(p): + return p[1] + +def assignment_expression(p): + return p[2] + +# ----- REPETITION ----- + +def isrepetition(p): + return isinstance(p, list) and len(p) > 2 and p[0] == 'while' + +def repetition_condition(p): + return p[1] + +def repetition_statements(p): + return p[2:] + +# ----- SELECTION ----- + +def isselection(p): + return isinstance(p, list) and (3 <= len(p) <= 4) and p[0] == 'if' + +def selection_condition(p): + return p[1] + +def selection_true(p): + return p[2] + +def hasfalse(p): + return len(p) == 4 + +def selection_false(p): + return p[3] + +# ----- INPUT ----- + +def isinput(p): + return isinstance(p, list) and len(p) == 2 and p[0] == 'read' + +def input_variable(p): + return p[1] + +# ----- OUTPUT ----- + +def isoutput(p): + return isinstance(p, list) and len(p) == 2 and p[0] == 'print' + +def output_variable(p): + return p[1] + +# ----- EXPRESSION ----- + +# No functions for expressions in general. Instead, see the differenct +# types of expressions: constants, variables and binary expressions. + +# ----- BINARYEXPR ----- + +def isbinary(p): + return isinstance(p, list) and len(p) == 3 and isbinaryoper(p[1]) + +def binary_operator(p): + return p[1] + +def binary_left(p): + return p[0] + +def binary_right(p): + return p[2] + +# ----- CONDITION ----- + +def iscondition(p): + return isinstance(p, list) and len(p) == 3 and iscondoper(p[1]) + +def condition_operator(p): + return p[1] + +def condition_left(p): + return p[0] + +def condition_right(p): + return p[2] + +# ----- BINARYOPER ----- + +def isbinaryoper(p): + return p in ['+', '-', '*', '/'] + +# ----- CONDOPER ----- + +def iscondoper(p): + return p in ['<', '>', '='] + +# ----- VARIABLE ----- + +def isvariable(p): + return isinstance(p, str) and p != "" + +# ----- CONSTANT ----- + +def isconstant(p): + return isinstance(p, int) or isinstance(p, float) |
