internal CppConstant(string name, string attributePrefix, string ns, string value, CppDataType dataType, string[] usings) : base(name, attributePrefix) { Namespace = ns; Value = value; DataType = dataType; Usings = usings; }
public static IEnumerable <CppField> Parse(ParseNode declaration, string[] usings, string ns, List <ParserMessage> messages, string attributePrefix, CppType containingType) { if (!declaration.IsValidFieldDeclaration()) { return(Enumerable.Empty <CppField>()); } ParseNode[] identifiers = declaration.GetFieldIdentifier(); if (identifiers.FirstOrDefault()?.ToString() == "using") { //using directive inside class/struct return(Enumerable.Empty <CppField>()); } ParseNode[] typeNodes = declaration.GetFieldTypeNodes(identifiers); if (identifiers.SequenceEqual(typeNodes)) { if (typeNodes.Any()) { (int line, int column)position = declaration.Position; messages.Add(new ParserMessage("CPP0001", position.line, position.column)); } //Empty group "private:" return(Enumerable.Empty <CppField>()); } CppDataType dataType = typeNodes.GetFieldDataType(usings, ns); IEnumerable <ParseNode> fieldIdentifiers = identifiers.Intersect(typeNodes).Any() ? identifiers.SkipWhile(i => !typeNodes.Contains(i)) .SkipWhile(typeNodes.Contains) : identifiers; IEnumerable <(string name, string[] multiplicity)> fields = fieldIdentifiers .Select(i => (i.ToString(), i.GetParent().GetFieldMultiplicity())); CppComment[] comments = declaration.GetFieldComments(); return(fields.Select(fd => new CppField(fd.name, dataType, comments, fd.multiplicity, attributePrefix, containingType))); }
private IEnumerable <IConstant> GetConstants(ParseNode root, string[] usings) { List <IConstant> constants = new List <IConstant>(); IEnumerable <ParseNode> declarations = root.GetHierarchy() .Where(n => n.RuleName == "declaration" && n.RuleType == "choice" && n.ToString().Contains("const ")); foreach (ParseNode declaration in declarations) { ParseConstant(declaration); } return(constants); void ParseConstant(ParseNode declaration) { if (declaration.IsValidFieldDeclaration() && ContainsConstIdentifier()) { } if (!declaration.IsValidFieldDeclaration() || !ContainsConstIdentifier() || IsPartOfMethodDefinition() || HasTypeDeclarationParent(declaration)) { return; } //paran_group //declaration_list ParseNode[] identifiers = declaration.GetFieldIdentifier() .SkipWhile(i => i.ToString().Trim() != "const") .Skip(1) .ToArray(); if (!identifiers.Any()) { return; } ParseNode[] typeNodes = declaration.GetFieldTypeNodes(identifiers); ParseNode[] valueNodes = declaration.GetFieldValue(); if (identifiers.SequenceEqual(typeNodes)) { return; } string ns = GetNamespace(declaration, skipFirst: false); CppDataType dataType = typeNodes.GetFieldDataType(usings, ns); IEnumerable <string> fields = identifiers.SkipWhile(i => !typeNodes.Contains(i)) .SkipWhile(typeNodes.Contains) .Where(i => !i.GetParent().GetFieldMultiplicity().Any()) .Select(i => i.ToString()); IEnumerable <string> values = valueNodes.Where(i => !string.IsNullOrEmpty(i.ToString().Trim())) .Select(i => i.ToString().Trim()); string value = string.Join(" ", values); if (string.IsNullOrEmpty(value)) { return; } foreach (string field in fields) { constants.Add(new CppConstant(field, settingsProvider.Settings.AttributePrefix, ns, value, dataType, usings)); } bool ContainsConstIdentifier() { return(declaration.GetFieldIdentifier().FirstOrDefault()? .ToString().Trim() == "const"); } bool IsPartOfMethodDefinition() { return(declaration.GetDeclarationListParent()?.GetParent()? .RuleName == "paran_group"); } } }
public static IEnumerable <CppField> Parse(ParseNode declaration, string[] usings, string ns, List <ParserMessage> messages, string attributePrefix, CppType containingType) { if (declaration.GetHierarchy().Any(n => n.RuleName == "paran_group") || declaration.GetHierarchy().Any(n => n.RuleName == "typedef_decl") || declaration.GetHierarchy().Any(n => n.RuleName == "pp_directive")) { return(Enumerable.Empty <CppField>()); } ParseNode[] identifiers = GetIdentifier(); ParseNode[] typeNodes = GetTypeDeclarationName() ?? GetTypeNodes(identifiers); if (identifiers.SequenceEqual(typeNodes)) { if (typeNodes.Any()) { (int line, int column)position = declaration.Position; messages.Add(new ParserMessage("CPP0001", position.line, position.column)); } //Empty group "private:" return(Enumerable.Empty <CppField>()); } string dataTypeName = typeNodes.Aggregate(string.Empty, (s, node) => $"{s}{node}"); IEnumerable <(string name, int[] multiplicity)> fields = identifiers.Except(typeNodes).Select(i => (i.ToString(), GetMultiplicity(i.GetParent()))); IComment[] comments = GetComments(); CppDataType dataType = new CppDataType(dataTypeName, usings, ns); return(fields.Select(fd => new CppField(fd.name, dataType, comments, fd.multiplicity, attributePrefix, containingType))); ParseNode[] GetTypeDeclarationName() { ParseNode typeDeclaration = declaration.GetHierarchy().FirstOrDefault(n => n.RuleName == "type_decl"); return(typeDeclaration?.GetHierarchy().Select(Identifier).Where(n => n != null).ToArray()); ParseNode Identifier(ParseNode node) { if (node.RuleType == "leaf" && node.RuleName == "identifier") { return(node); } return(null); } } IComment[] GetComments() { ParseNode content = declaration.ChildrenSkipUnnamed().First(n => n.RuleType == "plus" && n.RuleName == "declaration_content"); return(content.ChildrenSkipUnnamed() .Where(IsComment) .Where(c => !string.IsNullOrEmpty(c.ToString())) .Select(CppComment.Parse) .ToArray()); bool IsComment(ParseNode node) { return(node.RuleType == "sequence" && node.RuleName == "comment_set"); } } ParseNode[] GetIdentifier() { ParseNode content = declaration.ChildrenSkipUnnamed().FirstOrDefault(n => n.RuleType == "plus" && n.RuleName == "declaration_content"); if (content == null) { return(Array.Empty <ParseNode>()); } return(content.ChildrenSkipUnnamed() .Select(Identifier).Where(n => n != null) .ToArray()); ParseNode Identifier(ParseNode parent) { if (parent.RuleType == "choice" && parent.RuleName == "node") { ParseNode result = parent.FirstOrDefault(); if (result?.RuleType == "leaf" && result.RuleName == "identifier") { return(result); } } return(null); } } int[] GetMultiplicity(ParseNode identifier) { identifier = identifier.SkipUnnamedParents(); int index = identifier.GetParentIndex(); ParseNode parent = identifier.GetParent(); List <int> multiplicities = new List <int>(); bool firstMultiplicityFound = false; foreach (ParseNode sibling in parent.Skip(index + 1).SkipUnnamed()) { if (sibling.RuleType == "choice" && sibling.RuleName == "node") { ParseNode child = sibling.FirstOrDefault(); if (child?.RuleType == "sequence" && child.RuleName == "bracketed_group") { string bracketGroup = child.ToString().Trim(); if (int.TryParse(bracketGroup.Substring(1, bracketGroup.Length - 2), out int result)) { multiplicities.Add(result); firstMultiplicityFound = true; } } else if (firstMultiplicityFound) { break; } } } return(multiplicities.ToArray()); } ParseNode[] GetTypeNodes(ParseNode[] parseNodes) { return(parseNodes.TakeWhile(n => n.ToString().EndsWith("::", StringComparison.Ordinal)) .Concat(parseNodes.SkipWhile(n => n.ToString().EndsWith("::", StringComparison.Ordinal)).Take(1)) .ToArray()); } }