aboutsummaryrefslogtreecommitdiff
path: root/csharp/ProtocolBuffers/TextTokenizer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'csharp/ProtocolBuffers/TextTokenizer.cs')
-rw-r--r--csharp/ProtocolBuffers/TextTokenizer.cs46
1 files changed, 40 insertions, 6 deletions
diff --git a/csharp/ProtocolBuffers/TextTokenizer.cs b/csharp/ProtocolBuffers/TextTokenizer.cs
index 81c83c7d..d53ae596 100644
--- a/csharp/ProtocolBuffers/TextTokenizer.cs
+++ b/csharp/ProtocolBuffers/TextTokenizer.cs
@@ -53,13 +53,18 @@ namespace Google.ProtocolBuffers {
/// </summary>
private int previousColumn = 0;
- private static Regex WhitespaceAndCommentPattern = new Regex("\\G(\\s|(#[^\\\n]*\\n))+", RegexOptions.Compiled);
- private static Regex TokenPattern = new Regex(
+ private static readonly Regex WhitespaceAndCommentPattern = new Regex("\\G(\\s|(#.*$))+",
+ RegexOptions.Compiled | RegexOptions.Multiline);
+ private static readonly Regex TokenPattern = new Regex(
"\\G[a-zA-Z_][0-9a-zA-Z_+-]*|" + // an identifier
"\\G[0-9+-][0-9a-zA-Z_.+-]*|" + // a number
- "\\G\"([^\"\\\n\\\\]|\\\\[^\\\n])*(\"|\\\\?$)|" + // a double-quoted string
- "\\G\'([^\"\\\n\\\\]|\\\\[^\\\n])*(\'|\\\\?$)", // a single-quoted string
- RegexOptions.Compiled);
+ "\\G\"([^\"\\\n\\\\]|\\\\.)*(\"|\\\\?$)|" + // a double-quoted string
+ "\\G\'([^\"\\\n\\\\]|\\\\.)*(\'|\\\\?$)", // a single-quoted string
+ RegexOptions.Compiled | RegexOptions.Multiline);
+
+ private static readonly Regex DoubleInfinity = new Regex("^-?inf(inity)?$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
+ private static readonly Regex FloatInfinity = new Regex("^-?inf(inity)?f?$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
+ private static readonly Regex FloatNan = new Regex("^nanf?$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
/** Construct a tokenizer that parses tokens from the given text. */
public TextTokenizer(string text) {
@@ -243,6 +248,18 @@ namespace Google.ProtocolBuffers {
/// Otherwise, throw a FormatException.
/// </summary>
public double ConsumeDouble() {
+ // We need to parse infinity and nan separately because
+ // double.Parse() does not accept "inf", "infinity", or "nan".
+ if (DoubleInfinity.IsMatch(currentToken)) {
+ bool negative = currentToken.StartsWith("-");
+ NextToken();
+ return negative ? double.NegativeInfinity : double.PositiveInfinity;
+ }
+ if (currentToken.Equals("nan", StringComparison.InvariantCultureIgnoreCase)) {
+ NextToken();
+ return Double.NaN;
+ }
+
try {
double result = double.Parse(currentToken, CultureInfo.InvariantCulture);
NextToken();
@@ -258,7 +275,24 @@ namespace Google.ProtocolBuffers {
/// If the next token is a float, consume it and return its value.
/// Otherwise, throw a FormatException.
/// </summary>
- public float consumeFloat() {
+ public float ConsumeFloat() {
+
+ // We need to parse infinity and nan separately because
+ // Float.parseFloat() does not accept "inf", "infinity", or "nan".
+ if (FloatInfinity.IsMatch(currentToken)) {
+ bool negative = currentToken.StartsWith("-");
+ NextToken();
+ return negative ? float.NegativeInfinity : float.PositiveInfinity;
+ }
+ if (FloatNan.IsMatch(currentToken)) {
+ NextToken();
+ return float.NaN;
+ }
+
+ if (currentToken.EndsWith("f")) {
+ currentToken = currentToken.TrimEnd('f');
+ }
+
try {
float result = float.Parse(currentToken, CultureInfo.InvariantCulture);
NextToken();