-1

I am currently trying to right a Lexer in C# (probably stupid but it's just programming practice and it's the language I know best) and I'm getting a strange issue. I have split a separate file into tokens and am displaying it into the console. However, every time I run my program, I get one more line than there are tokens in the script. I've tried for nearly a day now to get this working, but it just won't. Here's my code, and the console itself:

public class Lexer
    {
        public static List<List<Lexer_Token>> GetTokens(string filePath)
        {
            List<List<Lexer_Token>> tokens = new List<List<Lexer_Token>>();
            string[] commands = GetCommands(Reader.ReadFile(filePath));

            for (int c = 0; c < commands.Length; c++)
            {
                List<Lexer_Token> currentTokens = StoreAsTokens(commands[c]);
                tokens.Add(currentTokens);
            }

            return tokens;
        }

        private static List<Lexer_Token> StoreAsTokens(string command)
        {
            List<Lexer_Token> tokenList = new List<Lexer_Token>();
            string[] tokens = SplitUpCommand(command, ' ');

            for (int t = 0; t < tokens.Length; t++)
            {
                string currentToken = tokens[t];
                Lexer_Token token = new Lexer_Token();
                token.symbol = currentToken;
                tokenList.Add(token);
            }

            return tokenList;
        }

        private static string[] SplitUpCommand(string command, char character)
        {
            return command.Split(character);
        }

        private static string[] GetCommands(string contents)
        {
            return contents.Split(';');
        }

        public static string FormatTokens(List<List<Lexer_Token>> list)
        {
            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < list.Count; i++)
            {
                List<Lexer_Token> currentTokenList = list[i];

                for (int j = 0; j < currentTokenList.Count; j++)
                {
                    Lexer_Token currentToken = currentTokenList[j];
                    sb.Append("ID: " + currentToken.id.ToString());
                    sb.Append(" Type: " + currentToken.type);
                    sb.Append(" Line: " + currentToken.lineNumber.ToString()
                        + "[" + currentToken.startingCharacterIndex.ToString() + "]");
                    sb.Append(" Symbol: " + currentToken.symbol);
                    if (i != list.Count - 1)
                    {
                        sb.Append("\n");
                    }
                }
            }

            return sb.ToString();
        }
    }

    public class Lexer_Token
    {
        public int id;
        public int lineNumber;
        public int startingCharacterIndex;
        public string type;
        public string symbol;
    }

The console output

Hamada
  • 1,836
  • 3
  • 13
  • 27
Shakier
  • 1
  • 1
  • 1
    There might be a newline at the end of the file, so the last "command" is empty. Try a trim on the file to remove newlines at the end of the string – mixable Jul 15 '20 at 07:54
  • 1
    have you stepped through with the debugger, i would say there is an extra space or something at the end of your `split` – traveler3468 Jul 15 '20 at 07:54

1 Answers1

0

You could possibly do this with Join and linq if you don't care about allocations, maybe a bit easier to read

static string Output(Lexer_Token currentToken)
{
   var sb = new StringBuilder();
   sb.Append($"ID: {currentToken.id}");
   sb.Append($" Type: {currentToken.type}");
   sb.Append($" Line: {currentToken.lineNumber}[{currentToken.startingCharacterIndex}]");
   sb.Append($" Symbol: {currentToken.symbol}");
   return sb.ToString();
}
public static string FormatTokens(List<List<Lexer_Token>> list)
{
   var lines = list.SelectMany(currentTokenList => currentTokenList).Select(Output);
   return string.Join(Environment.NewLine, lines);
}
TheGeneral
  • 79,002
  • 9
  • 103
  • 141