blob: cb1a2f00bd34030405a48677a9bda8ae17a82a45 (
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
98
99
|
##### LM #####
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 )
{
cons a: accum<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 #####
|