Skip to content

Commit

Permalink
Merge pull request #89 from Whitehouse112/main
Browse files Browse the repository at this point in the history
#85 Support integer numbers in scientific notation
  • Loading branch information
Adhara3 authored Sep 11, 2024
2 parents 6af49c9 + ee9fbac commit 5656e19
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 9 deletions.
24 changes: 23 additions & 1 deletion DbcParserLib.Tests/PropertiesLineParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,29 @@ public void FloatDefinitionCustomPropertyNoBoundariesIsParsedTest()
}

[Test]
public void ScientificNotationDefinitionCustomPropertyIsParsedTest()
public void ScientificNotationIntegerDefinitionCustomPropertyIsParsedTest()
{
var dbcBuilderMock = m_repository.Create<IDbcBuilder>();
var nextLineProviderMock = m_repository.Create<INextLineProvider>();

dbcBuilderMock.Setup(mock => mock.AddCustomProperty(It.IsAny<CustomPropertyObjectType>(), It.IsAny<CustomPropertyDefinition>()))
.Callback<CustomPropertyObjectType, CustomPropertyDefinition>((_, customProperty) =>
{
Assert.Multiple(() =>
{
Assert.That(customProperty.Name, Is.EqualTo("AttributeName"));
Assert.That(customProperty.DataType, Is.EqualTo(CustomPropertyDataType.Integer));
Assert.That(customProperty.IntegerCustomProperty.Minimum, Is.EqualTo(-1000));
Assert.That(customProperty.IntegerCustomProperty.Maximum, Is.EqualTo(1000));
});
});

var customPropertyLineParsers = CreateParser();
Assert.That(ParseLine(@"BA_DEF_ BU_ ""AttributeName"" INT -1e3 1e+3;", customPropertyLineParsers, dbcBuilderMock.Object, nextLineProviderMock.Object), Is.True);
}

[Test]
public void ScientificNotationFloatDefinitionCustomPropertyIsParsedTest()
{
var dbcBuilderMock = m_repository.Create<IDbcBuilder>();
var nextLineProviderMock = m_repository.Create<INextLineProvider>();
Expand Down
4 changes: 3 additions & 1 deletion DbcParserLib.Tests/PropertiesParsingFailuresTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,9 @@ public void DuplicateCustomPropertyErrorIsObserved()
lineParser.TryParse(line2, dbcBuilder, nextLineProviderMock.Object);
}

[TestCase("BA_DEF_ BO_ \"GenMsgCycleTime\" INT 1.5 65535;")]
[TestCase("BA_DEF_ BO_ \"attributeName\" INT 1.5 65535;")]
[TestCase("BA_DEF_ BO_ \"attributeName\" INT 0 1e-5;")]
[TestCase("BA_DEF_ BO_ \"attributeName\" INT 0 1.0e+05;")]
[TestCase("BA_DEF_ \"attributeName\" STRING")]
[TestCase("BA_DEF_ SGG_ \"attributeName\" FLOAT -3.4E+038 3.4E+038;")]
[TestCase("BA_DEF_ BU_ \"attributeName\" STRING 0;")]
Expand Down
18 changes: 15 additions & 3 deletions DbcParserLib/Parsers/PropertiesDefinitionLineParser.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using DbcParserLib.Model;
using DbcParserLib.Observers;
using System;
using System.ComponentModel;
using System.Globalization;
using System.Text.RegularExpressions;

Expand All @@ -23,7 +25,7 @@ internal class PropertiesDefinitionLineParser : ILineParser
private const string PropertiesDefinitionDefaultLineStarter = "BA_DEF_DEF_ ";

private readonly string m_propertyDefinitionParsingRegex = $@"BA_DEF_(?:\s+(?<{ObjectTypeGroup}>BU_|BO_|SG_|EV_))?\s+""(?<{AttributeNameGroup}>[a-zA-Z_][\w]*)""\s+" +
$@"(?:(?:(?<{IsIntegerValueGroup}>INT|HEX)\s+(?<{MinIntGroup}>-?\d+)\s+(?<{MaxIntGroup}>-?\d+))|" +
$@"(?:(?:(?<{IsIntegerValueGroup}>INT|HEX)\s+(?<{MinIntGroup}>-?[\d\+eE]+)\s+(?<{MaxIntGroup}>-?[\d\+eE]+))|" +
$@"(?:(?<{IsFloatValueGroup}>FLOAT)\s+(?<{MinFloatGroup}>[\d\+\-eE.]+)\s+(?<{MaxFloatGroup}>[\d\+\-eE.]+))" +
$@"|(?<{IsStringValueGroup}>STRING)|(?:(?<{IsEnumValueGroup}>ENUM)\s+(?<{EnumValueGroup}>(?:""[^""]*"",\s*)*(?:""[^""]*""))))\s*;";

Expand Down Expand Up @@ -80,10 +82,20 @@ public bool TryParse(string line, IDbcBuilder builder, INextLineProvider nextLin
CustomPropertyDataType dataType = CustomPropertyDataType.Integer;
if (match.Groups[IsIntegerValueGroup].Value.Equals("INT"))
{
//Since int.TryParse() is not able to parse scientic notation string we need to:
//Use double.TryParse() to parse digits or scientific notation string
//Cast values to integer (safe since regex accept only integer digits and positive exponent)
if(double.TryParse(match.Groups[MinIntGroup].Value, out var minValue) == false ||
double.TryParse(match.Groups[MaxIntGroup].Value, out var maxValue) == false)
{
m_observer.PropertyDefinitionSyntaxError();
return true;
}

customProperty.IntegerCustomProperty = new NumericCustomPropertyDefinition<int>
{
Minimum = int.Parse(match.Groups[MinIntGroup].Value, CultureInfo.InvariantCulture),
Maximum = int.Parse(match.Groups[MaxIntGroup].Value, CultureInfo.InvariantCulture),
Minimum = Convert.ToInt32(minValue),
Maximum = Convert.ToInt32(maxValue)
};
}
else if (match.Groups[IsIntegerValueGroup].Value.Equals("HEX"))
Expand Down
8 changes: 4 additions & 4 deletions DbcParserLib/Parsers/ValueTableLineParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ internal class ValueTableLineParser : ILineParser
private const string ValueTableGroup = "ValueTable";
private const string EnvVarGroup = "EnvVarName";
private const string ValueDescriptionGroup = "ValueDescription";
private const string EndValeDescriptionGroup = "ValueDescriptionEnd";
private const string EndValueDescriptionGroup = "ValueDescriptionEnd";
private const string ValueTableLineStarter = "VAL_ ";

private readonly string m_valueTableLinkParsingRegex = $@"VAL_\s+(?<{MessageIdGroup}>\d+)\s+(?<{SignalNameGroup}>[a-zA-Z_][\w]*)\s+(?<{ValueTableGroup}>[a-zA-Z_][\w]*)\s*;";
private readonly string m_valueTableParsingRegex = $@"VAL_\s+(?:(?:(?<{MessageIdGroup}>\d+)\s+(?<{SignalNameGroup}>[a-zA-Z_][\w]*))|(?<{EnvVarGroup}>[a-zA-Z_][\w]*))\s+" +
$@"(?<{ValueDescriptionGroup}>(?:(?:-?\d+)\s+(?:""[^""]*"")\s+)*)(?<{EndValeDescriptionGroup}>(?:(?:-?\d+)\s+(?:""[^""]*"")\s*));";
$@"(?<{ValueDescriptionGroup}>(?:(?:-?\d+)\s+(?:""[^""]*"")\s+)*)(?<{EndValueDescriptionGroup}>(?:(?:-?\d+)\s+(?:""[^""]*"")\s*));";

private readonly IParseFailureObserver m_observer;

Expand All @@ -42,8 +42,8 @@ public bool TryParse(string line, IDbcBuilder builder, INextLineProvider nextLin
if (match.Success)
{
var dictionary = string.IsNullOrEmpty(match.Groups[ValueDescriptionGroup].Value)
? match.Groups[EndValeDescriptionGroup].Value
: string.Concat(match.Groups[ValueDescriptionGroup].Value, match.Groups[EndValeDescriptionGroup].Value);
? match.Groups[EndValueDescriptionGroup].Value
: string.Concat(match.Groups[ValueDescriptionGroup].Value, match.Groups[EndValueDescriptionGroup].Value);

if (!string.IsNullOrEmpty(dictionary) && dictionary.TryParseToDict(out var valueTableDictionary))
{
Expand Down

0 comments on commit 5656e19

Please sign in to comment.