protected virtual ParenthesizedExpressionNode ParseParenthesizedExpression(IPrimaryParentNode parent, SpecialCharacterToken leftParenthesis) { // PARSE: '(' <expression> ')' ParenthesizedExpressionNode result = new ParenthesizedExpressionNode(parent, leftParenthesis); Token token = this.GetNextTokenxx(Preference.NegativeSign); ExpressionNode expression = this.ParseExpression(result, token); if (expression == null) { this.ReportParserError(result, SemanticErrors.MissingExpression, token); return(result); } // Ensure the parentheses are properly closed. token = this.GetNextTokenxx(Preference.Default); SpecialCharacterToken rightParenthesis = null; if (Parser.IsClosingParenthesis(token)) { rightParenthesis = (SpecialCharacterToken)token; } else { this.ReportParserError(result, SemanticErrors.MissingExpressionClosingParenthesis, token); this.ResidueToken = token; } result.SetContents(expression, rightParenthesis); return(result); }
protected virtual ArrayLiteralNode ParseArrayLiteral(ILiteralNodeParent parent, SpecialCharacterToken arrayToken) { // PARSE: <array literal> ::= '#(' <array element>* ')' // <array element> ::= <literal> | identifier Token token = this.GetNextTokenxx(Preference.Default); if (!Parser.IsOpeningParenthesis(token)) { this.ReportParserError(parent, SemanticErrors.MissingLiteralArrayOpeningParenthesis, token); // The hash token is thrown away and lost :-/ ... only the current token is passed on. this.ResidueToken = token; return(null); } List <LiteralNode> elements = new List <LiteralNode>(); ArrayLiteralNode result = new ArrayLiteralNode(parent, arrayToken, (SpecialCharacterToken)token); // Process tokens inside the array ... while (true) { // ... get next token in the array ... token = this.GetNextTokenxx(Preference.NegativeSign | Preference.UnquotedSelector); // Is this closing parenthesis? if (Parser.IsClosingParenthesis(token)) { // Closing parenthesis ... done with the array, return litral array node. result.SetContents(elements, (SpecialCharacterToken)token); this.ResidueToken = null; return(result); } if (token is EofToken) { // Unfinished source code ... return result.SetContents(elements, null); this.ReportParserError(parent, SemanticErrors.MissingLiteralArrayClosingParenthesis, token); this.ResidueToken = token; return(result); } // PARSE: <array element> ::= <literal> | identifier if (token is ILiteralArrayIdentifierToken) { // identifier ... special case only inside arrays. elements.Add(new IdentifierLiteralNode(result, (ILiteralArrayIdentifierToken)token)); } else { // ... it's not identifier, so it must be an literal LiteralNode element = this.ParseLiteral(result, token); if (element == null) { // Report error in source code ... here, it must be a literal this.ReportParserError(result, SemanticErrors.UnrecognizedLiteral, token); result.SetContents(elements, null); return(result); } else { // ... add the child element to the array elements. elements.Add(element); } } } }