From ff4eaa0997dfa22272e3ba1c63c5118e5c90c013 Mon Sep 17 00:00:00 2001 From: Brychan Dempsey Date: Mon, 15 Mar 2021 16:42:37 +1300 Subject: [PATCH] Fixed appending characters, Candidate for closing #2 --- Assignment 1/Program.cs | 101 ++++++++++++++++++++++++---------------- 1 file changed, 61 insertions(+), 40 deletions(-) diff --git a/Assignment 1/Program.cs b/Assignment 1/Program.cs index b343a15..24a5df7 100644 --- a/Assignment 1/Program.cs +++ b/Assignment 1/Program.cs @@ -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; } /// /// Checks ahead to see if the next non-whitespace character is the EoS indicator (';') @@ -445,16 +435,17 @@ namespace Assignment_1 /// true if the next char is , else false 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': /// /// Finds the next value in the stream /// @@ -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; } + /// + /// Finds the end of the complete literal definition, returning the stream to the original position + /// + /// + /// + /// 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 /// 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); } }