Beispiel #1
0
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}
}
Beispiel #2
0
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}
}