public ICodeNode Parse(Token token) { token = InternalScanner.GetNextToken(); // consume the REPEAT // create the LOOP and TEST nodes. ICodeNode loop_node = ICodeFactory.CreateICodeNode(ICodeNodeType.LOOP); ICodeNode test_node = ICodeFactory.CreateICodeNode(ICodeNodeType.TEST); // parse the statement list terminated by the UNTIL token. // the LOOP node is the parent of the statement subtrees. StatementParser stmnt_parser = StatementParser.CreateWithObservers(InternalScanner, SymTabStack, Observers); stmnt_parser.ParseList(token, loop_node, TokenType.UNTIL, ErrorCode.MISSING_UNTIL); token = InternalScanner.CurrentToken; // parse the expression. // the TEST node adopts the expression subtree as its only child. // the LOOP node adopts the TEST node. ExpressionParser expr_parser = ExpressionParser.CreateWithObservers(InternalScanner, SymTabStack, Observers); test_node.Add(expr_parser.Parse(token)); loop_node.Add(test_node); return loop_node; }
public ICodeNode Parse(Token token) { Token tok = InternalScanner.GetNextToken(); // consume the CASE token // create a SELECT node ICodeNode select_node = ICodeFactory.CreateICodeNode(ICodeNodeType.SELECT); // parse the CASE expression. // the SELECT node adopts the expression subtree as its first child. ExpressionParser expr_parser = ExpressionParser.CreateWithObservers(InternalScanner, SymTabStack, Observers); select_node.Add(expr_parser.Parse(tok)); tok = InternalScanner.CurrentToken; // synchronize the OF token. tok = Parser.Synchronize(OF_SET, InternalScanner, this); if (tok.TokenType == TokenType.OF) { tok = InternalScanner.GetNextToken(); // consume the OF } else { ErrorHandler.Flag(tok, ErrorCode.MISSING_OF, this); } // set of CASE branch constants. HashSet<object> constant_set = new HashSet<object>(); // loop to parse each CASE branch until the END token // or the end of the source file. while (!tok.IsEof && tok.TokenType != TokenType.END) { // the SELECT node adopts the CASE branch subtree select_node.Add(ParseBranch(tok, constant_set)); tok = InternalScanner.CurrentToken; if (tok.TokenType == TokenType.SEMICOLON) { tok = InternalScanner.GetNextToken(); // consume the ; } else if (CONSTANT_START_SET.Contains(tok.TokenType)) { ErrorHandler.Flag(tok, ErrorCode.MISSING_SEMICOLON, this); } } // look for the END token. if (tok.TokenType == TokenType.END) { tok = InternalScanner.GetNextToken(); // consume the END } else { ErrorHandler.Flag(tok, ErrorCode.MISSING_END, this); } return select_node; }
public static void Flag(Token token, ErrorCode err, message.MessageProducer mp) { var args = Tuple.Create(token.LineNumber, token.Position, token.Lexeme, err.Message); Message msg = new Message(MessageType.SyntaxError, args); mp.Send(msg); if (++errors > MAX_ERRORS) { AbortTranslation(ErrorCode.TOO_MANY_ERRORS, mp); } }
public ICodeNode Parse(Token token) { Contract.Requires(token.TokenType == TokenType.BEGIN); // ignore argument ! token = InternalScanner.GetNextToken(); // create the COMPOUND node. ICodeNode compound_node = ICodeFactory.CreateICodeNode(ICodeNodeType.COMPOUND); // parse the statement list terminated by the END token. StatementParser statement_parser = StatementParser.CreateWithObservers(InternalScanner, SymTabStack, observers); statement_parser.ParseList(token, compound_node, TokenType.END, ErrorCode.MISSING_END); return compound_node; }
public ICodeNode Parse(Token token) { ICodeNode node; switch (token.TokenType) { case TokenType.BEGIN: CompoundStatementParser cmpnd_parser = CompoundStatementParser.CreateWithObservers(InternalScanner, SymTabStack, observers); node = cmpnd_parser.Parse(token); break; case TokenType.IDENTIFIER: AssignmentStatementParser assign_parser = AssignmentStatementParser.CreateWithObservers(InternalScanner, SymTabStack, observers); node = assign_parser.Parse(token); break; case TokenType.REPEAT: RepeatStatementParser repeat_parser = RepeatStatementParser.CreateWithObservers(InternalScanner, SymTabStack, observers); node = repeat_parser.Parse(token); break; case TokenType.WHILE: WhileStatementParser while_parser = WhileStatementParser.CreateWithObservers(InternalScanner, SymTabStack, observers); node = while_parser.Parse(token); break; case TokenType.FOR: ForStatementParser for_parser = ForStatementParser.CreateWithObservers(InternalScanner, SymTabStack, Observers); node = for_parser.Parse(token); break; case TokenType.IF: IfStatementParser if_parser = IfStatementParser.CreateWithObservers(InternalScanner, SymTabStack, Observers); node = if_parser.Parse(token); break; case TokenType.CASE: CaseStatementParser case_parser = CaseStatementParser.CreateWithObservers(InternalScanner, SymTabStack, Observers); node = case_parser.Parse(token); break; default: node = ICodeFactory.CreateICodeNode(ICodeNodeType.NO_OP); break; } // set the current line number as an attribute. SetLineNumber(node, token.LineNumber); return node; }
public ICodeNode Parse(Token token) { // create the ASSIGN node ICodeNode assign_node = ICodeFactory.CreateICodeNode(ICodeNodeType.ASSIGN); // lookup up the target identifier in the symbol table stack. // enter the identifier into the table if it's not found. string target_name = token.Lexeme.ToLower(); SymbolTableEntry target_id = SymTabStack.FindInLocal(target_name); if (target_id == null) { target_id = SymTabStack.CreateInLocal(target_name); } target_id.AppendLine(token.LineNumber); Contract.Requires(token.TokenType == TokenType.IDENTIFIER); token = InternalScanner.GetNextToken(); // consume the identifier token // create the variable node and set its name attribute. ICodeNode variable_node = ICodeFactory.CreateICodeNode(ICodeNodeType.VARIABLE); variable_node.SetAttribute(ICodeKey.ID, target_id); // the assign node adopts the variable node as its first child. assign_node.Add(variable_node); // synchronize on the := token. token = Parser.Synchronize(COLON_EQUALS_SET, InternalScanner, this); // look for the := token if (token.TokenType == TokenType.COLON_EQUALS) { token = InternalScanner.GetNextToken(); // consume the := } else { ErrorHandler.Flag(token, ErrorCode.MISSING_COLON_EQUALS, this); } // parse the expression. The ASSIGN node adopts the expression's node // as its second child. ExpressionParser exp_parser = ExpressionParser.CreateWithObservers(InternalScanner, SymTabStack, observers); assign_node.Add(exp_parser.Parse(token)); return assign_node; }
public ICodeNode Parse(Token token) { Token tok = InternalScanner.GetNextToken(); // consume the IF token // create an IF node. ICodeNode if_node = ICodeFactory.CreateICodeNode(ICodeNodeType.IF); // parse the expression. // the IF node adopts the expression subtree as its first child. ExpressionParser expr_parser = ExpressionParser.CreateWithObservers(InternalScanner, SymTabStack, Observers); if_node.Add(expr_parser.Parse(tok)); // synchronize the THEN tok = Parser.Synchronize(THEN_SET, InternalScanner, this); if (tok.TokenType == TokenType.THEN) { tok = InternalScanner.GetNextToken(); // consume the THEN } else { ErrorHandler.Flag(tok, ErrorCode.MISSING_THEN, this); } // parse the THEN statement. // the IF node adopts the statement subtree as its second child. StatementParser stmt_parser = StatementParser.CreateWithObservers(InternalScanner, SymTabStack, Observers); if_node.Add(stmt_parser.Parse(tok)); tok = InternalScanner.CurrentToken; // look for an ELSE if (tok.TokenType == TokenType.ELSE) { tok = InternalScanner.GetNextToken(); // consume the THEN token // parse the ELSE statement. // the IF node adopts the statement subtree as its third child. if_node.Add(stmt_parser.Parse(tok)); } return if_node; }
public ICodeNode Parse(Token token) { token = InternalScanner.GetNextToken(); // consume the WHILE // create LOOP, TEST and NOT nodes ICodeNode loop_node = ICodeFactory.CreateICodeNode(ICodeNodeType.LOOP); ICodeNode break_node = ICodeFactory.CreateICodeNode(ICodeNodeType.TEST); ICodeNode not_node = ICodeFactory.CreateICodeNode(ICodeNodeType.NOT); // the LOOP node adopts the TEST node as its first child. // the TEST node adopts the NOT node as its only child. loop_node.Add(break_node); break_node.Add(not_node); ExpressionParser expr_parser = ExpressionParser.CreateWithObservers(InternalScanner, SymTabStack, Observers); not_node.Add(expr_parser.Parse(token)); // synchronize at the DO. token = Parser.Synchronize(DO_SET, InternalScanner, this); if (token.TokenType == TokenType.DO) { token = InternalScanner.GetNextToken(); } else { ErrorHandler.Flag(token, ErrorCode.MISSING_DO, this); } // parse the statement // the LOOP node adopts the statement subtree as its second child. StatementParser stmnt_parser = StatementParser.CreateWithObservers(InternalScanner, SymTabStack, Observers); loop_node.Add(stmnt_parser.Parse(token)); return loop_node; }
private void ParseConstantList(Token token, ICodeNode constants_node, HashSet<object> constant_set) { // loop to parse each constant. while (CONSTANT_START_SET.Contains(token.TokenType)) { // the constants list node adopts the constant node. constants_node.Add(ParseConstant(token, constant_set)); // synchronize at the comma between constants. token = Parser.Synchronize(COMMA_SET, InternalScanner, this); // look for the COMMA if (token.TokenType == TokenType.COMMA) { token = InternalScanner.GetNextToken(); // consume the , } else if (CONSTANT_START_SET.Contains(token.TokenType)) { ErrorHandler.Flag(token, ErrorCode.MISSING_COMMA, this); } } }
public void ParseList(Token token, ICodeNode parent, TokenType terminator, ErrorCode error) { var terminator_set = new HashSet<TokenType>(STMT_START_SET); terminator_set.Add(terminator); while(!token.IsEof && token.TokenType != terminator) { // parse a statement. The parent node adopts the statement node. ICodeNode statement_node = Parse(token); parent.Add(statement_node); token = InternalScanner.CurrentToken; // look for the semicolon between the statements. if (token.TokenType == TokenType.SEMICOLON) { token = InternalScanner.GetNextToken(); } else if (STMT_START_SET.Contains(token.TokenType)) { ErrorHandler.Flag(token, ErrorCode.MISSING_SEMICOLON, this); } // Synchronize at the start of the next statement // or at the terminator. token = Parser.Synchronize(terminator_set, InternalScanner, this); } // look for the terminator token if (token.TokenType == terminator) { token = InternalScanner.GetNextToken(); } else { ErrorHandler.Flag(token, error, this); } }
public ICodeNode Parse(Token token) { return ParseExpression(token); }
private ICodeNode ParseTerm(Token token) { // parse a factor and make its node the root node. ICodeNode root = ParseFactor(token); token = InternalScanner.CurrentToken; while (MUL_OPS.Contains(token.TokenType)) { // create a new operator node and adopt the current tree // as its first child. ICodeNodeType op = MUL_OPS_OPS_MAP[token.TokenType]; ICodeNode op_node = ICodeFactory.CreateICodeNode(op); op_node.Add(root); token = InternalScanner.GetNextToken(); // consume the operator // parse another factor. The operator node adopts // the term's tree as its second child. op_node.Add(ParseFactor(token)); // the operator node becomes the new root node. root = op_node; token = InternalScanner.CurrentToken; } return root; }
private ICodeNode ParseSimpleExpression(Token token) { TokenType sign = TokenType.INVALID; // type of leading sign, if any // look for a leading + or - sign if (token.TokenType == TokenType.PLUS || token.TokenType == TokenType.MINUS) { sign = token.TokenType; token = InternalScanner.GetNextToken(); // consume + or - } // parse a term and make the root of its tree the root node/ ICodeNode root = ParseTerm(token); // was there a leading - sign ? if (sign == TokenType.MINUS) { // create a NEGATE node and adopt the current tree // as its child. The NEGATE node becomes the new root node. ICodeNode negate = ICodeFactory.CreateICodeNode(ICodeNodeType.NEGATE); negate.Add(root); root = negate; } token = InternalScanner.CurrentToken; // loop over additive operators while (ADD_OPS.Contains(token.TokenType)) { // create a new operator node and adopt the current tree as its first child ICodeNodeType op_type = ADD_OPS_OPS_MAP[token.TokenType]; ICodeNode op_node = ICodeFactory.CreateICodeNode(op_type); op_node.Add(root); token = InternalScanner.GetNextToken(); // consume the operator // parse another term. The operator node adopts // the term's tree as its second child. op_node.Add(ParseTerm(token)); // the operator node becomes the new root node. root = op_node; token = InternalScanner.CurrentToken; } return root; }
private ICodeNode ParseFactor(Token token) { ICodeNode root = null; switch (token.TokenType) { case TokenType.IDENTIFIER: { // look the identifier in the symbol table stack. // flag the identifier as undefined if it's not found. string name = token.Lexeme.ToLower(); SymbolTableEntry id = SymTabStack.Find(name); if (id == null) { ErrorHandler.Flag(token, ErrorCode.IDENTIFIER_UNDEFINED, this); id = SymTabStack.CreateInLocal(name); } root = ICodeFactory.CreateICodeNode(ICodeNodeType.VARIABLE); root.SetAttribute(ICodeKey.ID, id); id.AppendLine(token.LineNumber); token = InternalScanner.GetNextToken(); } break; case TokenType.INTEGER: // create an INTEGER_CONSTANT node as the root node. root = ICodeFactory.CreateICodeNode(ICodeNodeType.INTEGER_CONSTANT); root.SetAttribute(ICodeKey.VALUE, token.Value); token = InternalScanner.GetNextToken(); break; case TokenType.REAL: // create a REAL_CONSTANT node as the root node. root = ICodeFactory.CreateICodeNode(ICodeNodeType.REAL_CONSTANT); root.SetAttribute(ICodeKey.VALUE, token.Value); token = InternalScanner.GetNextToken(); break; case TokenType.STRING: // create a STRING_CONSTANT node as the root node. root = ICodeFactory.CreateICodeNode(ICodeNodeType.STRING_CONSTANT); root.SetAttribute(ICodeKey.VALUE, token.Value); token = InternalScanner.GetNextToken(); break; case TokenType.NOT: token = InternalScanner.GetNextToken(); // consume NOT // create a NOT node as the root node root = ICodeFactory.CreateICodeNode(ICodeNodeType.NOT); // parse a factor. The NOT node adopts the // factor as its child. root.Add(ParseFactor(token)); break; case TokenType.LEFT_PAREN: token = InternalScanner.GetNextToken(); // consume the ( // parse an expression and make its node the root node. root = ParseExpression(token); // look for the matching ) token. token = InternalScanner.CurrentToken; if (token.TokenType == TokenType.RIGHT_PAREN) { token = InternalScanner.GetNextToken(); // consume the ) } else { ErrorHandler.Flag(token, ErrorCode.MISSING_RIGHT_PAREN, this); } break; default: ErrorHandler.Flag(token, ErrorCode.UNEXPECTED_TOKEN, this); break; } return root; }
private ICodeNode ParseExpression(Token token) { // parse a simple expression, and make it the root of its tree // root node. ICodeNode root = ParseSimpleExpression(token); token = InternalScanner.CurrentToken; if (REL_OPS.Contains(token.TokenType)) { // create a new operator node and adopt the current tree // as its first child. ICodeNodeType type = REL_OPS_MAP[token.TokenType]; ICodeNode op_node = ICodeFactory.CreateICodeNode(type); op_node.Add(root); token = InternalScanner.GetNextToken(); // consume the operator // parse the second simple expression. The operator node adopts // the simple expression's tree as its second child. op_node.Add(ParseSimpleExpression(token)); // the operator node becomes the new node root = op_node; } return root; }
public Token GetNextToken() { CurrentToken = ExtractToken(); return CurrentToken; }
private ICodeNode ParseConstant(Token token, HashSet<object> constant_set) { TokenType sign = TokenType.INVALID; ICodeNode constant_node = null; // synchronize at the start of a constant. token = Parser.Synchronize(CONSTANT_START_SET, InternalScanner, this); if (token.TokenType == TokenType.PLUS || token.TokenType == TokenType.MINUS) { sign = token.TokenType; token = InternalScanner.GetNextToken(); // consume sign } // parse the constant. switch (token.TokenType) { case TokenType.IDENTIFIER: constant_node = ParseIdentifierConstant(token, sign); break; case TokenType.INTEGER: constant_node = ParseIntegerConstant(token.Lexeme, sign); break; case TokenType.STRING: constant_node = ParseCharacterConstant(token, (string)token.Value, sign); break; default: ErrorHandler.Flag(token, ErrorCode.INVALID_CONSTANT, this); break; } // check for reused constants if (constant_node != null) { object value = constant_node.GetAttribute(ICodeKey.VALUE); if (constant_set.Contains(value)) { ErrorHandler.Flag(token, ErrorCode.CASE_CONSTANT_REUSED, this); } else { constant_set.Add(value); } } InternalScanner.GetNextToken(); // consume the constant return constant_node; }
private ICodeNode ParseCharacterConstant(Token token, string value, TokenType sign) { ICodeNode constant_node = null; if (sign != TokenType.INVALID) { ErrorHandler.Flag(token, ErrorCode.INVALID_CONSTANT, this); } else { if (value.Length == 1) { constant_node = ICodeFactory.CreateICodeNode(ICodeNodeType.STRING_CONSTANT); constant_node.SetAttribute(ICodeKey.VALUE, value); } else { ErrorHandler.Flag(token, ErrorCode.INVALID_CONSTANT, this); } } return constant_node; }
private ICodeNode ParseBranch(Token token, HashSet<object> const_set) { // create a SELECT_BRANCH node and a SELECT_CONSTANTS node // the SELECT _BRANCH adopts the SELECT_CONSTANTS node as its // first child. ICodeNode branch_node = ICodeFactory.CreateICodeNode(ICodeNodeType.SELECT_BRANCH); ICodeNode constant_nodes = ICodeFactory.CreateICodeNode(ICodeNodeType.SELECT_CONSTANTS); branch_node.Add(constant_nodes); // parse the list of CASE branch constants. // the SELECT_CONSTANTS node adopts each constant. ParseConstantList(token, constant_nodes, const_set); // look for the : token token = InternalScanner.CurrentToken; if (token.TokenType == TokenType.COLON) { token = InternalScanner.GetNextToken(); } else { ErrorHandler.Flag(token, ErrorCode.MISSING_COLON, this); } // parse the CASE branch statement. The SELECT_BRANCH node adopts // the statement subtree as its second child. StatementParser stmnt_parser = StatementParser.CreateWithObservers(InternalScanner, SymTabStack, Observers); branch_node.Add(stmnt_parser.Parse(token)); return branch_node; }
private ICodeNode ParseIdentifierConstant(Token token, TokenType sign) { // Placeholder! Don't allow for now. ErrorHandler.Flag(token, ErrorCode.INVALID_CONSTANT, this); return null; }
public ICodeNode Parse(Token token) { Token tok = InternalScanner.GetNextToken(); // consume the FOR Token target = tok; // create the COMPOUND, LOOP and TEST nodes ICodeNode compound = ICodeFactory.CreateICodeNode(ICodeNodeType.COMPOUND); ICodeNode loop = ICodeFactory.CreateICodeNode(ICodeNodeType.LOOP); ICodeNode test = ICodeFactory.CreateICodeNode(ICodeNodeType.TEST); // parse the embedded initial assignment. AssignmentStatementParser assign = AssignmentStatementParser.CreateWithObservers(InternalScanner, SymTabStack, Observers); ICodeNode init_assign_node = assign.Parse(tok); // set the current line number SetLineNumber(init_assign_node, target.LineNumber); // the COMPOUND node adopts the initial ASSIGN and the LOOP nodes // as its first and second children. compound.Add(init_assign_node); compound.Add(loop); // synchronize at the TO or DOWNTO tok = Parser.Synchronize(TO_DOWNTO_SET, InternalScanner, this); TokenType direction = tok.TokenType; // look for the TO or DOWNTO if (tok.TokenType == TokenType.TO || tok.TokenType == TokenType.DOWNTO) { tok = InternalScanner.GetNextToken(); // consume the TO or DOWNTO } else { direction = TokenType.TO; ErrorHandler.Flag(tok, ErrorCode.MISSING_TO_DOWN_TO, this); } // create a relational operator node: GT for TO, or LT for DOWNTO ICodeNode relop_node = ICodeFactory.CreateICodeNode(direction == TokenType.TO ? ICodeNodeType.GT : ICodeNodeType.LT); // copy the control VARIABLE node. The relational operator node // adopts the copied VARIABLE node, as its first child. ICodeNode control_var_node = init_assign_node.GetChildren().ElementAt(0); relop_node.Add(control_var_node.Copy()); // parse the termination expression. The relational operator node // adopts the expression as its second child. ExpressionParser expr_parser = ExpressionParser.CreateWithObservers(InternalScanner, SymTabStack, Observers); relop_node.Add(expr_parser.Parse(tok)); // the TEST node adopts the relational operator node as its only child. // the LOOP node adopts the TEST node as its first child. test.Add(relop_node); loop.Add(test); // synchronize at the DO. tok = Parser.Synchronize(DO_SET, InternalScanner, this); if (tok.TokenType == TokenType.DO) { tok = InternalScanner.GetNextToken(); } else { ErrorHandler.Flag(tok, ErrorCode.MISSING_DO, this); } // parse the nested statement. The LOOP node adopts the statement // node as its second child. StatementParser stmnt_parser = StatementParser.CreateWithObservers(InternalScanner, SymTabStack, Observers); loop.Add(stmnt_parser.Parse(tok)); // create an assignment with a copy of the control variable // to advance the value of the variable. ICodeNode next_assign = ICodeFactory.CreateICodeNode(ICodeNodeType.ASSIGN); next_assign.Add(control_var_node.Copy()); // create an arithmetic operator node // ADD for TO, SUBTRACT for DOWNTO ICodeNode arith_node = ICodeFactory.CreateICodeNode(direction == TokenType.TO ? ICodeNodeType.ADD : ICodeNodeType.SUBTRACT); // the operator node adopts adopts a copy of the loop variable as its // first child and the value 1 as its second child. arith_node.Add(control_var_node.Copy()); ICodeNode one_node = ICodeFactory.CreateICodeNode(ICodeNodeType.INTEGER_CONSTANT); one_node.SetAttribute(ICodeKey.VALUE, 1); arith_node.Add(one_node); // the next ASSIGN node adopts the arithmetic operator node as its // second child. The loop node adopts to the next ASSIGN node as its // third child. next_assign.Add(arith_node); loop.Add(next_assign); // set the current line number attribute. SetLineNumber(next_assign, target.LineNumber); return compound; }