Ver código fonte

Basic parser setup

lord-executor 8 anos atrás
pai
commit
5e77dcec09

+ 14 - 0
Parser.Tests/Integration/ParserIntegrationTests.cs

@@ -1,7 +1,9 @@
 using FluentAssertions;
+using Larkdown.Parser.Ast;
 using NUnit.Framework;
 using System;
 using System.Collections.Generic;
+using System.IO;
 using System.Text;
 
 namespace Larkdown.Parser.Tests.Integration
@@ -33,5 +35,17 @@ namespace Larkdown.Parser.Tests.Integration
 			Assert.AreEqual(true, true);
 			Assert.AreEqual(false, true);
 		}
+
+		[Test]
+		public void Parser__CanParse__Paragraphs()
+		{
+			var source = File.ReadAllText("Integration/Resources/paragraphs.lar");
+			var parser = new Parser();
+
+			var ast = parser.Parse(source);
+
+			ast.Nodes.Should().HaveCount(3);
+			ast.Nodes.Should().AllBeOfType<ParagraphNode>();
+		}
     }
 }

+ 9 - 0
Parser.Tests/Integration/Resources/paragraphs.lar

@@ -0,0 +1,9 @@
+This is a paragraph
+that spans over
+multiple lines.
+
+Another paragraph starts here
+and it also spans multiple lines.
+
+This is the final
+and third paragraph.

+ 2 - 0
Parser.Tests/Integration/Resources/text-formatting.lar

@@ -0,0 +1,2 @@
+Paragrphs can contain emphasis elemtns _with italics_ and *bold*, %Monospace%, ~strike-through~ and =underline=. These *emphasis elements*
+help make text more clear.

+ 10 - 1
Parser.Tests/Parser.Tests.csproj

@@ -18,7 +18,16 @@
   </ItemGroup>
 
   <ItemGroup>
-    <Folder Include="Integration\Resources\" />
+    <ProjectReference Include="..\Parser\Parser.csproj" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <None Update="Integration\Resources\paragraphs.lar">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+    <None Update="Integration\Resources\text-formatting.lar">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
   </ItemGroup>
 
 </Project>

+ 21 - 0
Parser/Ast/Ast.cs

@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Larkdown.Parser.Ast
+{
+    public class Ast
+    {
+		public IList<Node> Nodes { get; }
+
+		public Ast()
+		{
+			Nodes = new List<Node>();
+		}
+
+		public void Add(Node node)
+		{
+			Nodes.Add(node);
+		}
+    }
+}

+ 16 - 0
Parser/Ast/Node.cs

@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Larkdown.Parser.Ast
+{
+    public class Node
+    {
+		public string NodeType { get; }
+
+		public Node(string type)
+		{
+			NodeType = type;
+		}
+    }
+}

+ 23 - 0
Parser/Ast/ParagraphNode.cs

@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Larkdown.Parser.Ast
+{
+    public class ParagraphNode : Node
+    {
+		public string Text { get; private set; }
+
+		public ParagraphNode()
+			: base(nameof(ParagraphNode))
+		{
+			Text = String.Empty;
+		}
+
+		public ParagraphNode AddText(string text)
+		{
+			Text += " " + text;
+			return this;
+		}
+    }
+}

+ 42 - 0
Parser/Lexer/BlockLexer.cs

@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Larkdown.Parser.Lexer
+{
+	class BlockLexer
+	{
+		private IList<string> _lines;
+		private IEnumerator<string> _enumerator;
+
+		public BlockLexer(string source)
+		{
+			_lines = source.Split(new[] { "\n" }, 0);
+			_enumerator = _lines.GetEnumerator();
+		}
+
+		public BlockToken NextToken()
+		{
+			if (!_enumerator.MoveNext())
+			{
+				return null;
+			}
+
+			var line = _enumerator.Current;
+			var indent = 0;
+			while (indent < line.Length && IsIndent(line[indent++])) { }
+
+			if (indent > 0)
+			{
+				line = line.Substring(indent);
+			}
+
+			return new BlockToken(BlockTokenType.Line, indent, line);
+		}
+
+		private bool IsIndent(char c)
+		{
+			return c == ' ' || c == '\t';
+		}
+	}
+}

+ 20 - 0
Parser/Lexer/BlockToken.cs

@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Larkdown.Parser.Lexer
+{
+    class BlockToken
+    {
+		public BlockTokenType Type { get; }
+		public int Indentation { get; }
+		public string Content { get; }
+
+		public BlockToken(BlockTokenType type, int indent, string content)
+		{
+			Type = type;
+			Indentation = indent;
+			Content = content;
+		}
+    }
+}

+ 11 - 0
Parser/Lexer/BlockTokenType.cs

@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Larkdown.Parser.Lexer
+{
+    enum BlockTokenType
+    {
+		Line,
+    }
+}

+ 10 - 0
Parser/Lexer/InlineLexer.cs

@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Larkdown.Parser.Lexer
+{
+    class InlineLexer
+    {
+    }
+}

+ 40 - 0
Parser/Parser.cs

@@ -0,0 +1,40 @@
+using Larkdown.Parser.Ast;
+using Larkdown.Parser.Lexer;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Larkdown.Parser
+{
+    public class Parser
+    {
+		public Parser()
+		{
+		}
+
+		public Ast.Ast Parse(string source)
+		{
+			var ast = new Ast.Ast();
+			var lexer = new BlockLexer(source);
+			var node = new ParagraphNode();
+			BlockToken token;
+
+			while ((token = lexer.NextToken()) != null)
+			{
+				if (String.IsNullOrEmpty(token.Content))
+				{
+					ast.Add(node);
+					node = new ParagraphNode();
+				}
+				else
+				{
+					node.AddText(token.Content);
+				}
+			}
+
+			ast.Add(node);
+
+			return ast;
+		}
+    }
+}