blob: 2babef1f0b5929ed69a64125a9ddfaf61ad9f9ca (
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
|
lex c_token_list
{
token c_single_lit /( 'L'? "'" ( [^'\\\n] | '\\' any )* "'" )/
token c_double_lit /( 'L'? '"' ( [^"\\\n] | '\\' any )* '"' )/
token sym / ';' | ',' | '=' | '(' | ')' | ':' | '&' | '*' |
'[' | ']' | '~' | '+' | '-' | '/' | '<' | '>' | '|' |
'^' | '!' | '?' | '.' | '#'/
# Identifiers
token c_id /( [a-zA-Z_] [a-zA-Z0-9_]* )/
# Comments and whitespace.
token comm_c /( '/*' (any | '\n')* :>> '*/' )/
token comm_cxx /( '//' any* :> '\n' )/
token ws /( any - 33..126 )+/
}
def c_token
[c_single_lit]
| [c_double_lit]
| [sym]
| [c_id]
| [comm_c]
| [comm_cxx]
| [ws]
def c_token_list
[c_token c_token_list]
| [c_token]
# Can parse this, use ful for single constructs.
#def c
# [c_token*]
def c
[c_token_list]
lex start
{
literal '%%'
literal '{', '}'
literal 'protocol', 'client', 'server', 'port', 'by', 'tcp', 'udp'
token id /[A-Za-z_][A-Za-z_0-9]*/
token number /[0-9]+/
ignore /'/*' any* :>> '*/'/
ignore /[ \t\r\n]+/
}
def tcp_by_port
['tcp' 'by' 'port']
def udp_by_port
['udp' 'by' 'port']
def attribute
['client' id]
| ['server' id]
| ['port' number]
| ['udp' id]
| [tcp_by_port]
| [udp_by_port]
def tcp_protocol
['tcp' 'protocol' id '{' attribute* '}']
def udp_protocol
['udp' 'protocol' id '{' attribute* '}']
def protocol
[tcp_protocol]
| [udp_protocol]
def program
[c '%%' protocol*]
alias output accum<c>
def port
Port: int
Protocol: str
[]
# Parse the input.
parse P: program[ stdin ]
Output: output Output = construct output []
# Take off the leading C from the input file and send it out.
match P.tree [C: c '%%' protocol*]
Output << [$C]
Output <<
"#include <assert.h>
"
print( Output.finish() )
|