diff --git a/ass3/zbirnik/parsing/input_invalid.asm b/ass3/zbirnik/parsing/input_invalid.asm index 0b46a01..641133d 100644 --- a/ass3/zbirnik/parsing/input_invalid.asm +++ b/ass3/zbirnik/parsing/input_invalid.asm @@ -19,8 +19,14 @@ arithr START 0 .komentar1 MULR T, A STA prod + SUBR A, X + SHIFTR A, 10 + SHIFTL X, #101 +LA DIVR S, T . en komentar LDA ZERO ADDR S, A +lab SHIFTR A, 5 +CLR SHIFTR L, 100 .komentar DIVR T, A STA quot FIX . s komentarjem @@ -31,6 +37,12 @@ LOOP SUBR T, A .komentar5 JGT LOOP JEQ LOOP STA mod +Lab SVC #100 +lab CLEAR A + SVC 10 + TIXR S +test SVC @300 . se en komentar +LA TIXR T . komentar at the end HALT J HALT END arithr diff --git a/ass3/zbirnik/parsing/pregledovalnik.go b/ass3/zbirnik/parsing/pregledovalnik.go index 22cb8dc..9bad7c6 100644 --- a/ass3/zbirnik/parsing/pregledovalnik.go +++ b/ass3/zbirnik/parsing/pregledovalnik.go @@ -7,19 +7,6 @@ import ( "strings" ) -type ukaz interface { - Temp() -} - -func (f format_F1) Temp() {} - -type format_F1 struct { - opcode int - st_operandov int - format int // F1 - 1, F2 - 2, F3 - 3, F4 - 4, SIC - 5 - velikost int //v bajtih -} - var ukazna_tabela = map[string]int{ "ADD": 0x18, "ADDF": 0x58, @@ -82,39 +69,77 @@ var ukazna_tabela = map[string]int{ "WD": 0xDC, } -// Pregledovalnik bere vhodne vrstice in jih razgradi na posamezne enote. -// Razpoznane elemente okvalificira (oznaka / mnemonik / operand / komentar) -// // ::== [] { } [] +type ukaz interface { + Temp() +} +func (f format_F1) Temp() {} +func (f format_F2_n) Temp() {} +func (f format_F2_r) Temp() {} +func (f format_F2_rn) Temp() {} +var register string = `A|X|L|B|S|T|F` -func main() { - register = `A|X|L|B|S|T|F` - - inputbyte, err := os.ReadFile("input_invalid.asm") +type format_F1 struct { + oznaka string + opcode int + format int // F1 - 1, F2 - 2, F3 - 3, F4 - 4, SIC - 5 + velikost int //v bajtih +} + +type format_F2_n struct { + oznaka string + opcode int + format int + velikost int + n string +} + +type format_F2_r struct { + oznaka string + opcode int + format int + velikost int + r1 string +} + +type format_F2_rn struct { + oznaka string + opcode int + format int + velikost int + r1 string + n string +} + +type format_F2_rr struct { + oznaka string + opcode int + format int + velikost int + r1 string + r2 string +} + +func remove_comments_and_empty_lines(el string) bool { + match_pure_comment, err := regexp.MatchString(`(?m)^[\t ]*\..*$\n`, el) if err != nil { - fmt.Println("Error reading input file: ", err) - return + fmt.Println("Error while matching string.") } - input := string(inputbyte) - pattern := regexp.MustCompile(`.*\n`) - matches := pattern.FindAllString(input, -1) - var AST []ukaz - for _, el := range matches { - match_pure_comment, err := regexp.MatchString(`(?m)^[\t ]*\..*$\n`, el) - if err != nil { - fmt.Println("Error while matching string.") - } - if match_pure_comment { - continue - } - match_empty, err := regexp.MatchString(`(?m)^[\t ]*$\n`, el) - if err != nil { - fmt.Println("Error while matching string.") - } - if match_empty { - continue - } + if match_pure_comment { + return true + } + match_empty, err := regexp.MatchString(`(?m)^[\t ]*$\n`, el) + if err != nil { + fmt.Println("Error while matching string.") + } + if match_empty { + return true + } + return false +} + +func check_F1(el string, AST *[]ukaz) bool { match_F1, err := regexp.MatchString(`(?m)^[A-Za-z_]*[\t ]+[A-Za-z]+[\t ]*(\..*)?$\n`, el) if err != nil { fmt.Println("Error while matching string.") @@ -122,18 +147,129 @@ func main() { if match_F1 { var nov_ukaz format_F1 nov_ukaz.format = 1 - nov_ukaz.st_operandov = 0 nov_ukaz.velikost = 1 pattern := regexp.MustCompile(`[\t ]+[A-Za-z]+`) - mnemonik := strings.Trim(pattern.FindString(el), " \n") + mnemonik := strings.Trim(pattern.FindString(el), "\t ") nov_ukaz.opcode = ukazna_tabela[mnemonik]; - fmt.Println(mnemonik, nov_ukaz.opcode) - AST = append(AST, nov_ukaz) - continue + //fmt.Println("F1: ", mnemonik, nov_ukaz.opcode) + *AST = append(*AST, nov_ukaz) + return true } - match_F2, err := regexp.MatchString(`^[A-Za-z_]*[\t ]+[A-Za-z_]+[\t ](((`+register+`), `+register+`)|(`+register+`))[\t ]*(\..*)?$\n`) - if err != nil { - fmt.Println("Error while matching string.") + return false +} + +func check_F2_n(el string, AST *[]ukaz) bool { + match_F2_n, err := regexp.MatchString(`(?m)^[A-Za-z_]*[\t ]+SVC ((#?|@?)[0-9]+)[\t ]*(\..*)?$\n`, el) + if err != nil { + fmt.Println("Error while matching string.") + } + if match_F2_n { + var nov_ukaz format_F2_n + nov_ukaz.format = 2 + nov_ukaz.velikost = 2 + nov_ukaz.opcode = 10 + if !(strings.HasPrefix(el, " ") || strings.HasPrefix(el, "\t")) { + re := regexp.MustCompile(`(?m)^[A-Z-a-z_]+`) + nov_ukaz.oznaka = re.FindString(el) + } else { + nov_ukaz.oznaka = "" + } + re_par := regexp.MustCompile(`[\t ]+(#?|@?)[0-9]+`) + nov_ukaz.n = strings.Trim(re_par.FindString(el), "\t ") + //fmt.Println(nov_ukaz) + *AST = append(*AST, nov_ukaz) + return true + } + return false +} + +func check_F2_r(el string, AST *[]ukaz) bool { + match_F2_r, err := regexp.MatchString(`(?m)^[A-Za-z_]*[\t ]+[A-Za-z]+ (`+register+`)[\t ]*(\..*)?$\n`, el) + if err != nil { + fmt.Println("Error while matching string.") + } + if match_F2_r { + var nov_ukaz format_F2_r + nov_ukaz.format = 2 + nov_ukaz.velikost = 2 + if !(strings.HasPrefix(el, " ") || strings.HasPrefix(el, "\t")) { + re := regexp.MustCompile(`(?m)^[A-Z-a-z_]+`) + nov_ukaz.oznaka = re.FindString(el) + } else { + nov_ukaz.oznaka = "" + } + re_op := regexp.MustCompile(`[\t ]+[A-Za-z]+`) + nov_ukaz.opcode = ukazna_tabela[strings.Trim(re_op.FindString(el), "\t ")] + re_par := regexp.MustCompile(`[\t ]+[A-Za-z]+ (`+register+`)`) + nov_ukaz.r1 = strings.Split(strings.Trim(re_par.FindString(el), "\t \n"), " ")[1] + //fmt.Println(nov_ukaz) + *AST = append(*AST, nov_ukaz) + return true + } + return false +} + +func check_F2_rn(el string, AST *[]ukaz) bool { + match_F2_rn, err := regexp.MatchString(`(?m)^[A-Za-z_]*[\t ]+[A-Za-z]+ (`+register+`), ((#?|@?)[0-9]+)[\t ]*(\..*)?$\n`, el) + if err != nil { + fmt.Println("Error while matching string.") + } + if match_F2_rn { + var nov_ukaz format_F2_rn + nov_ukaz.format = 2 + nov_ukaz.velikost = 2 + if !(strings.HasPrefix(el, " ") || strings.HasPrefix(el, "\t")) { + re := regexp.MustCompile(`(?m)^[A-Z-a-z_]+`) + nov_ukaz.oznaka = re.FindString(el) + } else { + nov_ukaz.oznaka = "" + } + re_op := regexp.MustCompile(`[\t ]+[A-Za-z]+`) + nov_ukaz.opcode = ukazna_tabela[strings.Trim(re_op.FindString(el), "\t ")] + re_par1 := regexp.MustCompile(`[\t ]+[A-Za-z]+ (`+register+`)`) + nov_ukaz.r1 = strings.Split(strings.Trim(re_par1.FindString(el), "\t \n"), " ")[1] + re_par2 := regexp.MustCompile(`(`+register+`), ((#?|@?)[0-9]+)`) + nov_ukaz.n = strings.Split(re_par2.FindString(el), " ")[1] + fmt.Println("F2_rn: ", nov_ukaz) + *AST = append(*AST, nov_ukaz) + return true + } + return false +} + +// Pregledovalnik bere vhodne vrstice in jih razgradi na posamezne enote. +// Razpoznane elemente okvalificira (oznaka / mnemonik / operand / komentar) +// // ::== [] { } [] + +//TODO ideja kaj ce bi prvo leve labele razresil/odstranil in potem regex za ukaze +func main() { + inputbyte, err := os.ReadFile("input_invalid.asm") + if err != nil { + fmt.Println("Error reading input file: ", err) + return + } + + input := string(inputbyte) + pattern := regexp.MustCompile(`.*\n`) + matches := pattern.FindAllString(input, -1) + var AST []ukaz + + for _, el := range matches { + if remove_comments_and_empty_lines(el) { + continue } + if check_F1(el, &AST) { + continue + } + if check_F2_n(el, &AST) { + continue + } + if check_F2_r(el, &AST) { + continue; + } + if check_F2_rn(el, &AST) { + continue; + } + //match_F2, err := regexp.MatchString(`(?m)^[A-Za-z_]*[\t ]+[A-Za-z_]+[\t ](((`+register+`), (`+register+`))|((`+register+`), (#?|@?)[0-9]+)|(`+register+`))[\t ]*(\..*)?$\n`, el) } }