source: CIVL/grammar/PreprocessorParser.g@ 34760dc

1.23 2.0 acw/focus-triggers main test-branch
Last change on this file since 34760dc was 34760dc, checked in by Stephen Siegel <siegel@…>, 14 years ago

Debugged parser, added examples, for CIVLC.

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@6 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 5.8 KB
RevLine 
[d96fdd6d]1parser grammar PreprocessorParser;
2
3/* Author: Stephen F. Siegel, University of Delaware
4 * Last modified: June 1, 2012
5 *
6 * Grammar for C preprocessor.
7 * This grammar describes a C source file before preprocessing.
8 * It does not execute any preprocessor directives.
9 * It simply represents the file in a structured way.
10 *
11 * See the C11 Standard, Sec. 6.10.
12 *
13 * This grammar uses the PreprocessorLexer, which has already
14 * formed the preprocessor tokens.
15 */
16
17options {
18 tokenVocab=PreprocessorLexer;
19 output=AST;
20}
21
22/* "imaginary" tokens */
23tokens {
24 FILE; // root node
25 TEXT_BLOCK; // a list of tokens
26 PARAMLIST; // x1,x2,x3
27 EXPR; // an expression used in a conditional (#if)
28 SEQUENCE; // true branch of conditional directive
29 BODY; // body of macro definition
30}
31
32@header
33{
[af8a6cb]34package edu.udel.cis.vsl.civl.civlc.preproc.common;
[d96fdd6d]35}
36
37@members{
38@Override
39public void emitErrorMessage(String msg) { // don't try to recover!
40 throw new RuntimeException(msg);
41}
42}
43
44/** The whole file consists of 1 block followed by EOF */
45file : block EOF -> ^(FILE block? EOF)
46 ;
47
48/** A block is a sequence of directives and text blocks.
49 * A block may be empty.
50 */
51block : (directive | textblock)* ;
52
53/** These are the various kind of preprocessor directives
54 * specified in the C11 standard. Each one whose name ends in
55 * "block" is a complete block, so the "ifblock", for example,
56 * contains everything up to and including the final "#endif".
57 *
58 * Yes, a "nondirective" is a kind of directive. That is what
59 * C11 says.
60 *
61 */
62directive : macrodef
63 | macroundef
64 | includeline
65 | pragmaline
66 | ifblock
67 | ifdefblock
68 | ifndefblock
69 | errorline
70 | lineline
71 | nondirectiveline
72 ;
73
74/** A textblock is a maximal sequence of text lines. A
75 * text line is any line that doesn't have a "#' as its first
76 * non-whitespace character. In the tree, the text block
77 * just contains a sequence of all the tokens form all the lines
78 * concatenated. The white space tokens and newlines are included,
79 * as are comments. */
80textblock : (options {greedy=true;} : textline)+
81 -> ^(TEXT_BLOCK textline+) ;
82
83textline : white* (nonPoundPpToken wpptoken*)? lineend ;
84
85white : WS | COMMENT ;
86
87wpptoken : pptoken | white ;
88
89lineend : NEWLINE ;
90
91macrodef : PDEFINE white+ i=identifier
92 ( paramlist macrobody -> ^(PDEFINE $i paramlist macrobody)
93 | lineend -> ^(PDEFINE $i ^(BODY))
94 | white macrobody -> ^(PDEFINE $i macrobody)
95 )
96 ;
97
98macrobody : white*
99 ( t+=pptoken (t+=wpptoken* t+=pptoken)? white* lineend
100 -> ^(BODY $t+)
101 | lineend
102 -> ^(BODY)
103 )
104 ;
105
106paramlist : LPAREN white*
107 ( RPAREN -> ^(PARAMLIST)
108 | identifier (white* COMMA white* identifier)* white* RPAREN
109 -> ^(PARAMLIST identifier+)
110 )
111 ;
112
113macroundef : PUNDEF white+ identifier white* lineend
114 -> ^(PUNDEF identifier)
115 ;
116
117includeline : PINCLUDE white* HEADER_NAME white* lineend
118 -> ^(PINCLUDE HEADER_NAME)
119 ;
120
121ifblock : PIF white* expr lineend block elseblock? endifline
122 -> ^(PIF expr ^(SEQUENCE block?) elseblock?)
123 ;
124
125expr : ppdExpr (ppdExpr | white)* -> ^(EXPR ppdExpr+) ;
126
127definedExpr : DEFINED WS!*
128 ( identifier
129 | LPAREN! WS!* identifier WS!* RPAREN!
130 )
131 ;
132
133ppdExpr : pptoken | definedExpr ;
134
135elseblock : simpleelseblock | elifblock ;
136
137simpleelseblock : PELSE white* lineend block -> ^(PELSE block?) ;
138
139elifblock : c=PELIF white* expr lineend block elseblock?
140 ->
141 ^($c ^($c expr ^(SEQUENCE block?) elseblock?))
142 ;
143
144ifdefblock : PIFDEF white* identifier white* lineend
145 block elseblock? endifline
146 -> ^(PIFDEF identifier ^(SEQUENCE block?) elseblock?)
147 ;
148
149ifndefblock : PIFNDEF white* identifier white* lineend
150 block elseblock? endifline
151 -> ^(PIFNDEF identifier ^(SEQUENCE block) elseblock?)
152 ;
153
154endifline : PENDIF white* lineend ;
155
156pragmaline : PRAGMA wpptoken* lineend -> ^(PRAGMA wpptoken* lineend) ;
157
158errorline : PERROR wpptoken* lineend -> ^(PERROR wpptoken*) ;
159
160lineline : PLINE wpptoken* lineend -> ^(PLINE wpptoken*) ;
161
162nondirectiveline
163 : HASH wpptoken* lineend -> ^(HASH wpptoken*) ;
164
165/* A "preprocessor token" as defined in the C11 Standard. */
166pptoken : HEADER_NAME
167 | identifier
168 | pp_number
169 | CHARACTER_CONSTANT
170 | STRING_LITERAL
171 | punctuator
172 | OTHER
173 ;
174
175/* Any preprocessor token other than '#' */
176nonPoundPpToken : HEADER_NAME
177 | identifier
178 | pp_number
179 | CHARACTER_CONSTANT
180 | STRING_LITERAL
181 | nonPoundPunctuator
182 | OTHER
183 ;
184
185/* An "identifier" for the preprocessor is any C IDENTIFIER or C keyword: */
186/* Added for CIVL-C: any CIVL-C keyword */
187
188identifier : IDENTIFIER | c_keyword ;
189
190c_keyword : AUTO | BREAK | CASE | CHAR | CONST | CONTINUE | DEFAULT
191 | DO | DOUBLE | ELSE | ENUM | EXTERN | FLOAT | FOR | GOTO
192 | IF | INLINE | INT | LONG | REGISTER | RESTRICT | RETURN
193 | SHORT | SIGNED | SIZEOF | STATIC | STRUCT | SWITCH | TYPEDEF
194 | UNION | UNSIGNED | VOID | VOLATILE | WHILE | ALIGNAS | ALIGNOF
195 | ATOMIC | BOOL | COMPLEX | GENERIC | IMAGINARY | NORETURN
196 | STATICASSERT | THREADLOCAL
197 | ASSERT | ASSUME | CHOOSE | COLLECTIVE | INPUT | INVARIANT
[af8a6cb]198 | OUTPUT | PROC | SPAWN | WAIT | WHEN
[d96fdd6d]199 ;
200
201punctuator : nonPoundPunctuator | HASH ;
202
203/* a "pp_number" is any PP_NUMBER, INTEGER_CONSTANT, or FLOATING_CONSTANT */
204pp_number : INTEGER_CONSTANT | FLOATING_CONSTANT | PP_NUMBER ;
205
206/* Any punctuator other than '#' */
207nonPoundPunctuator
208 : AMPERSAND
209 | AND
210 | ARROW
211 | ASSIGN
[34760dc]212 | AT
[d96fdd6d]213 | BITANDEQ
214 | BITOR
215 | BITOREQ
216 | BITXOR
217 | BITXOREQ
218 | COLON
219 | COMMA
220 | DIV
221 | DIVEQ
222 | DOT
223 | ELLIPSIS
224 | EQUALS
225 | GT
226 | GTE
227 | HASHHASH
228 | LCURLY
229 | LPAREN
230 | LSQUARE
231 | LT
232 | LTE
233 | MINUSMINUS
234 | MOD
235 | MODEQ
236 | NEQ
237 | NOT
238 | OR
239 | PLUS
240 | PLUSEQ
241 | PLUSPLUS
242 | QMARK
243 | RCURLY
244 | RPAREN
245 | RSQUARE
246 | SEMI
247 | SHIFTLEFT
248 | SHIFTLEFTEQ
249 | SHIFTRIGHT
250 | SHIFTRIGHTEQ
251 | STAR
252 | STAREQ
253 | SUB
254 | SUBEQ
255 | TILDE
256 ;
Note: See TracBrowser for help on using the repository browser.