func MatchInt(line lib.Line, index int) (int, lib.Token) { l := line.Value t := lib.Token{-1, "", lib.NULL, lib.NULL} errorFlag := false errorReasons := list.New() if !unicode.IsDigit(rune(l[index])) { return index, lib.Token{} } i := index for i < len(l) && unicode.IsDigit(rune(l[i])) { i++ } if i-index > 10 { if !errorFlag { t = lib.Token{line.Number, "", lib.LEXERR, lib.XX_TOO_LONG} errorFlag = true } errorReasons.PushBack("LEXERR: EXTRA LONG INTEGER: ") } if index+1 < len(l) && string(l[index]) == "0" && unicode.IsDigit(rune(l[index+1])) { if !errorFlag { t = lib.Token{line.Number, "", lib.LEXERR, lib.LEADING_ZEROS} errorFlag = true } errorReasons.PushBack("LEXERR: LEADING ZEROS: ") } lexeme := l[index:i] if errorFlag { t.Lexeme = lexeme for e := errorReasons.Front(); e != nil; e = e.Next() { line.Errors.PushBack(lib.Error{e.Value.(string) + lexeme, &t}) } return i, t } return i, lib.Token{line.Number, lexeme, lib.NUM, lib.INT} }
func MatchLongReal(line lib.Line, index int) (int, lib.Token) { l := line.Value t := lib.Token{-1, "", lib.NULL, lib.NULL} errorFlag := false errorReasons := list.New() if !unicode.IsDigit(rune(l[index])) { return index, lib.Token{} } i := index for i < len(l) && unicode.IsDigit(rune(l[i])) { i++ } if i-index > 5 { if !errorFlag { t = lib.Token{line.Number, "", lib.LEXERR, lib.XX_TOO_LONG} errorFlag = true } errorReasons.PushBack("LEXERR: EXTRA LONG CHARACTERISTIC: ") } if index+1 < len(l) && string(l[index]) == "0" && unicode.IsDigit(rune(l[index+1])) { if !errorFlag { t = lib.Token{line.Number, "", lib.LEXERR, lib.LEADING_ZEROS} errorFlag = true } errorReasons.PushBack("LEXERR: LEADING ZEROS: ") } if i >= len(l) || (string(l[i]) != "." && string(l[i]) != "E") { return index, lib.Token{} } if string(l[i]) == "." { i++ idx := i if i >= len(l) || !unicode.IsDigit(rune(l[i])) { return index, lib.Token{} } for i < len(l) && unicode.IsDigit(rune(l[i])) { i++ } if i-idx > 5 { if !errorFlag { t = lib.Token{line.Number, "", lib.LEXERR, lib.YY_TOO_LONG} errorFlag = true } errorReasons.PushBack("LEXERR: EXTRA LONG FRACTIONAL PART: ") } if string(l[i-1]) == "0" && unicode.IsDigit(rune(l[i-2])) { if !errorFlag { t = lib.Token{line.Number, "", lib.LEXERR, lib.TRAILING_ZEROS} errorFlag = true } errorReasons.PushBack("LEXERR: TRAILING ZEROS: ") } if i >= len(l) || string(l[i]) != "E" { return index, lib.Token{} } } if string(l[i]) == "E" { i++ if i <= len(l) && (string(l[i]) == "+" || string(l[i]) == "-") { i++ } idx := i if i >= len(l) || !unicode.IsDigit(rune(l[i])) { return index, lib.Token{} } for i < len(l) && unicode.IsDigit(rune(l[i])) { i++ } if i-idx > 2 { if !errorFlag { t = lib.Token{line.Number, "", lib.LEXERR, lib.ZZ_TOO_LONG} errorFlag = true } errorReasons.PushBack("LEXERR: EXTRA LONG EXPONENTIAL PART: ") } if idx+1 < len(l) && string(l[idx]) == "0" && unicode.IsDigit(rune(l[idx+1])) { if !errorFlag { t = lib.Token{line.Number, "", lib.LEXERR, lib.LEADING_ZEROS} errorFlag = true } errorReasons.PushBack("LEXERR: LEADING ZEROS: ") } } lexeme := l[index:i] if errorFlag { t.Lexeme = lexeme for e := errorReasons.Front(); e != nil; e = e.Next() { line.Errors.PushBack(lib.Error{e.Value.(string) + lexeme, &t}) } return i, t } return i, lib.Token{line.Number, lexeme, lib.NUM, lib.LONG_REAL} }