Compare commits

...

No commits in common. "deepseek" and "master2" have entirely different histories.

20 changed files with 1391 additions and 338 deletions

View File

@ -1,133 +1,178 @@
%{
#include <stdio.h>
#include <stdbool.h>
#include "test.tab.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
extern int yylineno;
void yyerror(const char *s) {
fprintf(stderr, "\033[1;91mError at line %i: %s\033[0m\n", yylineno, s);
exit(1);
}
%}
%option noyywrap
%option yylineno
EXPONENT [eE][+-]?{DIGIT}+
DIGIT [0-9]
LETTER [a-zA-Z_]
LETTER_OR_DIGIT [a-zA-Z0-9_]
DIGIT [0-9]
LETTER [a-zA-Z_]
HEX [0-9a-fA-F]
OCT [0-7]
BIN [0-1]
QUOTE ["']
%%
{QUOTE}{LETTER}*{QUOTE} {return STRING;}
{LETTER}({LETTER}|{DIGIT})* { return IDENT;}
{DIGIT}+ { yylval.num = atoi(yytext); return NUMBER; }
"break" { return BREAK; }
"switch" { return SWITCH; }
"case" { return CASE; }
"chan" { return CHAN; }
"const" { return CONST; }
"continue" { return CONTINUE; }
"default" { return DEFAULT; }
"defer" { return DEFER; }
"else" { return ELSE; }
"fallthrough" { return FALLTHROUGH; }
"for" { return FOR; }
"func" { return FUNC; }
"go" { return GO; }
"goto" { return GOTO; }
"if" { return IF; }
"import" { return IMPORT; }
"interface" { return INTERFACE; }
"map" { return MAP; }
"package" { return PACKAGE; }
"range" { return RANGE; }
"return" { return RETURN; }
"select" { return SELECT; }
"struct" { return STRUCT; }
"type" { return TYPE; }
"var" { return VAR; }
"uint8" { return UINT8; }
"uint16" { return UINT16; }
"uint32" { return UINT32; }
"uint64" { return UINT64; }
"int8" { return INT8; }
"int16" { return INT16; }
"int32" { return INT32; }
"int64" { return INT64; }
"float32" { return FLOAT32; }
"float64" { return FLOAT64; }
"complex64" { return COMPLEX64; }
"complex128" { return COMPLEX128; }
"byte" { return BYTE; }
"rune" { return RUNE; }
"uint" { return UINT; }
"int" { return INT; }
"uintptr" { return UINT_PTR; }
"string" { return STRING_LIT;}
"true" { yylval.bool_val = true; return BOOL_LIT; }
"false" { yylval.bool_val = false; return BOOL_LIT; }
"nil" { return NIL; }
"+" { return PLUS; }
"-" { return MINUS; }
"*" { return STAR; }
"/" { return DIV; }
"%" { return MOD; }
"&" { return AMPERSAND; }
"|" { return PIPE; }
"^" { return XOR; }
"<<" { return LSHIFT; }
">>" { return RSHIFT; }
"&^" { return AND_NOT; }
"+=" { return PLUS_EQ; }
"-=" { return MINUS_EQ; }
"*=" { return MUL_EQ; }
"/=" { return DIV_EQ; }
"%=" { return MOD_EQ; }
"&=" { return AMPERSAND_EQ; }
"|=" { return PIPE_EQ; }
"^=" { return XOR_EQ; }
"<<=" { return LSHIFT_EQ; }
">>=" { return RSHIFT_EQ; }
"&^=" { return AND_NOT_EQ; }
"++" { return INC; }
"--" { return DEC; }
"==" { return EQ; }
"&&" { return AND; }
"||" { return OR; }
"!" { return NOT; }
"!=" { return NEQ; }
"<-" { return ARROW; }
"<" { return LT; }
">" { return GT; }
"=" { return ASSIGN; }
"<=" { return LEQ; }
">=" { return GEQ; }
":=" { return SHORT_ASSIGN; }
"..." { return DOTS; }
":" { return COLON; }
";" { return SEMICOLON; }
"," { return COMMA; }
"." { return DOT; }
"(" { return LPAREN; }
")" { return RPAREN; }
"[" { return LBRACK; }
"]" { return RBRACK; }
"{" { return LBRACE; }
"}" { return RBRACE; }
"//".* { }
"/\*"(.|\n)*?"\*/" { }
[ \t\n\r]+ { }
. { fprintf(stderr, "Unexpected symbol: %s\n", yytext); }
%%
"string" { return STRING; }
"chan" { return CHAN; }
"bool" { return BOOL; }
"uint" { return UINT; }
"uint8" { return UINT8; }
"uint16" { return UINT16; }
"uint32" { return UINT32; }
"uint64" { return UINT64; }
"int" { return INT; }
"int8" { return INT8; }
"int16" { return INT16; }
"int32" { return INT32; }
"int64" { return INT64; }
"complex64" { return COMPLEX64; }
"complex128" { return COMPLEX128; }
"byte" { return BYTE; }
"rune" { return RUNE; }
"float32" { return FLOAT32; }
"float64" { return FLOAT64; }
"uintptr" { return UINT_PTR; }
"if" { return IF; }
"else" { return ELSE; }
"<-" { return ARROW; }
"make" { return MAKE; }
"true" { return BOOL_LITERAL; }
"false" { return BOOL_LITERAL; }
"==" { return EQ; }
"&&" { return AND; }
"||" { return OR; }
"!" { return NOT; }
"!=" { return NEQ; }
"<" { return LT; }
">" { return GT; }
"<=" { return LEQ; }
">=" { return GEQ; }
"+=" { return PLUS_EQ; }
"-=" { return MINUS_EQ; }
"*=" { return MUL_EQ; }
"/=" { return DIV_EQ; }
"%=" { return MOD_EQ; }
"&=" { return AMPERSAND_EQ; }
"|=" { return PIPE_EQ; }
"^=" { return XOR_EQ; }
"<<=" { return LSHIFT_EQ; }
">>=" { return RSHIFT_EQ; }
"&^=" { return AND_NOT_EQ; }
"++" { return INC; }
"--" { return DEC; }
"interface{}" { return INTERFACE_LITERAL; }
"interface" { return INTERFACE; }
"map" { return MAP; }
"struct" { return STRUCT; }
"type" { return TYPE; }
"go" { return GO; }
"defer" { return DEFER; }
"range" { return RANGE; }
"for" { return FOR; }
"break" { return BREAK; }
"switch" { return SWITCH; }
"case" { return CASE; }
"chan" { return CHAN; }
"const" { return CONST; }
"continue" { return CONTINUE; }
"package" { return PACKAGE; }
"import" { return IMPORT; }
"var" { return VAR; }
"func" { return FUNC; }
"return" { return RETURN; }
":=" { return SHORT_DECLARATION; }
"=" { return ASSIGN; }
"+" { return PLUS; }
"-" { return MINUS; }
"*" { return MULT; }
"/" { return DIV; }
"%" { return MOD; }
"{" { return LBRACE; }
"}" { return RBRACE; }
"(" { return LPAREN; }
")" { return RPAREN; }
"[" { return LBRACK; }
"]" { return RBRACK; }
"," { return COMMA; }
";" { return SEMICOLON; }
"..." { return DOTS; }
":" { return COLON; }
"&" { return AMPERSAND; }
"//" {
int c;
while ((c = input()) != '\n' && c != 0);
if (c == '\n') yylineno++;
}
"/*" {
int c, prev = 0;
while ((c = input()) != 0) {
if (c == '\n') yylineno++;
if (prev == '*' && c == '/') break;
prev = c;
}
if (c == 0) yyerror("Unterminated comment");
}
\"([^"\\]|\\.)*\" { // правило для строк с возможность экранирования через \спецсимвол
return STRING_LITERAL;
}
{LETTER}({LETTER_OR_DIGIT}*\.)*{LETTER_OR_DIGIT}* {
yylval.str = strdup(yytext);
if (strchr(yytext, '.') != NULL) {
return WITH_DOT_IDENTIFIER;
} else {
return IDENTIFIER;
}
}
{DIGIT}+\.{DIGIT}*{EXPONENT}?i {
yylval.str = strdup(yytext);
return COMPLEX_LITERAL;
}
{DIGIT}+{EXPONENT}?i {
yylval.str = strdup(yytext);
return COMPLEX_LITERAL;
}
{DIGIT}+\.{DIGIT}*{EXPONENT}? {
return FLOAT_LITERAL;
}
{DIGIT}+{EXPONENT} {
return FLOAT_LITERAL;
}
{DIGIT}+ {
return NUMBER;
}
[ \t\r]+ ; // Пропускаем пробелы и табы
\n { yylineno++; }
. {
fprintf(stderr, "\033[91mUnexpected character at line %i: %c\033[0m\n",
yylineno, yytext[0]);
exit(1);
}
%%
int yywrap() {
return 1;
}

View File

@ -2,255 +2,561 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <math.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 void yyerror(const char *s);
extern int yylex();
extern FILE *yyin;
void free_node(char *str) {
if (str) free(str);
}
%}
%union {
char *str_val;
int int_val;
float float_val;
char rune_val;
bool bool_val;
char *str;
double num;
}
%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 SHORT_DECLARATION LBRACE RBRACE LBRACK RBRACK SEMICOLON ASSIGN LPAREN RPAREN COMMA COLON DOTS
%token VAR FUNC RETURN STRING_LITERAL FLOAT_LITERAL COMPLEX_LITERAL NUMBER PACKAGE IMPORT
%token INC DEC PLUS_EQ MINUS_EQ MUL_EQ DIV_EQ MOD_EQ
%token AMPERSAND_EQ PIPE_EQ XOR_EQ LSHIFT_EQ RSHIFT_EQ AND_NOT_EQ
%token FOR BREAK CONTINUE ARROW IF ELSE RANGE DEFER GO TYPE STRUCT MAP INTERFACE INTERFACE_LITERAL
%token CHAN CONST CASE SWITCH MAKE
%token PLUS MINUS MULT DIV MOD AMPERSAND
%token STRING
%token UINT UINT8 UINT16 UINT32 UINT64 UINT_PTR
%token INT INT8 INT16 INT32 INT64
%token RUNE BYTE BOOL_LITERAL BOOL
%token FLOAT32 FLOAT64
%token COMPLEX64 COMPLEX128
%token <str> IDENTIFIER WITH_DOT_IDENTIFIER
%token AND OR NOT EQ NEQ LT GT LEQ GEQ
%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_EQ MINUS_EQ MUL_EQ DIV_EQ MOD_EQ
%left AMPERSAND_EQ PIPE_EQ XOR_EQ
%left LSHIFT_EQ RSHIFT_EQ AND_NOT_EQ
%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
%left MULT DIV MOD
%left OR
%left AND
%right INC DEC
%right NOT
%nonassoc EQ NEQ LT GT LEQ GEQ
%left UMINUS
%right POINTER_TYPE
%%
// base
program:
| program top_level_stmt
package_declaration import_declaration
| program statement
;
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
statement:
| method_declaration
| GO func_call SEMICOLON
| DEFER func_call SEMICOLON
| func_call SEMICOLON
{ printf("\033[1;33mSTATEMENT: func_call\033[0m\n"); }
| var_declaration SEMICOLON
{ printf("\033[1;33mSTATEMENT: variable declaration\033[0m\n"); }
| var_multiple_short_declaration SEMICOLON
{ printf("\033[1;33mSTATEMENT: variable multiple declaration\033[0m\n"); }
| any_identifier ASSIGN math_expr SEMICOLON
| any_identifier ASSIGN literal SEMICOLON
| var_multiple_short_assignment SEMICOLON
| TYPE IDENTIFIER interface_declaration SEMICOLON
| func_declaration
{ printf("\033[1;33mSTATEMENT: function declaration\033[0m\n"); }
| type_delcaration SEMICOLON
{ printf("\033[1;33mSTATEMENT: type declaration\033[0m\n"); }
| cicle
{ printf("\033[1;33mSTATEMENT: cicle\033[0m\n"); }
| condition
{ printf("\033[1;33mSTATEMENT: condition\033[0m\n"); }
| IDENTIFIER COLON
{ printf("\033[1;33mSTATEMENT: label definition '%s'\033[0m\n", $1); }
| make SEMICOLON
| any_identifier ARROW math_expr SEMICOLON
| any_identifier ARROW literal SEMICOLON
;
block:
LBRACE stmt_list RBRACE
LBRACE statements_list RBRACE
;
stmt_list:
| stmt_list stmt
any_identifier:
IDENTIFIER
| WITH_DOT_IDENTIFIER
| MULT any_identifier %prec POINTER_TYPE { printf("DEREFERENCED IDENTIFIER\n"); }
| arr_element
| map_element
//
// lists
statements_list:
| statements_list expr SEMICOLON
| statements_list statement
| statements_list block
;
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
identifiers_list:
| IDENTIFIER { }
| identifiers_list COMMA IDENTIFIER { }
any_identifiers_list:
any_identifier { }
| any_identifiers_list COMMA any_identifier { }
math_expr_or_literals_list:
literal { }
| math_expr { }
| func_call { }
| math_expr_or_literals_list COMMA literal
| math_expr_or_literals_list COMMA math_expr
| math_expr_or_literals_list COMMA func_call
;
math_expr_or_literals_list_or_empty:
| math_expr_or_literals_list
literals_list:
literal
| literals_list COMMA literal
types_list:
| type
| types_list COMMA type
//
// condition
condition:
IF var_multiple_short_declaration SEMICOLON log_expr block else_part
| IF identifiers_list ASSIGN math_expr_or_literals_list SEMICOLON log_expr block else_part
| IF log_expr block else_part
else_part:
{ printf("\033[1;33mSTATEMENT: if condition with block\033[0m\n"); }
| ELSE IF log_expr block else_part { printf("\033[1;33mSTATEMENT: if condition with block else if block\033[0m\n"); }
| ELSE block { printf("\033[1;33mSTATEMENT: if condition with block else block\033[0m\n"); }
;
//
// cicle
cicle:
FOR loop_block
{ printf("\033[1;34mLOOP: infinite for loop\033[0m\n"); }
| FOR init_loop_statement SEMICOLON log_expr SEMICOLON post_statement loop_block
{ printf("\033[1;34mLOOP: full for loop with init, condition and post\033[0m\n"); }
| FOR log_expr loop_block
{ printf("\033[1;34mLOOP: for loop with condition only\033[0m\n"); }
| FOR identifiers_list SHORT_DECLARATION RANGE any_identifier loop_block
{ printf("\033[1;34mLOOP: range for loop\033[0m\n"); }
;
post_statement:
| identifiers_list ASSIGN math_expr_or_literals_list { }
| IDENTIFIER INC { }
| IDENTIFIER DEC { }
| IDENTIFIER PLUS_EQ math_expr { }
| IDENTIFIER MINUS_EQ math_expr { }
| IDENTIFIER MUL_EQ math_expr { }
| IDENTIFIER DIV_EQ math_expr { }
| IDENTIFIER MOD_EQ math_expr { }
| IDENTIFIER AMPERSAND_EQ math_expr { }
| IDENTIFIER PIPE_EQ math_expr { }
| IDENTIFIER XOR_EQ math_expr { }
| IDENTIFIER LSHIFT_EQ math_expr { }
| IDENTIFIER RSHIFT_EQ math_expr { }
| IDENTIFIER AND_NOT_EQ math_expr { }
loop_block:
LBRACE loop_statements RBRACE
;
init_loop_statement:
| identifiers_list SHORT_DECLARATION math_expr_or_literals_list
| identifiers_list ASSIGN math_expr_or_literals_list
loop_statements:
| loop_statements statement
| loop_statements loop_block
| loop_statements expr SEMICOLON
| loop_statements break_statement
| loop_statements continue_statement
| loop_statements IF log_expr loop_block else_part_loop
;
else_part_loop:
{ printf("\033[1;33mSTATEMENT: if condition with block\033[0m\n"); }
| ELSE IF log_expr loop_block else_part_loop { printf("\033[1;33mSTATEMENT: if condition with block else if block\033[0m\n"); }
| ELSE loop_block { printf("\033[1;33mSTATEMENT: if condition with block else block\033[0m\n"); }
;
break_statement:
BREAK SEMICOLON
{ printf("\033[1;31mBREAK\033[0m\n"); }
| BREAK IDENTIFIER SEMICOLON
{ printf("\033[1;31mBREAK TO LABEL: %s\033[0m\n", $2); }
;
continue_statement:
CONTINUE SEMICOLON
{ printf("\033[1;31mCONTINUE\033[0m\n"); }
| CONTINUE IDENTIFIER SEMICOLON
{ printf("\033[1;31mCONTINUE TO LABEL: %s\033[0m\n", $2); }
;
//
// expressions
expr:
RETURN math_expr_or_literals_list_or_empty { printf("\033[1;35mRETURN math expr\033[0m\n") }
| RETURN literal { printf("\033[1;35mRETURN literal\033[0m\n") }
| math_expr { }
;
math_expr:
any_identifier ASSIGN math_expr { }
| any_identifier PLUS_EQ math_expr
| any_identifier MINUS_EQ math_expr
| any_identifier MUL_EQ math_expr
| any_identifier DIV_EQ math_expr
| any_identifier MOD_EQ math_expr
| any_identifier AMPERSAND_EQ math_expr
| any_identifier PIPE_EQ math_expr
| any_identifier XOR_EQ math_expr
| any_identifier LSHIFT_EQ math_expr
| any_identifier RSHIFT_EQ math_expr
| any_identifier AND_NOT_EQ math_expr
| math_expr PLUS math_expr { printf("PLUS\n"); }
| math_expr MINUS math_expr { printf("MINUS\n"); }
| math_expr MULT math_expr { printf("MULT\n"); }
| math_expr DIV math_expr { printf("DIV\n"); }
| math_expr MOD math_expr { printf("MOD\n"); }
| MULT math_expr %prec POINTER_TYPE { printf("DEREFERENCE\n"); }
| AMPERSAND math_expr %prec UMINUS { printf("ADDRESS OF\n"); }
| MINUS math_expr %prec UMINUS { printf("UMINUS\n"); }
| LPAREN { printf("LPAREN\n"); } math_expr RPAREN { printf("RPAREN\n"); }
| NUMBER { printf("NUMBER\n"); }
| FLOAT_LITERAL { printf("FLOAT LITERAL\n"); }
| INTERFACE_LITERAL { printf("INTERFACE LITERAL\n"); }
| COMPLEX_LITERAL { printf("COMPLEX LITERAL\n"); }
| make { printf("make\n"); }
| any_identifier { printf("IDENTIFIER\n"); }
| any_identifier INC { printf("POST-INCREMENT: ++\n"); }
| any_identifier DEC { printf("POST-DECREMENT: --\n"); }
| func_call { printf("FUNCTION CALL IN EXPR\n"); }
| ARROW any_identifier { printf("TAKE FROM CHAN\n"); }
;
log_expr:
| log_expr AND log_expr { }
| log_expr OR log_expr { }
| NOT log_expr %prec UMINUS { }
| math_expr EQ math_expr { }
| math_expr NEQ math_expr { }
| math_expr LT math_expr { }
| math_expr LEQ math_expr { }
| math_expr GT math_expr { }
| math_expr GEQ math_expr { }
| LPAREN log_expr RPAREN { }
| BOOL_LITERAL
| func_call
;
//
// types
interface_types:
INTERFACE_LITERAL
struct_types:
STRUCT LBRACE declarate_field_list RBRACE
;
bool_types:
BOOL
int_types:
UINT { }
| UINT8 { }
| UINT16 { }
| UINT32 { }
| UINT64 { }
| INT { }
| INT8 { }
| INT16 { }
| INT32 {}
| INT64 { }
;
float_types:
FLOAT32
| FLOAT64
complex_types:
COMPLEX64
| COMPLEX128
string_types:
STRING { }
;
func_types:
FUNC LPAREN arg_list RPAREN return_type
type:
int_types { }
| IDENTIFIER
| MULT type %prec POINTER_TYPE { printf("POINTER TYPE\n"); }
| chan_types
| map_types
| slice_types
| arr_types { }
| interface_types
| struct_types { }
| func_types { }
| string_types { }
| float_types { }
| complex_types { }
| bool_types { }
;
//
// literals
literal:
STRING_LITERAL { }
| map_literal
| slice_literal
| arr_literal { }
| struct_literal { }
| func_literal { }
| INTERFACE_LITERAL
| COMPLEX_LITERAL { }
| BOOL_LITERAL { }
| FLOAT_LITERAL { }
| NUMBER { }
;
//
// Package & import blocks
package_declaration:
PACKAGE IDENTIFIER SEMICOLON
{ printf("\033[1;34mPACKAGE IDENTIFIER: %s\n\033[0m", $2); }
;
import_declaration:
| IMPORT { printf("\033[1;36mHELLO, IMPORT BLOCK\n\033[0m"); } import { printf("\033[1;36mBY, IMPORT BLOCK\n\n\033[0m"); }
| IMPORT { printf("\033[1;36mHELLO, IMPORT BLOCK\n\033[0m"); } LPAREN import_list RPAREN { printf("\033[1;36mBY, IMPORT BLOCK\n\n\033[0m"); }
;
import:
IDENTIFIER STRING_LITERAL { printf("\033[1;36mIMPORTED PACKAGE\n\033[0m"); } SEMICOLON
| STRING_LITERAL { printf("\033[1;36mIMPORTED PACKAGE\n\033[0m"); } SEMICOLON
;
import_list:
import
| import_list import
;
//
// arrays
// для случая arr5 := [4]int{1: 42, 3: 99}; с частичным указанием значений
arr_field:
NUMBER COLON math_expr
| NUMBER COLON literal
arr_field_list:
| arr_field
| arr_field_list COMMA arr_field
arr_literal:
LBRACK NUMBER RBRACK type LBRACE math_expr_or_literals_list_or_empty RBRACE
| LBRACK DOTS RBRACK type LBRACE math_expr_or_literals_list_or_empty RBRACE
| LBRACK NUMBER RBRACK type LBRACE arr_field_list RBRACE
arr_types:
LBRACK NUMBER RBRACK type
arr_element:
IDENTIFIER LBRACK NUMBER RBRACK
// slices
slice_literal:
LBRACK RBRACK type LBRACE math_expr_or_literals_list_or_empty RBRACE
slice_types:
LBRACK RBRACK type
// functions
// Анонимная функция
anon_func:
FUNC LPAREN arg_list RPAREN return_type block
{ printf("\033[1;35mANONYMOUS FUNC\n\033[0m"); }
;
// Литерал функции (если нужно для других правил)
func_literal: anon_func;
// Вызов функции
func_call:
any_identifier LPAREN math_expr_or_literals_list_or_empty RPAREN
| anon_func LPAREN math_expr_or_literals_list_or_empty RPAREN
| anon_func // Позволяет использовать func(){} как значение
;
arg_declaration:
identifiers_list type
{ printf("\033[1;35mARG DECLARATIONS\n\033[0m"); }
;
arg_list:
| arg_declaration
| arg_list COMMA arg_declaration
;
return_type:
| type
| LPAREN types_list RPAREN { }
| LPAREN arg_list RPAREN { }
;
func_declaration:
FUNC IDENTIFIER
{ printf("\033[1;35mHELLO, FUNC: %s\n\033[0m", $2); }
LPAREN arg_list RPAREN return_type block
{ printf("\033[1;35mBY, FUNC: %s\n\n\033[0m", $2); }
;
// Объявление метода
method_declaration:
FUNC LPAREN IDENTIFIER type RPAREN IDENTIFIER
{ printf("\033[1;35mMETHOD DECL: %s\n\033[0m", $6); }
LPAREN arg_list RPAREN return_type block
{ printf("\033[1;35mEND METHOD\n\033[0m"); }
;
// map
map_field:
literal COLON literal { }
| literal COLON math_expr { }
| literal COLON func_call { }
map_field_list:
| map_field
| map_field_list COMMA map_field
map_types:
MAP LBRACK type RBRACK type
map_literal:
map_types LBRACE map_field_list RBRACE
map_element:
IDENTIFIER LBRACK literal RBRACK
| IDENTIFIER LBRACK any_identifier RBRACK
// interface
interface_declaration:
INTERFACE {printf("INTERFACE\n"); } LBRACE interface_declarate_field_list RBRACE
interface_field:
IDENTIFIER LPAREN arg_list RPAREN {printf("ret type interface\n");} return_type
interface_declarate_field_list:
| interface_field SEMICOLON
| interface_declarate_field_list interface_field SEMICOLON
;
// struct
declarate_field_list:
| arg_declaration SEMICOLON
| IDENTIFIER SEMICOLON
| declarate_field_list arg_declaration SEMICOLON
| declarate_field_list IDENTIFIER SEMICOLON
;
field:
IDENTIFIER COLON literal { }
| IDENTIFIER COLON math_expr { }
| IDENTIFIER COLON func_call { }
field_list:
| field
| field_list COMMA field
struct_literal:
any_identifier LBRACE field_list RBRACE { printf("STRUCT LITERAL\n"); }
| any_identifier LBRACE math_expr_or_literals_list RBRACE { printf("STRUCT LITERAL\n"); }
//
chan_types:
CHAN type
// assignment
var_multiple_short_assignment:
identifiers_list ASSIGN math_expr_or_literals_list
// vars decl
var_multiple_short_declaration:
identifiers_list SHORT_DECLARATION math_expr_or_literals_list
var_declaration:
VAR IDENTIFIER type
| VAR IDENTIFIER any_identifier
| VAR identifiers_list any_identifier { { printf("\033[1;33mVAR DECL without init value\n\033[0m"); } }
| VAR identifiers_list type { { printf("\033[1;33mVAR DECL without init value\n\033[0m"); } }
| VAR identifiers_list ASSIGN math_expr_or_literals_list { { printf("\033[1;33mVAR DECL with literal init value\n\033[0m"); } }
| VAR identifiers_list type ASSIGN math_expr_or_literals_list { { printf("\033[1;33mVAR DECL with literal init value\n\033[0m"); } }
| VAR identifiers_list any_identifier ASSIGN math_expr_or_literals_list { { printf("\033[1;33mVAR DECL with literal init value\n\033[0m"); } }
| VAR IDENTIFIER any_identifier ASSIGN math_expr { { printf("\033[1;33mVAR DECL with type and math expr init value: %s\n\033[0m", $2); } }
| VAR IDENTIFIER any_identifier ASSIGN literal { { printf("\033[1;33mVAR DECL with type and literal init value: %s\n\033[0m", $2); } }
| VAR IDENTIFIER type ASSIGN math_expr { { printf("\033[1;33mVAR DECL with type and math expr init value: %s\n\033[0m", $2); } }
| VAR IDENTIFIER type ASSIGN literal { { printf("\033[1;33mVAR DECL with type and literal init value: %s\n\033[0m", $2); } }
;
// type decl
type_delcaration:
TYPE IDENTIFIER type { { printf("\033[1;33mTYPE DECL\n\033[0m"); } }
// make
make:
MAKE LPAREN type RPAREN
| MAKE LPAREN type COMMA math_expr RPAREN
| MAKE LPAREN type COMMA math_expr COMMA math_expr RPAREN
%%
//
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");
perror("\033[1;91mFailed to open file\033[0m");
return 1;
}
yyin = f;
}
yyparse();
printf("\033[1;92mGOOD CODE\033[0m\n");
return 0;
}

View File

@ -3,9 +3,9 @@ import subprocess
# ЭТИ ПУТИ НАДО ЗАДАТЬ ВРУЧНУЮ
# *.l и *.y файлы из директории ANALYZERS_DIR ДОЛЖНЫ НАЗЫВАТЬСЯ как basename этой директории!!!
ANALYZERS_DIR = r'C:\Users\Илья\Desktop\6sem\Компиляторы\Курсач\go-analyzer\analyzers\test'
FLEX_EXE_PATH = r"C:\Users\Илья\Desktop\win_flex_bison-latest\win_flex.exe"
BISON_EXE_PATH = r"C:\Users\Илья\Desktop\win_flex_bison-latest\win_bison.exe"
ANALYZERS_DIR = r'C:\Users\user\Desktop\УЧЕБА\6_СЕМ\КОМПИЛЯТОРЫ\go-analyzer-ilya\analyzers\test'
FLEX_EXE_PATH = r"C:\tools\win_flex_bison\win_flex.exe"
BISON_EXE_PATH = r"C:\tools\win_flex_bison\win_bison.exe"
def main():
# Подготовка путей

View File

@ -1,7 +1,46 @@
package main
import "fmt"
func main() {
fmt.Println("hello, sailor!")
type person struct {
name, second_name string
age int
}
type epmty struct {
}
func test(int, int) {
}
func ujas() (func() func() func() int, int, string) {
return func() func() func() int {
return func() func() int {
return func() int {
return 0
}
}
}, 1, "hello world"
}
func main() {
var a, b int
a, b = 1, 1
// a := "Tom"
// fmt.Println(a)
// arr := []int{1, 2, 3}
// for idx, val := range arr {
// fmt.Println(idx, val)
// }
// defer func() {
// if err := recover(); err != nil {
// log.Println("work failed:", err)
// }
// }()
// func(msg string) {
// fmt.Println("Message:", msg)
// }("Hello, IIFE!")
// return
}

48
tests/test.txt Normal file
View File

@ -0,0 +1,48 @@
package main;
import (
"fmt";
"log";
)
// A toy implementation of cube root using Newton's method.
func CubeRoot(x float64) float64 {
z := x/3; // Arbitrary initial value
for i := 0; i < 1e6; i++ {
prevz := z;
z -= (z*z*z-x) / (3*z*z);
if veryClose(z, prevz) {
return z;
}
}
// A million iterations has not converged; something is wrong.
panic(fmt.Sprintf("CubeRoot(%g) did not converge", x));
}
func test() {
z -= (z*z*z-x) / (3*z*z);
return "123";
}
func test(a int, b string) {
s := "123njda skjad";
a := 2;
return a + 1;
}
func main() {
CubeRoot(123.1);
var a int;
var c complex128 = 555.12i+1.123i;
a := 123+123e45 + 123.456 +123.456e-78+123i+123.456e10i;
a = 2+2*2-(1+10)+213i*2 - 2.123i - c;
a = a + 1;
a = a;
}

38
tests/test_arrays.txt Normal file
View File

@ -0,0 +1,38 @@
package main;
func main() {
// Явное указание размера и значений
arr := [4]int{3, 2, 5, 4};
// Автовычисление размера
arr := [...]int{3, 2, 5, 4};
// Частичное определение: все не определенные элементы - zero-values
arr8 := [3]int{};
arr6 := [3]bool{true};
arr5 := [4]int{1: 42, 3: 99};
//
var arr7 [4]int;
var arr7 [4]func() func() []func() string;
arr7 = [4]int{1,2,3,4};
arr7, arr8 = [4]int{1,2,3,4}, [4]int{1,2,3,4};
// Изменение элемента массива
arr[1];
arr[1] = 2+2*2;
arr[1] = [4]int{3, 2, 5, 4};
arr[1] = "test";
// СЛАЙСЫ
var slice1 []int;
var slice2 = []int{};
slice6 := []int{};
slice7 := []int{1, 2, 3};
slice7[2] = 123;
slice8, slice8 = []int{1,2,3,4}, []int{1,2,3,4};
// создание с использованием make
list := make([]int, 0, 5);
fmt.Println(list); // []
fmt.Println(len(list)); // 0
fmt.Println(cap(list)); // 5
}

View File

@ -1,13 +1,84 @@
{
{
{1}{}
block1 {
block2 { block3 }
block4 asjdb asd bajds ba
} 126316
block5
package main;
import (
"fmt";
"log";
)
func test_if() {
if a != a{
}
{
123
if !(a != 1) {
}
if a != 1 && a > 1 {
}
}
func test_func(a string, b int, c uint16) int {
var x int = 42;
y := "hello";
}
func func_without_args() int {
return 1;
}
func func_without_return_type(a string) {
return a;
}
func main() {
a := 229.162613;
if (a > 300) {
s := "test string";
}
for i := 5; i < 10; i &^= 1 {
i++;
break;
}
for i := 0; i < 10 && j > 5; i++ {
}
for {
var d complex128;
a := 229.162613;
break gotocheck;
s := "test string";
b := 2 - 1;
}
for i := 0; i < 10; i += 2 { }
for i := 0; i < 10; i = i * 2 {
break;
}
for i := 10; i > 0; i-- { }
a = 1;
a = test;
s := "test string";
var a int;
var a int8;
var a int16;
var a int32;
var a int64;
var a uint8;
var a uint16;
var a uint32;
var a uint64;
var b float32;
var c float64;
var d complex128;
var e complex64;
var a string = "123123";
{
b := 2 - 1;
s := "123";
}
}

23
tests/test_chans.txt Normal file
View File

@ -0,0 +1,23 @@
package main;
func main() {
var ch chan int;
// 2. Инициализация канала с помощью make
ch = make(chan int);
fmt.Printf("После make: ch = %v\n", ch);
// 3. Запуск горутины для отправки данных
go func() {
fmt.Println("Горутина: отправляю 42 в канал");
ch <- 42; // Отправка данных
}();
// 4. Основной поток получает данные
time.Sleep(100 * time.Millisecond); // Даем время горутине запуститься
value := <-ch;
fmt.Println("Получено:", value);
// 5. Закрытие канала
close(ch);
}

71
tests/test_cicle.txt Normal file
View File

@ -0,0 +1,71 @@
package main;
func main() {
for i := 5 - 3*(6-7); i < 10; i++ {
}
for {
break;
}
i := 0;
for i < 5 {
i++;
}
for j := 0; j < 10; j++ {
}
for o := 0; o < 10; o++ {
if o%2 == 0 {
continue;
}
}
for n := 0; ; n++ {
if n > 5 {
break;
}
}
outer:
for p := 0; p < 3; p++ {
for q := 0; q < 3; q++ {
if p*q > 2 {
break outer;
}
}
}
outer2:
for r := 0; r < 3; r++ {
for s := 0; s < 3; s++ {
if r*s > 1 {
continue outer2;
}
}
}
for t := 10; t > 0; t-- {
}
u := 0;
for u < 5 {
u++;
}
for k, l := 0, 10; k < l; k, l = k+1, l-1 {
}
for idx, val := range arr {
}
for key, value := range m {
}
return;
}

23
tests/test_func_calls.txt Normal file
View File

@ -0,0 +1,23 @@
package main;
import (
"fmt";
)
func test(a int) int {
return a;
}
func isValid() bool {
return true;
}
func main() {
a := test(1); // вызов функции обычной
fmt.Println(test(test(1)*2+3 - a)); // вызов функции из fmt
return;
return 1,2,3,a,"123",1.232, test(1)*2;
}

113
tests/test_funcs.txt Normal file
View File

@ -0,0 +1,113 @@
package main;
import "fmt";
func server(a int) {
for work := range workChan {
}
}
func iife(work int) {
var add MathFunc = func(a, b int) int {
return a + b;
};
var err error;
var app models.App;
log.SetPrefix(fmt.Sprintf("%s | ", app.Cfg.ServerDomain));
cache := candycache.Cacher(10 * time.Minute);
cache.Set("key7", -2.1231, 10*time.Minute);
router := setupRoutes(app);
if app, err = models.InitApp(); err != nil {
log.Fatal(err);
}
// Обработка страничек постов
for key := range app.Posts {
postLink := a(key);
router.Handle(postLink, m(controllers_pages.PostPageHandler(app)));
}
for i := 1; i < 3; i++ {
go func(a int) {
fmt.Println(123);
}();
func(){}();
go func(a, b string) {
fmt.Println("Message:", a + b);
}("Hello", ", world!");
defer func() {
if err := recover(); err != nil {
go log.Println("work failed:", err);
}
}();
}
}
func ujas() (func() func() func() int, int, string) {
return func() func() func() int {
return func() func() int {
return func() int {
return 0;
};
};
}, 1, "hello world";
}
func A(x, y int) {
}
func B(x, y int) () {
}
func C(x, y int) int {
}
func D(x, y int) (int, string) {
}
func E(x, y int) (z, f, u int, a string) {
}
// анонимные функции
func anon_func(a,b,c,d string, a int) {
// Присваиваем анонимную функцию переменной
square := func(x, y int) int {
return x * y;
};
fmt.Println(square(5, 5)); // Выведет: 25
}
// замыкания
func intSeq() func() int {
i := 0;
return func() int {
i++;
return i;
};
}
func main() {
nextInt := intSeq(intSeq(), intSeq(), intSeq(), intSeq(intSeq())); // рекурсия
fmt.Println(nextInt());
fmt.Println(nextInt());
fmt.Println(nextInt());
newInts := intSeq();
fmt.Println(newInts());
}

64
tests/test_if.txt Normal file
View File

@ -0,0 +1,64 @@
package main;
import "fmt";
func main() {
if true {
}
if false {
} else {
}
x := 10;
if x < 5 {
} else if x < 15 {
} else {
}
if true {
if false {
} else {
}
}
if (x > 5 || x < 15) && x != 10 {
}
if z := x * 2; z > 15 && z < 25 {
}
if false {
}
if isValid() {
}
if shouldReturn() {
return;
}
}
func isValid() bool {
return true;
}
func shouldReturn() bool {
return false;
}
if app, err = models.InitApp(); err != nil {
log.Fatal(err);
}
if a, b := 1, 2; a < b && b < 3 {
}
if y := 20; y > 15 {
}

46
tests/test_interfaces.txt Normal file
View File

@ -0,0 +1,46 @@
package main;
import "fmt";
type test interface{
a(a int) (a, b int);
b() (a, b int, string);
};
type Vehicle interface{
move();
};
func drive(vehicle Vehicle){
vehicle.move();
}
type Car struct{ };
type Aircraft struct{};
func (c Car) move(){
fmt.Println("Автомобиль едет");
}
func (a Aircraft) move(){
fmt.Println("Самолет летит");
}
func main() {
tesla := Car{};
boing := Aircraft{};
drive(tesla);
drive(boing);
var anything interface{}; // Пустой интерфейс
b := interface{}; // short decl
anything = 42;
fmt.Printf("Тип: %T, Значение: %v\n", anything, anything); // int, 42
anything = "hello";
fmt.Printf("Тип: %T, Значение: %v\n", anything, anything); // string, hello
anything = 3.14;
fmt.Printf("Тип: %T, Значение: %v\n", anything, anything); // float64, 3.14
}

43
tests/test_maps.txt Normal file
View File

@ -0,0 +1,43 @@
package main;
func test() int {
return 123;
}
func main() {
var m1 map[string]int; // nil-мапа
// Литерал
m3 := map[string]int{
"Alice": 25,
"Bob": 30,
"1": test()
};
m_hard := map[string]map[float32]func() int {
"group1": map[float32]func() int {
3.14: func() int { return 42; },
2.71: func() int { return 100; }
},
"group2": map[float32]func() int{
1.41: func() int {
fmt.Println("Вызвана функция из group2!");
return 200;
},
0.01: func() int { return 1; }
}
};
m3 := map[string]int{ // Литерал
"Alice": 25,
"Bob": 30
};
// Добавление элемента
m3["Charlie"] = 28;
// Проверка наличия ключа
age, ok := m3["Alice"]; // ok = true, age = 25
}

24
tests/test_methods.txt Normal file
View File

@ -0,0 +1,24 @@
package main;
// Circle - структура, представляющая круг
type Circle struct {
Radius float64;
};
// Реализация методов интерфейса Geometry для Circle
func (c Circle) Area() float64 {
return math.Pi * c.Radius * c.Radius;
}
func (c Circle) Perimeter() float64 {
return 2 * math.Pi * c.Radius;
}
func (c Circle) Name() string {
return "Круг";
}
func main() {
}

View File

@ -0,0 +1,36 @@
package main;
func dva() {
return 2;
}
func test() {
a := 1; // декларация одной переменной (число)
a := "test"; // декларация одной переменной (строка)
var a, b, c, d int;
var a = 2+2*2;
var a, b, c, d = 1,2,3,4;
var a, b, c, d int = 1,2,3,4;
a = 123;
s = "string";
a, b := 1, 2; // декларация нескольких переменных (целые литералы)
a, b := b, a; // swap
a, b := "hello", "sailor"; // декларация нескольких переменных (строковые литералы)
a, b, c, d, v := "hello", 2, 3.123, true, dva(); // декларация нескольких переменных (всякое)
// цикл с множественной декларацией и множественным присвоением
for k, l := 0, 10; k < l; k, l = k+1, l-1 {
}
}
func main() {
test();
}

13
tests/test_ptr.txt Normal file
View File

@ -0,0 +1,13 @@
package main;
func main() {
var x *int;
y := &x;
*x = 10;
z := 5 * 10;
var pf *float64;
if pf != nil {
fmt.Println("Value:", *pf);
}
}

57
tests/test_types.txt Normal file
View File

@ -0,0 +1,57 @@
package main;
import (
"fmt";
"your_project/models";
)
type mile uint;
type BinaryOp func(int, int) int;
type text []string;
type empty struct{
};
type person struct{
name string;
age int;
};
type person2 struct{
name,second_name string;
age int;
person;
};
func main() {
var p models.Person;
var a,b,c,d models.Person;
var a,b,c models.Person = models.Person{name:"Tom", age:24}, models.Person{"Tom", 24}, models.Person{"Tom", 24};
var p models.Person = person{};
p1 := models.Person{"Tom", 24};
a, undefined := 1, person {};
var alice person = person{age: 23, name: "Alice"};
var tom = person {name: "Tom", age: 24};
var tom1 Person = Person{Name: "Tom", Age: 24};
tom2 := Person{Name: "Tom", Age: 24};
// Явное указание типа с пакетом
var tom3 models.Person = models.Person{Name: "Tom", Age: 24};
// Краткая форма
tom4 := models.Person{Name: "Tom", Age: 24};
// Вывод типа
var tom5 = models.Person{Name: "Tom", Age: 24};
fmt.Println(tom.name); // Tom
fmt.Println(tom.age); // 24
tom.age = 38; // изменяем значение
fmt.Println(tom.name, tom.age); // Tom 38
}

View File

@ -1,7 +0,0 @@
func main() {
println("Hello world");
}
func add(a int, b int) int {
return a + b
}