public Parser(Scanner scanner, ErrorContainer errors) { this.scanner = scanner; this.errors = errors; }
public static TypeBinding DecideType(Expression expression, SymbolTable symbolTable, ErrorContainer errors) { if (expression is BinaryOperator) { var binOp = (BinaryOperator)expression; TypeBinding leftType = DecideType (binOp.LeftOperand, symbolTable, errors); TypeBinding rightType = DecideType (binOp.RightOperand, symbolTable, errors); if(leftType == null || rightType == null) { return null; } if (leftType != rightType) { errors.AddError (binOp.Oper, ErrorType.SemanticError, "Types of left and right operand do not match"); return null; } var ret = rightType.Operate (binOp.Oper.Lexeme); if(ret == null) { errors.AddError (binOp.Oper, ErrorType.SemanticError, "Could not apply operator to given types"); } return ret; } else if (expression is UnaryOperator) { var unOp = (UnaryOperator)expression; TypeBinding operandType = DecideType (unOp.Operand, symbolTable, errors); if (operandType == null) { return null; } var ret = operandType.Operate (unOp.Oper.Lexeme); if(ret == null) { errors.AddError(unOp.Oper, ErrorType.SemanticError, "Could not apply operator to given type"); } return ret; } else if (expression is ExpressionLeaf) { var leaf = (ExpressionLeaf)expression; switch(leaf.Token.Category) { case Category.Literal_Integer: return GetTypeByName(PRIMITIVE_INTEGER_NAME); case Category.Literal_String: return GetTypeByName(PRIMITIVE_STRING_NAME); case Category.Identifier: if (symbolTable.IsDeclared (leaf.Token)) { return TypeBindings.GetTypeByName(symbolTable.GetVariableType(leaf.Token)); } else { errors.AddError (leaf.Token, ErrorType.SemanticError, "Undeclared variable"); return null; } } return null; } return null; }
/* * Public methods */ public Scanner(StreamReader charStream, ErrorContainer errContainer) { this.transitionTable = new List<KeyValuePair<Func<char, bool>, Action>> () { //simple one char lexemes Transition ( c => simpleLexemes.ContainsKey(c.ToString()), () => simpleLexemes.TryGetValue(current.ToString(), out category) ), //identifier or reserved keyword Transition ( c => Char.IsLetter(c), () => ReadWhile ( x => Char.IsLetterOrDigit(x) || x =='_')), //x => !simpleLexemes.ContainsKey(x.ToString()) && x != '.' && !Char.IsWhiteSpace(x)) ), //integer literal Transition ( c => Char.IsNumber(c), () => { category = Category.Literal_Integer; ReadWhile (x => Char.IsDigit(x)); }), //string literal Transition ( c => c == '"', () => ScanString () ), //colon or assignment Transition ( c => c == ':', () => { if(PeekChar () == '=') { category = Category.Assignment; lexeme += NextChar (); } else { category = Category.Colon; } }), //inline comment, multiline comment or division operator Transition ( c => c == '/', () => { if(PeekChar() == '/') { SkipWhile(x => x != '\n' ); SkipBlank(); ScanNextToken(); } else if(PeekChar () == '*') { while(true) { SkipWhile(x => x != '*'); if(charStream.EndOfStream) { errors.AddError(lexemeBeginLine, lexemeBeginColumn, ErrorType.LexicalError, "Unclosed multiline comment"); category = Category.NONE; lexeme = "End_Of_File"; return; } NextChar(); if(PeekChar () == '/') { NextChar (); SkipBlank(); break; } } ScanNextToken(); } else { //lexeme += NextChar(); category = Category.Binary_Operator; } } ), //for loop range Transition ( c => c == '.', () => { if(PeekChar() == '.') { category = Category.Loop_Range; lexeme += NextChar(); } }) }; this.errors = errContainer; this.charStream = charStream; SkipBlank (); while (!charStream.EndOfStream) { tokenBuffer.Enqueue(ScanNextToken()); } tokenBuffer.Enqueue(new Token(Category.End_Of_File, "END_OF_FILE", line, column)); }
public SemanticAnalyser(AbstractSyntaxTree ast, ErrorContainer errors) { this.ast = ast; this.errors = errors; }
public ExpressionBuilder(ErrorContainer errors) { this.errors = errors; }