%{
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: gsp_gram.y,v 1.4 2025/11/24 08:04:28 nia Exp $");
#endif
#include <stdio.h>
#include "gsp_ass.h"
%}
%union {
long y_int;
char *y_id;
expr y_expr;
operand y_opnd;
}
%token LEFT_SHIFT, RIGHT_SHIFT
%term <y_id> ID, STRING
%term <y_int> NUMBER, REGISTER
%term UMINUS
%nonassoc ':'
%left LEFT_SHIFT, RIGHT_SHIFT
%left '^'
%left '|'
%left '&'
%left '+', '-'
%left '*', '/'
%nonassoc '~', UMINUS
%start line
%type <y_expr> expr
%type <y_opnd> operand, operands, ea
%%
line : label ID operands { statement($2, $3); }
| ID operands { statement($1, $2); }
| label
| ID '=' expr { do_asg($1, $3, 0); }
|
| error
;
label : ID ':' { set_label($1); }
| NUMBER ':' { set_numeric_label($1); }
;
operands : { $$ = NULL; }
| operand { $$ = $1; }
| operands ',' operand { $$ = add_operand($1, $3); }
;
operand : REGISTER { $$ = reg_op($1); }
| ea { $$ = $1; }
| expr { $$ = expr_op($1); }
| STRING { $$ = string_op($1); }
;
ea : '@' expr { $$ = abs_adr($2); }
| '*' REGISTER { $$ = reg_ind($2, M_IND); }
| '*' REGISTER ID { $$ = reg_indxy($2, $3); }
| '*' REGISTER '+' { $$ = reg_ind($2, M_POSTINC); }
| '*' '-' REGISTER { $$ = reg_ind($3, M_PREDEC); }
| '-' '*' REGISTER { $$ = reg_ind($3, M_PREDEC); }
| '*' REGISTER '(' expr ')'
{ $$ = reg_index($2, $4); }
;
expr : ID { $$ = id_expr($1); }
| NUMBER { $$ = num_expr($1); }
| '.' { $$ = here_expr(); }
| '(' expr ')' { $$ = $2; }
| '~' expr { $$ = bexpr('~', $2, NULL); }
| '-' expr %prec UMINUS
{ $$ = bexpr(NEG, $2, NULL); }
| expr '*' expr { $$ = bexpr('*', $1, $3); }
| expr '/' expr { $$ = bexpr('/', $1, $3); }
| expr '+' expr { $$ = bexpr('+', $1, $3); }
| expr '-' expr { $$ = bexpr('-', $1, $3); }
| expr '&' expr { $$ = bexpr('&', $1, $3); }
| expr '|' expr { $$ = bexpr('|', $1, $3); }
| expr '^' expr { $$ = bexpr('^', $1, $3); }
| expr ':' expr { $$ = bexpr(':', $1, $3); }
| expr LEFT_SHIFT expr { $$ = bexpr(LEFT_SHIFT, $1, $3); }
| expr RIGHT_SHIFT expr { $$ = bexpr(RIGHT_SHIFT, $1, $3); }
;