diff options
| author | nyamatongwe <unknown> | 2002-10-05 21:36:07 +0000 | 
|---|---|---|
| committer | nyamatongwe <unknown> | 2002-10-05 21:36:07 +0000 | 
| commit | 25171eb9355a88a107de3e251bb7f19790bdf971 (patch) | |
| tree | a6476e43bcfc0c151f3fe70c744f4d99ff6d5e30 /src | |
| parent | 6184b2808a10717d98a05ff7f5d933e026842f8e (diff) | |
| download | scintilla-mirror-25171eb9355a88a107de3e251bb7f19790bdf971.tar.gz | |
Updated Ada lexer.
Diffstat (limited to 'src')
| -rw-r--r-- | src/LexAda.cxx | 619 | 
1 files changed, 297 insertions, 322 deletions
| diff --git a/src/LexAda.cxx b/src/LexAda.cxx index 657218eef..595a05df9 100644 --- a/src/LexAda.cxx +++ b/src/LexAda.cxx @@ -1,3 +1,10 @@ +// Scintilla source code edit control +/** @file LexAda.cxx + ** Lexer for Ada 95 + **/ +// Copyright 2002 by Sergey Koshcheyev <sergey.k@seznam.cz> +// The License.txt file describes the conditions under which this software may be distributed. +  #include <stdlib.h>  #include <ctype.h>  #include <string.h> @@ -15,11 +22,11 @@   */  static void ColouriseDocument( -	unsigned int startPos, -	int length, -	int initStyle, -	WordList *keywordlists[], -	Accessor &styler); +    unsigned int startPos, +    int length, +    int initStyle, +    WordList *keywordlists[], +    Accessor &styler);  LexerModule lmAda(SCLEX_ADA, ColouriseDocument, "ada"); @@ -27,174 +34,172 @@ LexerModule lmAda(SCLEX_ADA, ColouriseDocument, "ada");   * Implementation   */ -static void ColouriseCharacter  (StyleContext& sc); -static void ColouriseContext    (StyleContext& sc, char chEnd, int stateEOL); -static void ColouriseComment    (StyleContext& sc); -static void ColouriseDelimiter  (StyleContext& sc); -static void ColouriseLabel      (StyleContext& sc, WordList& keywords); -static void ColouriseNumber     (StyleContext& sc); -static void ColouriseString     (StyleContext& sc); -static void ColouriseWhiteSpace (StyleContext& sc); -static void ColouriseWord       (StyleContext& sc, WordList& keywords); - -static inline bool isDelimiterCharacter (int ch); -static inline bool isNumberStartCharacter (int ch); -static inline bool isNumberCharacter (int ch); -static inline bool isSeparatorOrDelimiter (int ch); -static        bool isValidIdentifier (const SString& identifier); -static        bool isValidNumber (const SString& number); -static inline bool isWordStartCharacter (int ch); -static inline bool isWordCharacter (int ch); - -static void ColouriseCharacter (StyleContext& sc) -{ -	sc.SetState (SCE_ADA_CHARACTER); -	 +// Functions that have apostropheStartsAttribute as a parameter set it according to whether +// an apostrophe encountered after processing the current token will start an attribute or +// a character literal. +static void ColouriseCharacter(StyleContext& sc, bool& apostropheStartsAttribute); +static void ColouriseComment(StyleContext& sc, bool& apostropheStartsAttribute); +static void ColouriseContext(StyleContext& sc, char chEnd, int stateEOL); +static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute); +static void ColouriseLabel(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute); +static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute); +static void ColouriseString(StyleContext& sc, bool& apostropheStartsAttribute); +static void ColouriseWhiteSpace(StyleContext& sc, bool& apostropheStartsAttribute); +static void ColouriseWord(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute); + +static inline bool IsDelimiterCharacter(int ch); +static inline bool IsNumberStartCharacter(int ch); +static inline bool IsNumberCharacter(int ch); +static inline bool IsSeparatorOrDelimiterCharacter(int ch); +static bool IsValidIdentifier(const SString& identifier); +static bool IsValidNumber(const SString& number); +static inline bool IsWordStartCharacter(int ch); +static inline bool IsWordCharacter(int ch); + +static void ColouriseCharacter(StyleContext& sc, bool& apostropheStartsAttribute) { +	apostropheStartsAttribute = true; + +	sc.SetState(SCE_ADA_CHARACTER); +  	// Skip the apostrophe and one more character (so that '' is shown as non-terminated and '''  	// is handled correctly) -	sc.Forward (); -	sc.Forward (); +	sc.Forward(); +	sc.Forward(); -	ColouriseContext (sc, '\'', SCE_ADA_CHARACTEREOL); +	ColouriseContext(sc, '\'', SCE_ADA_CHARACTEREOL);  } -static void ColouriseContext (StyleContext& sc, char chEnd, int stateEOL) -{ -	while (!sc.atLineEnd && !sc.Match (chEnd)) -	{ -		sc.Forward (); +static void ColouriseContext(StyleContext& sc, char chEnd, int stateEOL) { +	while (!sc.atLineEnd && !sc.Match(chEnd)) { +		sc.Forward();  	} -	if (!sc.atLineEnd) -	{ -		sc.ForwardSetState (SCE_ADA_DEFAULT); -	} -	else -	{ -		sc.ChangeState (stateEOL); +	if (!sc.atLineEnd) { +		sc.ForwardSetState(SCE_ADA_DEFAULT); +	} else { +		sc.ChangeState(stateEOL);  	}  } -static void ColouriseComment (StyleContext& sc) -{ -	sc.SetState (SCE_ADA_COMMENTLINE); +static void ColouriseComment(StyleContext& sc, bool& /*apostropheStartsAttribute*/) { +	// Apostrophe meaning is not changed, but the parameter is present for uniformity -	while (!sc.atLineEnd) -	{ -		sc.Forward (); +	sc.SetState(SCE_ADA_COMMENTLINE); + +	while (!sc.atLineEnd) { +		sc.Forward();  	}  } -static void ColouriseDelimiter (StyleContext& sc) -{ -	sc.SetState (SCE_ADA_DELIMITER); -	sc.ForwardSetState (SCE_ADA_DEFAULT); +static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute) { +	apostropheStartsAttribute = sc.Match (')'); +	sc.SetState(SCE_ADA_DELIMITER); +	sc.ForwardSetState(SCE_ADA_DEFAULT);  } -static void ColouriseLabel (StyleContext& sc, WordList& keywords) -{ -	sc.SetState (SCE_ADA_LABEL); +static void ColouriseLabel(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute) { +	apostropheStartsAttribute = false; + +	sc.SetState(SCE_ADA_LABEL);  	// Skip "<<" -	sc.Forward (); -	sc.Forward (); +	sc.Forward(); +	sc.Forward();  	SString identifier; -	while (!sc.atLineEnd && !isSeparatorOrDelimiter (sc.ch)) -	{ -		identifier += (char) tolower (sc.ch); -		sc.Forward (); +	while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) { +		identifier += static_cast<char>(tolower(sc.ch)); +		sc.Forward();  	}  	// Skip ">>" -	if (sc.Match ('>', '>')) -	{ -		sc.Forward (); -		sc.Forward (); -	} -	else -	{ -		sc.ChangeState (SCE_ADA_BADLABEL); +	if (sc.Match('>', '>')) { +		sc.Forward(); +		sc.Forward(); +	} else { +		sc.ChangeState(SCE_ADA_ILLEGAL);  	} -	if (!isValidIdentifier (identifier) || keywords.InList (identifier.c_str ())) -	{ -		sc.ChangeState (SCE_ADA_BADLABEL); +	// If the name is an invalid identifier or a keyword, then make it invalid label +	if (!IsValidIdentifier(identifier) || keywords.InList(identifier.c_str())) { +		sc.ChangeState(SCE_ADA_ILLEGAL);  	} -	sc.SetState (SCE_ADA_DEFAULT); +	sc.SetState(SCE_ADA_DEFAULT); +  } -static void ColouriseNumber (StyleContext& sc) -{ +static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute) { +	apostropheStartsAttribute = true; +  	SString number; -	sc.SetState (SCE_ADA_NUMBER); -	 -	while (!isSeparatorOrDelimiter (sc.ch)) -	{ -		number += (char) sc.ch; -		sc.Forward (); +	sc.SetState(SCE_ADA_NUMBER); + +	// Get all characters up to a delimiter or a separator, including points, but excluding +	// double points (ranges). +	while (!IsSeparatorOrDelimiterCharacter(sc.ch) || (sc.ch == '.' && sc.chNext != '.')) { +		number += static_cast<char>(sc.ch); +		sc.Forward();  	}  	// Special case: exponent with sign -	if (tolower (sc.chPrev) == 'e' -		&& (sc.Match ('+') || sc.Match ('-')) -		&& isdigit (sc.chNext)) -	{ -		number += (char) sc.ch; +	if ((sc.chPrev == 'e' || sc.chPrev == 'E') && +	        (sc.ch == '+' || sc.ch == '-')) { +		number += static_cast<char>(sc.ch);  		sc.Forward (); -		 -		while (!isSeparatorOrDelimiter (sc.ch)) -		{ -			number += (char) sc.ch; -			sc.Forward (); + +		while (!IsSeparatorOrDelimiterCharacter(sc.ch)) { +			number += static_cast<char>(sc.ch); +			sc.Forward();  		}  	} -	 -	if (!isValidNumber (number)) -	{ -		sc.ChangeState (SCE_ADA_BADNUMBER); + +	if (!IsValidNumber(number)) { +		sc.ChangeState(SCE_ADA_ILLEGAL);  	} -	 -	sc.SetState (SCE_ADA_DEFAULT); + +	sc.SetState(SCE_ADA_DEFAULT);  } -static void ColouriseString (StyleContext& sc) -{ -	sc.SetState (SCE_ADA_STRING); -	sc.Forward (); +static void ColouriseString(StyleContext& sc, bool& apostropheStartsAttribute) { +	apostropheStartsAttribute = true; + +	sc.SetState(SCE_ADA_STRING); +	sc.Forward(); -	ColouriseContext (sc, '"', SCE_ADA_STRINGEOL); +	ColouriseContext(sc, '"', SCE_ADA_STRINGEOL);  } -static void ColouriseWhiteSpace (StyleContext& sc) -{ -	sc.SetState (SCE_ADA_DEFAULT); -	sc.ForwardSetState (SCE_ADA_DEFAULT); +static void ColouriseWhiteSpace(StyleContext& sc, bool& /*apostropheStartsAttribute*/) { +	// Apostrophe meaning is not changed, but the parameter is present for uniformity +	sc.SetState(SCE_ADA_DEFAULT); +	sc.ForwardSetState(SCE_ADA_DEFAULT);  } -static void ColouriseWord (StyleContext& sc, WordList& keywords) -{ -	SString identifier; -	sc.SetState (SCE_ADA_IDENTIFIER); +static void ColouriseWord(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute) { +	apostropheStartsAttribute = true; +	sc.SetState(SCE_ADA_IDENTIFIER); -	while (!sc.atLineEnd && isWordCharacter (sc.ch)) -	{ -		identifier += (char) tolower (sc.ch); -		sc.Forward (); -	} +	SString word; -	if (!isValidIdentifier (identifier)) -	{ -		sc.ChangeState (SCE_ADA_BADIDENTIFIER); +	while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) { +		word += static_cast<char>(tolower(sc.ch)); +		sc.Forward();  	} -	else if (keywords.InList (identifier.c_str ())) -	{ -		sc.ChangeState (SCE_ADA_WORD); + +	if (!IsValidIdentifier(word)) { +		sc.ChangeState(SCE_ADA_ILLEGAL); + +	} else if (keywords.InList(word.c_str())) { +		sc.ChangeState(SCE_ADA_WORD); + +		if (word != "all") { +			apostropheStartsAttribute = false; +		}  	} -	 -	sc.SetState (SCE_ADA_DEFAULT); + +	sc.SetState(SCE_ADA_DEFAULT);  }  // @@ -202,98 +207,70 @@ static void ColouriseWord (StyleContext& sc, WordList& keywords)  //  static void ColouriseDocument( -	unsigned int startPos, -	int length, -	int initStyle, -	WordList *keywordlists[], -	Accessor &styler) -{ +    unsigned int startPos, +    int length, +    int initStyle, +    WordList *keywordlists[], +    Accessor &styler) {  	WordList &keywords = *keywordlists[0];  	StyleContext sc(startPos, length, initStyle, styler); -	// Apostrophe can start either an attribute or a character constant. Which  -	int lineCurrent = styler.GetLine (startPos); -	int lineState   = styler.GetLineState (lineCurrent); -	 -	bool apostropheStartsAttribute = (lineState & 1) != 0; - -	while (sc.More ()) -	{ -		if (sc.atLineEnd) -		{ -			sc.Forward (); +	int lineCurrent = styler.GetLine(startPos); +	bool apostropheStartsAttribute = (styler.GetLineState(lineCurrent) & 1) != 0; + +	while (sc.More()) { +		if (sc.atLineEnd) { +			// Go to the next line +			sc.Forward();  			lineCurrent++; -			// Remember the apostrophe setting -			styler.SetLineState (lineCurrent, apostropheStartsAttribute ? 1 : 0); +			// Remember the line state for future incremental lexing +			styler.SetLineState(lineCurrent, apostropheStartsAttribute); -			// Don't leak any styles onto the next line -			sc.SetState (SCE_ADA_DEFAULT); +			// Don't continue any styles on the next line +			sc.SetState(SCE_ADA_DEFAULT);  		}  		// Comments -		if (sc.Match ('-', '-')) -		{ -			ColouriseComment (sc); -		} -		 +		if (sc.Match('-', '-')) { +			ColouriseComment(sc, apostropheStartsAttribute); +  		// Strings -		else if (sc.Match ('"')) -		{ -			apostropheStartsAttribute = false; -			ColouriseString (sc); -		} +		} else if (sc.Match('"')) { +			ColouriseString(sc, apostropheStartsAttribute);  		// Characters -		else if (sc.Match ('\'') && !apostropheStartsAttribute) -		{ -			apostropheStartsAttribute = false; -			ColouriseCharacter (sc); -		} +		} else if (sc.Match('\'') && !apostropheStartsAttribute) { +			ColouriseCharacter(sc, apostropheStartsAttribute);  		// Labels -		else if (sc.Match ('<', '<')) -		{ -			apostropheStartsAttribute = false; -			ColouriseLabel (sc, keywords); -		} +		} else if (sc.Match('<', '<')) { +			ColouriseLabel(sc, keywords, apostropheStartsAttribute);  		// Whitespace -		else if (isspace (sc.ch)) -		{ -			ColouriseWhiteSpace (sc); -		} +		} else if (isspace(sc.ch)) { +			ColouriseWhiteSpace(sc, apostropheStartsAttribute);  		// Delimiters -		else if (isDelimiterCharacter (sc.ch)) -		{ -			apostropheStartsAttribute = sc.ch == ')'; -			ColouriseDelimiter (sc); -		} +		} else if (IsDelimiterCharacter(sc.ch)) { +			ColouriseDelimiter(sc, apostropheStartsAttribute);  		// Numbers -		else if (isdigit (sc.ch)) -		{ -			apostropheStartsAttribute = false; -			ColouriseNumber (sc); -		} +		} else if (isdigit(sc.ch) || sc.ch == '#') { +			ColouriseNumber(sc, apostropheStartsAttribute);  		// Keywords or identifiers -		else -		{ -			apostropheStartsAttribute = true; -			ColouriseWord (sc, keywords); +		} else { +			ColouriseWord(sc, keywords, apostropheStartsAttribute);  		}  	} -	sc.Complete (); +	sc.Complete();  } -static inline bool isDelimiterCharacter (int ch) -{ -	switch (ch) -	{ +static inline bool IsDelimiterCharacter(int ch) { +	switch (ch) {  	case '&':  	case '\'':  	case '(': @@ -316,223 +293,221 @@ static inline bool isDelimiterCharacter (int ch)  	}  } -static inline bool isNumberCharacter (int ch) -{ -	return isNumberStartCharacter (ch) -		|| ch == '_' -		|| ch == '.' -		|| ch == '#' -		|| (ch >= 'a' && ch <= 'f') -		|| (ch >= 'A' && ch <= 'F'); +static inline bool IsNumberCharacter(int ch) { +	return IsNumberStartCharacter(ch) || +	       ch == '_' || +	       ch == '.' || +	       ch == '#' || +	       (ch >= 'a' && ch <= 'f') || +	       (ch >= 'A' && ch <= 'F');  } -static inline bool isNumberStartCharacter (int ch) -{ -	return isdigit (ch) != 0; +static inline bool IsNumberStartCharacter(int ch) { +	return isdigit(ch) != 0;  } -static inline bool isSeparatorOrDelimiter (int ch) -{ -	return isspace (ch) || isDelimiterCharacter (ch); +static inline bool IsSeparatorOrDelimiterCharacter(int ch) { +	return isspace(ch) || IsDelimiterCharacter(ch);  } -static bool isValidIdentifier (const SString& identifier) -{ -	// First character can't be '_', so we set the variable to true initially +static bool IsValidIdentifier(const SString& identifier) { +	// First character can't be '_', so initialize the flag to true  	bool lastWasUnderscore = true; -	int length = identifier.length (); -	 +	int length = identifier.length(); +  	// Zero-length identifiers are not valid (these can occur inside labels) -	if (length == 0) return false; +	if (length == 0) { +		return false; +	} -	if (!isWordStartCharacter (identifier[0])) return false; +	// Check for valid character at the start +	if (!IsWordStartCharacter(identifier[0])) { +		return false; +	}  	// Check for only valid characters and no double underscores -	for (int i = 0; i < length; i++) -	{ -		if (!isWordCharacter (identifier[i])) return false; -		else if (identifier[i] == '_' && lastWasUnderscore) return false; +	for (int i = 0; i < length; i++) { +		if (!IsWordCharacter(identifier[i]) || +		        (identifier[i] == '_' && lastWasUnderscore)) { +			return false; +		}  		lastWasUnderscore = identifier[i] == '_';  	}  	// Check for underscore at the end -	if (lastWasUnderscore == true) return false; +	if (lastWasUnderscore == true) { +		return false; +	}  	// All checks passed  	return true;  } -static bool isValidNumber (const SString& number) -{ -	int hashPos = number.search ("#"); +static bool IsValidNumber(const SString& number) { +	int hashPos = number.search("#");  	bool seenDot = false; -	 +  	int i = 0; -	int length = number.length (); +	int length = number.length(); -	if (length == 0) return false; // Just in case +	if (length == 0) +		return false; // Just in case  	// Decimal number -	if (hashPos == -1) -	{ +	if (hashPos == -1) {  		bool canBeSpecial = false; -		for (; i < length; i++) -		{ -			if (number[i] == '_') -			{ -				if (!canBeSpecial) return false; +		for (; i < length; i++) { +			if (number[i] == '_') { +				if (!canBeSpecial) { +					return false; +				}  				canBeSpecial = false; -			} -			else if (number[i] == '.') -			{ -				if (!canBeSpecial || seenDot) return false; +			} else if (number[i] == '.') { +				if (!canBeSpecial || seenDot) { +					return false; +				}  				canBeSpecial = false;  				seenDot = true; -			} -			else if (isdigit (number[i])) -			{ +			} else if (isdigit(number[i])) {  				canBeSpecial = true; -			} -			else if (number[i] != 'e' && number[i] != 'E') -			{ -				return false; +			} else { +				break;  			}  		} -		 -		if (!canBeSpecial) return false; -	} -	 -	// Based number -	else -	{ + +		if (!canBeSpecial) +			return false; +	} else { +		// Based number  		bool canBeSpecial = false;  		int base = 0;  		// Parse base -		for (; i < length; i++) -		{ +		for (; i < length; i++) {  			int ch = number[i]; -			if (ch == '_') -			{ -				if (!canBeSpecial) return false; +			if (ch == '_') { +				if (!canBeSpecial) +					return false;  				canBeSpecial = false; -			} -			else if (isdigit (ch)) -			{ +			} else if (isdigit (ch)) {  				base = base * 10 + (ch - '0'); -				if (base > 16) return false; +				if (base > 16) +					return false;  				canBeSpecial = true; -			} -			else if (ch == '#' && canBeSpecial) -			{ +			} else if (ch == '#' && canBeSpecial) {  				break; -			} -			else -			{ +			} else {  				return false;  			}  		} -		if (base < 2) return false; -		if (i == length) return false; -		 +		if (base < 2) +			return false; +		if (i == length) +			return false; +  		i++; // Skip over '#'  		// Parse number  		canBeSpecial = false; -		for (; i < length; i++) -		{ -			int ch = tolower (number[i]); -			if (ch == '_') -			{ -				if (!canBeSpecial) return false; +		for (; i < length; i++) { +			int ch = tolower(number[i]); + +			if (ch == '_') { +				if (!canBeSpecial) { +					return false; +				}  				canBeSpecial = false; -			} -			else if (ch == '.') -			{ -				if (!canBeSpecial || seenDot) return false; + +			} else if (ch == '.') { +				if (!canBeSpecial || seenDot) { +					return false; +				}  				canBeSpecial = false;  				seenDot = true; -			} -			else if (isdigit (ch)) -			{ -				if (ch - '0' >= base) return false; + +			} else if (isdigit (ch)) { +				if (ch - '0' >= base) { +					return false; +				}  				canBeSpecial = true; -			} -			else if (ch >= 'a' && ch <= 'f') -			{ -				if (ch - 'a' + 10 >= base) return false; + +			} else if (ch >= 'a' && ch <= 'f') { +				if (ch - 'a' + 10 >= base) { +					return false; +				}  				canBeSpecial = true; -			} -			else if (ch == '#' && canBeSpecial) -			{ + +			} else if (ch == '#' && canBeSpecial) {  				break; -			} -			else -			{ + +			} else {  				return false;  			}  		} -		 -		if (i == length) return false; + +		if (i == length) { +			return false; +		} +  		i++;  	}  	// Exponent (optional) -	if (i < length) -	{ -		if (number[i] != 'e' && number[i] != 'E') return false; +	if (i < length) { +		if (number[i] != 'e' && number[i] != 'E') +			return false; + +		i++; // Move past 'E' + +		if (i == length) { +			return false; +		} -		i++; -		 -		if (i == length) return false; -		  		if (number[i] == '+')  			i++; -		else if (number[i] == '-') -		{ -			if (seenDot) +		else if (number[i] == '-') { +			if (seenDot) {  				i++; -			else +			} else {  				return false; // Integer literals should not have negative exponents +			} +		} + +		if (i == length) { +			return false;  		} -		 -		if (i == length) return false;  		bool canBeSpecial = false; -		for (; i < length; i++) -		{ -			if (number[i] == '_') -			{ -				if (!canBeSpecial) return false; +		for (; i < length; i++) { +			if (number[i] == '_') { +				if (!canBeSpecial) { +					return false; +				}  				canBeSpecial = false; -			} -			else if (isdigit (number[i])) -			{ +			} else if (isdigit(number[i])) {  				canBeSpecial = true; -			} -			else -			{ +			} else {  				return false;  			}  		} -		 -		if (!canBeSpecial) return false; + +		if (!canBeSpecial) +			return false;  	} -	return i == length; // if i == length, number was parsed successfully. +	// if i == length, number was parsed successfully. +	return i == length;  } -static inline bool isWordCharacter (int ch) -{ -	return isWordStartCharacter (ch) || isdigit (ch); +static inline bool IsWordCharacter(int ch) { +	return IsWordStartCharacter(ch) || isdigit(ch);  } -static inline bool isWordStartCharacter (int ch) -{ -	return isalpha (ch) || ch == '_'; +static inline bool IsWordStartCharacter(int ch) { +	return isalpha(ch) || ch == '_';  } | 
