/
Factory.pas
99 lines (85 loc) · 2.47 KB
/
Factory.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
unit Factory;
{$mode delphi}
interface
uses
Classes, SysUtils, DocumentTypes;
type
{ The output type. This determines which formatter will be used. }
TFormatterType = (
{ HTML }
ftHtml,
{ Rich text format }
ftRtf
);
{ Formats the given input stream and writes the formatted output into the output stream. }
procedure Process(FormatterType: TFormatterType; DocumentType: TDocumentType;
InputStream, OutputStream: TStream);
implementation
uses
PascalParser, CppParser, EditorConfigParser,
FormatterBase, RTFFormatter, HTMLFormatter, Recognizers, TokenTypes, Parsers, ParseResult, Tokenizers;
function CreateFormatter(FormatterType: TFormatterType;
OutputStream: TStream): TFormatterBase;
begin
case FormatterType of
ftHtml:
Result := THTMLFormatter.Create(OutputStream);
ftRtf:
Result := TRTFFormatter.Create(OutputStream);
else
raise Exception.Create('Not implemented!');
end;
end;
function CreateRecognizers(DocumentType: TDocumentType): TTokenRecognizers;
begin
case DocumentType of
dtCpp: Result := CppParser.CreateRecognizers;
dtPascal: Result := PascalParser.CreateRecognizers;
dtEditorConfig: Result := EditorConfigParser.CreateRecognizers;
else raise Exception.Create('Not implemented!')
end;
end;
function CreateParser(DocumentType: TDocumentType): TParser<TFmt>;
begin
case DocumentType of
dtCpp: Result := CppParser.CreateParser;
dtPascal: Result := PascalParser.CreateParser;
dtEditorConfig: Result := EditorConfigParser.CreateParser;
else raise Exception.Create('Not implemented!')
end;
end;
procedure Process(FormatterType: TFormatterType; DocumentType: TDocumentType;
InputStream, OutputStream: TStream);
var
formatter: TFormatterBase;
Recognizers: TTokenRecognizers;
Parser: TParser<TFmt>;
Tokenizer: TUndoTokenizer;
Next: TParseResult<TFmt>;
Fmt: TFmt;
begin
formatter := CreateFormatter(FormatterType, OutputStream);
try
formatter.WriteHeader;
Recognizers := CreateRecognizers(DocumentType);
Tokenizer := CreateUndoTokenizer(InputStream, Recognizers);
Parser := CreateParser(DocumentType);
try
repeat
Next := Parser.Parse(Tokenizer);
if Next.Success then
begin
Fmt := Next.Data;
formatter.WriteToken(Fmt.Text, Fmt.Kind);
end;
until not Next.Success;
finally
Parser.Free;
Tokenizer.Free;
end;
formatter.WriteFooter;
finally
formatter.Free;
end;
end;
end.