go-analyzer/analyzers/test/test.y

256 lines
4.3 KiB
Plaintext

%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
extern int yylineno;
extern char *yytext;
void yyerror(const char *s) {
fprintf(stderr, "\033[91mError at line %d: %s\033[0m\n", yylineno, s);
exit(1);
}
extern int yylex();
extern FILE *yyin;
%}
%union {
char *str_val;
int int_val;
float float_val;
char rune_val;
bool bool_val;
}
%token BREAK CASE CHAN CONST CONTINUE DEFAULT DEFER ELSE FALLTHROUGH FOR FUNC
%token GO GOTO IF IMPORT INTERFACE MAP PACKAGE RANGE RETURN SELECT STRUCT
%token SWITCH TYPE VAR
%token <bool_val> BOOL_LIT
%token NIL
%token <str_val> IDENT
%token <int_val> INT_LIT
%token <float_val> FLOAT_LIT
%token <str_val> STRING_LIT
%token <str_val> RAW_STRING_LIT
%token <rune_val> RUNE_LIT
%token PLUS MINUS STAR SLASH PERCENT
%token AMPERSAND PIPE CARET LSHIFT RSHIFT AMPERSAND_CARET
%token PLUS_EQ MINUS_EQ STAR_EQ SLASH_EQ PERCENT_EQ
%token AMPERSAND_EQ PIPE_EQ CARET_EQ LSHIFT_EQ RSHIFT_EQ AMPERSAND_CARET_EQ
%token LAND LOR ARROW INC DEC
%token EQ NEQ LT GT LEQ GEQ
%token NOT ASSIGN DECLARE_ASSIGN ELLIPSIS
%token COLON SEMICOLON COMMA DOT
%token LPAREN RPAREN LBRACK RBRACK LBRACE RBRACE
%right INC DEC
%right ARROW
%right NOT
%left STAR SLASH PERCENT
%left PLUS MINUS
%left LSHIFT RSHIFT AMPERSAND_CARET
%left AMPERSAND PIPE CARET
%left EQ NEQ LT GT LEQ GEQ
%left LAND
%left LOR
%right ASSIGN DECLARE_ASSIGN
%right PLUS_EQ MINUS_EQ STAR_EQ SLASH_EQ PERCENT_EQ
%right AMPERSAND_EQ PIPE_EQ CARET_EQ LSHIFT_EQ RSHIFT_EQ AMPERSAND_CARET_EQ
%left DOT ELLIPSIS
%left COLON SEMICOLON COMMA
%%
program:
| program top_level_stmt
;
top_level_stmt:
decl_stmt
| func_decl
| block
;
decl_stmt:
VAR IDENT type ASSIGN expr
| CONST IDENT type ASSIGN expr
;
func_decl:
FUNC IDENT LPAREN params RPAREN block
;
params:
| param_list
;
param_list:
IDENT type
| param_list COMMA IDENT type
;
type:
IDENT
| LBRACK RBRACK type
| STAR type
;
expr:
literal
| IDENT
| expr PLUS expr
| expr MINUS expr
| expr STAR expr
| expr SLASH expr
| expr PERCENT expr
| expr LSHIFT expr
| expr RSHIFT expr
| expr AMPERSAND expr
| expr PIPE expr
| expr CARET expr
| expr AMPERSAND_CARET expr
| expr LAND expr
| expr LOR expr
| expr EQ expr
| expr NEQ expr
| expr LT expr
| expr GT expr
| expr LEQ expr
| expr GEQ expr
| NOT expr
| MINUS expr %prec NOT
| LPAREN expr RPAREN
| expr DOT IDENT
| IDENT LPAREN args RPAREN
;
args:
| expr
| args COMMA expr
;
type:
basic_type
| array
| slice
| pointer
| struct_type
| interface
| function
| map
| channel
basic_type:
uint8
| uint16
| uint32
| uint64
| int8
| "int16"
| "int32"
| "int64"
| "float32"
| "float64"
| "complex64"
| "complex128"
| "uint"
| "int"
| "uintptr"
| "bool"
| "string"
array:
LBRACK INT RBRACK type
slice:
LBRACK RBRACK type
pointer:
STAR type
struct_type:
STRUCT "{" (field_decl ";")* "}"
interface:
INTERFACE "{" (method_spec ";")* "}"
function_type:
FUNC signature
map:
MAP "[" key_type "]" type
channel:
CHAN type
| CHAN ARROW type
| ARROW CHAN type
field_decl:
identifier_list type
method_spec:
method_name signature
signature:
parameters [ result ]
parameters:
"(" [ parameter_list ] ")"
result:
type
| "(" type_list ")"
key_type:
type // для map ключом может быть только comparable тип
literal:
INT_LIT
| FLOAT_LIT
| STRING_LIT
| RAW_STRING_LIT
| RUNE_LIT
| BOOL_LIT
| NIL
;
block:
LBRACE stmt_list RBRACE
;
stmt_list:
| stmt_list stmt
;
stmt:
expr SEMICOLON
| decl_stmt SEMICOLON
| block
| RETURN expr SEMICOLON
| IF expr block
| IF expr block ELSE block
| FOR block
| FOR expr SEMICOLON expr SEMICOLON expr block
| FOR IDENT ASSIGN expr SEMICOLON expr SEMICOLON expr block
;
%%
int main(int argc, char **argv) {
if (argc > 1) {
FILE *f = fopen(argv[1], "r");
if (!f) {
perror("\033[91mFailed to open file\033[0m");
return 1;
}
yyin = f;
}
yyparse();
return 0;
}