From 3762041bab63340aeb5ecaf488acce0d3c70591d Mon Sep 17 00:00:00 2001 From: Alex Mandelias Date: Wed, 12 Jan 2022 16:25:17 +0200 Subject: [PATCH 1/4] fix operate_assign --- minipython.grammar | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/minipython.grammar b/minipython.grammar index 0f6ab4c..8af18b9 100644 --- a/minipython.grammar +++ b/minipython.grammar @@ -113,9 +113,9 @@ Productions | {empty_line} tab* {-> New statement.empty()}; operate_assign = - {assign} assign {-> New operate_assign.assign(assign)} - | {sub_assign} sub_assign {-> New operate_assign.sub_assign(sub_assign)} - | {div_assign} div_assign {-> New operate_assign.div_assign(div_assign)}; + {assign} assign {-> New operate_assign.assign()} + | {sub_assign} sub_assign {-> New operate_assign.sub_assign()} + | {div_assign} div_assign {-> New operate_assign.div_assign()}; /* Expression */ /* First the lowest priority (addition and subtraction) */ @@ -233,9 +233,9 @@ Abstract Syntax Tree | {empty} ; /*]*/ operate_assign = - {assign} assign - | {sub_assign} sub_assign - | {div_assign} div_assign; + {assign} + | {sub_assign} + | {div_assign}; expr = {add} [ex1]:expr [ex2]:expr From 8b672e9d04a914073ecc2e3a77edbbb95d3ca6a7 Mon Sep 17 00:00:00 2001 From: Alex Mandelias Date: Wed, 12 Jan 2022 16:38:08 +0200 Subject: [PATCH 2/4] more random changes --- minipython.grammar | 85 +++++++++++++++++++++------------------------- 1 file changed, 38 insertions(+), 47 deletions(-) diff --git a/minipython.grammar b/minipython.grammar index 8af18b9..62a9c6b 100644 --- a/minipython.grammar +++ b/minipython.grammar @@ -99,13 +99,13 @@ Productions argument_list {-> argument} = {argument_list} comma identifier default_value? {-> New argument(identifier, default_value.value)}; /* Statement */ - statement = {if} tab* if comparison colon statement {-> New statement.if(comparison, statement)} + statement = {if} tab* if [comp]:comparison colon [stmt]:statement {-> New statement.if(comp, stmt)} | {while} tab* while comparison colon statement {-> New statement.while(comparison, statement)} | {for} tab* for [id1]:identifier in [id2]:identifier colon statement {-> New statement.for(id1, id2, statement)} | {return} tab* return expression {-> New statement.return(expression.expr)} | {print} tab* print expression expression_list* {-> New statement.print([expression.expr expression_list.expr])} | {assign_var} tab* identifier operate_assign expression {-> New statement.assign_var(identifier, operate_assign, expression.expr)} - | {assign_array} tab* identifier l_br [ex1]:expression r_br assign [ex2]:expression {-> New statement.assign_array(identifier, ex1.expr, ex2.expr)} + | {assign_array} tab* identifier l_br [ex1]:expression r_br assign [ex2]:expression {-> New statement.assign_arr(identifier, ex1.expr, ex2.expr)} | {assertion} tab* assert expression expression_list? {-> New statement.assertion([expression.expr expression_list.expr])} | {func_call} tab* function_call {-> New statement.func_call(function_call)} /* Note that the Import Statement is NOT included in BNF */ @@ -124,10 +124,10 @@ Productions | {subtraction} expression op_sub res2 {-> New expr.sub(expression.expr, res2.expr)}; /* Then second lowest (multiplication, division and modulo) */ - res2 {-> expr} = {res3} res3 {-> res3.expr } - | {multiplication} res2 op_mul res3 {-> New expr.mul(res2.expr, res3.expr) } - | {division} res2 op_div res3 {-> New expr.div(res2.expr, res3.expr) } - | {modulo} res2 op_mod res3 {-> New expr.mod(res2.expr, res3.expr) }; + res2 {-> expr} = {res3} res3 {-> res3.expr} + | {multiplication} res2 op_mul res3 {-> New expr.mul(res2.expr, res3.expr)} + | {division} res2 op_div res3 {-> New expr.div(res2.expr, res3.expr)} + | {modulo} res2 op_mod res3 {-> New expr.mod(res2.expr, res3.expr)}; /* Then the highest (exponentiation) */ res3 {-> expr} = {other_expr} other_expr {-> other_expr.expr} @@ -143,9 +143,8 @@ Productions | {ls_def} l_br expression expression_list* r_br {-> New expr.ls_def([expression.expr expression_list.expr])}; minimax = {max} max {->New minimax.max()} | {min} min {-> New minimax.min()}; - value_list {->value} = {value_list} comma value {-> value}; + value_list {-> value} = {value_list} comma value {-> value}; -/*[*/ /* Import import_statement{->statement} = @@ -157,10 +156,12 @@ Productions import_as {-> identifier} = {import_as} as identifier {-> New identifier(identifier)}; module_list {-> identifier*} = {module_list} comma module import_as? {-> New identifier([identifier import_as])}; - id_dot {->identifier} = {id_dot} identifier dot; - identifier_list {->identifier} = {identifier_list} comma identifier import_as? ; + id_dot {-> identifier} = {id_dot} identifier dot; + identifier_list {-> identifier} = {identifier_list} comma identifier import_as? ; */ +/*[*/ + /* Comparison */ /* First the lowest priority (and, or) */ comparison = @@ -177,27 +178,26 @@ Productions logical_value {-> comparison} = {true} true {-> New comparison.true()} | {false} false {-> New comparison.false()} - | {expr_compare} [ex1]:expression single_comparison [ex2]:expression {-> New comparison.single(ex1.expr, single_comparison, ex2.expr)}; + | {expr_compare} [ex1]:expression comparison_operator [ex2]:expression {-> New comparison.single(ex1.expr, comparison_operator, ex2.expr)}; - single_comparison = - {gt} greater_than {-> New single_comparison.gt()} - | {lt} less_than {-> New single_comparison.lt()} - | {ge} great_eq {-> New single_comparison.ge()} - | {le} less_eq {-> New single_comparison.le()} - | {ne} not_eq {-> New single_comparison.ne()} - | {eq} eq {-> New single_comparison.eq()}; + comparison_operator = + {gt} greater_than {-> New comparison_operator.gt()} + | {lt} less_than {-> New comparison_operator.lt()} + | {ge} great_eq {-> New comparison_operator.ge()} + | {le} less_eq {-> New comparison_operator.le()} + | {ne} not_eq {-> New comparison_operator.ne()} + | {eq} eq {-> New comparison_operator.eq()}; /* Function Call + Arglist */ - function_call = {func_call} identifier l_par arglist? r_par {-> New function_call.fc(identifier, [arglist.expr])}; - + function_call = {func_call} identifier l_par arglist? r_par {-> New function_call(identifier, [arglist.expr])}; arglist {-> expr*} = {arg_list} expression expression_list* {-> [expression.expr expression_list.expr]}; /* Value */ value = {id_func} identifier dot function_call {-> New value.id_func_call(identifier, function_call)} | {number} number {-> number.value} - | {str_double} string_double_quotes{-> New value.string1(string_double_quotes)} - | {str_single} string_single_quotes{-> New value.string2(string_single_quotes)} + | {str_double} string_double_quotes {-> New value.string1(string_double_quotes)} + | {str_single} string_single_quotes {-> New value.string2(string_single_quotes)} | {none} none {-> New value.none()}; /* Number + Identifier */ @@ -206,36 +206,31 @@ Productions /* Leftover production that used at many places */ expression_list {-> expr} = {expression_list} comma expression {-> expression.expr}; -/*#*/ - + Abstract Syntax Tree - /* Goal */ goal = command*; command = {function} function | {statement} statement; - - /* Function + Argument */ + function = identifier argument* statement; argument = identifier value; - /* Statement */ statement = {if} comparison statement | {while} comparison statement | {for} [id1]:identifier [id2]:identifier statement | {return} expr | {print} expr* | {assign_var} identifier operate_assign expr - | {assign_array} identifier [ex1]:expr [ex2]:expr + | {assign_arr} identifier [ex1]:expr [ex2]:expr | {assertion} expr* | {func_call} function_call /* Note that the Import Statement is NOT included in BNF */ - /* | {import_module} moduleas* - | {from_import_statement} module identifier_as**/ + /* + | {import_module} moduleas* + | {from_import_statement} module identifier_as* + */ | {empty} ; -/*]*/ - operate_assign = - {assign} - | {sub_assign} - | {div_assign}; + + operate_assign = {assign} | {sub_assign} | {div_assign}; expr = {add} [ex1]:expr [ex2]:expr @@ -250,14 +245,16 @@ Abstract Syntax Tree | {minimax} value* | {ls_def} expr* | {func_call} function_call; - +/*#*/ +/*]*/ + /* module = {module} identifier*; moduleas = module identifier*; identifier_as = [id1]:identifier [id2]:identifier*; */ - function_call = {fc} identifier expr*; + function_call = identifier expr*; value = {val} value | {number} num @@ -265,22 +262,16 @@ Abstract Syntax Tree | {id_func_call} identifier function_call | {string1} string_double_quotes | {string2} string_single_quotes; - + minimax = {min} | {max}; identifier = {id} id; - single_comparison = - {gt} - | {lt} - | {ge} - | {le} - | {ne} - | {eq}; + comparison_operator = {gt} | {lt} | {ge} | {le} | {ne} | {eq}; comparison = {neg} comparison | {and} [comp1]:comparison [comp2]:comparison | {or} [comp1]:comparison [comp2]:comparison - | {single} [ex1]:expr single_comparison [ex2]:expr + | {single} [ex1]:expr comparison_operator [ex2]:expr | {true} | {false}; From 2ebe14451d034d531dfaf5db559406bc78aa97dd Mon Sep 17 00:00:00 2001 From: Alex Mandelias Date: Wed, 12 Jan 2022 16:52:13 +0200 Subject: [PATCH 3/4] add short names to everything --- minipython.grammar | 100 ++++++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 46 deletions(-) diff --git a/minipython.grammar b/minipython.grammar index 62a9c6b..6d8c096 100644 --- a/minipython.grammar +++ b/minipython.grammar @@ -99,15 +99,16 @@ Productions argument_list {-> argument} = {argument_list} comma identifier default_value? {-> New argument(identifier, default_value.value)}; /* Statement */ - statement = {if} tab* if [comp]:comparison colon [stmt]:statement {-> New statement.if(comp, stmt)} - | {while} tab* while comparison colon statement {-> New statement.while(comparison, statement)} - | {for} tab* for [id1]:identifier in [id2]:identifier colon statement {-> New statement.for(id1, id2, statement)} - | {return} tab* return expression {-> New statement.return(expression.expr)} - | {print} tab* print expression expression_list* {-> New statement.print([expression.expr expression_list.expr])} - | {assign_var} tab* identifier operate_assign expression {-> New statement.assign_var(identifier, operate_assign, expression.expr)} - | {assign_array} tab* identifier l_br [ex1]:expression r_br assign [ex2]:expression {-> New statement.assign_arr(identifier, ex1.expr, ex2.expr)} - | {assertion} tab* assert expression expression_list? {-> New statement.assertion([expression.expr expression_list.expr])} - | {func_call} tab* function_call {-> New statement.func_call(function_call)} + statement = + {if} tab* if [cmp]:comparison colon [stmt]:statement {-> New statement.if(cmp, stmt)} + | {while} tab* while [cmp]:comparison colon [stmt]:statement {-> New statement.while(cmp, stmt)} + | {for} tab* for [id1]:identifier in [id2]:identifier colon [stmt]:statement {-> New statement.for(id1, id2, stmt)} + | {return} tab* return [exp]:expression {-> New statement.return(exp.expr)} + | {print} tab* print [exp]:expression [exp_ls]:expression_list* {-> New statement.print([exp.expr exp_ls.expr])} + | {assign_var} tab* [id]:identifier [op_assign]:operate_assign [exp]:expression {-> New statement.assign_var(id, op_assign, exp.expr)} + | {assign_lst} tab* [id]:identifier l_br [exp1]:expression r_br assign [exp2]:expression {-> New statement.assign_lst(id, exp1.expr, exp2.expr)} + | {assertion} tab* assert [exp]:expression [exp_ls]:expression_list? {-> New statement.assertion([exp.expr exp_ls.expr])} + | {func_call} tab* [fc]:function_call {-> New statement.func_call(fc)} /* Note that the Import Statement is NOT included in BNF */ /* | {import_statement} tab* import_statement {-> import_statement.statement}*/ | {empty_line} tab* {-> New statement.empty()}; @@ -119,31 +120,37 @@ Productions /* Expression */ /* First the lowest priority (addition and subtraction) */ - expression {-> expr} = {res2} res2 {-> res2.expr} - | {addition} expression op_add res2 {-> New expr.add(expression.expr, res2.expr)} - | {subtraction} expression op_sub res2 {-> New expr.sub(expression.expr, res2.expr)}; + expression {-> expr} = + {res2} [r2]:res2 {-> r2.expr} + | {addition} [exp]:expression op_add [r2]:res2 {-> New expr.add(exp.expr, r2.expr)} + | {subtraction} [exp]:expression op_sub [r2]:res2 {-> New expr.sub(exp.expr, r2.expr)}; /* Then second lowest (multiplication, division and modulo) */ - res2 {-> expr} = {res3} res3 {-> res3.expr} - | {multiplication} res2 op_mul res3 {-> New expr.mul(res2.expr, res3.expr)} - | {division} res2 op_div res3 {-> New expr.div(res2.expr, res3.expr)} - | {modulo} res2 op_mod res3 {-> New expr.mod(res2.expr, res3.expr)}; + res2 {-> expr} = + {res3} [r3]:res3 {-> r3.expr} + | {multiplication} [r2]:res2 op_mul [r3]:res3 {-> New expr.mul(r2.expr, r3.expr)} + | {division} [r2]:res2 op_div [r3]:res3 {-> New expr.div(r2.expr, r3.expr)} + | {modulo} [r2]:res2 op_mod [r3]:res3 {-> New expr.mod(r2.expr, r3.expr)}; /* Then the highest (exponentiation) */ - res3 {-> expr} = {other_expr} other_expr {-> other_expr.expr} - | {exponentiation} other_expr op_exp res3 {-> New expr.exp(other_expr.expr, res3.expr)}; + res3 {-> expr} = + {other_expr} [other]:other_expr {-> other.expr} + | {exponentiation} [other]:other_expr op_exp [r3]:res3 {-> New expr.exp(other.expr, r3.expr)}; /* Lastly, each of the above expressions can be one of the following */ - other_expr {-> expr} = {id_bracket} identifier l_br expression r_br {-> New expr.id_bracket(identifier, expression.expr)} - | {func_call} function_call {-> New expr.func_call(function_call)} - | {value} value {-> New expr.value(value)} - | {id} identifier {-> New expr.id(identifier)} - | {length_expr} length l_par expression r_par {-> expression.expr} - | {minimax} minimax l_par value value_list* r_par {-> New expr.minimax([value value_list.value])} - | {ls_def} l_br expression expression_list* r_br {-> New expr.ls_def([expression.expr expression_list.expr])}; - - minimax = {max} max {->New minimax.max()} | {min} min {-> New minimax.min()}; - value_list {-> value} = {value_list} comma value {-> value}; + other_expr {-> expr} = + {id_bracket} [id]:identifier l_br [exp]:expression r_br {-> New expr.id_bracket(id, exp.expr)} + | {func_call} [fc]:function_call {-> New expr.func_call(fc)} + | {value} [val]:value {-> New expr.value(val)} + | {id} [id]:identifier {-> New expr.id(id)} + | {length_expr} length l_par [exp]:expression r_par {-> exp.expr} + | {minimax} [minimax]:minimax l_par [val]:value [val_ls]:value_list* r_par {-> New expr.minimax(minimax, [val val_ls.value])} + | {ls_def} l_br [exp]:expression [exp_ls]:expression_list* r_br {-> New expr.ls_def([exp.expr exp_ls.expr])}; + + minimax = + {max} max {->New minimax.max()} + | {min} min {-> New minimax.min()}; + value_list {-> value} = {value_list} comma [val]:value {-> val}; /* Import @@ -165,20 +172,20 @@ Productions /* Comparison */ /* First the lowest priority (and, or) */ comparison = - {negation} negation {-> negation.comparison} - | {and_comparison} comparison logical_and negation {-> New comparison.and(comparison, negation.comparison)} - | {or_comparison} comparison logical_or negation {-> New comparison.or(comparison, negation.comparison)}; + {negation} [neg]:negation {-> neg.comparison} + | {and_comparison} [cmp]:comparison logical_and [neg]:negation {-> New comparison.and(cmp, neg.comparison)} + | {or_comparison} [cmp]:comparison logical_or [neg]:negation {-> New comparison.or(cmp, neg.comparison)}; /* Then the highest (not) */ negation {-> comparison} = - {logical_value} logical_value {-> logical_value.comparison} - | {negation} logical_not logical_value {-> New comparison.neg(logical_value.comparison)}; + {logical_value} [lv]:logical_value {-> lv.comparison} + | {negation} logical_not [lv]:logical_value {-> New comparison.neg(lv.comparison)}; /* Lastly, boolean literals and simple comparison expressions */ logical_value {-> comparison} = {true} true {-> New comparison.true()} | {false} false {-> New comparison.false()} - | {expr_compare} [ex1]:expression comparison_operator [ex2]:expression {-> New comparison.single(ex1.expr, comparison_operator, ex2.expr)}; + | {expr_compare} [exp1]:expression [cmp_op]:comparison_operator [exp2]:expression {-> New comparison.single(exp1.expr, cmp_op, exp2.expr)}; comparison_operator = {gt} greater_than {-> New comparison_operator.gt()} @@ -189,23 +196,23 @@ Productions | {eq} eq {-> New comparison_operator.eq()}; /* Function Call + Arglist */ - function_call = {func_call} identifier l_par arglist? r_par {-> New function_call(identifier, [arglist.expr])}; - arglist {-> expr*} = {arg_list} expression expression_list* {-> [expression.expr expression_list.expr]}; + function_call = {func_call} [id]:identifier l_par [arg_ls]:arglist? r_par {-> New function_call(id, [arg_ls.expr])}; + arglist {-> expr*} = {arg_list} [exp]:expression [exp_ls]:expression_list* {-> [exp.expr exp_ls.expr]}; /* Value */ value = - {id_func} identifier dot function_call {-> New value.id_func_call(identifier, function_call)} - | {number} number {-> number.value} - | {str_double} string_double_quotes {-> New value.string1(string_double_quotes)} - | {str_single} string_single_quotes {-> New value.string2(string_single_quotes)} + {id_func} [id]:identifier dot [fc]:function_call {-> New value.id_func_call(id, fc)} + | {number} [num]:number {-> num.value} + | {str_double} [ssq]:string_double_quotes {-> New value.string1(ssq)} + | {str_single} [sdq]:string_single_quotes {-> New value.string2(sdq)} | {none} none {-> New value.none()}; /* Number + Identifier */ - number {-> value} = {num} num {-> New value.number(num)}; - identifier = {identifier} id {-> New identifier.id(id)}; + number {-> value} = {num} [num]:num {-> New value.number(num)}; + identifier = {identifier} [id]:id {-> New identifier.id(id)}; /* Leftover production that used at many places */ - expression_list {-> expr} = {expression_list} comma expression {-> expression.expr}; + expression_list {-> expr} = {expression_list} comma [exp]:expression {-> exp.expr}; Abstract Syntax Tree goal = command*; @@ -220,7 +227,7 @@ Abstract Syntax Tree | {return} expr | {print} expr* | {assign_var} identifier operate_assign expr - | {assign_arr} identifier [ex1]:expr [ex2]:expr + | {assign_lst} identifier [ex1]:expr [ex2]:expr | {assertion} expr* | {func_call} function_call /* Note that the Import Statement is NOT included in BNF */ @@ -242,9 +249,11 @@ Abstract Syntax Tree | {id_bracket} identifier expr | {value} value | {id} identifier - | {minimax} value* + | {minimax} minimax value* | {ls_def} expr* | {func_call} function_call; + + minimax = {min} | {max}; /*#*/ /*]*/ @@ -263,7 +272,6 @@ Abstract Syntax Tree | {string1} string_double_quotes | {string2} string_single_quotes; - minimax = {min} | {max}; identifier = {id} id; From 00bbbf5f0ab8c36ae35e9106621f0885309caf3c Mon Sep 17 00:00:00 2001 From: Alex Mandelias Date: Wed, 12 Jan 2022 17:53:48 +0200 Subject: [PATCH 4/4] more stuff' --- minipython.grammar | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/minipython.grammar b/minipython.grammar index 6d8c096..1af962f 100644 --- a/minipython.grammar +++ b/minipython.grammar @@ -86,18 +86,19 @@ Ignored Tokens Productions /* Goal */ - goal = {commands} command more_commands* {-> New goal([command more_commands.command])}; + goal = {commands} [com]:command [coms]:more_commands* {-> New goal([com coms.command])}; command = - {function} function {-> New command.function(function)} - | {statement} statement {-> New command.statement(statement)}; - more_commands {-> command} = {more_commands} eoltoken command {-> command}; + {function} [func]:function {-> New command.function(func)} + | {statement} [stmt]:statement {-> New command.statement(stmt)}; + more_commands {-> command} = {more_commands} eoltoken [com]:command {-> com}; /* Function + Argument */ - function = {func_def} def identifier l_par argument? r_par colon statement {-> New function(identifier, [argument], statement) }; - argument = {argument} identifier default_value? argument_list* {-> New argument(identifier, default_value.value)}; - default_value {-> value} = {default_value} assign value {-> New value.val(value)}; - argument_list {-> argument} = {argument_list} comma identifier default_value? {-> New argument(identifier, default_value.value)}; + function = {func_def} def [id]:identifier l_par [arg]:argument? r_par colon [stmt]:statement {-> New function(id, [arg], stmt) }; + argument = {argument} [id]:identifier [dv]:default_value? [arg_ls]:argument_list* {-> New argument(id, dv.value, [arg_ls])}; + default_value {-> value} = {default_value} assign [val]:value {-> New value.val(val)}; + argument_list {-> argument} = {argument_list} comma [id]:identifier [dv]:default_value? {-> New argument(id, dv.value)}; +/*[*/ /* Statement */ statement = {if} tab* if [cmp]:comparison colon [stmt]:statement {-> New statement.if(cmp, stmt)} @@ -109,8 +110,10 @@ Productions | {assign_lst} tab* [id]:identifier l_br [exp1]:expression r_br assign [exp2]:expression {-> New statement.assign_lst(id, exp1.expr, exp2.expr)} | {assertion} tab* assert [exp]:expression [exp_ls]:expression_list? {-> New statement.assertion([exp.expr exp_ls.expr])} | {func_call} tab* [fc]:function_call {-> New statement.func_call(fc)} - /* Note that the Import Statement is NOT included in BNF */ - /* | {import_statement} tab* import_statement {-> import_statement.statement}*/ + /* Note that the Import Statement is NOT included in BNF as a Statement */ + /* + | {import_statement} tab* import_statement {-> import_statement.statement} + */ | {empty_line} tab* {-> New statement.empty()}; operate_assign = @@ -167,7 +170,6 @@ Productions identifier_list {-> identifier} = {identifier_list} comma identifier import_as? ; */ -/*[*/ /* Comparison */ /* First the lowest priority (and, or) */ @@ -214,6 +216,8 @@ Productions /* Leftover production that used at many places */ expression_list {-> expr} = {expression_list} comma [exp]:expression {-> exp.expr}; +/*#*/ + Abstract Syntax Tree goal = command*; command = {function} function | {statement} statement; @@ -230,7 +234,7 @@ Abstract Syntax Tree | {assign_lst} identifier [ex1]:expr [ex2]:expr | {assertion} expr* | {func_call} function_call - /* Note that the Import Statement is NOT included in BNF */ + /* Note that the Import Statement is NOT included in BNF as a Statement */ /* | {import_module} moduleas* | {from_import_statement} module identifier_as* @@ -240,11 +244,11 @@ Abstract Syntax Tree operate_assign = {assign} | {sub_assign} | {div_assign}; expr = - {add} [ex1]:expr [ex2]:expr - | {sub} [ex1]:expr [ex2]:expr - | {mul} [ex1]:expr [ex2]:expr - | {div} [ex1]:expr [ex2]:expr - | {mod} [ex1]:expr [ex2]:expr + {add} [exp1]:expr [exp2]:expr + | {sub} [exp1]:expr [exp2]:expr + | {mul} [exp1]:expr [exp2]:expr + | {div} [exp1]:expr [exp2]:expr + | {mod} [exp1]:expr [exp2]:expr | {exp} [base]:expr [power]:expr | {id_bracket} identifier expr | {value} value @@ -254,7 +258,6 @@ Abstract Syntax Tree | {func_call} function_call; minimax = {min} | {max}; -/*#*/ /*]*/ /* @@ -278,8 +281,8 @@ Abstract Syntax Tree comparison_operator = {gt} | {lt} | {ge} | {le} | {ne} | {eq}; comparison = {neg} comparison - | {and} [comp1]:comparison [comp2]:comparison - | {or} [comp1]:comparison [comp2]:comparison - | {single} [ex1]:expr comparison_operator [ex2]:expr + | {and} [cmp1]:comparison [cmp2]:comparison + | {or} [cmp1]:comparison [cmp2]:comparison + | {single} [exp1]:expr comparison_operator [exp2]:expr | {true} | {false};