parent
63a53a6436
commit
ff4eaa0997
@ -289,7 +289,7 @@ namespace Assignment_1
|
||||
}
|
||||
string 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);
|
||||
return false;
|
||||
@ -402,40 +402,30 @@ namespace Assignment_1
|
||||
// Variable symbols should be evaluated immediately.
|
||||
// Start by ensuring we don't try reading past the end of the stream
|
||||
// Also check for the EoS
|
||||
|
||||
long realStart = s.Position;
|
||||
string result = "";
|
||||
while (s.Position < s.Length && !IsNextEoS(s))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 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)
|
||||
{
|
||||
long currStart = s.Position;
|
||||
if (IsNextEoS(s, '+'))
|
||||
{
|
||||
// next char is an append; skip
|
||||
sequenceCount = 0;
|
||||
s.Position = FindNextWord(s, out _);
|
||||
}
|
||||
else
|
||||
{
|
||||
sequenceCount++;
|
||||
string tValue;
|
||||
s.Position = FindValue(s, out tValue);
|
||||
result += tValue;
|
||||
string value;
|
||||
long firstPos = s.Position;
|
||||
long val = FindValue(s, out value);
|
||||
if (val == -1)
|
||||
{
|
||||
Console.WriteLine("Could not parse value");
|
||||
}
|
||||
s.Position = val;
|
||||
result += value;
|
||||
}
|
||||
}
|
||||
expression = result;
|
||||
return wordEnd;
|
||||
return s.Position;
|
||||
}
|
||||
/// <summary>
|
||||
/// 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>
|
||||
static bool IsNextEoS(Stream s, char EoSChar = ';')
|
||||
{
|
||||
long pos = s.Position;
|
||||
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;
|
||||
else return false;
|
||||
}
|
||||
|
||||
// Most atomic unit is 'value':
|
||||
/// <summary>
|
||||
/// Finds the next value in the stream
|
||||
/// </summary>
|
||||
@ -464,16 +455,18 @@ namespace Assignment_1
|
||||
long FindValue(Stream s, out string returnedValue)
|
||||
{
|
||||
SkipWhitespace(s);
|
||||
int result = s.ReadByte();
|
||||
char result = PeekChar(s);
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
s.Position--;
|
||||
string keyValue;
|
||||
long t = FindExistingIdentifier(s, out keyValue);
|
||||
// Set the key value to result + this read string
|
||||
//keyValue = result + keyValue;
|
||||
|
||||
if (!Symbols.ContainsKey(keyValue))
|
||||
{
|
||||
@ -495,20 +488,30 @@ namespace Assignment_1
|
||||
{
|
||||
string 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
|
||||
identifier = identifier.TrimEnd(';');
|
||||
wordEnd--;
|
||||
s.Position--;
|
||||
}
|
||||
// Lookup the value in the symbol table
|
||||
returnedKey = identifier;
|
||||
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 pos = s.Position;
|
||||
// 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;
|
||||
long resultPosition = FindNextOccurance(s, (c, s) =>
|
||||
{
|
||||
@ -535,6 +538,7 @@ namespace Assignment_1
|
||||
{
|
||||
returnedLiteral = "";
|
||||
}
|
||||
s.Position = pos;
|
||||
return resultPosition;
|
||||
}
|
||||
#endregion
|
||||
@ -562,18 +566,35 @@ namespace Assignment_1
|
||||
/// <returns></returns>
|
||||
static long FindNextWord(Stream s, out string nextWord)
|
||||
{
|
||||
// Find the next occurance of a whitespace character
|
||||
long originalPos = s.Position;
|
||||
string tempstring;
|
||||
long nextWSOccurance = FindNextOccurance(s, (c, s) => Char.IsWhiteSpace(c), out tempstring);
|
||||
while (tempstring.Length == 0 && s.Position < s.Length)
|
||||
StringBuilder newWord = new StringBuilder();
|
||||
// Record our current position
|
||||
long start = s.Position;
|
||||
// Check if the character at the current pos is whitespace, if so, keep advancing until it isn't
|
||||
char currentChar = ReadChar(s);
|
||||
while (s.Position < s.Length && char.IsWhiteSpace(currentChar))
|
||||
{
|
||||
nextWSOccurance = FindNextOccurance(s, (c, s) => Char.IsWhiteSpace(c), out tempstring);
|
||||
s.Position++;
|
||||
currentChar = ReadChar(s);
|
||||
}
|
||||
nextWord = tempstring;
|
||||
s.Position = originalPos;
|
||||
return nextWSOccurance;
|
||||
// Add the last read value to the SB
|
||||
newWord.Append(currentChar);
|
||||
// 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);
|
||||
while (s.Position < s.Length && char.IsWhiteSpace(c))
|
||||
{
|
||||
s.Position++;
|
||||
ReadChar(s); // move by the size of that character
|
||||
c = PeekChar(s);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user