Persistence 2.0

This is a revised version of the old parser persistence format.

Symbols

Symbols reside in a common preprocessor table (Symbols), and in high level symbol scopes (Globals, Statics, modules, procedures).

The symbols in the preprocessor table can have several meanings, at the same time:
Directives, pragmas and keywords are implemented as appropriate to a source language.
Macros and symbols are added from the actual source code; only these symbols occur in meta-files.

Macros (#define) can be classified further into: The preprocessor expands all default and dummy macros, so that no macro names occur in the meta-code, unless they are marked for special treatment (by the user). The default macros occur in meta files, so that the user can assign more appropriate types to each macro, for use in the next run of the parser.

Meta files come in two flavours, either as module files <module>.txt, or as project files <prj>.txt.
Module files contain all symbols which are defined in the according module (*.c).
All other symbols, i.e. macros and undefined symbols, go into the project file.

Every symbol is stored as one or multiple lines. Macros are stored as found in the source files, i.e. all but the last line end with a backslash. Defined procedure symbols always are stored in multiple lines, the last line contains a single semicolon ";". Other symbols can be broken on a special character (currently ";"), when the lines are longer than allowed in the Delphi IDE.

The first character in a non-continuation line indicates the symbol type:

TypeSym ::= "t" (StructType | SimpleType) .
SimpleType ::= ident "=" Type .

StructType ::= ("E"|"S"|"U") ":" (ident|#) "=" "{" { Field ";" } "}" .
//everything to the left of "=" is part of the typename!
    Field ::= [ident] ":" [Bitfield] Type ["=" Expression] .
    Bitfield ::= "{" Value "}" .
ProcSym ::= "p" ident ":" [Scope] ProcType [Block] [";"] .
    ProcType ::= "(" {Param ";"} [":~;"] ")" [Call] [Type] .
    Param ::= [ident]":"[Ref][Type][Values] .
    Ref ::= "@"|"&"|"#"|"?" .    //var,ref,const,out - default: value
VarConstSym ::= ("v"|"c"|"e") [Scope] ident ":" Type [Values] .
//LabSym ::= "L" ident .
MacroSym ::= ("#"|"M"...) ident [ "(" { Ident"," } ")" ] [Body] .

Type ::= Qualified | Array | Pointer | StructUnion | Enum | Typename | Basetype .
    Qualified ::= ["#"|"V"] Type . //Const/Volatile
    Array ::= "[" ExprList "]" Type .
    Pointer ::= "*" Type .
    StructUnion ::= ("S"|"U"|"I") (":"(ident|#) | "{" { Field "," } "}") .
    Enum ::= "E" (":"(ident|#) | "{" { ident [Value] "," } "}") .
    Typename ::= '"' ident '"' .
    Basetype ::= ["+"|"-"] (num|"v"|"c"|"s"|"i"|"l"|"L"|"f"|"d"|"D"|"~") .
Value ::= (num|string|char|ident|[op]"(" ExprList ")" | ":" Type "=" Value) .
//op is any C operator.
ExprList ::= { Value "," } .
Values ::= "=" Value .
Block ::= "{(" { (Value|stmt) ";"} "}" .

Possibly expression lists should be enclosed in "[...]"?
-> Intentionally ambigous with array type!
-> Separate by "=" from preceding type.
Otherwise "[" could be used as array-index operator!
Blocks (with declarations and statements) instead are enclosed in "{...}".