private void AddIdentifier(string value) { if (Identifiers.Any(e => e.Name.Equals(value))) { return; } int index = Identifiers.Count + 1; Identifiers.Add(new Identifier { Index = index, Type = Lexemes.Any() ? Lexemes.Last()?.Token ?? "" : "", Name = value } ); }
public OuterLexemes Parse(string code) { int lineNumber = 1; var lexemeBuilder = new StringBuilder(); foreach (string symbol in code.Select(c => c.ToString())) { int realLineNumber = lineNumber; if (symbol.Equals("\n")) { lineNumber++; } if (TrimDelimiters.Contains(symbol) || Delimiters.Contains(symbol)) { string lexeme = lexemeBuilder.ToString(); if (PredefinedWords.Contains(lexeme) || Operators.Contains(lexeme)) { AddLexeme(lexeme, realLineNumber); } else if (IsIdentifier(lexeme)) { // Duplicated identifier if (Lexemes.Any() && Lexemes.Last().SubString.Equals("var") && Identifiers.Any(e => e.Name.Equals(lexeme))) { AddError($"Duplicate declaration of {lexeme} identifier", realLineNumber); lexemeBuilder.Clear(); continue; } // Usage of undeclared identifier if (Lexemes.Any() && !Lexemes.Last().SubString.Equals("var") && !Lexemes.Last().SubString.Equals("program") && !Identifiers.Any(e => e.Name.Equals(lexeme))) { AddError($"Usage of undeclared identifier: {lexeme}", realLineNumber); lexemeBuilder.Clear(); continue; } AddIdentifier(lexeme); AddLexeme(lexeme, realLineNumber, IdentifierType.Identifier); } else if (IsConstant(lexeme)) { AddConstant(lexeme); AddLexeme(lexeme, realLineNumber, IdentifierType.Constant); } else if (!string.IsNullOrEmpty(lexeme)) { AddError($"Unknown lexeme: {lexeme}", realLineNumber); lexemeBuilder.Clear(); continue; } if (Delimiters.Contains(symbol)) { AddLexeme(symbol, realLineNumber); } lexemeBuilder.Clear(); continue; } if (!TrimDelimiters.Contains(symbol)) { lexemeBuilder.Append(symbol); } } return(new OuterLexemes() { Identifiers = Identifiers, Constants = Constants, Lexemes = Lexemes, Errors = Errors, Grammar = GrammarLexemes }); }
public void Parse() { Tokenizer.Tokenize(this); foreach (var us in UserSegments) { if (!us.Closed) { us.OpenToken.ParentLexeme.Error = new Error(ErrorType.UnclosedSegment, us.OpenToken); } if (!us.Opened) { us.CloseToken.ParentLexeme.Error = new Error(ErrorType.UnopenedSegment, us.CloseToken); } } // Replace EQUs foreach (var lexeme in Lexemes) { if (lexeme.Error == null) { lexeme.ProceedEqu(); lexeme.Structure = lexeme.GetStructure(); } } foreach (var lexeme in Lexemes) { if (lexeme.Error == null) { if (!lexeme.HasLabel && lexeme.Structure.HasName && lexeme.Structure != null && lexeme.Structure.HasInstruction && lexeme.Tokens[lexeme.Structure.InstructionIndex].Type == TokenType.Instruction) { lexeme.Error = new Error(ErrorType.UnexpectedToken, lexeme.Tokens[0]); continue; } if (!lexeme.HasLabel && lexeme.Structure != null && lexeme.Structure.HasName && !lexeme.Structure.HasInstruction) { lexeme.Error = new Error(ErrorType.UnexpectedToken, lexeme.Tokens[0]); continue; } lexeme.AssignInlineUserSegmentsAndLabels(out var error); if (error != null) { lexeme.Error = error; } } } var lastLexeme = Lexemes.Last(); if (lastLexeme.Tokens.Count != 1 || lastLexeme.Tokens[0].Type != TokenType.EndKeyword) { lastLexeme.Error = new Error(ErrorType.MissingEndKeyword); } }
private void ProceedConditionalDirectives() { var toDelete = new List <int>(); var openedIf = false; var openedElse = false; var ifCond = false; for (var i = 0; i < Lexemes.Count; i++) { var lexeme = Lexemes[i]; if (lexeme.Error != null) { continue; } if (lexeme.Tokens[0].Type == TokenType.IfDirective) { if (openedIf || openedElse) { lexeme.Error = new Error(ErrorType.UnexpectedDirective, lexeme.Tokens[0]); continue; } openedIf = true; if (lexeme.Tokens.Count != 2) { lexeme.Error = new Error(ErrorType.WrongDirectiveFormat, lexeme.Tokens[0]); continue; } var cond = lexeme.Tokens[1]; if (cond.IsNumber()) { ifCond = cond.ToValue() != 0; } else { lexeme.Error = new Error(ErrorType.IncorrectInstructionTypes, lexeme.Tokens[0]); continue; } toDelete.Add(i); } else if (lexeme.Tokens[0].Type == TokenType.ElseDirective) { if (!openedIf) { lexeme.Error = new Error(ErrorType.UnexpectedDirective, lexeme.Tokens[0]); continue; } openedIf = false; openedElse = true; toDelete.Add(i); } else if (lexeme.Tokens[0].Type == TokenType.EndifDirective) { if (!openedIf && !openedElse) { lexeme.Error = new Error(ErrorType.UnexpectedDirective, lexeme.Tokens[0]); continue; } openedElse = false; openedIf = false; toDelete.Add(i); } else { if (openedIf && !ifCond) { toDelete.Add(i); } else if (openedElse && ifCond) { toDelete.Add(i); } } } if (openedIf || openedElse) { var lastLexeme = Lexemes.Last(); lastLexeme.Error = new Error(ErrorType.MissingEndKeyword); } toDelete.Reverse(); foreach (var index in toDelete) { Lexemes.RemoveAt(index); } }