source: CIVL/grammar/CivlCParser.g@ a070b96

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

Debugging grammar

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

  • Property mode set to 100644
File size: 34.1 KB
RevLine 
[d96fdd6d]1/* Grammar for programming CIVL-C.
2 * Based on C11 grammar.
3 *
4 * Author: Stephen F. Siegel
5 * Last modified:
6 *
7 * This grammar assumes the input token stream is the result of
8 * translation phase 7, as specified in the Standard.
9 * In particular, all the preprocessing has already been
10 * done.
11 *
12 * In addition to the Standard, I borrowed from the older
13 * C grammar included with the ANTLR distribution.
14 *
15 */
16parser grammar CivlCParser;
17
18options
19{
20 language=Java;
21 tokenVocab=PreprocessorParser;
22 output=AST;
23}
24
25tokens
26{
27 ABSENT; // represents missing syntactic element
28 GENERIC_ASSOC_LIST; // generic association list
29 GENERIC_ASSOCIATION; // a generic association
30 ENUMERATION_CONSTANT; // use of enumeration constant
31 COMPOUND_LITERAL; // literal for structs, etc.
[59b5362]32 CONTRACT; // procedure contracts
[d96fdd6d]33 CALL; // function call
34 INDEX; // array subscript operator
35 ARGUMENT_LIST; // list of arguments to an operator
36 POST_INCREMENT;
37 POST_DECREMENT;
38 PRE_INCREMENT;
39 PRE_DECREMENT;
40 OPERATOR; // symbol indicating an operator
41 TYPE; // symbol indicating "type"
42 EXPR; // symbol indicating "expression"
43 PARENTHESIZED_EXPRESSION;
44 CAST; // type cast operator
45 DECLARATION; // a declaration
46 DECLARATION_SPECIFIERS; // list of declaration specifiers
47 INIT_DECLARATOR_LIST; // list of initializer-declarator pairs
48 INIT_DECLARATOR; // initializer-declaration pair
49 STRUCT_DECLARATION_LIST; // list of field declarations
50 STRUCT_DECLARATION; // a field declaration
51 SPECIFIER_QUALIFIER_LIST; // list of type specifiers and qualifiers
52 STRUCT_DECLARATOR_LIST; // list of struct/union declarators
53 STRUCT_DECLARATOR; // a struct/union declarator
54 ENUMERATOR_LIST; // list of enumerators in enum type definition
55 ENUMERATOR; // identifier and optional int constant
56 DECLARATOR; // a declarator
57 DIRECT_DECLARATOR; // declarator after removing leading *s
58 TYPE_QUALIFIER_LIST; // list of type qualifiers
59 ARRAY_SUFFIX; // [..] used in declarator
60 FUNCTION_SUFFIX; // (..) used in declarator
61 POINTER; // * used in declarator
62 PARAMETER_TYPE_LIST; // parameter list and optional "..."
63 PARAMETER_LIST; // list of parameter decls in function decl
64 PARAMETER_DECLARATION;// parameter declaration in function decl
65 IDENTIFIER_LIST; // list of parameter names only in function decl
66 TYPE_NAME; // type specification without identifier
67 ABSTRACT_DECLARATOR; // declarator without identifier
68 DIRECT_ABSTRACT_DECLARATOR; // direct declarator sans identifier
69 SCALAR_INITIALIZER; //
70 INITIALIZER_LIST;
71 DESIGNATED_INITIALIZER;
72 DESIGNATION;
73 ARRAY_ELEMENT_DESIGNATOR;
74 FIELD_DESIGNATOR;
75 IDENTIFIER_LABELED_STATEMENT;
76 CASE_LABELED_STATEMENT;
77 DEFAULT_LABELED_STATEMENT;
78 COMPOUND_STATEMENT;
79 BLOCK_ITEM_LIST;
80 EXPRESSION_STATEMENT;
81 TRANSLATION_UNIT;
82 DECLARATION_LIST;
83 FUNCTION_DEFINITION;
84 TYPEDEF_NAME;
85 TOKEN_LIST;
86}
87
88scope Symbols {
89 Set<String> types; // to keep track of typedefs
90 Set<String> enumerationConstants; // to keep track of enum constants
91 boolean isFunctionDefinition; // "function scope": entire function definition
92}
93
94scope DeclarationScope {
95 boolean isTypedef; // is the current declaration a typedef
96}
97
98@header
99{
[af8a6cb]100package edu.udel.cis.vsl.civl.civlc.parse.common;
[d96fdd6d]101
102import java.util.Set;
103import java.util.HashSet;
[af8a6cb]104import edu.udel.cis.vsl.civl.civlc.parse.IF.RuntimeParseException;
[d96fdd6d]105}
106
107@members {
108 @Override
109 public void displayRecognitionError(String[] tokenNames, RecognitionException e) {
110 String hdr = getErrorHeader(e);
111 String msg = getErrorMessage(e, tokenNames);
112
113 throw new RuntimeParseException(hdr+" "+msg, e.token);
114 }
115
116 @Override
117 public void emitErrorMessage(String msg) { // don't try to recover!
118 throw new RuntimeParseException(msg);
119 }
120
121 boolean isTypeName(String name) {
122 for (Object scope : Symbols_stack)
123 if (((Symbols_scope)scope).types.contains(name)) return true;
124 return false;
125 }
126
127 boolean isEnumerationConstant(String name) {
128 boolean answer = false;
129
130 // System.err.print("Is "+name+" an enumeration constant: ");
131 for (Object scope : Symbols_stack) {
132 if (((Symbols_scope)scope).enumerationConstants.contains(name)) {
133 answer=true;
134 break;
135 }
136 }
137 // System.err.println(answer);
138 // System.err.flush();
139 return answer;
140 }
141}
142
143
144/* ***** A.2.1: Expressions ***** */
145
146/* Constants from A.1.5 */
147
148constant
149 : enumerationConstant
150 | INTEGER_CONSTANT
151 | FLOATING_CONSTANT
152 | CHARACTER_CONSTANT
[59b5362]153 | SELF | TRUE | FALSE | RESULT
[d96fdd6d]154 ;
155
156enumerationConstant
157 : {isEnumerationConstant(input.LT(1).getText())}? IDENTIFIER ->
158 ^(ENUMERATION_CONSTANT IDENTIFIER)
159 ;
160
161/* 6.5.1 */
162primaryExpression
163 : constant
164 | // {!isEnumerationConstant(input.LT(1).getText())}?
165 IDENTIFIER
166 | STRING_LITERAL
167 | LPAREN expression RPAREN
168 -> ^(PARENTHESIZED_EXPRESSION LPAREN expression RPAREN)
169 | genericSelection
170 ;
171
172/* 6.5.1.1 */
173
174genericSelection
175 : GENERIC LPAREN assignmentExpression COMMA genericAssocList
176 RPAREN
177 -> ^(GENERIC assignmentExpression genericAssocList)
178 ;
179
180/* 6.5.1.1 */
181genericAssocList
182 : genericAssociation (COMMA genericAssociation)*
183 -> ^(GENERIC_ASSOC_LIST genericAssociation+)
184 ;
185
186/* 6.5.1.1 */
187genericAssociation
188 : typeName COLON assignmentExpression
189 -> ^(GENERIC_ASSOCIATION typeName assignmentExpression)
190 | DEFAULT COLON assignmentExpression
191 -> ^(GENERIC_ASSOCIATION DEFAULT assignmentExpression)
192 ;
193
194/* 6.5.2 */
195postfixExpression
196 : (postfixExpressionRoot -> postfixExpressionRoot)
197 ( l=LSQUARE expression RSQUARE
198 -> ^(OPERATOR
199 INDEX[$l]
200 ^(ARGUMENT_LIST $postfixExpression expression)
201 RSQUARE)
202 | LPAREN argumentExpressionList RPAREN
203 -> ^(CALL LPAREN $postfixExpression argumentExpressionList RPAREN)
204 | DOT IDENTIFIER
205 -> ^(DOT $postfixExpression IDENTIFIER)
206 | ARROW IDENTIFIER
207 -> ^(ARROW $postfixExpression IDENTIFIER)
208 | p=PLUSPLUS
209 -> ^(OPERATOR POST_INCREMENT[$p]
210 ^(ARGUMENT_LIST $postfixExpression))
211 | AT IDENTIFIER
212 -> ^(AT $postfixExpression IDENTIFIER)
213 | m=MINUSMINUS
214 -> ^(OPERATOR POST_DECREMENT[$m]
215 ^(ARGUMENT_LIST $postfixExpression))
216 )*
217 ;
218
219/*
220 * The "(typename) {...}" is a "compound literal".
221 * See C11 Sec. 6.5.2.5. I don't know what
222 * it means when it ends with an extra COMMA.
223 * I assume it doesn't mean anything and is just
224 * allowed as a convenience for the poor C programmer
225 * (but why?).
226 *
227 * Ambiguity: need to distinguish the compound literal
228 * "(typename) {...}" from the primaryExpression
229 * "(expression)". Presence of '{' implies it must
230 * be the compound literal.
231 */
232postfixExpressionRoot
233 : (LPAREN typeName RPAREN LCURLY)=>
234 LPAREN typeName RPAREN LCURLY initializerList
235 ( RCURLY
236 | COMMA RCURLY
237 )
238 -> ^(COMPOUND_LITERAL LPAREN typeName initializerList RCURLY)
239 | primaryExpression
240 ;
241
242/* 6.5.2 */
243argumentExpressionList
244 : -> ^(ARGUMENT_LIST)
245 | assignmentExpression (COMMA assignmentExpression)*
246 -> ^(ARGUMENT_LIST assignmentExpression+)
247 ;
248
249/* 6.5.3 */
250unaryExpression
251 : postfixExpression
252 | p=PLUSPLUS unaryExpression
253 -> ^(OPERATOR PRE_INCREMENT[$p]
254 ^(ARGUMENT_LIST unaryExpression))
255 | m=MINUSMINUS unaryExpression
256 -> ^(OPERATOR PRE_DECREMENT[$m]
257 ^(ARGUMENT_LIST unaryExpression))
258 | unaryOperator castExpression
259 -> ^(OPERATOR unaryOperator ^(ARGUMENT_LIST castExpression))
260 | (SIZEOF LPAREN typeName)=> SIZEOF LPAREN typeName RPAREN
261 -> ^(SIZEOF TYPE typeName)
262 | SIZEOF unaryExpression
263 -> ^(SIZEOF EXPR unaryExpression)
264 | ALIGNOF LPAREN typeName RPAREN
265 -> ^(ALIGNOF typeName)
266 | spawnExpression
267 ;
268
269
270spawnExpression
271 : SPAWN postfixExpressionRoot LPAREN
272 argumentExpressionList RPAREN
273 -> ^(SPAWN postfixExpressionRoot argumentExpressionList)
274 ;
275
276
277/* 6.5.3 */
278unaryOperator
279 : AMPERSAND | STAR | PLUS | SUB | TILDE | NOT
280 ;
281
282/* 6.5.4 */
283// ambiguity: (expr) is a unary expression and looks
284// like (typeName).
285castExpression
286 : (LPAREN typeName RPAREN)=> l=LPAREN typeName RPAREN castExpression
287 -> ^(CAST typeName castExpression $l)
288 | unaryExpression
289 ;
290
291/* 6.5.5 */
292multiplicativeExpression
293 : (castExpression -> castExpression)
294 ( STAR y=castExpression
295 -> ^(OPERATOR STAR ^(ARGUMENT_LIST $multiplicativeExpression $y))
296 | DIV y=castExpression
297 -> ^(OPERATOR DIV ^(ARGUMENT_LIST $multiplicativeExpression $y))
298 | MOD y=castExpression
299 -> ^(OPERATOR MOD ^(ARGUMENT_LIST $multiplicativeExpression $y))
300 )*
301 ;
302
303/* 6.5.6 */
304additiveExpression
305 : (multiplicativeExpression -> multiplicativeExpression)
306 ( PLUS y=multiplicativeExpression
307 -> ^(OPERATOR PLUS ^(ARGUMENT_LIST $additiveExpression $y))
308 | SUB y=multiplicativeExpression
309 -> ^(OPERATOR SUB ^(ARGUMENT_LIST $additiveExpression $y))
310 )*
311 ;
312
313/* 6.5.7 */
314shiftExpression
315 : (additiveExpression -> additiveExpression)
316 ( SHIFTLEFT y=additiveExpression
317 -> ^(OPERATOR SHIFTLEFT ^(ARGUMENT_LIST $shiftExpression $y))
318 | SHIFTRIGHT y=additiveExpression
319 -> ^(OPERATOR SHIFTRIGHT ^(ARGUMENT_LIST $shiftExpression $y))
320 )*
321 ;
322
323/* 6.5.8 */
324relationalExpression
325 : ( shiftExpression -> shiftExpression )
326 ( relationalOperator y=shiftExpression
327 -> ^(OPERATOR relationalOperator ^(ARGUMENT_LIST $relationalExpression $y))
328 )*
329 ;
330
331relationalOperator
332 : LT | GT | LTE | GTE
333 ;
334
335/* 6.5.9 */
336equalityExpression
337 : ( relationalExpression -> relationalExpression )
338 ( equalityOperator y=relationalExpression
339 -> ^(OPERATOR equalityOperator ^(ARGUMENT_LIST $equalityExpression $y))
340 )*
341 ;
342
343equalityOperator
344 : EQUALS | NEQ
345 ;
346
347/* 6.5.10 */
348andExpression
349 : ( equalityExpression -> equalityExpression )
350 ( AMPERSAND y=equalityExpression
351 -> ^(OPERATOR AMPERSAND ^(ARGUMENT_LIST $andExpression $y))
352 )*
353 ;
354
355/* 6.5.11 */
356exclusiveOrExpression
357 : ( andExpression -> andExpression )
358 ( BITXOR y=andExpression
359 -> ^(OPERATOR BITXOR ^(ARGUMENT_LIST $exclusiveOrExpression $y))
360 )*
361 ;
362
363/* 6.5.12 */
364inclusiveOrExpression
365 : ( exclusiveOrExpression -> exclusiveOrExpression )
366 ( BITOR y=exclusiveOrExpression
367 -> ^(OPERATOR BITOR ^(ARGUMENT_LIST $inclusiveOrExpression $y))
368 )*
369 ;
370
371/* 6.5.13 */
372logicalAndExpression
373 : ( inclusiveOrExpression -> inclusiveOrExpression )
374 ( AND y=inclusiveOrExpression
375 -> ^(OPERATOR AND ^(ARGUMENT_LIST $logicalAndExpression $y))
376 )*
377 ;
378
379/* 6.5.14 */
380logicalOrExpression
381 : ( logicalAndExpression -> logicalAndExpression )
382 ( OR y=logicalAndExpression
383 -> ^(OPERATOR OR ^(ARGUMENT_LIST $logicalOrExpression $y))
384 )*
385 ;
386
387
388/* 6.5.15 */
389conditionalExpression
390 : logicalOrExpression
391 ( -> logicalOrExpression
392 | QMARK expression COLON conditionalExpression
393 -> ^(OPERATOR QMARK
394 ^(ARGUMENT_LIST
395 logicalOrExpression
396 expression
397 conditionalExpression))
398 )
399 ;
400
401/* 6.5.16
402 * conditionalExpression or
403 * Root: OPERATOR
404 * Child 0: assignmentOperator
405 * Child 1: ARGUMENT_LIST
406 * Child 1.0: unaryExpression
407 * Child 1.1: assignmentExpression
408 */
409assignmentExpression
410 : (unaryExpression assignmentOperator)=>
411 unaryExpression assignmentOperator assignmentExpression
412 -> ^(OPERATOR assignmentOperator
413 ^(ARGUMENT_LIST unaryExpression assignmentExpression))
414 | conditionalExpression
415 ;
416
417/* 6.5.16 */
418assignmentOperator
419 : ASSIGN | STAREQ | DIVEQ | MODEQ | PLUSEQ | SUBEQ
420 | SHIFTLEFTEQ | SHIFTRIGHTEQ | BITANDEQ | BITXOREQ | BITOREQ
421 ;
422
423/* 6.5.17
424 * assignmentExpression or
425 * Root: OPERATOR
426 * Child 0: COMMA
427 * Child 1: ARGUMENT_LIST
428 * Child 1.0: arg0
429 * Child 1.1: arg1
430 */
[34760dc]431commaExpression
[d96fdd6d]432 : ( x=assignmentExpression -> assignmentExpression)
433 ( COMMA y=assignmentExpression
434 -> ^(OPERATOR COMMA ^(ARGUMENT_LIST $x $y))
435 )*
436 ;
437
[34760dc]438expression
[a070b96]439 : COLLECTIVE LPAREN proc=conditionalExpression
440 COMMA intExpr=conditionalExpression RPAREN
441 body=conditionalExpression
442 -> ^(COLLECTIVE $proc $intExpr $body)
[34760dc]443 | commaExpression
444 ;
445
[d96fdd6d]446/* 6.6 */
447constantExpression
448 : conditionalExpression
449 ;
450
451/* ***** A.2.2: Declarations ***** */
452
453/* 6.7.
454 *
455 * This rule will construct either a DECLARATION or
456 * STATICASSERT tree:
457
458 * Root: DECLARATION
459 * Child 0: declarationSpecifiers
460 * Child 1: initDeclaratorList or ABSENT
461 *
462 * Root: STATICASSERT
463 * Child 0: constantExpression
464 * Child 1: stringLiteral
465 *
466 * The declarationSpecifiers rule returns a bit telling whether
467 * "typedef" occurred among the specifiers. This bit is passed
468 * to the initDeclaratorList rule, and down the call chain,
469 * where eventually an IDENTIFIER should be reached. At that point,
470 * if the bit is true, the IDENTIFIER is added to the set of typedef
471 * names.
472 *
473 */
474declaration
475scope DeclarationScope;
476@init {
477 $DeclarationScope::isTypedef = false;
478}
479 : d=declarationSpecifiers
480 (
[59b5362]481 i=initDeclaratorList contract_opt SEMI
482 -> ^(DECLARATION $d $i contract_opt)
483 | SEMI
484 -> ^(DECLARATION $d ABSENT)
[d96fdd6d]485 )
486 | staticAssertDeclaration
487 ;
488
489/* 6.7
490 * Root: DECLARATION_SPECIFIERS
491 * Children: declarationSpecifier (any number)
492 */
493declarationSpecifiers
494 : l=declarationSpecifierList
495 -> ^(DECLARATION_SPECIFIERS declarationSpecifierList)
496 ;
497
498/* Tree: flat list of declarationSpecifier
499 */
500declarationSpecifierList
501 : (
502 {!$DeclarationScope::isTypedef || input.LT(2).getType() != SEMI }?
503 s=declarationSpecifier
504 )+
505 ;
506
507declarationSpecifier
508 : s=storageClassSpecifier
509 | typeSpecifierOrQualifier
510 | functionSpecifier
511 | alignmentSpecifier
512 ;
513
514/*
515 * I factored this out of the declarationSpecifiers rule
516 * to deal with the ambiguity of "ATOMIC" in one place.
517 * "ATOMIC ( typeName )" matches atomicTypeSpecifier, which
518 * is a typeSpecifier. "ATOMIC" matches typeQualifier.
519 * When you see "ATOMIC" all you have to do is look at the
520 * next token. If it's '(', typeSpecifier is it.
521 */
522typeSpecifierOrQualifier
523 : (typeSpecifier)=> typeSpecifier
524 | typeQualifier
525 ;
526
527/* 6.7
528 * Root: INIT_DECLARATOR_LIST
529 * Children: initDeclarator
530 */
531initDeclaratorList
532 : i+=initDeclarator (COMMA i+=initDeclarator)*
533 -> ^(INIT_DECLARATOR_LIST $i+)
534 ;
535
536/* 6.7
537 * Root: INIT_DECLARATOR
538 * Child 0: declarator
539 * Child 1: initializer or ABSENT
540 */
541initDeclarator
542 : d=declarator
543 ( -> ^(INIT_DECLARATOR $d ABSENT)
544 | (ASSIGN i=initializer) -> ^(INIT_DECLARATOR $d $i)
545 )
546 ;
547
548/* 6.7.1 */
549storageClassSpecifier
550 : TYPEDEF {$DeclarationScope::isTypedef = true;}
551 | (EXTERN | STATIC | THREADLOCAL | AUTO | REGISTER)
552 ;
553
554/* 6.7.2 */
555typeSpecifier
556 : VOID | CHAR | SHORT | INT | LONG | FLOAT | DOUBLE
557 | SIGNED | UNSIGNED | BOOL | COMPLEX
[34760dc]558 | PROC
[d96fdd6d]559 | atomicTypeSpecifier
560 | structOrUnionSpecifier
561 | enumSpecifier
562 | typedefName
563 ;
564
565/* 6.7.2.1
566 * Root: STRUCT or UNION
567 * Child 0: IDENTIFIER (the tag) or ABSENT
568 * Child 1: structDeclarationList or ABSENT
569 */
570structOrUnionSpecifier
571 : structOrUnion
572 ( IDENTIFIER LCURLY structDeclarationList RCURLY
573 -> ^(structOrUnion IDENTIFIER structDeclarationList RCURLY)
574 | LCURLY structDeclarationList RCURLY
575 -> ^(structOrUnion ABSENT structDeclarationList RCURLY)
576 | IDENTIFIER
577 -> ^(structOrUnion IDENTIFIER ABSENT)
578 )
579 ;
580
581/* 6.7.2.1 */
582structOrUnion
583 : STRUCT | UNION
584 ;
585
586/* 6.7.2.1
587 * Root: STRUCT_DECLARATION_LIST
588 * Children: structDeclaration
589 */
590structDeclarationList
591 : structDeclaration+
592 -> ^(STRUCT_DECLARATION_LIST structDeclaration+)
593 ;
594
595/* 6.7.2.1
596 * Two possible trees:
597 *
598 * Root: STRUCT_DECLARATION
599 * Child 0: specifierQualifierList
600 * Child 1: structDeclaratorList or ABSENT
601 *
602 * or
603 *
604 * staticAssertDeclaration (root: STATICASSERT)
605 */
606structDeclaration
607scope DeclarationScope;
608@init {
609 $DeclarationScope::isTypedef = false;
610}
611 : s=specifierQualifierList
612 ( -> ^(STRUCT_DECLARATION $s ABSENT)
613 | structDeclaratorList
614 -> ^(STRUCT_DECLARATION $s structDeclaratorList)
615 )
616 SEMI
617 | staticAssertDeclaration
618 ;
619
620/* 6.7.2.1
621 * Root: SPECIFIER_QUALIFIER_LIST
622 * Children: typeSpecifierOrQualifier
623 */
624specifierQualifierList
625 : typeSpecifierOrQualifier+
626 -> ^(SPECIFIER_QUALIFIER_LIST typeSpecifierOrQualifier+)
627 ;
628
629/* 6.7.2.1
630 * Root: STRUCT_DECLARATOR_LIST
631 * Children: structDeclarator (at least 1)
632 */
633structDeclaratorList
634 : s+=structDeclarator (COMMA s+=structDeclarator)*
635 -> ^(STRUCT_DECLARATOR_LIST $s+)
636 ;
637
638/* 6.7.2.1
639 * Root: STRUCT_DECLARATOR
640 * Child 0: declarator or ABSENT
641 * Child 1: constantExpression or ABSENT
642 */
643structDeclarator
644 : declarator
645 ( -> ^(STRUCT_DECLARATOR declarator ABSENT)
646 | COLON constantExpression
647 -> ^(STRUCT_DECLARATOR declarator constantExpression)
648 )
649 | COLON constantExpression
650 -> ^(STRUCT_DECLARATOR ABSENT constantExpression)
651 ;
652
653/* 6.7.2.2
654 * Root: ENUM
655 * Child 0: IDENTIFIER (tag) or ABSENT
656 * Child 1: enumeratorList
657 */
658enumSpecifier
659 : ENUM
660 ( IDENTIFIER
661 -> ^(ENUM IDENTIFIER ABSENT)
662 | IDENTIFIER LCURLY enumeratorList COMMA? RCURLY
663 -> ^(ENUM IDENTIFIER enumeratorList)
664 | LCURLY enumeratorList COMMA? RCURLY
665 -> ^(ENUM ABSENT enumeratorList)
666 )
667 ;
668
669/* 6.7.2.2
670 * Root: ENUMERATOR_LIST
671 * Children: enumerator
672 */
673enumeratorList
674 : enumerator (COMMA enumerator)*
675 -> ^(ENUMERATOR_LIST enumerator+)
676 ;
677
678/* 6.7.2.2
679 * Root: ENUMERATOR
680 * Child 0: IDENTIFIER
681 * Child 1: constantExpression or ABSENT
682 */
683enumerator
684 : IDENTIFIER
685 {
686 $Symbols::enumerationConstants.add($IDENTIFIER.text);
687 // System.err.println("define enum constant "+$IDENTIFIER.text);
688 }
689 ( -> ^(ENUMERATOR IDENTIFIER ABSENT)
690 | (ASSIGN constantExpression)
691 -> ^(ENUMERATOR IDENTIFIER constantExpression)
692 )
693 ;
694
695/* 6.7.2.4 */
696atomicTypeSpecifier
697 : ATOMIC LPAREN typeName RPAREN
698 -> ^(ATOMIC typeName)
699 ;
700
701/* 6.7.3 */
702typeQualifier
703 : CONST | RESTRICT | VOLATILE | ATOMIC
704 | INPUT | OUTPUT
705 ;
706
707/* 6.7.4 */
708functionSpecifier
709 : INLINE | NORETURN
710 ;
711
712/* 6.7.5
713 * Root: ALIGNAS
714 * Child 0: TYPE or EXPR
715 * Child 1: typeName (if Child 0 is TYPE) or constantExpression
716 * (if Child 0 is EXPR)
717 */
718alignmentSpecifier
719 : ALIGNAS LPAREN
720 ( typeName RPAREN
721 -> ^(ALIGNAS TYPE typeName)
722 | constantExpression RPAREN
723 -> ^(ALIGNAS EXPR constantExpression)
724 )
725 ;
726
727/* 6.7.6
728 * Root: DECLARATOR
729 * Child 0: pointer or ABSENT
730 * Child 1: directDeclarator
731 */
732declarator
733 : d=directDeclarator
734 -> ^(DECLARATOR ABSENT $d)
735 | pointer d=directDeclarator
736 -> ^(DECLARATOR pointer $d)
737 ;
738
739/* 6.7.6
740 * Root: DIRECT_DECLARATOR
741 * Child 0: directDeclaratorPrefix
742 * Children 1..: list of directDeclaratorSuffix (may be empty)
743 */
744directDeclarator
745 : p=directDeclaratorPrefix
746 ( -> ^(DIRECT_DECLARATOR $p)
747 | s+=directDeclaratorSuffix+ ->^(DIRECT_DECLARATOR $p $s+)
748 )
749 ;
750
751/*
752 * Tree: either an IDENTIFIER or a declarator.
753 */
754directDeclaratorPrefix
755 : IDENTIFIER
756 {
757 if ($DeclarationScope::isTypedef) {
758 $Symbols::types.add($IDENTIFIER.text);
759 //System.err.println("define type "+$IDENTIFIER.text);
760 }
761 }
762 | LPAREN! declarator RPAREN!
763 ;
764
765
766directDeclaratorSuffix
767 : directDeclaratorArraySuffix
768 | directDeclaratorFunctionSuffix
769 ;
770
771/*
772 * Root: ARRAY_SUFFIX
773 * child 0: LSQUARE (for source information)
774 * child 1: STATIC or ABSENT
775 * child 2: TYPE_QUALIFIER_LIST
776 * child 3: expression (array extent),
777 * "*" (unspecified variable length), or ABSENT
778 * child 4: RSQUARE (for source information)
779 */
780directDeclaratorArraySuffix
781 : LSQUARE
782 ( typeQualifierList_opt assignmentExpression_opt RSQUARE
783 -> ^(ARRAY_SUFFIX LSQUARE ABSENT typeQualifierList_opt
784 assignmentExpression_opt RSQUARE)
785 | STATIC typeQualifierList_opt assignmentExpression RSQUARE
786 -> ^(ARRAY_SUFFIX LSQUARE STATIC typeQualifierList_opt
787 assignmentExpression RSQUARE)
788 | typeQualifierList STATIC assignmentExpression RSQUARE
789 -> ^(ARRAY_SUFFIX LSQUARE STATIC typeQualifierList
790 assignmentExpression RSQUARE)
791 | typeQualifierList_opt STAR RSQUARE
792 -> ^(ARRAY_SUFFIX LSQUARE ABSENT typeQualifierList_opt
793 STAR RSQUARE)
794 )
795 ;
796
797/*
798 * Root: FUNCTION_SUFFIX
799 * child 0: LPAREN (for source information)
800 * child 1: either parameterTypeList or identifierList or ABSENT
801 * child 2: RPAREN (for source information)
802 */
803directDeclaratorFunctionSuffix
804 : LPAREN
805 ( parameterTypeList RPAREN
806 -> ^(FUNCTION_SUFFIX LPAREN parameterTypeList RPAREN)
807 | identifierList RPAREN
808 -> ^(FUNCTION_SUFFIX LPAREN identifierList RPAREN)
809 | RPAREN -> ^(FUNCTION_SUFFIX LPAREN ABSENT RPAREN)
810 )
811 ;
812
813/*
814 * Root: TYPE_QUALIFIER_LIST
815 * Children: typeQualifier
816 */
817typeQualifierList_opt
818 : typeQualifier* -> ^(TYPE_QUALIFIER_LIST typeQualifier*)
819 ;
820
821/*
822 * Tree: assignmentExpression or ABSENT
823 */
824assignmentExpression_opt
825 : -> ABSENT
826 | assignmentExpression
827 ;
828
829/* 6.7.6
830 * Root: POINTER
831 * chilren: STAR
832 */
833pointer
834 : pointer_part+ -> ^(POINTER pointer_part+)
835 ;
836
837/*
838 * Root: STAR
839 * child 0: TYPE_QUALIFIER_LIST
840 */
841pointer_part
842 : STAR typeQualifierList_opt -> ^(STAR typeQualifierList_opt)
843 ;
844
845/* 6.7.6
846 * Root: TYPE_QUALIFIER_LIST
847 * children: typeQualifier
848 */
849typeQualifierList
850 : typeQualifier+ -> ^(TYPE_QUALIFIER_LIST typeQualifier+)
851 ;
852
853/* 6.7.6
854 * Root: PARAMETER_TYPE_LIST
855 * child 0: parameterList (at least 1 parameter declaration)
856 * child 1: ELLIPSIS or ABSENT
857 *
858 * If the parameterTypeList occurs in a function prototype
859 * (that is not part of a function definition), it defines
860 * a new scope (a "function prototype scope"). If it occurs
861 * in a function definition, it does not define a new scope.
862 */
863
864parameterTypeList
865 : {$Symbols::isFunctionDefinition}? parameterTypeListWithoutScope
866 | parameterTypeListWithScope
867 ;
868
869parameterTypeListWithScope
870scope Symbols;
871@init {
872 $Symbols::types = new HashSet<String>();
873 $Symbols::enumerationConstants = new HashSet<String>();
874 $Symbols::isFunctionDefinition = false;
875}
876 : parameterTypeListWithoutScope
877 ;
878
879parameterTypeListWithoutScope
880 : parameterList
881 ( -> ^(PARAMETER_TYPE_LIST parameterList ABSENT)
882 | COMMA ELLIPSIS
883 -> ^(PARAMETER_TYPE_LIST parameterList ELLIPSIS)
884 )
885 ;
886
887/* 6.7.6
888 * Root: PARAMETER_LIST
889 * children: parameterDeclaration
890 */
891parameterList
892 : parameterDeclaration (COMMA parameterDeclaration)*
893 -> ^(PARAMETER_LIST parameterDeclaration+)
894 ;
895
896/* 6.7.6
897 * Root: PARAMETER_DECLARATION
898 * Child 0: declarationSpecifiers
899 * Child 1: declarator, or abstractDeclarator, or ABSENT
900 */
901parameterDeclaration
902scope DeclarationScope;
903@init {
904 $DeclarationScope::isTypedef = false;
905}
906 : declarationSpecifiers
907 ( -> ^(PARAMETER_DECLARATION declarationSpecifiers ABSENT)
908 | declaratorOrAbstractDeclarator
909 -> ^(PARAMETER_DECLARATION
910 declarationSpecifiers declaratorOrAbstractDeclarator)
911 )
912 ;
913
914
915// this has non-LL* decision due to recursive rule invocations
916// reachable from alts 1,2... E.g., both can start with pointer.
917
918declaratorOrAbstractDeclarator
919 : (declarator)=> declarator
920 | abstractDeclarator
921 ;
922
923
924/* 6.7.6
925 * Root: IDENTIFIER_LIST
926 * children: IDENTIFIER (at least 1)
927 */
928identifierList
929 : IDENTIFIER ( COMMA IDENTIFIER )*
930 -> ^(IDENTIFIER_LIST IDENTIFIER+)
931 ;
932
933/* 6.7.6. This is how a type is described without attaching
934 * it to an identifier.
935 * Root: TYPE_NAME
936 * child 0: specifierQualifierList
937 * child 1: abstractDeclarator or ABSENT
938 */
939typeName
940 : specifierQualifierList
941 ( -> ^(TYPE_NAME specifierQualifierList ABSENT)
942 | abstractDeclarator
943 -> ^(TYPE_NAME specifierQualifierList abstractDeclarator)
944 )
945 ;
946
947/* 6.7.7. Abstract declarators are like declarators without
948 * the IDENTIFIER.
949 *
950 * Root: ABSTRACT_DECLARATOR
951 * Child 0. pointer (may be ABSENT). Some number of *s with possible
952 * type qualifiers.
953 * Child 1. directAbstractDeclarator (may be ABSENT).
954 */
955abstractDeclarator
956 : pointer
957 -> ^(ABSTRACT_DECLARATOR pointer ABSENT)
958 | directAbstractDeclarator
959 -> ^(ABSTRACT_DECLARATOR ABSENT directAbstractDeclarator)
960 | pointer directAbstractDeclarator
961 -> ^(ABSTRACT_DECLARATOR pointer directAbstractDeclarator)
962 ;
963
964/* 6.7.7
965 *
966 * Root: DIRECT_ABSTRACT_DECLARATOR
967 * Child 0. abstract declarator or ABSENT.
968 * Children 1..: any number of direct abstract declarator suffixes
969 *
970 * Note that the difference between this and a directDeclarator
971 * is that Child 0 of a direct declarator would be either
972 * an IDENTIFIER or a declarator, but never ABSENT.
973 */
974directAbstractDeclarator
975 : LPAREN abstractDeclarator RPAREN directAbstractDeclaratorSuffix*
976 -> ^(DIRECT_ABSTRACT_DECLARATOR abstractDeclarator
977 directAbstractDeclaratorSuffix*)
978 | directAbstractDeclaratorSuffix+
979 -> ^(DIRECT_ABSTRACT_DECLARATOR ABSENT directAbstractDeclaratorSuffix+)
980 ;
981
982
983/* 6.7.8
984 * Root: TYPEDEF_NAME
985 * Child 0: IDENTIFIER
986 *
987 * Ambiguity: example:
988 * typedef int foo;
989 * typedef int foo;
990 *
991 * This is perfectly legal: you can define a typedef twice
992 * as long as both definitions are equivalent. However,
993 * the first definition causes foo to be entered into the type name
994 * table, so when parsing the second definition, foo is
995 * interpreted as a typedefName (a type specifier), and the
996 * declaration would have empty declarator. This is not
997 * what you want, so you have to forbid it somehow. I do this
998 * by requiring that if you are "in" a typedef, a typedef name
999 * cannot be immediately followed by a semicolon. This is sound
1000 * because the C11 Standard requires at least one declarator
1001 * to be present in a typedef.
1002 */
1003typedefName
1004 : {isTypeName(input.LT(1).getText())}? IDENTIFIER
1005 -> ^(TYPEDEF_NAME IDENTIFIER)
1006 ;
1007
1008/* 6.7.7
1009 * Two possibilities:
1010 *
1011 * Root: ARRAY_SUFFIX
1012 * Child 0: STATIC or ABSENT
1013 * Child 1: typeQualifierList or ABSENT
1014 * Child 2: expression or STAR or ABSENT
1015 *
1016 * Root: FUNCTION_SUFFIX
1017 * Child 0: parameterTypeList or ABSENT
1018 */
1019directAbstractDeclaratorSuffix
1020 : LSQUARE
1021 ( typeQualifierList_opt assignmentExpression_opt RSQUARE
1022 -> ^(ARRAY_SUFFIX ABSENT typeQualifierList_opt
1023 assignmentExpression_opt)
1024 | STATIC typeQualifierList_opt assignmentExpression RSQUARE
1025 -> ^(ARRAY_SUFFIX STATIC typeQualifierList_opt
1026 assignmentExpression)
1027 | typeQualifierList STATIC assignmentExpression RSQUARE
1028 -> ^(ARRAY_SUFFIX STATIC typeQualifierList assignmentExpression)
1029 | STAR RSQUARE
1030 -> ^(ARRAY_SUFFIX ABSENT ABSENT STAR)
1031 )
1032 | LPAREN
1033 ( parameterTypeList RPAREN
1034 -> ^(FUNCTION_SUFFIX parameterTypeList)
1035 | RPAREN
1036 -> ^(FUNCTION_SUFFIX ABSENT)
1037 )
1038 ;
1039
1040/* 6.7.9 */
1041initializer
1042 : assignmentExpression -> ^(SCALAR_INITIALIZER assignmentExpression)
1043 | LCURLY initializerList
1044 ( RCURLY
1045 | COMMA RCURLY
1046 )
1047 -> initializerList
1048 ;
1049
1050/* 6.7.9 */
1051initializerList
1052 : designatedInitializer (COMMA designatedInitializer)*
1053 -> ^(INITIALIZER_LIST designatedInitializer+)
1054 ;
1055
1056designatedInitializer
1057 : initializer
1058 -> ^(DESIGNATED_INITIALIZER ABSENT initializer)
1059 | designation initializer
1060 -> ^(DESIGNATED_INITIALIZER designation initializer)
1061 ;
1062
1063/* 6.7.9 */
1064designation
1065 : designatorList ASSIGN -> ^(DESIGNATION designatorList)
1066 ;
1067
1068/* 6.7.9 */
1069designatorList
1070 : designator+
1071 ;
1072
1073/* 6.7.9 */
1074designator
1075 : LSQUARE constantExpression RSQUARE
1076 -> ^(ARRAY_ELEMENT_DESIGNATOR constantExpression)
1077 | DOT IDENTIFIER
1078 -> ^(FIELD_DESIGNATOR IDENTIFIER)
1079 ;
1080
1081/* 6.7.10 */
1082staticAssertDeclaration
1083 : STATICASSERT LPAREN constantExpression COMMA STRING_LITERAL
1084 RPAREN SEMI
1085 -> ^(STATICASSERT constantExpression STRING_LITERAL)
1086 ;
1087
1088
1089/* ***** A.2.3: Statements ***** */
1090
1091/* 6.8 */
1092statement
1093 : labeledStatement
1094 | compoundStatement
1095 | expressionStatement
1096 | selectionStatement
1097 | iterationStatement
1098 | jumpStatement
1099 | pragma
1100 | assertStatement
1101 | assumeStatement
1102 | waitStatement
1103 | whenStatement
1104 | chooseStatement
1105 ;
1106
1107statementWithScope
1108scope Symbols;
1109@init {
1110 $Symbols::types = new HashSet<String>();
1111 $Symbols::enumerationConstants = new HashSet<String>();
1112 $Symbols::isFunctionDefinition = false;
1113}
1114 : statement
1115 ;
1116
1117/* 6.8.1
1118 * Three possible trees:
1119 *
1120 * Root: IDENTIFIER_LABELED_STATEMENT
1121 * Child 0: IDENTIFIER
1122 * Child 1: statement
1123 *
1124 * Root: CASE_LABELED_STATEMENT
1125 * Child 0: CASE
1126 * Child 1: constantExpression
1127 * Child 2: statement
1128 *
1129 * Root: DEFAULT_LABELED_STATEMENT
1130 * Child 0: DEFAULT
1131 * Child 1: statement
1132 */
1133labeledStatement
1134 : IDENTIFIER COLON statement
1135 -> ^(IDENTIFIER_LABELED_STATEMENT IDENTIFIER statement)
1136 | CASE constantExpression COLON statement
1137 -> ^(CASE_LABELED_STATEMENT CASE constantExpression statement)
1138 | DEFAULT COLON statement
1139 -> ^(DEFAULT_LABELED_STATEMENT DEFAULT statement)
1140 ;
1141
1142/* 6.8.2
1143 * Root: BLOCK
1144 * Child 0: LCURLY (for source information)
1145 * Child 1: blockItemList or ABSENT
1146 * Child 2: RCURLY (for source information)
1147 */
1148compoundStatement
1149scope Symbols;
1150@init {
1151 $Symbols::types = new HashSet<String>();
1152 $Symbols::enumerationConstants = new HashSet<String>();
1153 $Symbols::isFunctionDefinition = false;
1154}
1155 : LCURLY
1156 ( RCURLY
1157 -> ^(COMPOUND_STATEMENT LCURLY ABSENT RCURLY)
1158 | blockItemList RCURLY
1159 -> ^(COMPOUND_STATEMENT LCURLY blockItemList RCURLY)
1160 )
1161 ;
1162
1163/* 6.8.2 */
1164blockItemList
1165 : blockItem+ -> ^(BLOCK_ITEM_LIST blockItem+)
1166 ;
1167
1168/* 6.8.2 */
1169blockItem
[34760dc]1170 : (declarationSpecifiers declarator declarationList_opt LCURLY)=>
1171 functionDefinition
1172 | declaration
[d96fdd6d]1173 | statement
1174 ;
1175
1176/* 6.8.3
1177 * Root: EXPRESSION_STATEMENT
1178 * Child 0: expression or ABSENT
1179 * Child 1: SEMI (for source information)
1180 */
1181expressionStatement
1182 : expression SEMI -> ^(EXPRESSION_STATEMENT expression SEMI)
1183 | SEMI -> ^(EXPRESSION_STATEMENT ABSENT SEMI)
1184 ;
1185
1186/* 6.8.4
1187 * Two possible trees:
1188 *
1189 * Root: IF
1190 * Child 0: expression
1191 * Child 1: statement (true branch)
1192 * Child 2: statement or ABSENT (false branch)
1193 *
1194 * Root: SWITCH
1195 * Child 0: expression
1196 * Child 1: statement
1197 */
1198selectionStatement
1199scope Symbols;
1200@init {
1201 $Symbols::types = new HashSet<String>();
1202 $Symbols::enumerationConstants = new HashSet<String>();
1203 $Symbols::isFunctionDefinition = false;
1204}
1205 : IF LPAREN expression RPAREN s1=statementWithScope
1206 ( (ELSE)=> ELSE s2=statementWithScope
1207 -> ^(IF expression $s1 $s2)
1208 | -> ^(IF expression $s1 ABSENT)
1209 )
1210 | SWITCH LPAREN expression RPAREN s=statementWithScope
1211 -> ^(SWITCH expression $s)
1212 ;
1213
1214/* 6.8.5
1215 * Three possible trees:
1216 *
1217 * Root: WHILE
1218 * Child 0: expression
1219 * Child 1: statement
1220 *
1221 * Root: DO
1222 * Child 0: statement
1223 * Child 1: expression
1224 *
1225 * Root: FOR
1226 * Child 0: clause-1: declaration, expression, or ABSENT
1227 * (for loop initializer)
1228 * Child 1: expression or ABSENT (condition)
1229 * Child 2: expression or ABSENT (incrementer)
1230 * Child 3: statement (body)
1231 *
1232 */
1233iterationStatement
1234scope Symbols;
1235@init {
1236 $Symbols::types = new HashSet<String>();
1237 $Symbols::enumerationConstants = new HashSet<String>();
1238 $Symbols::isFunctionDefinition = false;
1239}
1240 : WHILE LPAREN expression RPAREN invariant_opt
1241 s=statementWithScope
1242 -> ^(WHILE expression $s invariant_opt)
1243 | DO s=statementWithScope WHILE LPAREN expression RPAREN
1244 invariant_opt SEMI
1245 -> ^(DO $s expression invariant_opt)
1246 | FOR LPAREN
1247 ( d=declaration e1=expression_opt SEMI e2=expression_opt
1248 RPAREN i=invariant_opt s=statementWithScope
1249 -> ^(FOR $d $e1 $e2 $s $i)
1250 | e0=expression_opt SEMI e1=expression_opt SEMI
1251 e2=expression_opt RPAREN s=statementWithScope
1252 -> ^(FOR $e0 $e1 $e2 $s $i)
1253 )
1254 ;
1255
1256expression_opt
1257 : expression
1258 | -> ABSENT
1259 ;
1260
1261invariant_opt
1262 : -> ABSENT
1263 | INVARIANT LPAREN expression RPAREN
1264 -> ^(INVARIANT expression)
1265 ;
1266
1267
1268/* 6.8.6
1269 * Four possible trees:
1270 *
1271 * Root: GOTO
1272 * Child 0: IDENTIFIER
1273 * Child 1: SEMI (for source information)
1274 *
1275 * Root: CONTINUE
1276 * Child 0: SEMI (for source information)
1277 *
1278 * Root: BREAK
1279 * Child 0: SEMI (for source information)
1280 *
1281 * Root: RETURN
1282 * Child 0: expression or ABSENT
1283 * Child 1: SEMI (for source information)
1284 */
1285jumpStatement
1286 : GOTO IDENTIFIER SEMI -> ^(GOTO IDENTIFIER SEMI)
1287 | CONTINUE SEMI -> ^(CONTINUE SEMI)
1288 | BREAK SEMI -> ^(BREAK SEMI)
1289 | RETURN expression_opt SEMI -> ^(RETURN expression_opt SEMI)
1290 ;
1291
1292/*
1293 * Root: PRAGMA
1294 * child 0: IDENTIFIER (first token following # pragma)
1295 * child 1: TOKEN_LIST (chilren are list of tokens following identifier)
1296 * child 2: NEWLINE (character which ends the pragma)
1297 */
1298pragma : PRAGMA IDENTIFIER pragmaBody NEWLINE
1299 -> ^(PRAGMA IDENTIFIER ^(TOKEN_LIST pragmaBody) NEWLINE)
1300 ;
1301
1302pragmaBody
1303 : (~ NEWLINE)*
1304 ;
1305
1306assertStatement
1307 : ASSERT expression SEMI -> ^(ASSERT expression)
1308 ;
1309
1310assumeStatement
1311 : ASSUME expression SEMI -> ^(ASSUME expression)
1312 ;
1313
1314waitStatement
1315 : WAIT expression SEMI -> ^(WAIT expression)
1316 ;
1317
1318whenStatement
1319 : WHEN LPAREN expression RPAREN statement
1320 -> ^(WHEN expression statement)
1321 ;
1322
1323chooseStatement
1324 : CHOOSE LCURLY statement+ RCURLY
1325 -> ^(CHOOSE statement+)
1326 ;
1327
1328/* ***** A.2.4: External Definitions ***** */
1329
1330/* 6.9
1331 * Root: TRANSLATION_UNIT
1332 * Children: externalDeclaration
1333 */
1334translationUnit
1335scope Symbols; // the global scope
1336scope DeclarationScope; // just to have an outermost one with isTypedef false
1337@init {
1338 $Symbols::types = new HashSet<String>();
1339 $Symbols::enumerationConstants = new HashSet<String>();
1340 $Symbols::isFunctionDefinition = false;
1341 $DeclarationScope::isTypedef = false;
1342}
1343 : externalDeclaration* EOF
1344 -> ^(TRANSLATION_UNIT externalDeclaration*)
1345 ;
1346
1347/* 6.9
1348 * Need to look ahead to distinguish function definition from
1349 * a declaration. As soon as you see the "{", you know you
1350 * are in a function definition.
1351 */
1352externalDeclaration
[59b5362]1353 : (declarationSpecifiers declarator
1354 contract_opt declarationList_opt LCURLY)=>
[d96fdd6d]1355 functionDefinition
1356 | declaration
1357 | pragma
1358 ;
1359
1360/* 6.9.1 */
1361functionDefinition
1362scope Symbols; // "function scope"
1363@init {
1364 $Symbols::types = new HashSet<String>();
1365 $Symbols::enumerationConstants = new HashSet<String>();
1366 $Symbols::isFunctionDefinition = true;
1367}
[59b5362]1368 : declarationSpecifiers declarator contract_opt
[d96fdd6d]1369 declarationList_opt compoundStatement
1370 -> ^(FUNCTION_DEFINITION declarationSpecifiers declarator
[59b5362]1371 declarationList_opt compoundStatement contract_opt)
[d96fdd6d]1372 ;
1373
1374
1375/* 6.9.1
1376 * Root: DECLARATION_LIST
1377 * Children: declaration (any number)
1378 */
1379declarationList_opt
1380 : declaration* -> ^(DECLARATION_LIST declaration*)
1381 ;
[59b5362]1382
1383contractItem
1384 : REQUIRES expression SEMI -> ^(REQUIRES expression)
1385 | ENSURES expression SEMI -> ^(ENSURES expression)
1386 ;
1387
1388contract_opt
1389 : contractItem* -> ^(CONTRACT contractItem*)
1390 ;
Note: See TracBrowser for help on using the repository browser.