%{ #define YYSTYPE SLTNode * #include #include #include "sun_parser.h" #include "sun_lexer.h" void yyerror(const YYLTYPE *location, SLTNode **moduleOut, yyscan_t *scanner, const char *error); %} %pure-parser %parse-param {SLTNode **moduleOut} %parse-param {yyscan_t *scanner} %lex-param {yyscan_t *scanner} %error-verbose %locations %token IF "if" %token ELSE "else" %token FOR "for" %token DO "do" %token WHILE "while" %token BREAK "break" %token TYPE "struct" %token RETURN "return" %token SLEEP "sleep" %token BOOL_FALSE "false" %token BOOL_TRUE "true" %token ADD_ASSIGN "+=" %token SUBTRACT_ASSIGN "-=" %token MULTIPLY_ASSIGN "*=" %token DIVIDE_ASSIGN "/=" %token MOD_ASSIGN "%=" %token LOGICAL_AND "&&" %token LOGICAL_OR "||" %token EQUAL "==" %token NOT_EQUAL "!=" %token LT_EQUAL "<=" %token GT_EQUAL ">=" /*%token INCREMENT "++" %token DECREMENT "--"*/ %token IDENTIFIER %token INT %token FLOAT %token STRING /* https://en.cppreference.com/w/c/language/operator_precedence */ %left ',' %right '=' "+=" "-=" "*=" "/=" "%=" /* etc... */ %left "||" %left "&&" %left '|' %left '^' %left '&' %left "==" "!=" %left '<' "<=" '>' ">=" /* %left "<<" ">>" */ %left '+' '-' %left '*' '/' '%' %right U_PLUS U_MINUS '!' '~' /* %right "++" "--" "" */ /* %left "++" "--" "" */ %start module %% module : optional_statements_or_definitions { $$ = sltNodeMakeModule($1); *moduleOut = $$; } ; optional_statements_or_definitions : /* Nothing */ { $$ = NULL; } | statements_or_definitions ; statements_or_definitions : definition { $$ = sltNodeMakeSequence(NULL, $1); } | statement { $$ = sltNodeMakeSequence(NULL, $1); } | statements_or_definitions definition { $$ = sltNodeMakeSequence($1, $2); } | statements_or_definitions statement { $$ = sltNodeMakeSequence($1, $2); } ; definition : function_definition /*| type_definition*/ | variable_definition ';' ; function_definition : IDENTIFIER IDENTIFIER '(' optional_parameter_definitions ')' '{' optional_statements '}' { $$ = sltNodeMakeFunctionDefinition($1, $2, $4, $7); } ; optional_parameter_definitions : /* Nothing */ { $$ = NULL; } | parameter_definitions ; parameter_definitions : parameter_definition { $$ = sltNodeMakeSequence(NULL, $1); } | parameter_definitions ',' parameter_definition { $$ = sltNodeMakeSequence($1, $3); } ; parameter_definition : IDENTIFIER IDENTIFIER { $$ = sltNodeMakeFunctionParameterDefinition($1, $2); } ; /*type_definition : "struct" IDENTIFIER '{' type_member_definitions '}' { $$ = sltNodeMakeTypeDefinition($2, $4); } ; type_member_definitions : type_member_definition ';' { $$ = sltNodeMakeSequence(NULL, $1); } | type_member_definitions type_member_definition ';' { $$ = sltNodeMakeSequence($1, $2); } ; type_member_definition : IDENTIFIER IDENTIFIER { $$ = sltNodeMakeTypeMemberDefinition($1, $2); } ;*/ variable_definition : IDENTIFIER IDENTIFIER { $$ = sltNodeMakeVariableDefinition($1, $2, NULL); } | IDENTIFIER IDENTIFIER '=' expression { $$ = sltNodeMakeVariableDefinition($1, $2, $4); } ; optional_statements : /* nothing */ { $$ = NULL; } | statements ; statements : statement { if ($1 != NULL) { $$ = sltNodeMakeSequence(NULL, $1); } } | statements statement { if ($2 != NULL) { $$ = sltNodeMakeSequence($1, $2); } else { $$ = $1; } } ; statement : ';' { $$ = NULL; /* Otherwise this will pass up the ';' character */ } | variable_definition ';' | "return" optional_expression ';' { $$ = sltNodeMakeReturn($2); } | "sleep" ';' { $$ = sltNodeMakeSleep(); } | selection_statement | iteration_statement | "break" ';' { $$ = sltNodeMakeBreak(); } | expression ';' | '{' optional_statements '}' { if ($2 != NULL) { $$ = sltNodeMakeStatementBlock($2); } else { $$ = NULL; } } ; selection_statement : "if" '(' expression ')' statement { $$ = sltNodeMakeSelection($3, $5, NULL); } | "if" '(' expression ')' statement "else" statement { $$ = sltNodeMakeSelection($3, $5, $7); } ; iteration_statement : "for" '(' optional_expression_or_variable_definition ';' optional_expression ';' optional_expression ')' statement { $$ = sltNodeMakeForIteration($3, $5, $7, $9); } | "while" '(' expression ')' statement { $$ = sltNodeMakeWhileIteration($3, $5); } | "do" statement "while" '(' expression ')' ';' { $$ = sltNodeMakeDoIteration($5, $2); } ; optional_expression_or_variable_definition : /* nothing */ { $$ = NULL; } | expression | variable_definition ; optional_expression : /* nothing */ { $$ = NULL; } | expression ; expression : assignment_expression ; assignment_expression : logic_expression | unary_expression assignment_operator assignment_expression { $$ = sltNodeMakeAssignment($1, ($2 == NULL) ? $3 : sltNodeMakeBinaryOperation($2, $1, $3)); } ; assignment_operator : '=' { $$ = NULL; } | "+=" { $$ = sltNodeMakeOperator(SLTOperatorTypeAdd); } | "-=" { $$ = sltNodeMakeOperator(SLTOperatorTypeSubtract); } | "*=" { $$ = sltNodeMakeOperator(SLTOperatorTypeMultiply); } | "/=" { $$ = sltNodeMakeOperator(SLTOperatorTypeDivide); } | "%=" { $$ = sltNodeMakeOperator(SLTOperatorTypeModulo); } ; logic_expression : bit_logic_expression | logic_expression logic_operator bit_logic_expression { $$ = sltNodeMakeBinaryOperation($2, $1, $3); } ; logic_operator : "&&" { $$ = sltNodeMakeOperator(SLTOperatorTypeLogicalAnd); } | "||" { $$ = sltNodeMakeOperator(SLTOperatorTypeLogicalOr); } ; bit_logic_expression : equality_expression | bit_logic_expression bit_logic_operator equality_expression { $$ = sltNodeMakeBinaryOperation($2, $1, $3); } ; bit_logic_operator : '&' { $$ = sltNodeMakeOperator(SLTOperatorTypeBitwiseAnd); } | '|' { $$ = sltNodeMakeOperator(SLTOperatorTypeBitwiseOr); } | '^' { $$ = sltNodeMakeOperator(SLTOperatorTypeBitwiseXor); } ; equality_expression : arithmetic_expression | equality_expression equality_operator arithmetic_expression { $$ = sltNodeMakeBinaryOperation($2, $1, $3); } ; equality_operator : "==" { $$ = sltNodeMakeOperator(SLTOperatorTypeEqual); } | "!=" { $$ = sltNodeMakeOperator(SLTOperatorTypeNotEqual); } | "<=" { $$ = sltNodeMakeOperator(SLTOperatorTypeLessThanEqual); } | ">=" { $$ = sltNodeMakeOperator(SLTOperatorTypeGreaterThanEqual); } | '<' { $$ = sltNodeMakeOperator(SLTOperatorTypeLessThan); } | '>' { $$ = sltNodeMakeOperator(SLTOperatorTypeGreaterThan); } ; arithmetic_expression : unary_expression | arithmetic_expression '+' arithmetic_expression { $$ = sltNodeMakeBinaryOperation(sltNodeMakeOperator(SLTOperatorTypeAdd), $1, $3); } | arithmetic_expression '-' arithmetic_expression { $$ = sltNodeMakeBinaryOperation(sltNodeMakeOperator(SLTOperatorTypeSubtract), $1, $3); } | arithmetic_expression '*' arithmetic_expression { $$ = sltNodeMakeBinaryOperation(sltNodeMakeOperator(SLTOperatorTypeMultiply), $1, $3); } | arithmetic_expression '/' arithmetic_expression { $$ = sltNodeMakeBinaryOperation(sltNodeMakeOperator(SLTOperatorTypeDivide), $1, $3); } | arithmetic_expression '%' arithmetic_expression { $$ = sltNodeMakeBinaryOperation(sltNodeMakeOperator(SLTOperatorTypeModulo), $1, $3); } ; unary_expression : postfix_expression | '-' %prec U_MINUS unary_expression { $$ = sltNodeMakeUnaryOperation(sltNodeMakeOperator(SLTOperatorTypeNegative), $2); } | '~' unary_expression { $$ = sltNodeMakeUnaryOperation(sltNodeMakeOperator(SLTOperatorTypeBitwiseNot), $2); } | '!' unary_expression { $$ = sltNodeMakeUnaryOperation(sltNodeMakeOperator(SLTOperatorTypeLogicalNot), $2); } ; /*unary_operator : "++" { $$ = sltNodeMakeOperator(SLTOperatorTypePreIncrement); } | "--" { $$ = sltNodeMakeOperator(SLTOperatorTypePreDecrement); } |'+' { $$ = sltNodeMakeOperator(SLTOperatorTypePositive); } | '-' %prec U_MINUS { $$ = sltNodeMakeOperator(SLTOperatorTypeNegative); } | '~' { $$ = sltNodeMakeOperator(SLTOperatorTypeBitwiseNot); } | '!' { $$ = sltNodeMakeOperator(SLTOperatorTypeLogicalNot); } ;*/ postfix_expression : primary_expression | postfix_expression '[' expression ']' { $$ = sltNodeMakeArrayAccess($1, $3); } | postfix_expression '(' optional_arguments ')' { $$ = sltNodeMakeFunctionCall($1, $3); } | postfix_expression '.' IDENTIFIER { $$ = sltNodeMakeTypeAccess($1, $3); } /*| postfix_expression postfix_unary_operator { $$ = sltNodeMakeUnaryOperation($1, $2); }*/ ; /*postfix_unary_operator : "++" { $$ = sltNodeMakeOperator(SLTOperatorTypePostIncrement); } | "--" { $$ = sltNodeMakeOperator(SLTOperatorTypePostDecrement); } ;*/ optional_arguments : /* nothing */ { $$ = NULL; } | arguments ; arguments : expression { $$ = sltNodeMakeSequence(NULL, sltNodeMakeArgument($1)); } | arguments ',' expression { $$ = sltNodeMakeSequence($1, sltNodeMakeArgument($3)); } ; primary_expression : IDENTIFIER | BOOL_FALSE | BOOL_TRUE | INT | FLOAT | STRING | '(' expression ')' { $$ = sltNodeMakeCompound($2); } ; %% void yyerror(const YYLTYPE *location, SLTNode **moduleOut, yyscan_t *scanner, const char *error) { //void yyerror(const YYLTYPE *location, yyscan_t scanner, const char *error) { printf("[ERROR] Line #%u, Characters %u: %s\n", /*yyget_lineno(scanner)*/location->first_line, /*yyget_column(scanner)*/location->first_column, error); }