📄 parser.cs
字号:
using System;
using System.Collections.Generic;
using System.Text;
namespace QiHe.CodeLib.Csv
{
public partial class Parser
{
public CsvData ParseCsvData(ParserInput<Char> input, out bool success)
{
this.SetInput(input);
CsvData csvData = ParseCsvData(out success);
return csvData;
}
private CsvData ParseCsvData(out bool success)
{
CsvData csvData = new CsvData();
int start_position = position;
while (true)
{
Record record = ParseRecord(out success);
if (success)
{
csvData.Records.Add(record);
}
else { break; }
}
success = true;
ParseEndOfFile(out success);
if (!success)
{
Error("Failed to parse EndOfFile of CsvData.");
position = start_position;
}
return csvData;
}
private Record ParseRecord(out bool success)
{
Record record = new Record();
int start_position = position;
while (true)
{
int seq_start_position = position;
string str = ParseField(out success);
if (success)
{
record.Fields.Add(str);
}
else { break; }
while (true)
{
while (true)
{
ParseSeparator(out success);
if (!success) { break; }
str = ParseField(out success);
if (success)
{
record.Fields.Add(str);
}
else { break; }
break;
}
if (!success) { break; }
}
success = true;
break;
}
if (!success)
{
Error("Failed to parse Fields of Record.");
position = start_position;
return record;
}
ParseEnfOfLine(out success);
if (!success)
{
Error("Failed to parse EnfOfLine of Record.");
position = start_position;
}
return record;
}
private string ParseField(out bool success)
{
string str = null;
int start_position = position;
ParseSpacing(out success);
while (true)
{
str = ParseQuotedText(out success);
if (success) { ClearError(); break; }
str = ParseUnQuotedText(out success);
if (success) { ClearError(); break; }
break;
}
if (!success)
{
Error("Failed to parse (QuotedText / UnQuotedText) of Field.");
position = start_position;
}
return str;
}
private string ParseUnQuotedText(out bool success)
{
string str = null;
List<char> chars = new List<char>();
while (true)
{
char ch = MatchTerminalSet(",\"\r\n", true, out success);
if (success)
{
chars.Add(ch);
}
else { break; }
}
success = true;
if (success) { if(chars.Count==0) return null; else return new string(chars.ToArray()); }
return str;
}
private string ParseQuotedText(out bool success)
{
string str = null;
int start_position = position;
MatchTerminal('"', out success);
if (!success)
{
Error("Failed to parse '\\\"' of QuotedText.");
position = start_position;
return str;
}
List<char> chars = new List<char>();
while (true)
{
char ch;
while (true)
{
ch = MatchTerminalSet("\"\r\n\\", true, out success);
if (success) { ClearError(); break; }
ch = ParseEscapeSequence(out success);
if (success) { ClearError(); break; }
break;
}
if (success)
{
chars.Add(ch);
}
else { break; }
}
success = true;
MatchTerminal('"', out success);
if (success) { return new string(chars.ToArray()); }
else
{
Error("Failed to parse '\\\"' of QuotedText.");
position = start_position;
}
return str;
}
private char ParseEscapeSequence(out bool success)
{
char ch = default(char);
MatchTerminalString("\\\\", out success);
if (success) { return '\\'; }
MatchTerminalString("\\\"", out success);
if (success) { return '\"'; }
MatchTerminalString("\\r", out success);
if (success) { return '\r'; }
MatchTerminalString("\\n", out success);
if (success) { return '\n'; }
MatchTerminalString("\\t", out success);
if (success) { return '\t'; }
return ch;
}
private char ParseSpace(out bool success)
{
char ch = default(char);
ch = MatchTerminal(' ', out success);
if (success) { ClearError(); return ch; }
ch = MatchTerminal('\t', out success);
if (success) { ClearError(); return ch; }
return ch;
}
private void ParseSpacing(out bool success)
{
while (true)
{
ParseSpace(out success);
if (!success) { break; }
}
success = true;
}
private void ParseSeparator(out bool success)
{
MatchTerminal(',', out success);
if (!success)
{
Error("Failed to parse ',' in Separator.");
}
}
private void ParseEnfOfLine(out bool success)
{
MatchTerminalString("\r\n", out success);
if (success) { return; }
MatchTerminal('\r', out success);
if (success) { return; }
MatchTerminal('\n', out success);
if (success) { return; }
}
private void ParseEndOfFile(out bool success)
{
success = !Input.HasInput(position);
if (!success)
{
Error("Failed to parse EndOfInput in EndOfFile.");
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -