/// <summary> /// parse and add default attribute to entry /// <para>"def_bool" / "def_tristate" < expr > ["if" < expr >]</para> /// </summary> /// <param name="sr">for get location</param> /// <param name="entry">attribute will add to this entry</param> /// <param name="inStr">source line</param> /// <param name="type">"def_bool"/"def_tristate"</param> private static void ParseAttrDefaultType(FileReader sr, MenuEntry entry, string inStr, MenuAttributeType type) { // remove "def_" if (!Enum.TryParse(type.ToString().Substring(4), true, out MenuAttributeType defValType)) { throw sr.GenExpWithLocation($"Fail to parse \"{type}\" attribute."); } if (entry.Attributes.Any(attribute => attribute.AttributeType == MenuAttributeType.ValueType)) { throw sr.GenExpWithLocation( $"Could not add {type} attribute when \"ValueType\" attribute exist."); } entry.Attributes.Add(new MenuAttribute { AttributeType = MenuAttributeType.ValueType, ExpressionType = defValType }); //set entry value type entry.ValueType = defValType; if (!string.IsNullOrEmpty(inStr)) { ParseAttrWithValAndCond(sr, entry, inStr, MenuAttributeType.Default); } }
/// <summary> /// Add value type and prompt to entry /// <para>"bool"/"tristate"/"string"/"hex"/"int" [<prompt>]</para> /// </summary> /// <param name="sr">for get location</param> /// <param name="entry">attribute will add to this entry</param> /// <param name="inStr">prompt</param> /// <param name="type">"bool"/"tristate"/"string"/"hex"/"int"</param> private static void ParseAttrValueType(FileReader sr, MenuEntry entry, string inStr, MenuAttributeType type) { // type definition: "bool"/"tristate"/"string"/"hex"/"int" [<prompt>] if (entry.Attributes.Any(attribute => attribute.AttributeType == MenuAttributeType.ValueType)) { throw sr.GenExpWithLocation( "Could not add multi \"ValueType\" attribute."); } // add value type entry.Attributes.Add(new MenuAttribute { AttributeType = MenuAttributeType.ValueType, ExpressionType = type }); // set entry value type entry.ValueType = type; if (string.IsNullOrEmpty(inStr)) { return; } // add prompt entry.Attributes.Add(new MenuAttribute() { AttributeType = MenuAttributeType.Prompt, SymbolValue = RemoveQuotationMark(inStr) }); }
/// <summary> /// Split option type and value /// <para>format: <type>[=<value>]</para> /// </summary> /// <param name="src">source line</param> /// <param name="optionType">option type</param> /// <param name="value">option value, for env option only.</param> /// <returns>isSuccess</returns> private static bool GetOptionTypeValue(string src, out MenuAttributeType optionType, out string value) { var match = FindOptionSymbolValueRegex.Match(src); // remove blank, '-', '_' var type = ClearAttributeKeyRegex.Replace(match.Groups["key"].Value, ""); value = match.Groups["val"].Value; return(Enum.TryParse(type, true, out optionType)); }
/// <summary> /// choice's child entry can only be config or if block with configures. /// Value type of all config should be bool or tristate. /// Assign choice value type from first config if choice value has not assigned. /// </summary> /// <param name="entry">choice entry</param> /// <param name="choiceType">choice value type</param> private static void CheckConfigValueTypeInChoice(MenuEntry entry, ref MenuAttributeType choiceType) { foreach (var childEntry in entry.ChildEntries) { switch (childEntry.EntryType) { case MenuEntryType.Config: var attr = childEntry.Attributes .FirstOrDefault(attribute => attribute.AttributeType == MenuAttributeType.ValueType); if (attr == null) { break; } var valueType = attr.ExpressionType; if (valueType != MenuAttributeType.Bool && valueType != MenuAttributeType.Tristate) { throw new ParseException( $"Choice contains config which type is \"{valueType}\".", childEntry.Location); } if (choiceType == MenuAttributeType.Invalid) { choiceType = valueType; break; } if (valueType != choiceType) { throw new ParseException( $"Choice type is \"{choiceType}\", but it contains config which type is \"{valueType}\".", childEntry.Location); } break; case MenuEntryType.If: CheckConfigValueTypeInChoice(childEntry, ref choiceType); break; default: throw new ParseException( $"Choice contains invalid entry which type is \"{childEntry.EntryType}\".", childEntry.Location); } } }
/// <summary> /// parse and add attribute to entry. /// <para>prototype is <type> < expr > ["if" < expr >]</para> /// </summary> /// <param name="inStr">source line</param> /// <param name="entry">attribute will add to this entry</param> /// <param name="type">attribute type</param> /// <param name="sr">for get location</param> /// <param name="isRemoveQuotationMark">whether remove quotation mark from value expression</param> private static void ParseAttrWithValAndCond(FileReader sr, MenuEntry entry, string inStr, MenuAttributeType type, bool isRemoveQuotationMark = false) { // <type> < expression > ["if" < condition >] if (!GetAttributeSymbolValueCodition(inStr, out var expression, out var condition)) { throw sr.GenExpWithLocation($"Could not parse \"{type}\" attribute."); } entry.Attributes.Add(new MenuAttribute { AttributeType = type, SymbolValue = isRemoveQuotationMark? RemoveQuotationMark(expression) : expression, Condition = condition, }); }