private static ErlangListItemSyntax ParseListItem(TokenBuffer buffer, ParseStyle style) { var expression = ParseExpression(buffer, style); if (expression != null) { ErlangPunctuationToken separator = null; var sep = buffer.Peek(); if (ErlangToken.IsComma(sep) || ErlangToken.IsPipe(sep)) { buffer.Advance(); separator = (ErlangPunctuationToken)sep; } return(new ErlangListItemSyntax(expression, separator)); } return(null); }
internal static ErlangListSyntax ParseList(TokenBuffer buffer, ParseStyle style) { var left = buffer.Peek(); if (ErlangToken.IsString(left)) { buffer.Advance(); return(new ErlangListStringSyntax((ErlangStringToken)left)); } else if (ErlangToken.IsLeftBracket(left)) { buffer.Advance(); var items = new List <ErlangListItemSyntax>(); ErlangExpressionSyntax tail = null; while (buffer.TokensRemain()) { var item = ParseListItem(buffer, style); if (item == null) { break; } items.Add(item); if (!ErlangToken.IsComma(item.Separator)) { break; } } if (items.Count == 1 && ErlangToken.IsDoublePipe(buffer.Peek())) { // list comprehension, parse generator expression and filters // result of generator expressions get filtered, e.g. // [X || {X, some_atom} <- some_list()]. var listItem = items.Single(); var doublePipe = (ErlangPipePipeToken)buffer.Peek(); buffer.Advance(); return(ParseListComprehension((ErlangLeftBracketToken)left, listItem.Item, doublePipe, buffer, style)); } else if (items.Count > 0) { var lastSep = items.Last().Separator; if (ErlangToken.IsPipe(lastSep)) { // list tail, only parse one more expression tail = ParseExpression(buffer, style); } else if (lastSep != null) { Debug.Assert(false, "unexpected list separator"); } } ErlangRightBracketToken rightBracket = null; var next = buffer.Peek(); if (ErlangToken.IsRightBracket(next)) { buffer.Advance(); rightBracket = (ErlangRightBracketToken)next; } else { Debug.Assert(false, "Missing closing bracket"); } return(new ErlangListRegularSyntax((ErlangLeftBracketToken)left, items, tail, rightBracket)); } return(null); }