if и loop сделаны, добавлены для них тесты, нужно будет доделать в процессе
parent
3874c3d4bb
commit
b73d25de50
|
@ -7,7 +7,7 @@
|
|||
extern int yylineno;
|
||||
|
||||
void yyerror(const char *s) {
|
||||
fprintf(stderr, "\033[91mError at line %i: %s\033[0m\n", yylineno, s);
|
||||
fprintf(stderr, "\033[1;91mError at line %i: %s\033[0m\n", yylineno, s);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,51 @@ LETTER_OR_DIGIT [a-zA-Z0-9_]
|
|||
"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; }
|
||||
"true" { return BOOL_LIT; }
|
||||
"false" { return BOOL_LIT; }
|
||||
"if" { return IF; }
|
||||
"else" { return ELSE; }
|
||||
"<-" { return ARROW; }
|
||||
|
||||
"==" { 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; }
|
||||
|
||||
"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; }
|
||||
|
@ -50,6 +94,8 @@ LETTER_OR_DIGIT [a-zA-Z0-9_]
|
|||
")" { return RPAREN; }
|
||||
"," { return COMMA; }
|
||||
";" { return SEMICOLON; }
|
||||
"..." { return DOTS; }
|
||||
":" { return COLON; }
|
||||
|
||||
\"([^"\\]|\\.)*\" { // правило для строк с возможность экранирования через \спецсимвол
|
||||
return STRING_LITERAL;
|
||||
|
|
|
@ -21,17 +21,32 @@ void free_node(char *str) {
|
|||
double num;
|
||||
}
|
||||
|
||||
%token SHORT_DECLARATION LBRACE RBRACE SEMICOLON ASSIGN LPAREN RPAREN COMMA
|
||||
%token SHORT_DECLARATION LBRACE RBRACE SEMICOLON ASSIGN LPAREN RPAREN COMMA COLON DOTS
|
||||
%token VAR FUNC RETURN STRING_LITERAL FLOAT_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
|
||||
%token CHAN CONST CASE SWITCH
|
||||
%token PLUS MINUS MULT DIV MOD
|
||||
%token STRING
|
||||
%token UINT UINT8 UINT16 UINT32 UINT64
|
||||
%token UINT UINT8 UINT16 UINT32 UINT64 UINT_PTR
|
||||
%token INT INT8 INT16 INT32 INT64
|
||||
|
||||
%token RUNE BYTE BOOL_LIT
|
||||
%token FLOAT32 FLOAT64
|
||||
%token COMPLEX64 COMPLEX128
|
||||
%token <str> IDENTIFIER
|
||||
%token AND OR NOT EQ NEQ LT GT LEQ GEQ
|
||||
|
||||
%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 MULT DIV MOD
|
||||
%left OR
|
||||
%left AND
|
||||
%right INC DEC
|
||||
%right NOT
|
||||
%nonassoc EQ NEQ LT GT LEQ GEQ
|
||||
%left UMINUS
|
||||
|
||||
%%
|
||||
|
@ -41,21 +56,103 @@ program:
|
|||
| program statement
|
||||
;
|
||||
|
||||
|
||||
statement:
|
||||
expr SEMICOLON
|
||||
| var_declaration SEMICOLON
|
||||
{ printf("\033[1;33mSTATEMENT: variable declaration\033[0m\n"); }
|
||||
| func_declaration
|
||||
| block
|
||||
{ printf("\033[1;33mSTATEMENT: function declaration\033[0m\n"); }
|
||||
| cicle
|
||||
{ printf("\033[1;33mSTATEMENT: loop construct\033[0m\n"); }
|
||||
| IF log_expr block else_part
|
||||
| IDENTIFIER COLON
|
||||
{ printf("\033[1;33mSTATEMENT: label definition '%s'\033[0m\n", $1); }
|
||||
;
|
||||
|
||||
|
||||
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:
|
||||
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"); }
|
||||
;
|
||||
|
||||
|
||||
post_statement:
|
||||
| IDENTIFIER ASSIGN math_expr { }
|
||||
| IDENTIFIER INC { }
|
||||
| IDENTIFIER DEC { }
|
||||
| INC IDENTIFIER { }
|
||||
| DEC IDENTIFIER { }
|
||||
| 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 { }
|
||||
|
||||
block:
|
||||
LBRACE statements_list RBRACE
|
||||
;
|
||||
|
||||
|
||||
statements_list:
|
||||
| statements_list statement
|
||||
| statements_list block
|
||||
| statements_list expr SEMICOLON
|
||||
;
|
||||
|
||||
loop_block:
|
||||
LBRACE loop_statements RBRACE
|
||||
;
|
||||
|
||||
init_loop_statement:
|
||||
| IDENTIFIER SHORT_DECLARATION math_expr
|
||||
| IDENTIFIER ASSIGN math_expr
|
||||
|
||||
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); }
|
||||
;
|
||||
|
||||
|
||||
|
||||
expr:
|
||||
RETURN math_expr { printf("\033[1;35mRETURN math expr\033[0m\n") }
|
||||
| RETURN literal { printf("\033[1;35mRETURN literal\033[0m\n") }
|
||||
|
@ -74,9 +171,28 @@ math_expr:
|
|||
| NUMBER { printf("NUMBER\n"); }
|
||||
| FLOAT_LITERAL { printf("FLOAT LITERAL\n"); }
|
||||
| IDENTIFIER { printf("IDENTIFIER: %s\n", $1); }
|
||||
| IDENTIFIER INC { printf("POST-INCREMENT: %s++\n", $1); }
|
||||
| IDENTIFIER DEC { printf("POST-DECREMENT: %s--\n", $1); }
|
||||
;
|
||||
|
||||
log_expr:
|
||||
| log_expr AND log_expr { }
|
||||
| log_expr OR log_expr { }
|
||||
| NOT log_expr %prec UMINUS { }
|
||||
| comparison_expr { }
|
||||
| LPAREN log_expr RPAREN { }
|
||||
| BOOL_LIT
|
||||
;
|
||||
|
||||
comparison_expr:
|
||||
| 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 { }
|
||||
;
|
||||
|
||||
/* Остальные правила остаются без изменений */
|
||||
int_types:
|
||||
UINT { }
|
||||
| UINT8 { }
|
||||
|
@ -90,6 +206,14 @@ int_types:
|
|||
| INT64 { }
|
||||
;
|
||||
|
||||
float_types:
|
||||
FLOAT32
|
||||
| FLOAT64
|
||||
|
||||
complex_types:
|
||||
COMPLEX64
|
||||
| COMPLEX128
|
||||
|
||||
string_types:
|
||||
STRING { }
|
||||
;
|
||||
|
@ -97,10 +221,13 @@ string_types:
|
|||
type:
|
||||
int_types { }
|
||||
| string_types { }
|
||||
| float_types { }
|
||||
| complex_types { }
|
||||
;
|
||||
|
||||
literal:
|
||||
STRING_LITERAL { }
|
||||
| BOOL_LIT { }
|
||||
| FLOAT_LITERAL { }
|
||||
| NUMBER { }
|
||||
;
|
||||
|
@ -112,12 +239,13 @@ package_declaration:
|
|||
;
|
||||
|
||||
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"); } 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:
|
||||
STRING_LITERAL { printf("\033[1;36mIMPORTED PACKAGE\n\033[0m"); } SEMICOLON
|
||||
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:
|
||||
|
@ -126,6 +254,7 @@ import_list:
|
|||
;
|
||||
//
|
||||
|
||||
// functions decl
|
||||
arg_declaration:
|
||||
IDENTIFIER type
|
||||
{ printf("\033[1;35mARG: %s\n\033[0m", $1); }
|
||||
|
@ -146,7 +275,9 @@ func_declaration:
|
|||
LPAREN arg_list RPAREN return_type block
|
||||
{ printf("\033[1;35mBY, FUNC: %s\n\n\033[0m", $2); }
|
||||
;
|
||||
//
|
||||
|
||||
// vars decl
|
||||
var_declaration:
|
||||
IDENTIFIER SHORT_DECLARATION math_expr { printf("\033[1;33mSHORT DECL with math expr: %s\n\033[0m", $1); }
|
||||
| IDENTIFIER SHORT_DECLARATION literal { printf("\033[1;33mSHORT DECL with literal: %s\n\033[0m", $1); }
|
||||
|
@ -156,17 +287,18 @@ var_declaration:
|
|||
;
|
||||
|
||||
%%
|
||||
//
|
||||
|
||||
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[92mGOOD CODE\033[0m");
|
||||
printf("\033[1;92mGOOD CODE\033[0m\n");
|
||||
return 0;
|
||||
}
|
6
main.py
6
main.py
|
@ -3,9 +3,9 @@ import subprocess
|
|||
|
||||
# ЭТИ ПУТИ НАДО ЗАДАТЬ ВРУЧНУЮ
|
||||
# *.l и *.y файлы из директории ANALYZERS_DIR ДОЛЖНЫ НАЗЫВАТЬСЯ как basename этой директории!!!
|
||||
ANALYZERS_DIR = r'C:\Users\user\Desktop\УЧЕБА\6_СЕМ\КОМПИЛЯТОРЫ\go-analyzer\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"
|
||||
ANALYZERS_DIR = r'C:\Users\Илья\Desktop\6sem\Компиляторы\Курсач\2\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"
|
||||
|
||||
def main():
|
||||
# Подготовка путей
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
package main;
|
||||
|
||||
import (
|
||||
"fmt";
|
||||
"log";
|
||||
)
|
||||
|
||||
func test_func(a string, b int, c uint16) int {
|
||||
var x int = 42;
|
||||
|
@ -11,12 +17,29 @@ func func_without_args() int {
|
|||
func func_without_return_type(a string) {
|
||||
return a;
|
||||
}
|
||||
|
||||
a := 1 + 2;
|
||||
{
|
||||
|
||||
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 = s;
|
||||
|
||||
|
@ -31,7 +54,10 @@ a := 1 + 2;
|
|||
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";
|
||||
{
|
||||
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
package main;
|
||||
|
||||
func main() {
|
||||
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 {
|
||||
}
|
||||
|
||||
arr := []int{1, 2, 3}
|
||||
for idx, val := range arr {
|
||||
}
|
||||
|
||||
m := map[string]int{"a": 1, "b": 2}
|
||||
for key, value := range m {
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
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 a, b := 1, 2; a < b && b < 3 {
|
||||
}
|
||||
if y := 20; y > 15 {
|
||||
}
|
Loading…
Reference in New Issue