blob: 0967a60be3b99274aa3faff50d3c405d335d0d4f (
plain)
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
|
lex
literal `type `include
token id /[A-Za-z_][A-Za-z_0-9]*/
ignore /'#' [^\n]* '\n'/
ignore /[ \t\r\n]+/
end
lex
token ifn_part /[a-zA-Z0-9_.\-]+/
token ifn_slash /'/'/
end
def ifn_path_part
[ifn_part]
| [ifn_slash]
def ifn_path
[ifn_path_part ifn_path]
| [ifn_path_part]
literal `%%
lex
token em_ws /( any - 33..126 )+/
end
def em_item
[em_ws]
def prelude
[em_item* `%%]
def item
[`include ifn_path]
| [`type id]
def start
[prelude item*]
start parseStart( InputFile: stream )
{
return parse start[ InputFile ]
}
start parseTxt( T: str )
{
A: parser<start> = new parser<start>()
send A [T] eos
return A->tree
}
item* concatItems( IL1: item*, IL2: item* )
{
for IL: item* in IL1 {
if match IL [] {
IL = IL2
break
}
}
return IL1
}
item* expandIncludes( ItemList: ref<item*> )
{
for IL: item* in ItemList {
if match IL
[`include FN: ifn_path Rest: item*]
{
S: start = parseTxt(
"
"%%
"
)
match S [em_item* `%% IncludedItems: item*]
IL = concatItems( IncludedItems, Rest )
}
}
}
int main()
{
S: start = parseStart(stdin)
match S [em_item* `%% ItemList: item*]
expandIncludes( ItemList )
}
main()
##### IN #####
%%
include smtp.vpt
##### EXP #####
|