home *** CD-ROM | disk | FTP | other *** search
/ cs.rhul.ac.uk / www.cs.rhul.ac.uk.zip / www.cs.rhul.ac.uk / pub / rdp / rdp_cs3460.tar / pretty_c.bnf < prev    next >
Text File  |  1998-05-07  |  5KB  |  103 lines

  1. (*******************************************************************************
  2. *
  3. * RDP release 1.50 by Adrian Johnstone (A.Johnstone@rhbnc.ac.uk) 20 December 1997
  4. *
  5. * pretty_c.bnf - a pretty printer for ANSI C
  6. *
  7. * This file may be freely distributed. Please mail improvements to the author.
  8. *
  9. * This grammar illustrates a rather different approach to writing language
  10. * parsers. Instead of trying to exactly define the language with the
  11. * grammar we try and find a simple grammar that accepts the language, and
  12. * also allow it to accept lots of incorrect strings. The rationale is that
  13. * a pretty printer does not need to check a program for syntax errors
  14. * because a conventional compiler will be used subsequently to do that.
  15. * As a result we end up with a very flat, loose grammar
  16. *
  17. *******************************************************************************)
  18. TITLE("C pretty printer V1.50 (c) Adrian Johnstone 1997")
  19. SUFFIX("c")
  20. PARSER(program)
  21. OUTPUT_FILE("pretty.c")
  22. TEXT_SIZE(100_000)
  23. USES("pr_c_aux.h")
  24.  
  25. ARG_NUMERIC(i indent_size "Number of spaces per indent level: 0 means use tabs (default 2)")
  26. ARG_NUMERIC(c comment_start "Preferred start column for trailing comments (default 30)")
  27.  
  28. program ::= [* enum kinds kind;
  29.                long unsigned line, column;
  30.                pretty_open(rdp_sourcefilename, rdp_outputfilename);
  31.             *]
  32.             {
  33.               [* line = scan_line_number(); column = scan_column_number(); *]
  34.               (
  35.                 comment: lexeme        [* kind = K_COMMENT;        *] |
  36.                 string: lexeme         [* kind = K_STRING;         *] |
  37.                 character: lexeme      [* kind = K_CHARACTER;      *] |
  38.                 block_open: lexeme     [* kind = K_BLOCK_OPEN;     *] |
  39.                 block_close: lexeme    [* kind = K_BLOCK_CLOSE;    *] |
  40.                 preprocessor: lexeme   [* kind = K_PREPROCESSOR;   *] |
  41.                 monadic: lexeme        [* kind = K_MONADIC;        *] |
  42.                 diadic: lexeme         [* kind = K_DIADIC;         *] |
  43.                 open_bracket: lexeme   [* kind = K_OPEN_BRACKET;   *] |
  44.                 close_bracket: lexeme  [* kind = K_CLOSE_BRACKET;  *] |
  45.                 item: lexeme           [* kind = K_ITEM;           *] |
  46.                 field_delim: lexeme    [* kind = K_FIELD_DELIM;    *] |
  47.                 punctuation: lexeme    [* kind = K_PUNCTUATION;    *] |
  48.                 keyword: lexeme        [* kind = K_KEYWORD;        *] |
  49.                 keyword_indent: lexeme [* kind = K_KEYWORD_INDENT; *] |
  50.                 EOLN: lexeme           [* kind = K_EOLN;           *]
  51.               )
  52.               [* pretty_print(lexeme, kind, column, line); *]
  53.             }
  54.             [* pretty_close(rdp_sourcefilename, rdp_outputfilename); *].
  55.  
  56. comment: char* ::= COMMENT_VISIBLE('/*' '*/'):result.
  57.  
  58. preprocessor: char* ::= COMMENT_LINE_VISIBLE('#'):result.
  59.  
  60. monadic: char* ::= '!':result | '++':result | '--':result | '~':result .
  61.  
  62. diadic: char* ::= '&&':result | '&':result | '^':result | '|':result |
  63.                   '||':result | '%':result | '*':result | '/':result |
  64.                   '+':result | '-':result | '<<':result | '>>':result |
  65.                   '<':result | '<=':result | '==':result | '>':result |
  66.                   '>=':result | '?':result | '!=':result | '%=':result |
  67.                   '&=':result | '*=':result | '+=':result | '-=':result |
  68.                   '/=':result | '=':result | '^=':result | '|=':result |
  69.                   '<<=':result | '>>=':result | '\\':result.
  70.  
  71. block_open: char* ::= '{':result.
  72.  
  73. block_close: char* ::= '}':result.
  74.  
  75. open_bracket: char* ::= '(':result | '[':result.
  76.  
  77. close_bracket: char* ::= ')':result | ']':result.
  78.  
  79. item: char* ::= ([* result = SCAN_CAST->id; *] (INTEGER | REAL)) |
  80.                 ID:result | '...':result .
  81.  
  82. string: char* ::= STRING_ESC('"''\\'):result.
  83.  
  84. character:char* ::= STRING_ESC('\'''\\'): result.
  85.  
  86. field_delim: char* ::= '->':result | '.':result.
  87.  
  88. punctuation: char* ::= ':':result | ';':result | ',': result.
  89.  
  90. keyword: char* ::= 'auto':result | 'break':result | 'case':result |
  91.                    'char':result | 'const':result | 'continue':result |
  92.                    'default':result | 'double':result | 'enum':result |
  93.                    'extern':result | 'float':result | 'goto':result |
  94.                    'int':result | 'long':result | 'register':result |
  95.                    'return':result | 'short':result | 'signed':result |
  96.                    'sizeof':result | 'static':result | 'struct':result |
  97.                    'union':result | 'unsigned':result | 'void':result |
  98.                    'volatile':result.
  99.  
  100. keyword_indent: char* ::= 'do':result | 'else':result | 'for':result |
  101.                           'if':result | 'switch':result | 'while':result.
  102.  
  103.