blob: 03a3b046e805aa2535003287bd337da7cc061333 (
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
|
namespace string
lex
literal '"'
token data /[^"\\]+/
token escape /'\\' any/
end
def string_data
[data]
| [escape]
def string
['"' string_data* '"']
str unquote( S: string )
{
match S ['"' DL: string_data* '"']
for E: escape in DL
E.data = 'x'
return $DL
}
end string
namespace hash
lex
literal 'define', 'include'
literal '#', '\n' ni
token id /[a-zA-Z_][a-zA-Z_0-9]*/
token number /[0-9]+/
ignore /[ \t]/
end
def hash
['#' 'define' Id: id number '\n']
| ['#' 'include' Inc: string::string '\n']
end hash
token rest_of_line /[^\n]* '\n'/
namespace lang
lex
ignore /space/
literal '*', '(', ')', ';'
token id /[a-zA-Z_][a-zA-Z_0-9]*/
token number /[0-9]+/
token hash /'#'/ {
parse_stop H: hash::hash[ input ]
if ( H.tree ) {
if ( H.tree.Inc ) {
FN: str = unquote( H.tree.Inc )
print( 'opening ' FN '\n' )
IS: stream = open( FN 'r' )
if ( ! IS ) {
print( 'ERROR: failed to open ' FN '\n' )
exit(1)
}
input.push( IS )
}
}
else {
parse_stop L: rest_of_line[ input ]
if ! L.tree {
print( "ERROR: stuck: " L.error )
exit(1)
}
print( "ERROR: failed to parse # directive: " L.tree )
}
}
end
def item
[id]
| ['(' item* ')']
def statement
[item* ';']
def start
[statement*]
end lang
parse Input: lang::start[ stdin ]
if ! Input.tree
print( Input.error '\n' )
else {
#print( Input.tree '\n' )
S: lang::start = Input.tree
print( Input.tree '\n' )
}
|