private IEnumerable <ArgPattern> ParseAtom(ArgTokens tokenParser) { // atom ::= '(' expr ')' | '[' expr ']' | 'options' // | long | shorts | argument | command ; var token = tokenParser.Current(); var result = new List <ArgPattern>(); switch (token) { case "[": case "(": { tokenParser.Move(); string matching; if (token == "(") { matching = ")"; result.Add(new ArgRequired(ParseExpression(tokenParser).ToArray())); } else { matching = "]"; result.Add(new ArgOptional(ParseExpression(tokenParser).ToArray())); } if (tokenParser.Move() != matching) { throw new Exception("unmatched '" + token + "'"); } } break; default: if ((token.StartsWith("<") && token.EndsWith(">")) || token.All(c => Char.IsUpper(c))) { result.Add(new ArgArgument(tokenParser.Move())); } else if (token.StartsWith("-")) { result.Add(ParseOption(tokenParser)); tokenParser.Move(); } else { result.Add(new ArgCommand(tokenParser.Move())); } break; } return(result); }
private IEnumerable <ArgPattern> ParseSequence(ArgTokens tokenParser) { var result = new List <ArgPattern>(); while (!new[] { null, "]", ")", "|" }.Contains(tokenParser.Current())) { var atom = ParseAtom(tokenParser); if (tokenParser.Current() == "...") { result.Add(new ArgOneOrMore(atom.ToArray())); tokenParser.Move(); return(result); } result.AddRange(atom); } return(result); }
private IEnumerable <ArgPattern> ParseExpression(ArgTokens tokenParser) { var seq = ParseSequence(tokenParser); if (tokenParser.Current() != "|") { return(seq); } var result = new List <ArgPattern>(); if (seq.Count() > 1) { result.Add(new ArgRequired(seq.ToArray())); } else { result.AddRange(seq); } while (tokenParser.Current() == "|") { tokenParser.Move(); seq = ParseSequence(tokenParser); if (seq.Count() > 1) { result.Add(new ArgRequired(seq.ToArray())); } else { result.AddRange(seq); } } result = result.Distinct().ToList(); if (result.Count > 1) { return new[] { new ArgEither(result.ToArray()) } } ; return(result); }