Added some helper methods for building parsers
git-svn-id: file:///srv/devel/repo-conversion/nusu@284 d2e56fa2-650e-0410-a79f-9358c0239efd
This commit is contained in:
parent
56cc2cee12
commit
23fe4cfd37
|
@ -223,6 +223,10 @@
|
||||||
<Compile Include="Source\Parsing\CommandLine.Parser.cs">
|
<Compile Include="Source\Parsing\CommandLine.Parser.cs">
|
||||||
<DependentUpon>CommandLine.cs</DependentUpon>
|
<DependentUpon>CommandLine.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Source\Parsing\ParserHelper.cs" />
|
||||||
|
<Compile Include="Source\Parsing\ParserHelper.Test.cs">
|
||||||
|
<DependentUpon>ParserHelper.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Source\PropertyChangedEventArgsHelper.cs" />
|
<Compile Include="Source\PropertyChangedEventArgsHelper.cs" />
|
||||||
<Compile Include="Source\PropertyChangedEventArgsHelper.Test.cs">
|
<Compile Include="Source\PropertyChangedEventArgsHelper.Test.cs">
|
||||||
<DependentUpon>PropertyChangedEventArgsHelper.cs</DependentUpon>
|
<DependentUpon>PropertyChangedEventArgsHelper.cs</DependentUpon>
|
||||||
|
|
|
@ -254,6 +254,10 @@
|
||||||
<Compile Include="Source\Parsing\CommandLine.Parser.cs">
|
<Compile Include="Source\Parsing\CommandLine.Parser.cs">
|
||||||
<DependentUpon>CommandLine.cs</DependentUpon>
|
<DependentUpon>CommandLine.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Source\Parsing\ParserHelper.cs" />
|
||||||
|
<Compile Include="Source\Parsing\ParserHelper.Test.cs">
|
||||||
|
<DependentUpon>ParserHelper.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Source\PropertyChangedEventArgsHelper.cs" />
|
<Compile Include="Source\PropertyChangedEventArgsHelper.cs" />
|
||||||
<Compile Include="Source\PropertyChangedEventArgsHelper.Test.cs">
|
<Compile Include="Source\PropertyChangedEventArgsHelper.Test.cs">
|
||||||
<DependentUpon>PropertyChangedEventArgsHelper.cs</DependentUpon>
|
<DependentUpon>PropertyChangedEventArgsHelper.cs</DependentUpon>
|
||||||
|
|
|
@ -265,6 +265,10 @@
|
||||||
<Compile Include="Source\Parsing\CommandLine.Parser.cs">
|
<Compile Include="Source\Parsing\CommandLine.Parser.cs">
|
||||||
<DependentUpon>CommandLine.cs</DependentUpon>
|
<DependentUpon>CommandLine.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Source\Parsing\ParserHelper.cs" />
|
||||||
|
<Compile Include="Source\Parsing\ParserHelper.Test.cs">
|
||||||
|
<DependentUpon>ParserHelper.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Source\PropertyChangedEventArgsHelper.cs" />
|
<Compile Include="Source\PropertyChangedEventArgsHelper.cs" />
|
||||||
<Compile Include="Source\PropertyChangedEventArgsHelper.Test.cs">
|
<Compile Include="Source\PropertyChangedEventArgsHelper.Test.cs">
|
||||||
<DependentUpon>PropertyChangedEventArgsHelper.cs</DependentUpon>
|
<DependentUpon>PropertyChangedEventArgsHelper.cs</DependentUpon>
|
||||||
|
|
165
Source/Parsing/ParserHelper.Test.cs
Normal file
165
Source/Parsing/ParserHelper.Test.cs
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
#region CPL License
|
||||||
|
/*
|
||||||
|
Nuclex Framework
|
||||||
|
Copyright (C) 2002-2013 Nuclex Development Labs
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the IBM Common Public License as
|
||||||
|
published by the IBM Corporation; either version 1.0 of the
|
||||||
|
License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
IBM Common Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the IBM Common Public
|
||||||
|
License along with this library
|
||||||
|
*/
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
#if UNITTEST
|
||||||
|
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace Nuclex.Support.Parsing {
|
||||||
|
|
||||||
|
/// <summary>Verifies that the parser helper methods are correct</summary>
|
||||||
|
[TestFixture]
|
||||||
|
internal class ParserHelperTest {
|
||||||
|
|
||||||
|
/// <summary>Ensures that the SkipSpaces() method can handle null strings</summary>
|
||||||
|
[Test]
|
||||||
|
public void CanSkipSpacesInNullString() {
|
||||||
|
int index = 0;
|
||||||
|
Assert.DoesNotThrow(
|
||||||
|
delegate() { ParserHelper.SkipSpaces((string)null, ref index); }
|
||||||
|
);
|
||||||
|
Assert.AreEqual(0, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Ensures that the SkipSpaces() method can handle empty strings</summary>
|
||||||
|
[Test]
|
||||||
|
public void CanSkipSpacesInEmptyString() {
|
||||||
|
int index = 0;
|
||||||
|
Assert.DoesNotThrow(
|
||||||
|
delegate() { ParserHelper.SkipSpaces(string.Empty, ref index); }
|
||||||
|
);
|
||||||
|
Assert.AreEqual(0, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Ensures that the SkipSpaces() method can skip spaces</summary>
|
||||||
|
[Test]
|
||||||
|
public void SpacesCanBeSkipped() {
|
||||||
|
int index = 7;
|
||||||
|
ParserHelper.SkipSpaces(" Test Test ", ref index);
|
||||||
|
Assert.AreEqual(10, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Ensures that the SkipNonSpaces() method can handle null strings</summary>
|
||||||
|
[Test]
|
||||||
|
public void CanSkipNonSpacesInNullString() {
|
||||||
|
int index = 0;
|
||||||
|
Assert.DoesNotThrow(
|
||||||
|
delegate() { ParserHelper.SkipNonSpaces((string)null, ref index); }
|
||||||
|
);
|
||||||
|
Assert.AreEqual(0, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Ensures that the SkipNonSpaces() method can handle empty strings</summary>
|
||||||
|
[Test]
|
||||||
|
public void CanSkipNonSpacesInEmptyString() {
|
||||||
|
int index = 0;
|
||||||
|
Assert.DoesNotThrow(
|
||||||
|
delegate() { ParserHelper.SkipNonSpaces(string.Empty, ref index); }
|
||||||
|
);
|
||||||
|
Assert.AreEqual(0, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Ensures that the SkipNonSpaces() method can skip non-space characters</summary>
|
||||||
|
[Test]
|
||||||
|
public void NonSpacesCanBeSkipped() {
|
||||||
|
int index = 7;
|
||||||
|
ParserHelper.SkipNonSpaces("Test Test Test", ref index);
|
||||||
|
Assert.AreEqual(11, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Ensures that the SkipNumbers() method can handle null strings</summary>
|
||||||
|
[Test]
|
||||||
|
public void CanSkipNumbersInNullString() {
|
||||||
|
int index = 0;
|
||||||
|
Assert.DoesNotThrow(
|
||||||
|
delegate() { ParserHelper.SkipNumbers((string)null, ref index); }
|
||||||
|
);
|
||||||
|
Assert.AreEqual(0, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Ensures that the SkipNumbers() method can handle empty strings</summary>
|
||||||
|
[Test]
|
||||||
|
public void CanSkipNumbersInEmptyString() {
|
||||||
|
int index = 0;
|
||||||
|
Assert.DoesNotThrow(
|
||||||
|
delegate() { ParserHelper.SkipNumbers(string.Empty, ref index); }
|
||||||
|
);
|
||||||
|
Assert.AreEqual(0, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Ensures that the SkipNumbers() method can skip numbers</summary>
|
||||||
|
[Test]
|
||||||
|
public void NumbersCanBeSkipped() {
|
||||||
|
int index = 6;
|
||||||
|
ParserHelper.SkipNumbers("123abc456def789", ref index);
|
||||||
|
Assert.AreEqual(9, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Ensures that the SkipIntegers() method can handle null strings</summary>
|
||||||
|
[Test]
|
||||||
|
public void CanSkipIntegersInNullString() {
|
||||||
|
int index = 0;
|
||||||
|
Assert.IsFalse(ParserHelper.SkipInteger((string)null, ref index));
|
||||||
|
Assert.AreEqual(0, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Ensures that the SkipNumbers() method can handle empty strings</summary>
|
||||||
|
[Test]
|
||||||
|
public void CanSkipIntegersInEmptyString() {
|
||||||
|
int index = 0;
|
||||||
|
Assert.IsFalse(ParserHelper.SkipInteger(string.Empty, ref index));
|
||||||
|
Assert.AreEqual(0, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Verifies that a prefix alone can not be skipped as an integer</summary>
|
||||||
|
[Test]
|
||||||
|
public void PrefixAloneIsNotAnInteger() {
|
||||||
|
int index = 0;
|
||||||
|
Assert.IsFalse(ParserHelper.SkipInteger("+Test", ref index));
|
||||||
|
Assert.AreEqual(0, index);
|
||||||
|
Assert.IsFalse(ParserHelper.SkipInteger("-", ref index));
|
||||||
|
Assert.AreEqual(0, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Verifies that a prefixed integer can be skipped</summary>
|
||||||
|
[Test]
|
||||||
|
public void PrefixedIntegersCanBeSkipped() {
|
||||||
|
int index = 0;
|
||||||
|
Assert.IsTrue(ParserHelper.SkipInteger("+123", ref index));
|
||||||
|
Assert.AreEqual(4, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Verifies that an integer without a prefix can be skipped</summary>
|
||||||
|
[Test]
|
||||||
|
public void PlainIntegersCanBeSkipped() {
|
||||||
|
int index = 0;
|
||||||
|
Assert.IsTrue(ParserHelper.SkipInteger("12345", ref index));
|
||||||
|
Assert.AreEqual(5, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Nuclex.Support.Parsing
|
||||||
|
|
||||||
|
#endif // UNITTEST
|
120
Source/Parsing/ParserHelper.cs
Normal file
120
Source/Parsing/ParserHelper.cs
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
#region CPL License
|
||||||
|
/*
|
||||||
|
Nuclex Framework
|
||||||
|
Copyright (C) 2002-2013 Nuclex Development Labs
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the IBM Common Public License as
|
||||||
|
published by the IBM Corporation; either version 1.0 of the
|
||||||
|
License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
IBM Common Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the IBM Common Public
|
||||||
|
License along with this library
|
||||||
|
*/
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Nuclex.Support.Parsing {
|
||||||
|
|
||||||
|
/// <summary>Provides helper methods for parsers</summary>
|
||||||
|
public class ParserHelper {
|
||||||
|
|
||||||
|
/// <summary>Advances the index past any whitespace in the string</summary>
|
||||||
|
/// <param name="text">String which is being indexed</param>
|
||||||
|
/// <param name="index">Index that will be advanced</param>
|
||||||
|
public static void SkipSpaces(string text, ref int index) {
|
||||||
|
if(text == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int length = text.Length;
|
||||||
|
while(index < length) {
|
||||||
|
if(!char.IsWhiteSpace(text, index)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Advances the index to the next whitespace in the string</summary>
|
||||||
|
/// <param name="text">String which is being indexed</param>
|
||||||
|
/// <param name="index">Index that will be advanced</param>
|
||||||
|
public static void SkipNonSpaces(string text, ref int index) {
|
||||||
|
if(text == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int length = text.Length;
|
||||||
|
while(index < length) {
|
||||||
|
if(char.IsWhiteSpace(text, index)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Advances the index to the next character that isn't numeric</summary>
|
||||||
|
/// <param name="text">String which is being indexed</param>
|
||||||
|
/// <param name="index">Index that will be advanced</param>
|
||||||
|
public static void SkipNumbers(string text, ref int index) {
|
||||||
|
if(text == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int length = text.Length;
|
||||||
|
while(index < length) {
|
||||||
|
if(!char.IsNumber(text, index)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Skips an integer in the provided string</summary>
|
||||||
|
/// <param name="text">String in which an integer will be skipped</param>
|
||||||
|
/// <param name="index">Index at which the integer begins</param>
|
||||||
|
/// <returns>True if an integer was found and skipped, otherwise false</returns>
|
||||||
|
public static bool SkipInteger(string text, ref int index) {
|
||||||
|
if(text == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int length = text.Length;
|
||||||
|
if(index >= length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the number begins with a minus or plus sign, skip over the sign
|
||||||
|
int nextIndex;
|
||||||
|
if((text[index] == '-') || (text[index] == '+')) {
|
||||||
|
nextIndex = index + 1;
|
||||||
|
|
||||||
|
SkipNumbers(text, ref nextIndex);
|
||||||
|
if(nextIndex == (index + 1)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
nextIndex = index;
|
||||||
|
|
||||||
|
SkipNumbers(text, ref nextIndex);
|
||||||
|
if(nextIndex == index) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
index = nextIndex;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Nuclex.Support.Parsing
|
Loading…
Reference in New Issue
Block a user