Skip to content

Instantly share code, notes, and snippets.

@keyle
Created December 20, 2011 07:08
Show Gist options
  • Save keyle/1500611 to your computer and use it in GitHub Desktop.
Save keyle/1500611 to your computer and use it in GitHub Desktop.
Parser taken from Halite.Parse as reference
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