-
Notifications
You must be signed in to change notification settings - Fork 0
/
core-rc_parser.peg
128 lines (98 loc) · 3.3 KB
/
core-rc_parser.peg
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
##
## @file core-rc_parser.peg @brief PE grammer for core-rc file
##
## Copyright (c) 2009, 2010, 2021 by Lutz Sammer. All Rights Reserved.
##
## Contributor(s):
##
## License: AGPLv3
##
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU Affero General Public License as
## published by the Free Software Foundation, either version 3 of the
## License.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU Affero General Public License for more details.
##
## $Id: $
##############################################################################
#
# NOTE: the grammer self is also AGPLv3 and (c)
#
#
configs <- spaces (include &{YYACCEPT}/ config &{YYACCEPT})* end_of_file
include <- "include" spaces string
{ ParseInclude(ParsePop()); }
config <- lvalue '=' spaces expr
{ const ConfigObject * v1 = ParsePop();
ParseAssign(ParsePop(), v1); }
lvalue <- identifier
{ ParseLvalue() }
((('.' spaces identifier) / ('[' spaces expr ']' spaces))
{ const ConfigObject * v1 = ParsePop();
ParseDot(ParsePop(), v1); } )*
array <- { ParseArrayStart(); }
'[' spaces (array_item (',' spaces)?)* ']' spaces
{ ParseArrayFinal(); }
array_item
<- '[' spaces expr ']' spaces '=' spaces expr
{ const ConfigObject * v1 = ParsePop();
ParseArrayAddItem(ParsePop(), v1); }
/ (identifier / word) '=' spaces expr
{ const ConfigObject * v1 = ParsePop();
ParseArrayAddItem(ParsePop(), v1); }
/ expr
{ ParseArrayNextItem(ParsePop()); }
expr <- '(' spaces expr ')' spaces
/ expr0 '~' spaces expr
{ const ConfigObject * v1 = ParsePop();
ParseStringCat(ParsePop(), v1); }
/ expr0
expr0 <- "nil" spaces
{ ParsePushNil(); }
/ "false" spaces
{ ParsePushI(0); }
/ "true" spaces
{ ParsePushI(1); }
/ number / string / word
/ identifier
{ ParseVariable(ParsePop()); }
/ array
#----------------------------------------------------------------------------
word <- '`' identifier
identifier <- < [a-zA-Z_][-0-9a-zA-Z_]* > spaces
{ ParsePushS(yytext); }
string <- string1
{ ParsePushS(yytext); }
string1 <- '"' < (!'"' char)* > '"' spaces
/ '{' end_of_line? < (!(end_of_line? '}') .)* > end_of_line? '}' spaces
character <- '\'' < char > spaces
{ ParsePushI(*yytext); }
char <- '\\' [abefnrtv'"\\]
/ '\\' [xX] hex_digit hex_digit
/ '\\' [0-3][0-7][0-7]
/ '\\' [uU] hex_digit hex_digit hex_digit hex_digit
/ !'\\' .
number <- float / integer / character
integer <- (decimal / hex / octal ) spaces
{ ParsePushI(strtol(yytext, NULL, 0)); }
decimal <- < [-+]? [1-9] [0-9]* >
hex <- < '0' [xX] hex_digit+ >
hex_digit <- [0-9a-fA-F]
octal <- < '0' [0-7]* >
float <- float1
{ ParsePushF(strtod(yytext, NULL)); }
float1 <- < [-+]? [0-9]+ '.' [0-9]* ([eE] [+-]? [0-9]*)? > spaces
/ < [-+]? [0-9]* '.' [0-9]+ ([eE] [+-]? [0-9]*)? > spaces
/ < [-+]? [0-9]+ [eE] [+-]? [0-9]* > spaces
#----------------------------------------------------------------------------
spaces <- (space / comment)*
comment <- ";{" (!";}" .)* ";}"
/ ';' (!end_of_line .)* end_of_line
space <- ' ' / '\t' / '\f' / '\v' / end_of_line
end_of_line <- "\r\n" / '\r' / '\n'
{ ++ParseLineNr; }
end_of_file <- !.