Created
December 20, 2011 07:08
-
-
Save keyle/1500611 to your computer and use it in GitHub Desktop.
Parser taken from Halite.Parse as reference
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
namespace Halite.Parse | |
{ | |
/// <summary> | |
/// Contains parsers and functions related to parsing. Parsers are functions that process a string starting at a certain index and | |
/// either give a meaningful interpretation an update the index, or return false (leaving the index unaltered). Some parser have a | |
/// return type of void and can never fail. | |
/// </summary> | |
public static class Parser | |
{ | |
/// Determines wether the given character is a digit. | |
/// </summary> | |
public static bool IsDigit(char Char) | |
{ | |
int i = (int)Char; | |
if (i >= 48 && i <= 57) return true; | |
return false; | |
} | |
/// <summary> | |
/// Determines wether the given character is valid in a word. Note that digits are not valid as the first character in a word. | |
/// </summary> | |
public static bool IsWordChar(char Char) | |
{ | |
int i = (int)Char; | |
if (i >= 94 && i <= 122) return true; // ^ _ ` Lowercases | |
if (i >= 47 && i <= 90) return true; // / Digits : ; < = > ? @ Uppercases | |
if (i >= 35 && i <= 39) return true; // # $ % & ' | |
if (i == 42) return true; // * | |
if (i == 43) return true; // + | |
if (i == 45) return true; // - | |
if (i == 33) return true; // ! | |
if (i == 124) return true; // | | |
if (i == 126) return true; // ~ | |
if (i == 92) return true; // \ | |
return false; | |
} | |
/// <summary> | |
/// Tries parsing the target string in the given text. | |
/// </summary> | |
public static bool AcceptString(string Target, string String, ref int Index) | |
{ | |
int cur = Index; | |
if (String.Length - cur < Target.Length) | |
return false; | |
for (int t = 0; t < Target.Length; t++) | |
{ | |
if (String[cur++] != Target[t]) | |
return false; | |
} | |
Index = cur; | |
return true; | |
} | |
/// <summary> | |
/// Greedily parses whitespace (spaces or tabs) in the given text. Returns true if any whitespace was found. | |
/// </summary> | |
public static bool AcceptWhitespace(string String, ref int Index) | |
{ | |
bool found = false; | |
while (Index < String.Length) | |
{ | |
char c = String[Index]; | |
switch (c) | |
{ | |
case ' ': | |
case '\t': | |
found = true; | |
Index++; | |
continue; | |
default: | |
return found; | |
} | |
} | |
return found; | |
} | |
/// <summary> | |
/// Greedily parses extended whitespace (whitespace including comments and newlines) in the given text. Returns true if any whitespace was found. | |
/// </summary> | |
public static bool AcceptExtendedWhitespace(string String, ref int Index) | |
{ | |
bool found = false; | |
int cur = Index; | |
if (AcceptWhitespace(String, ref cur)) | |
{ | |
AcceptComment(String, ref cur); | |
found = true; | |
} | |
while (true) | |
{ | |
if (AcceptNewline(String, ref cur)) | |
{ | |
found = true; | |
AcceptWhitespace(String, ref cur); | |
AcceptComment(String, ref cur); | |
continue; | |
} | |
break; | |
} | |
Index = cur; | |
return found; | |
} | |
/// <summary> | |
/// Greedily parses indentation (spaces or tabes) in the given text. | |
/// </summary> | |
public static void AcceptIndentation(string String, ref int Index, ref int Indentation) | |
{ | |
Indentation = 0; | |
while (Index < String.Length) | |
{ | |
char c = String[Index]; | |
switch (c) | |
{ | |
case ' ': | |
case '\t': | |
Indentation++; | |
Index++; | |
continue; | |
default: | |
return; | |
} | |
} | |
} | |
/// <summary> | |
/// Tries parsing a comment (starting with the comment start token) in the given text. | |
/// </summary> | |
public static bool AcceptComment(string String, ref int Index) | |
{ | |
int cur = Index; | |
if (AcceptString(Token.CommentStart, String, ref cur)) | |
{ | |
while (cur < String.Length) | |
{ | |
char c = String[cur]; | |
switch (c) | |
{ | |
case '\n': | |
case '\r': | |
Index = cur; | |
return true; | |
default: | |
cur++; | |
continue; | |
} | |
} | |
Index = cur; | |
return true; | |
} | |
return false; | |
} | |
/// <summary> | |
/// Tries parsing a newline in the given text. | |
/// </summary> | |
public static bool AcceptNewline(string String, ref int Index) | |
{ | |
if (Index < String.Length) | |
{ | |
char a = String[Index]; | |
if (a != '\n' && a != '\r') | |
return false; | |
Index++; | |
if (Index < String.Length) | |
{ | |
char b = String[Index]; | |
if (b != '\n' && b != '\r') | |
return false; | |
Index++; | |
} | |
return true; | |
} | |
return false; | |
} | |
/// <summary> | |
/// Greedily parses a word in the given text. | |
/// </summary> | |
public static bool AcceptWord(string String, ref int Index, ref string Word) | |
{ | |
int cur = Index; | |
while (cur < String.Length) | |
{ | |
char c = String[cur]; | |
if (cur == Index) | |
{ | |
if (Parser.IsDigit(c) || !Parser.IsWordChar(c)) | |
break; | |
} | |
else | |
{ | |
if (!Parser.IsWordChar(c)) | |
break; | |
} | |
cur++; | |
} | |
if (cur > Index) | |
{ | |
Word = String.Substring(Index, cur - Index); | |
Index = cur; | |
return true; | |
} | |
return false; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment