Skip to content

Commit 39aad19

Browse files
committed
Initial commit...
1 parent d0b3727 commit 39aad19

11 files changed

+536
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
4+
<PropertyGroup>
5+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
6+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
7+
<ProjectGuid>{C2B2BD49-7201-4A59-8D29-D88EEB1FB3F2}</ProjectGuid>
8+
<OutputType>Library</OutputType>
9+
<AppDesignerFolder>Properties</AppDesignerFolder>
10+
<RootNamespace>BooleanLogicParser.Tests</RootNamespace>
11+
<AssemblyName>BooleanLogicParser.Tests</AssemblyName>
12+
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
13+
<FileAlignment>512</FileAlignment>
14+
</PropertyGroup>
15+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
16+
<DebugSymbols>true</DebugSymbols>
17+
<DebugType>full</DebugType>
18+
<Optimize>false</Optimize>
19+
<OutputPath>bin\Debug\</OutputPath>
20+
<DefineConstants>DEBUG;TRACE</DefineConstants>
21+
<ErrorReport>prompt</ErrorReport>
22+
<WarningLevel>4</WarningLevel>
23+
</PropertyGroup>
24+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
25+
<DebugType>pdbonly</DebugType>
26+
<Optimize>true</Optimize>
27+
<OutputPath>bin\Release\</OutputPath>
28+
<DefineConstants>TRACE</DefineConstants>
29+
<ErrorReport>prompt</ErrorReport>
30+
<WarningLevel>4</WarningLevel>
31+
</PropertyGroup>
32+
<ItemGroup>
33+
<Reference Include="nunit.framework">
34+
<HintPath>..\packages\NUnit.2.6.3\lib\nunit.framework.dll</HintPath>
35+
</Reference>
36+
<Reference Include="System" />
37+
<Reference Include="System.Core" />
38+
<Reference Include="System.Xml.Linq" />
39+
<Reference Include="System.Data.DataSetExtensions" />
40+
<Reference Include="Microsoft.CSharp" />
41+
<Reference Include="System.Data" />
42+
<Reference Include="System.Xml" />
43+
</ItemGroup>
44+
<ItemGroup>
45+
<Compile Include="ParserTests.cs" />
46+
<Compile Include="TokenizerTests.cs" />
47+
<Compile Include="Properties\AssemblyInfo.cs" />
48+
</ItemGroup>
49+
<ItemGroup>
50+
<None Include="packages.config" />
51+
</ItemGroup>
52+
<ItemGroup>
53+
<ProjectReference Include="..\BooleanLogicParser\BooleanLogicParser.csproj">
54+
<Project>{671BC84B-7C04-49CE-ABFA-86A1972BE701}</Project>
55+
<Name>BooleanLogicParser</Name>
56+
</ProjectReference>
57+
</ItemGroup>
58+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
59+
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
60+
Other similar extension points exist, see Microsoft.Common.targets.
61+
<Target Name="BeforeBuild">
62+
</Target>
63+
<Target Name="AfterBuild">
64+
</Target>
65+
-->
66+
</Project>
+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using System;
2+
using NUnit.Framework;
3+
4+
namespace BooleanLogicParser.Tests
5+
{
6+
[TestFixture]
7+
public class ParserTests
8+
{
9+
[TestCase("true", ExpectedResult = true)]
10+
[TestCase(")", ExpectedException = (typeof(Exception)))]
11+
[TestCase("az", ExpectedException = (typeof(Exception)))]
12+
[TestCase("", ExpectedException = (typeof(Exception)))]
13+
[TestCase("()", ExpectedException = typeof(Exception))]
14+
[TestCase("true and", ExpectedException = typeof(Exception))]
15+
[TestCase("false", ExpectedResult = false)]
16+
[TestCase("true ", ExpectedResult = true)]
17+
[TestCase("false ", ExpectedResult = false)]
18+
[TestCase(" true", ExpectedResult = true)]
19+
[TestCase(" false", ExpectedResult = false)]
20+
[TestCase(" true ", ExpectedResult = true)]
21+
[TestCase(" false ", ExpectedResult = false)]
22+
[TestCase("(false)", ExpectedResult = false)]
23+
[TestCase("(true)", ExpectedResult = true)]
24+
[TestCase("true and false", ExpectedResult = false)]
25+
[TestCase("false and true", ExpectedResult = false)]
26+
[TestCase("false and false", ExpectedResult = false)]
27+
[TestCase("true and true", ExpectedResult = true)]
28+
[TestCase("!true", ExpectedResult = false)]
29+
[TestCase("!(true)", ExpectedResult = false)]
30+
[TestCase("!(true", ExpectedException = typeof(Exception))]
31+
[TestCase("!(!(true))", ExpectedResult = true)]
32+
[TestCase("!false", ExpectedResult = true)]
33+
[TestCase("!(false)", ExpectedResult = true)]
34+
[TestCase("(!(false)) and (!(true))", ExpectedResult = false)]
35+
[TestCase("!((!(false)) and (!(true)))", ExpectedResult = true)]
36+
[TestCase("!false and !true", ExpectedResult = false)]
37+
[TestCase("false and true and true", ExpectedResult = false)]
38+
[TestCase("false or true or false", ExpectedResult = true)]
39+
public bool CanParseSingleToken(string expression)
40+
{
41+
var tokens = new Tokenizer(expression).Tokenize();
42+
var parser = new Parser(tokens);
43+
return parser.Parse();
44+
}
45+
}
46+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System.Reflection;
2+
using System.Runtime.CompilerServices;
3+
using System.Runtime.InteropServices;
4+
5+
// General Information about an assembly is controlled through the following
6+
// set of attributes. Change these attribute values to modify the information
7+
// associated with an assembly.
8+
[assembly: AssemblyTitle("BooleanLogicParser.Tests")]
9+
[assembly: AssemblyDescription("")]
10+
[assembly: AssemblyConfiguration("")]
11+
[assembly: AssemblyCompany("")]
12+
[assembly: AssemblyProduct("BooleanLogicParser.Tests")]
13+
[assembly: AssemblyCopyright("Copyright © 2014")]
14+
[assembly: AssemblyTrademark("")]
15+
[assembly: AssemblyCulture("")]
16+
17+
// Setting ComVisible to false makes the types in this assembly not visible
18+
// to COM components. If you need to access a type in this assembly from
19+
// COM, set the ComVisible attribute to true on that type.
20+
[assembly: ComVisible(false)]
21+
22+
// The following GUID is for the ID of the typelib if this project is exposed to COM
23+
[assembly: Guid("2b297da3-7ee2-49db-9a5d-3a28f5a7cb91")]
24+
25+
// Version information for an assembly consists of the following four values:
26+
//
27+
// Major Version
28+
// Minor Version
29+
// Build Number
30+
// Revision
31+
//
32+
// You can specify all the values or you can default the Build and Revision Numbers
33+
// by using the '*' as shown below:
34+
// [assembly: AssemblyVersion("1.0.*")]
35+
[assembly: AssemblyVersion("1.0.0.0")]
36+
[assembly: AssemblyFileVersion("1.0.0.0")]
+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System;
2+
using System.Linq;
3+
using NUnit.Framework;
4+
5+
namespace BooleanLogicParser.Tests
6+
{
7+
[TestFixture]
8+
public class TokenizerTests
9+
{
10+
[TestCase("And", ExpectedResult = typeof(AndToken))]
11+
[TestCase("and", ExpectedResult = typeof(AndToken))]
12+
[TestCase("Or", ExpectedResult = typeof(OrToken))]
13+
[TestCase("or", ExpectedResult = typeof(OrToken))]
14+
[TestCase("True", ExpectedResult = typeof(TrueToken))]
15+
[TestCase("False", ExpectedResult = typeof(FalseToken))]
16+
[TestCase("!", ExpectedResult = typeof(NegationToken))]
17+
[TestCase("(", ExpectedResult = typeof(OpenParenthesisToken))]
18+
[TestCase(")", ExpectedResult = typeof(ClosedParenthesisToken))]
19+
[TestCase("a", ExpectedException = typeof(Exception))]
20+
[TestCase("(trae)", ExpectedException = typeof(Exception))]
21+
public Type CanParseSingleToken(string expression)
22+
{
23+
var tokens = new Tokenizer(expression).Tokenize();
24+
return (tokens.First().GetType());
25+
}
26+
27+
public void CanParseComplexTokenStructure()
28+
{
29+
var tokens = new Tokenizer("!(True And False)").Tokenize();
30+
var list = tokens.ToList();
31+
Assert.IsTrue(list[0] is NegationToken);
32+
Assert.IsTrue(list[1] is OpenParenthesisToken);
33+
Assert.IsTrue(list[2] is TrueToken);
34+
Assert.IsTrue(list[3] is AndToken);
35+
Assert.IsTrue(list[4] is FalseToken);
36+
Assert.IsTrue(list[5] is ClosedParenthesisToken);
37+
}
38+
}
39+
}
+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<packages>
3+
<package id="NUnit" version="2.6.3" targetFramework="net45" />
4+
</packages>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
4+
<PropertyGroup>
5+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
6+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
7+
<ProjectGuid>{671BC84B-7C04-49CE-ABFA-86A1972BE701}</ProjectGuid>
8+
<OutputType>Library</OutputType>
9+
<AppDesignerFolder>Properties</AppDesignerFolder>
10+
<RootNamespace>BooleanLogicParser</RootNamespace>
11+
<AssemblyName>BooleanLogicParser</AssemblyName>
12+
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
13+
<FileAlignment>512</FileAlignment>
14+
</PropertyGroup>
15+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
16+
<DebugSymbols>true</DebugSymbols>
17+
<DebugType>full</DebugType>
18+
<Optimize>false</Optimize>
19+
<OutputPath>bin\Debug\</OutputPath>
20+
<DefineConstants>DEBUG;TRACE</DefineConstants>
21+
<ErrorReport>prompt</ErrorReport>
22+
<WarningLevel>4</WarningLevel>
23+
</PropertyGroup>
24+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
25+
<DebugType>pdbonly</DebugType>
26+
<Optimize>true</Optimize>
27+
<OutputPath>bin\Release\</OutputPath>
28+
<DefineConstants>TRACE</DefineConstants>
29+
<ErrorReport>prompt</ErrorReport>
30+
<WarningLevel>4</WarningLevel>
31+
</PropertyGroup>
32+
<ItemGroup>
33+
<Reference Include="System" />
34+
<Reference Include="System.Core" />
35+
<Reference Include="System.Xml.Linq" />
36+
<Reference Include="System.Data.DataSetExtensions" />
37+
<Reference Include="Microsoft.CSharp" />
38+
<Reference Include="System.Data" />
39+
<Reference Include="System.Xml" />
40+
</ItemGroup>
41+
<ItemGroup>
42+
<Compile Include="Parser.cs" />
43+
<Compile Include="Tokens.cs" />
44+
<Compile Include="Properties\AssemblyInfo.cs" />
45+
<Compile Include="Tokenizer.cs" />
46+
</ItemGroup>
47+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
48+
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
49+
Other similar extension points exist, see Microsoft.Common.targets.
50+
<Target Name="BeforeBuild">
51+
</Target>
52+
<Target Name="AfterBuild">
53+
</Target>
54+
-->
55+
</Project>

BooleanLogicParser/Parser.cs

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace BooleanLogicParser
5+
{
6+
// Expression := [ "!" ] <Boolean> { <BooleanOperator> <Boolean> } ...
7+
// Boolean := <BooleanConstant> | <Expression> | "(" <Expression> ")"
8+
// BooleanOperator := "And" | "Or"
9+
// BooleanConstant := "True" | "False"
10+
public class Parser
11+
{
12+
private readonly IEnumerator<Token> _tokens;
13+
14+
public Parser(IEnumerable<Token> tokens)
15+
{
16+
_tokens = tokens.GetEnumerator();
17+
_tokens.MoveNext();
18+
}
19+
20+
public bool Parse()
21+
{
22+
while (_tokens.Current != null)
23+
{
24+
var isNegated = _tokens.Current is NegationToken;
25+
if (isNegated)
26+
_tokens.MoveNext();
27+
28+
var boolean = ParseBoolean();
29+
if (isNegated)
30+
boolean = !boolean;
31+
32+
while (_tokens.Current is OperandToken)
33+
{
34+
var operand = _tokens.Current;
35+
if (!_tokens.MoveNext())
36+
{
37+
throw new Exception("Missing expression after operand");
38+
}
39+
var nextBoolean = ParseBoolean();
40+
41+
if (operand is AndToken)
42+
boolean = boolean && nextBoolean;
43+
else
44+
boolean = boolean || nextBoolean;
45+
46+
}
47+
48+
return boolean;
49+
}
50+
51+
throw new Exception("Empty expression");
52+
}
53+
54+
private bool ParseBoolean()
55+
{
56+
if (_tokens.Current is BooleanValueToken)
57+
{
58+
var current = _tokens.Current;
59+
_tokens.MoveNext();
60+
61+
if (current is TrueToken)
62+
return true;
63+
64+
return false;
65+
}
66+
if (_tokens.Current is OpenParenthesisToken)
67+
{
68+
_tokens.MoveNext();
69+
70+
var expInPars = Parse();
71+
72+
if (!(_tokens.Current is ClosedParenthesisToken))
73+
throw new Exception("Expecting Closing Parenthesis");
74+
75+
_tokens.MoveNext();
76+
77+
return expInPars;
78+
}
79+
if (_tokens.Current is ClosedParenthesisToken)
80+
throw new Exception("Unexpected Closed Parenthesis");
81+
82+
// since its not a BooleanConstant or Expression in parenthesis, it must be a expression again
83+
var val = Parse();
84+
return val;
85+
}
86+
}
87+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System.Reflection;
2+
using System.Runtime.CompilerServices;
3+
using System.Runtime.InteropServices;
4+
5+
// General Information about an assembly is controlled through the following
6+
// set of attributes. Change these attribute values to modify the information
7+
// associated with an assembly.
8+
[assembly: AssemblyTitle("BooleanLogicParser")]
9+
[assembly: AssemblyDescription("")]
10+
[assembly: AssemblyConfiguration("")]
11+
[assembly: AssemblyCompany("")]
12+
[assembly: AssemblyProduct("BooleanLogicParser")]
13+
[assembly: AssemblyCopyright("Copyright © 2014")]
14+
[assembly: AssemblyTrademark("")]
15+
[assembly: AssemblyCulture("")]
16+
17+
// Setting ComVisible to false makes the types in this assembly not visible
18+
// to COM components. If you need to access a type in this assembly from
19+
// COM, set the ComVisible attribute to true on that type.
20+
[assembly: ComVisible(false)]
21+
22+
// The following GUID is for the ID of the typelib if this project is exposed to COM
23+
[assembly: Guid("7a44312c-a5d5-4b3a-b518-3d1fa4b30745")]
24+
25+
// Version information for an assembly consists of the following four values:
26+
//
27+
// Major Version
28+
// Minor Version
29+
// Build Number
30+
// Revision
31+
//
32+
// You can specify all the values or you can default the Build and Revision Numbers
33+
// by using the '*' as shown below:
34+
// [assembly: AssemblyVersion("1.0.*")]
35+
[assembly: AssemblyVersion("1.0.0.0")]
36+
[assembly: AssemblyFileVersion("1.0.0.0")]

0 commit comments

Comments
 (0)