Skip to content

Commit

Permalink
Added ParserQuirks.EnumValueArrayContainsEnumValuesNotEnumNames value…
Browse files Browse the repository at this point in the history
… for #25
  • Loading branch information
mikeclayton committed Jan 28, 2019
1 parent 1c35b71 commit fcab156
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 12 deletions.
42 changes: 40 additions & 2 deletions src/Kingsland.MofParser.UnitTests/CodeGen/MofGeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1248,6 +1248,19 @@ public static void QualifiedEnumValueShouldRoundtrip()
public static class EnumValueArrayTests
{

[Test]
public static void EmptyEnumValueArrayShouldRoundtrip()
{
RoundtripTests.AssertRoundtrip(
"instance of GOLF_Date\r\n" +
"{\r\n" +
"\tYear = 2011;\r\n" +
"\tMonth = {June};\r\n" +
"\tDay = 31;\r\n" +
"};"
);
}

[Test]
public static void EnumValueArrayWithSingleEnumValueShouldRoundtrip()
{
Expand All @@ -1272,13 +1285,38 @@ public static void EnumValueArrayWithMultipleEnumValuesShouldRoundtrip()
}

[Test(Description = "https://github.com/mikeclayton/MofParser/issues/25")]
public static void EnumValueArrayWithQualifiedEnumValuesShouldRoundtrip()
public static void EnumValueArrayWithQualifiedEnumValuesAndQuirksEnabledShouldRoundtrip()
{
RoundtripTests.AssertRoundtrip(
"instance of GOLF_Date\r\n" +
"{\r\n" +
"\tMonth = {MonthEnums.July};\r\n" +
"};"
"};",
ParserQuirks.EnumValueArrayContainsEnumValuesNotEnumNames
);
}

[Test(Description = "https://github.com/mikeclayton/MofParser/issues/25")]
public static void EnumValueArrayWithQualifiedEnumValuesAndQuirksDisabledShouldThrow()
{
var sourceMof =
"instance of GOLF_Date\r\n" +
"{\r\n" +
"\tMonth = {MonthEnums.July};\r\n" +
"};";
var tokens = Lexing.Lexer.Lex(SourceReader.From(sourceMof));
var tokensMof = TokenMofGenerator.ConvertToMof(tokens);
var ex = Assert.Throws<UnexpectedTokenException>(
() =>
{
var astNodes = Parser.Parse(tokens);
}
);
Assert.AreEqual(
"Unexpected token found at Position 46, Line Number 3, Column Number 21.\r\n" +
"Token Type: 'DotOperatorToken'\r\n" +
"Token Text: '.'",
ex.Message
);
}

Expand Down
52 changes: 42 additions & 10 deletions src/Kingsland.MofParser/Parsing/ParserEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -362,11 +362,14 @@ public static QualifierValueAst ParseQualifierValueAst(ParserStream stream, Pars
break;
}

// see https://github.com/mikeclayton/MofParser/issues/49
//
// Pseudo-ABNF for MOF V2 qualifiers:
//
// qualifierList_v2 = "[" qualifierValue_v2 *( "," qualifierValue_v2 ) "]"
// qualifierValue_v2 = qualifierName [ qualifierValueInitializer / qualiferValueArrayInitializer ] ":" qualifierFlavourList_v2
// qualifierFlavorList_v2 = qualifierFlavorName *( " " qualifierFlavorName )
//
var quirkEnabled = (quirks & ParserQuirks.AllowMofV2Qualifiers) == ParserQuirks.AllowMofV2Qualifiers;
if (quirkEnabled)
{
Expand Down Expand Up @@ -2150,22 +2153,51 @@ public static EnumValueArrayAst ParseEnumValueArrayAst(ParserStream stream, Pars
// "{"
var blockOpen = stream.Read<BlockOpenToken>();

// note - we're using enumValue, not enumName
// [ enumValue *( "," enumValue ) ]
if (!stream.TryPeek<BlockCloseToken>())
// see https://github.com/mikeclayton/MofParser/issues/25
var quirkEnabled = (quirks & ParserQuirks.EnumValueArrayContainsEnumValuesNotEnumNames) == ParserQuirks.EnumValueArrayContainsEnumValuesNotEnumNames;
if (quirkEnabled)
{

// enumValue
node.Values.Add(
ParserEngine.ParseEnumValueAst(stream, quirks)
);

// *( "," enumValue )
while (stream.TryRead<CommaToken>(out var comma))
// [ enumValue *( "," enumValue ) ]
if (!stream.TryPeek<BlockCloseToken>())
{
// enumValue
node.Values.Add(
ParserEngine.ParseEnumValueAst(stream, quirks)
);
// *( "," enumValue )
while (stream.TryRead<CommaToken>(out var comma))
{
node.Values.Add(
ParserEngine.ParseEnumValueAst(stream, quirks)
);
}
}

}
else
{

// [ enumName *( "," enumName ) ]
if (!stream.TryPeek<BlockCloseToken>())
{
// enumName
node.Values.Add(
new EnumValueAst.Builder
{
EnumLiteral = stream.Read<IdentifierToken>()
}.Build()
);
// *( "," enumName )
while (stream.TryRead<CommaToken>(out var comma))
{
node.Values.Add(
new EnumValueAst.Builder
{
EnumLiteral = stream.Read<IdentifierToken>()
}.Build()
);
}
}

}
Expand Down
31 changes: 31 additions & 0 deletions src/Kingsland.MofParser/Parsing/ParserQuirks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ public enum ParserQuirks
/// Allows deprecated qualifier "flavors" to be used in MOF files.
/// </summary>
/// <remarks>
///
/// See https://github.com/mikeclayton/MofParser/issues/49
///
/// A MOF v2 qualifier declaration has to be converted to MOF v3 qualifierTypeDeclaration because the
/// MOF v2 qualifier flavor has been replaced by the MOF v3 qualifierPolicy.
///
Expand All @@ -28,9 +31,37 @@ public enum ParserQuirks
/// but this is no longer valid in MOF V3.
///
/// If this quirk is enabled we'll read qualifier flavors anyway for compatibility witn MOF V2 mof files.
///
/// </remarks>
AllowMofV2Qualifiers = 1,

/// <summary>
/// Allows deprecated qualifier "flavors" to be used in MOF files.
/// </summary>
/// <remarks>
///
/// See https://github.com/mikeclayton/MofParser/issues/25
///
/// Enum value arrays are defined in the MOF 3.0.1 spec as:
///
/// enumValueArray = "{" [ enumName *( "," enumName ) ] "}"
///
/// but should *probably* be
///
/// enumValueArray = "{" [ enumValue *( "," enumValue ) ] "}"
///
/// because this is invalid otherwise:
///
/// instance of MY_Class
/// {
/// Months = { MonthEnum.January, MonthEnum.April, MonthEnum.June, MonthEnum.September };
/// };
///
/// If this quirk is enabled we'll assume enum array entries are enumValues instead of enumNames.
///
/// </remarks>
EnumValueArrayContainsEnumValuesNotEnumNames = 2

}

}

0 comments on commit fcab156

Please sign in to comment.