// Set the current line number as a statement node attribute. protected internal void SetLineNumber(ICodeNode node, Token token) { if (node != null) { node.SetAttribute(ICodeKeyImplementation.LINE, token.lineNumber); } }
public override ICodeNode Parse(Token token) { // Create the ASSIGN node. ICodeNode assignNode = ICodeFactory.CreateICodeNode(ICodeNodeTypeImplementation.ASSIGN); string targetName = token.text.ToLower(); SymbolTableEntry targetID = symbolTableStack.Lookup(targetName); if (targetID == null) { targetID = symbolTableStack.EnterLocal(targetName); } targetID.AppendLineNumber(token.lineNumber); token = NextToken(); ICodeNode variableNode = ICodeFactory.CreateICodeNode(ICodeNodeTypeImplementation.VARIABLE); variableNode.SetAttribute(ICodeKeyImplementation.ID, targetID); assignNode.AddChild(variableNode); if (token.type == PascalTokenType.COLON_EQUALS) { token = NextToken(); } else { errorHandler.flag(token, PascalErrorCode.MISSING_COLON_EQUALS, this); } ExpressionParser expressionParser = new ExpressionParser(this); assignNode.AddChild(expressionParser.Parse(token)); return(assignNode); }
// Set the current line number as a statement node attribute. protected internal void SetLineNumber(ICodeNode node, Token token) { if (node != null) node.SetAttribute(ICodeKeyImplementation.LINE, token.lineNumber); }
private ICodeNode ParseFactor(Token token) { TokenType tokenType = token.type; ICodeNode rootNode = null; switch (tokenType.ToString()) { case "IDENTIFIER": { // Look up the identifier in the symbol table stack. // Flag the identifier as undefined if it's not found. String name = token.text.ToLower(); SymbolTableEntry id = symbolTableStack.Lookup(name); if (id == null) { errorHandler.flag(token, PascalErrorCode.IDENTIFIER_UNDEFINED, this); id = symbolTableStack.EnterLocal(name); } rootNode = ICodeFactory.CreateICodeNode(ICodeNodeTypeImplementation.VARIABLE); rootNode.SetAttribute(ICodeKeyImplementation.ID, id); id.AppendLineNumber(token.lineNumber); token = NextToken(); // consume the identifier break; } case "INTEGER": { // Create an INTEGER_CONSTANT node as the root node. rootNode = ICodeFactory.CreateICodeNode(ICodeNodeTypeImplementation.INTEGER_CONSTANT); rootNode.SetAttribute(ICodeKeyImplementation.VALUE, token.value); token = NextToken(); // consume the number break; } case "REAL": { // Create an REAL_CONSTANT node as the root node. rootNode = ICodeFactory.CreateICodeNode(ICodeNodeTypeImplementation.REAL_CONSTANT); rootNode.SetAttribute(ICodeKeyImplementation.VALUE, token.value); token = NextToken(); // consume the number break; } case "STRING": { String value = (String)token.value; // Create a STRING_CONSTANT node as the root node. rootNode = ICodeFactory.CreateICodeNode(ICodeNodeTypeImplementation.STRING_CONSTANT); rootNode.SetAttribute(ICodeKeyImplementation.VALUE, value); token = NextToken(); // consume the string break; } case "NOT": { token = NextToken(); // consume the NOT // Create a NOT node as the root node. rootNode = ICodeFactory.CreateICodeNode(ICodeNodeTypeImplementation.NOT); // Parse the factor. The NOT node adopts the // factor node as its child. rootNode.AddChild(ParseFactor(token)); break; } case "LEFT_PAREN": { token = NextToken(); // consume the ( // Parse an expression and make its node the root node. rootNode = ParseExpression(token); // Look for the matching ) token. token = CurrentToken(); if (token.type == PascalTokenType.RIGHT_PAREN) { token = NextToken(); // consume the ) } else { errorHandler.flag(token, PascalErrorCode.MISSING_RIGHT_PAREN, this); } break; } default: { errorHandler.flag(token, PascalErrorCode.UNEXPECTED_TOKEN, this); break; } } return(rootNode); }