parent
63a53a6436
commit
ff4eaa0997
@ -289,7 +289,7 @@ namespace Assignment_1
|
|||||||
}
|
}
|
||||||
string identifier;
|
string identifier;
|
||||||
long identifierEndPos = FindIdentifier(source, out identifier);
|
long identifierEndPos = FindIdentifier(source, out identifier);
|
||||||
if (identifierEndPos <= source.Position + 1 || identifier.Trim().Length == 0)
|
if (identifierEndPos < source.Position || identifier.Trim().Length == 0)
|
||||||
{
|
{
|
||||||
WriteDebugLine(lineStart, "set ".Length, "expected an identifier", source);
|
WriteDebugLine(lineStart, "set ".Length, "expected an identifier", source);
|
||||||
return false;
|
return false;
|
||||||
@ -402,40 +402,30 @@ namespace Assignment_1
|
|||||||
// Variable symbols should be evaluated immediately.
|
// Variable symbols should be evaluated immediately.
|
||||||
// Start by ensuring we don't try reading past the end of the stream
|
// Start by ensuring we don't try reading past the end of the stream
|
||||||
// Also check for the EoS
|
// Also check for the EoS
|
||||||
|
long realStart = s.Position;
|
||||||
string result = "";
|
string result = "";
|
||||||
while (s.Position < s.Length && !IsNextEoS(s))
|
while (s.Position < s.Length && !IsNextEoS(s))
|
||||||
{
|
{
|
||||||
|
long currStart = s.Position;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// must contain at least one value, so parse the next word
|
|
||||||
string result;
|
|
||||||
long wordEnd = FindValue(s, out result);
|
|
||||||
int sequenceCount = 0;
|
|
||||||
// If the word after the word we just parsed is the concatenation operator ('+'),
|
|
||||||
// then there may be more we can parse afterwards.
|
|
||||||
// Ensure we aren't at the end of the stream; the next value isn't the EoS, and that we haven't
|
|
||||||
// parsed two values in a row
|
|
||||||
while (s.Position < s.Length && !IsNextEoS(s) && sequenceCount < 2)
|
|
||||||
{
|
|
||||||
if (IsNextEoS(s, '+'))
|
if (IsNextEoS(s, '+'))
|
||||||
{
|
{
|
||||||
// next char is an append; skip
|
|
||||||
sequenceCount = 0;
|
|
||||||
s.Position = FindNextWord(s, out _);
|
s.Position = FindNextWord(s, out _);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sequenceCount++;
|
string value;
|
||||||
string tValue;
|
long firstPos = s.Position;
|
||||||
s.Position = FindValue(s, out tValue);
|
long val = FindValue(s, out value);
|
||||||
result += tValue;
|
if (val == -1)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Could not parse value");
|
||||||
|
}
|
||||||
|
s.Position = val;
|
||||||
|
result += value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expression = result;
|
expression = result;
|
||||||
return wordEnd;
|
return s.Position;
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks ahead to see if the next non-whitespace character is the EoS indicator (';')
|
/// Checks ahead to see if the next non-whitespace character is the EoS indicator (';')
|
||||||
@ -445,16 +435,17 @@ namespace Assignment_1
|
|||||||
/// <returns>true if the next char is <paramref name="EoSChar"/>, else false</returns>
|
/// <returns>true if the next char is <paramref name="EoSChar"/>, else false</returns>
|
||||||
static bool IsNextEoS(Stream s, char EoSChar = ';')
|
static bool IsNextEoS(Stream s, char EoSChar = ';')
|
||||||
{
|
{
|
||||||
|
long pos = s.Position;
|
||||||
char readChar = PeekChar(s);
|
char readChar = PeekChar(s);
|
||||||
while (readChar != -1 && char.IsWhiteSpace(readChar))
|
while (readChar != 0 && char.IsWhiteSpace(readChar))
|
||||||
{
|
{
|
||||||
readChar = PeekChar(s);
|
readChar = ReadChar(s);
|
||||||
}
|
}
|
||||||
|
s.Position = pos;
|
||||||
if (readChar == EoSChar) return true;
|
if (readChar == EoSChar) return true;
|
||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Most atomic unit is 'value':
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Finds the next value in the stream
|
/// Finds the next value in the stream
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -464,16 +455,18 @@ namespace Assignment_1
|
|||||||
long FindValue(Stream s, out string returnedValue)
|
long FindValue(Stream s, out string returnedValue)
|
||||||
{
|
{
|
||||||
SkipWhitespace(s);
|
SkipWhitespace(s);
|
||||||
int result = s.ReadByte();
|
char result = PeekChar(s);
|
||||||
if (result == '\"')
|
if (result == '\"')
|
||||||
{
|
{
|
||||||
|
// The first char is a ", i.e. the start of a literal - search as if it were a literal.
|
||||||
return FindLiteral(s, out returnedValue);
|
return FindLiteral(s, out returnedValue);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
s.Position--;
|
|
||||||
string keyValue;
|
string keyValue;
|
||||||
long t = FindExistingIdentifier(s, out keyValue);
|
long t = FindExistingIdentifier(s, out keyValue);
|
||||||
|
// Set the key value to result + this read string
|
||||||
|
//keyValue = result + keyValue;
|
||||||
|
|
||||||
if (!Symbols.ContainsKey(keyValue))
|
if (!Symbols.ContainsKey(keyValue))
|
||||||
{
|
{
|
||||||
@ -495,20 +488,30 @@ namespace Assignment_1
|
|||||||
{
|
{
|
||||||
string identifier;
|
string identifier;
|
||||||
long wordEnd = FindNextWord(s, out identifier);
|
long wordEnd = FindNextWord(s, out identifier);
|
||||||
if (identifier.EndsWith(';') && identifier.Length > 1)
|
if (identifier.Length > 1 && identifier.EndsWith(';'))
|
||||||
{
|
{
|
||||||
// Remove the trailing semicolon from the parse & backtrack the identifier length one spot
|
// Remove the trailing semicolon from the parse & backtrack the identifier length one spot
|
||||||
identifier = identifier.TrimEnd(';');
|
identifier = identifier.TrimEnd(';');
|
||||||
wordEnd--;
|
wordEnd--;
|
||||||
|
s.Position--;
|
||||||
}
|
}
|
||||||
// Lookup the value in the symbol table
|
// Lookup the value in the symbol table
|
||||||
returnedKey = identifier;
|
returnedKey = identifier;
|
||||||
return wordEnd;
|
return wordEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Finds the end of the complete literal definition, returning the stream to the original position
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="s"></param>
|
||||||
|
/// <param name="returnedLiteral"></param>
|
||||||
|
/// <returns></returns>
|
||||||
long FindLiteral(Stream s, out string returnedLiteral)
|
long FindLiteral(Stream s, out string returnedLiteral)
|
||||||
{
|
{
|
||||||
|
long pos = s.Position;
|
||||||
// Is a literal. Now we must parse until we find the end of the literal
|
// Is a literal. Now we must parse until we find the end of the literal
|
||||||
|
// Remove the first char, if it is a literal definition.
|
||||||
|
if (PeekChar(s) == '\"') ReadChar(s);
|
||||||
string resultLiteral;
|
string resultLiteral;
|
||||||
long resultPosition = FindNextOccurance(s, (c, s) =>
|
long resultPosition = FindNextOccurance(s, (c, s) =>
|
||||||
{
|
{
|
||||||
@ -535,6 +538,7 @@ namespace Assignment_1
|
|||||||
{
|
{
|
||||||
returnedLiteral = "";
|
returnedLiteral = "";
|
||||||
}
|
}
|
||||||
|
s.Position = pos;
|
||||||
return resultPosition;
|
return resultPosition;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
@ -562,18 +566,35 @@ namespace Assignment_1
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
static long FindNextWord(Stream s, out string nextWord)
|
static long FindNextWord(Stream s, out string nextWord)
|
||||||
{
|
{
|
||||||
// Find the next occurance of a whitespace character
|
StringBuilder newWord = new StringBuilder();
|
||||||
long originalPos = s.Position;
|
// Record our current position
|
||||||
string tempstring;
|
long start = s.Position;
|
||||||
long nextWSOccurance = FindNextOccurance(s, (c, s) => Char.IsWhiteSpace(c), out tempstring);
|
// Check if the character at the current pos is whitespace, if so, keep advancing until it isn't
|
||||||
while (tempstring.Length == 0 && s.Position < s.Length)
|
char currentChar = ReadChar(s);
|
||||||
|
while (s.Position < s.Length && char.IsWhiteSpace(currentChar))
|
||||||
{
|
{
|
||||||
nextWSOccurance = FindNextOccurance(s, (c, s) => Char.IsWhiteSpace(c), out tempstring);
|
currentChar = ReadChar(s);
|
||||||
s.Position++;
|
|
||||||
}
|
}
|
||||||
nextWord = tempstring;
|
// Add the last read value to the SB
|
||||||
s.Position = originalPos;
|
newWord.Append(currentChar);
|
||||||
return nextWSOccurance;
|
// Start a second loop, this time checking we're not a whitespace char
|
||||||
|
while (s.Position < s.Length)
|
||||||
|
{
|
||||||
|
currentChar = ReadChar(s);
|
||||||
|
if (char.IsWhiteSpace(currentChar))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newWord.Append(currentChar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nextWord = newWord.ToString();
|
||||||
|
|
||||||
|
long endPos = s.Position;
|
||||||
|
s.Position = start;
|
||||||
|
return endPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -686,7 +707,7 @@ namespace Assignment_1
|
|||||||
char c = PeekChar(s);
|
char c = PeekChar(s);
|
||||||
while (s.Position < s.Length && char.IsWhiteSpace(c))
|
while (s.Position < s.Length && char.IsWhiteSpace(c))
|
||||||
{
|
{
|
||||||
s.Position++;
|
ReadChar(s); // move by the size of that character
|
||||||
c = PeekChar(s);
|
c = PeekChar(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user