public LexicalStateMachine() { CurrentState = LexicalMachineState.EMPTY; transitions = new Dictionary <LexicalStateTransition, LexicalMachineState> { { new LexicalStateTransition(LexicalMachineState.EMPTY, AtomType.DIGIT), LexicalMachineState.INT_TOKEN }, { new LexicalStateTransition(LexicalMachineState.EMPTY, AtomType.LETTER), LexicalMachineState.VAR_TOKEN }, { new LexicalStateTransition(LexicalMachineState.EMPTY, AtomType.QUOTE), LexicalMachineState.QUOTED_STRING_TOKEN }, { new LexicalStateTransition(LexicalMachineState.EMPTY, AtomType.SPECIAL), LexicalMachineState.SPECIAL_TOKEN }, { new LexicalStateTransition(LexicalMachineState.EMPTY, AtomType.OPENING_PAR), LexicalMachineState.SPECIAL_TOKEN }, { new LexicalStateTransition(LexicalMachineState.EMPTY, AtomType.CLOSING_PAR), LexicalMachineState.SPECIAL_TOKEN }, { new LexicalStateTransition(LexicalMachineState.EMPTY, AtomType.DELIMITER), LexicalMachineState.EMPTY }, { new LexicalStateTransition(LexicalMachineState.EMPTY, AtomType.CONTROL), LexicalMachineState.EMPTY }, { new LexicalStateTransition(LexicalMachineState.VAR_TOKEN, AtomType.DIGIT), LexicalMachineState.EMPTY }, { new LexicalStateTransition(LexicalMachineState.VAR_TOKEN, AtomType.DELIMITER), LexicalMachineState.EMPTY }, { new LexicalStateTransition(LexicalMachineState.VAR_TOKEN, AtomType.LETTER), LexicalMachineState.STRING_TOKEN }, { new LexicalStateTransition(LexicalMachineState.VAR_TOKEN, AtomType.OPENING_PAR), LexicalMachineState.ARRAY_TOKEN }, { new LexicalStateTransition(LexicalMachineState.VAR_TOKEN, AtomType.SPECIAL), LexicalMachineState.SPECIAL_TOKEN }, { new LexicalStateTransition(LexicalMachineState.VAR_TOKEN, AtomType.CONTROL), LexicalMachineState.EMPTY }, { new LexicalStateTransition(LexicalMachineState.INT_TOKEN, AtomType.DIGIT), LexicalMachineState.INT_TOKEN }, { new LexicalStateTransition(LexicalMachineState.INT_TOKEN, AtomType.SPECIAL), LexicalMachineState.SPECIAL_TOKEN }, { new LexicalStateTransition(LexicalMachineState.INT_TOKEN, AtomType.OPENING_PAR), LexicalMachineState.SPECIAL_TOKEN }, { new LexicalStateTransition(LexicalMachineState.INT_TOKEN, AtomType.CLOSING_PAR), LexicalMachineState.SPECIAL_TOKEN }, { new LexicalStateTransition(LexicalMachineState.INT_TOKEN, AtomType.DELIMITER), LexicalMachineState.EMPTY }, { new LexicalStateTransition(LexicalMachineState.INT_TOKEN, AtomType.CONTROL), LexicalMachineState.EMPTY }, { new LexicalStateTransition(LexicalMachineState.STRING_TOKEN, AtomType.LETTER), LexicalMachineState.STRING_TOKEN }, { new LexicalStateTransition(LexicalMachineState.STRING_TOKEN, AtomType.DIGIT), LexicalMachineState.STRING_TOKEN }, { new LexicalStateTransition(LexicalMachineState.STRING_TOKEN, AtomType.QUOTE), LexicalMachineState.STRING_TOKEN }, { new LexicalStateTransition(LexicalMachineState.STRING_TOKEN, AtomType.OPENING_PAR), LexicalMachineState.ARRAY_TOKEN }, { new LexicalStateTransition(LexicalMachineState.STRING_TOKEN, AtomType.SPECIAL), LexicalMachineState.SPECIAL_TOKEN }, { new LexicalStateTransition(LexicalMachineState.STRING_TOKEN, AtomType.CONTROL), LexicalMachineState.EMPTY }, { new LexicalStateTransition(LexicalMachineState.STRING_TOKEN, AtomType.DELIMITER), LexicalMachineState.EMPTY }, { new LexicalStateTransition(LexicalMachineState.QUOTED_STRING_TOKEN, AtomType.DIGIT), LexicalMachineState.QUOTED_STRING_TOKEN }, { new LexicalStateTransition(LexicalMachineState.QUOTED_STRING_TOKEN, AtomType.LETTER), LexicalMachineState.QUOTED_STRING_TOKEN }, { new LexicalStateTransition(LexicalMachineState.QUOTED_STRING_TOKEN, AtomType.DELIMITER), LexicalMachineState.QUOTED_STRING_TOKEN }, { new LexicalStateTransition(LexicalMachineState.QUOTED_STRING_TOKEN, AtomType.SPECIAL), LexicalMachineState.QUOTED_STRING_TOKEN }, { new LexicalStateTransition(LexicalMachineState.QUOTED_STRING_TOKEN, AtomType.QUOTE), LexicalMachineState.EMPTY }, { new LexicalStateTransition(LexicalMachineState.SPECIAL_TOKEN, AtomType.LETTER), LexicalMachineState.STRING_TOKEN }, { new LexicalStateTransition(LexicalMachineState.SPECIAL_TOKEN, AtomType.DIGIT), LexicalMachineState.INT_TOKEN }, { new LexicalStateTransition(LexicalMachineState.SPECIAL_TOKEN, AtomType.SPECIAL), LexicalMachineState.SPECIAL_TOKEN }, { new LexicalStateTransition(LexicalMachineState.SPECIAL_TOKEN, AtomType.OPENING_PAR), LexicalMachineState.SPECIAL_TOKEN }, { new LexicalStateTransition(LexicalMachineState.SPECIAL_TOKEN, AtomType.CLOSING_PAR), LexicalMachineState.SPECIAL_TOKEN }, { new LexicalStateTransition(LexicalMachineState.SPECIAL_TOKEN, AtomType.DELIMITER), LexicalMachineState.EMPTY }, { new LexicalStateTransition(LexicalMachineState.SPECIAL_TOKEN, AtomType.CONTROL), LexicalMachineState.EMPTY }, { new LexicalStateTransition(LexicalMachineState.ARRAY_TOKEN, AtomType.DIGIT), LexicalMachineState.INDEX_OF_ARRAY_TOKEN }, { new LexicalStateTransition(LexicalMachineState.INDEX_OF_ARRAY_TOKEN, AtomType.DIGIT), LexicalMachineState.INDEX_OF_ARRAY_TOKEN }, { new LexicalStateTransition(LexicalMachineState.INDEX_OF_ARRAY_TOKEN, AtomType.CLOSING_PAR), LexicalMachineState.EMPTY }, { new LexicalStateTransition(LexicalMachineState.INDEX_OF_ARRAY_TOKEN, AtomType.CONTROL), LexicalMachineState.EMPTY }, }; }
public void MoveNext(AsciiAtom command) { LexicalMachineState nextState = GetNext(command.Category); if (nextState == LexicalMachineState.ARRAY_TOKEN && this.CurrentState == LexicalMachineState.VAR_TOKEN) { this.arrayToken = this.currentToken; this.ClearToken(); this.CurrentState = nextState; return; } else if (this.CurrentState == LexicalMachineState.INDEX_OF_ARRAY_TOKEN && command.Category != AtomType.DIGIT) { this.indexOrSize = int.Parse(this.currentToken); this.ClearToken(); this.OnTokenIdentified(command); this.CurrentState = nextState; return; } else if (nextState == LexicalMachineState.VAR_TOKEN && this.CurrentState == LexicalMachineState.EMPTY) { this.UpdateTokenState(command); this.CurrentState = nextState; return; } else if (nextState == LexicalMachineState.EMPTY && this.CurrentState == LexicalMachineState.VAR_TOKEN || nextState == LexicalMachineState.EMPTY && this.CurrentState == LexicalMachineState.QUOTED_STRING_TOKEN) { this.UpdateTokenState(command); this.OnTokenIdentified(command); this.ClearToken(); this.CurrentState = nextState; return; } else if (nextState == LexicalMachineState.EMPTY && command.Category == AtomType.CONTROL || nextState == LexicalMachineState.EMPTY && this.CurrentState != LexicalMachineState.EMPTY || nextState == LexicalMachineState.SPECIAL_TOKEN && (this.CurrentState == LexicalMachineState.STRING_TOKEN || this.CurrentState == LexicalMachineState.INT_TOKEN || this.CurrentState == LexicalMachineState.SPECIAL_TOKEN) || this.CurrentState == LexicalMachineState.SPECIAL_TOKEN && (nextState == LexicalMachineState.INT_TOKEN || nextState == LexicalMachineState.STRING_TOKEN)) { this.OnTokenIdentified(command); this.ClearToken(); } this.UpdateTokenState(command); this.CurrentState = nextState; }
public LexicalMachineState GetNext(AtomType command) { LexicalMachineState nextState = this.CurrentState; LexicalStateTransition transition = new LexicalStateTransition(CurrentState, command); if (!transitions.TryGetValue(transition, out nextState)) { throw new Exception("Lexical: Invalid transition: " + CurrentState + " -> " + command); } Console.WriteLine("Lexical :" + this.CurrentState + " -> " + nextState + " : " + command.ToString()); return(nextState); }
public Token(LexicalMachineState state, string tokenString, AsciiAtom command) { this.Text = tokenString; if (state == LexicalMachineState.STRING_TOKEN) { this.Type = this.Text.ToUpper() switch { "PRINT" => TokenType.PRINT, "DIM" => TokenType.DIM, "LET" => TokenType.LET, "READ" => TokenType.READ, "DATA" => TokenType.DATA, "FOR" => TokenType.FOR, "TO" => TokenType.TO, "NEXT" => TokenType.NEXT, "GO" => TokenType.GO, "GOTO" => TokenType.GOTO, "GOSUB" => TokenType.GOSUB, "RETURN" => TokenType.RETURN, "REM" => TokenType.REMARK, "IF" => TokenType.IF, "STEP" => TokenType.STEP, "THEN" => TokenType.THEN, "END" => TokenType.FINAL, _ => TokenType.STRING }; } else if (state == LexicalMachineState.INT_TOKEN) { this.Type = TokenType.INT; } else if (state == LexicalMachineState.SPECIAL_TOKEN) { this.Type = this.Text switch { "=" => TokenType.EQUALS, ":=" => TokenType.EQUALS, ">" => TokenType.GREATER, ">=" => TokenType.GREATER_OR_EQUAL, "<" => TokenType.LESS, "<=" => TokenType.LESS_OR_EQUAL, "<>" => TokenType.NOT_EQUAL, "(" => TokenType.OPENING_BRACES, ")" => TokenType.CLOSING_BRACES, "," => TokenType.COMMA, "+" => TokenType.PLUS, "-" => TokenType.MINUS, "*" => TokenType.MULT, "/" => TokenType.DIV, _ => TokenType.ERROR }; } else if (state == LexicalMachineState.VAR_TOKEN) { this.Type = TokenType.VAR; } else if (state == LexicalMachineState.QUOTED_STRING_TOKEN) { this.Type = TokenType.QUOTED_STRING; } else if (command.Category == AtomType.CONTROL) { this.Type = TokenType.END; } else { this.Type = TokenType.ERROR; } }
public LexicalStateTransition(LexicalMachineState currentState, AtomType command) { this.CurrentState = currentState; this.Command = command; }