public Tokens GenerateTokens() { int N = Expression.Length; Tokens tokens = new Tokens(N); StringBuilder tokenValue = new StringBuilder(N); State currentState = State.BEGIN; int position = 0; while (position <= N && !LexicalError) { char symbol = position < N ? Expression[position] : EndOfExpression; switch (currentState) { case State.BEGIN: if (Char.IsLetter(symbol)) { tokenValue.Append(symbol); currentState = State.VAR; } else if (Char.IsDigit(symbol)) { tokenValue.Append(symbol); currentState = State.NUM1; } else if ("+-*/^()".Contains(symbol)) { tokenValue.Append(symbol); currentState = State.OK; } else if (symbol != EndOfExpression) { if (position < N) { var error = String.Format("Invalid symbol {0}", symbol); TokenError = new Token(TerminalSymbolType.UnRecognized, position, error); tokens.Add(TokenError); LexicalError = true; } } position++; break; case State.VAR: if (Char.IsLetter(symbol)) { tokenValue.Append(symbol); position++; currentState = State.FUNC; } else { tokens.Add(new Token(TokenType.Variable, position, tokenValue.ToString())); tokenValue.Clear(); currentState = State.BEGIN; } break; case State.FUNC: if (Char.IsLetter(symbol)) { tokenValue.Append(symbol); position++; } else { var str = tokenValue.ToString(); if (IsFunction(str)) { tokens.Add(new Token(TokenType.Function, position, str)); tokenValue.Clear(); currentState = State.BEGIN; } else { var error = String.Format("Unrecognized {0}", str); TokenError = new Token(TokenType.UnRecognized, position, error); tokens.Add(TokenError); LexicalError = true; } } break; case State.OK: tokens.Add(makeOneCharToken(tokenValue.ToString(), position)); tokenValue.Clear(); currentState = State.BEGIN; break; case State.NUM1: if (Char.IsDigit(symbol)) { tokenValue.Append(symbol); position++; } else if (symbol == '.') { tokenValue.Append(symbol); position++; currentState = State.TRANS; } else { tokens.Add(new Token(TokenType.Value, position, tokenValue.ToString())); tokenValue.Clear(); currentState = State.BEGIN; } break; case State.TRANS: if (Char.IsDigit(symbol)) { tokenValue.Append(symbol); position++; currentState = State.NUM2; } else { var error = String.Format("Invalid number format {0}", tokenValue.Append(symbol)); TokenError = new Token(TokenType.UnRecognized, position, error); tokens.Add(TokenError); LexicalError = true; } break; case State.NUM2: if (Char.IsDigit(symbol)) { tokenValue.Append(symbol); position++; } else { tokens.Add(new Token(TokenType.Value, position, tokenValue.ToString())); tokenValue.Clear(); currentState = State.BEGIN; } break; } } return tokens; }
public void ValidateSintax() { var stack = new Stack<Symbol>(); stack.Push(new Symbol(NonTerminalSymbol.E)); int N = Tokens.Count; int position = 0; while (stack.Count > 0) { Symbol current = stack.Pop(); if (!current.IsTerminal) { NonTerminalSymbol symbolValue = current.NonTerminalSymbol; Console.Out.Write(symbolValue); if (symbolValue == NonTerminalSymbol.E) { Console.Out.WriteLine(" -> TX"); stack.Push(new Symbol(NonTerminalSymbol.X)); stack.Push(new Symbol(NonTerminalSymbol.T)); } else if (symbolValue == NonTerminalSymbol.T) { if (Tokens[position] == TerminalSymbolType.Function) { Console.Out.WriteLine(" -> F(E)X"); stack.Push(new Symbol(NonTerminalSymbol.X)); stack.Push(new Symbol(TerminalSymbolType.ClosingParenthesis)); stack.Push(new Symbol(NonTerminalSymbol.E)); stack.Push(new Symbol(TerminalSymbolType.OpeningParenthesis)); stack.Push(new Symbol(TerminalSymbolType.Function)); } else if (Tokens[position] == TerminalSymbolType.OpeningParenthesis) { Console.Out.WriteLine(" -> (E)X"); stack.Push(new Symbol(NonTerminalSymbol.X)); stack.Push(new Symbol(TerminalSymbolType.ClosingParenthesis)); stack.Push(new Symbol(NonTerminalSymbol.E)); stack.Push(new Symbol(TerminalSymbolType.OpeningParenthesis)); } else if (Tokens[position] == TerminalSymbolType.Value) { Console.Out.WriteLine(" -> valueX"); stack.Push(new Symbol(NonTerminalSymbol.X)); stack.Push(new Symbol(TerminalSymbolType.Value)); } else if (Tokens[position] == TerminalSymbolType.Variable) { Console.Out.WriteLine(" -> varX"); stack.Push(new Symbol(NonTerminalSymbol.X)); stack.Push(new Symbol(TerminalSymbolType.Variable)); } else if ("+-".Contains(Tokens[position].Value[0])) { Console.Out.WriteLine(" -> {0}U", Tokens[position].Value); stack.Push(new Symbol(NonTerminalSymbol.U)); stack.Push(new Symbol(TerminalSymbolType.Operator)); } else { var errorMsg = String.Format("Unexpected token '{0}'", Tokens[position].Value); TokenError = new TerminalSymbol(Tokens[position].Type, Tokens[position].Column, errorMsg); SyntaxError = true; break; } } else if (symbolValue == NonTerminalSymbol.X) { if (position >= N) { Console.Out.WriteLine(" -> eps"); } else if (Tokens[position] == TerminalSymbolType.Operator) { Console.Out.WriteLine(" -> {0}E", Tokens[position].Value); stack.Push(new Symbol(NonTerminalSymbol.U)); stack.Push(new Symbol(TerminalSymbolType.Operator)); } else if (Tokens[position] != TerminalSymbolType.ClosingParenthesis) { var errorMsg = String.Format("Unexpected token '{0}'", Tokens[position].Value); TokenError = new TerminalSymbol(Tokens[position].Type, Tokens[position].Column, errorMsg); SyntaxError = true; break; } else { // Reading a closing parenthesis Console.Out.WriteLine(" -> eps"); } } else if (symbolValue == NonTerminalSymbol.U) { if (Tokens[position] == TerminalSymbolType.Function) { Console.Out.WriteLine(" -> F(E)X"); stack.Push(new Symbol(NonTerminalSymbol.X)); stack.Push(new Symbol(TerminalSymbolType.ClosingParenthesis)); stack.Push(new Symbol(NonTerminalSymbol.E)); stack.Push(new Symbol(TerminalSymbolType.OpeningParenthesis)); stack.Push(new Symbol(TerminalSymbolType.Function)); } else if (Tokens[position] == TerminalSymbolType.OpeningParenthesis) { Console.Out.WriteLine(" -> (E)X"); stack.Push(new Symbol(NonTerminalSymbol.X)); stack.Push(new Symbol(TerminalSymbolType.ClosingParenthesis)); stack.Push(new Symbol(NonTerminalSymbol.E)); stack.Push(new Symbol(TerminalSymbolType.OpeningParenthesis)); } else if (Tokens[position] == TerminalSymbolType.Value) { Console.Out.WriteLine(" -> valueX"); stack.Push(new Symbol(NonTerminalSymbol.X)); stack.Push(new Symbol(TerminalSymbolType.Value)); } else if (Tokens[position] == TerminalSymbolType.Variable) { Console.Out.WriteLine(" -> varX"); stack.Push(new Symbol(NonTerminalSymbol.X)); stack.Push(new Symbol(TerminalSymbolType.Variable)); } else { var errorMsg = String.Format("Unexpected token '{0}'", Tokens[position].Value); TokenError = new TerminalSymbol(Tokens[position].Type, Tokens[position].Column, errorMsg); SyntaxError = true; break; } } } else { TerminalSymbolType symbolValue = current.TerminalSymbol; Console.Out.Write(" >> Expecting {0}", symbolValue); if (position < N) { if (Tokens[position] == symbolValue) { Console.Out.WriteLine(" - matched with {0}", Tokens[position]); position++; } else { var errorMsg = String.Format("Expecting {0}, got {1}", symbolValue, Tokens[position].Value); TokenError = new TerminalSymbol(Tokens[position].Type, Tokens[position].Column, errorMsg); SyntaxError = true; break; } } else { var errorMsg = String.Format("Expecting {0}, got enf of expression", symbolValue); TokenError = new TerminalSymbol(TerminalSymbolType.UnRecognized, N, errorMsg); SyntaxError = true; break; } } } if (position < N && !SyntaxError) { TokenError = new TerminalSymbol(TerminalSymbolType.UnRecognized, position, "Sintax error"); SyntaxError = true; } }