In the following, ISO/IEC 14977:1996 Information technology -- Syntactic metalanguage -- Extended BNF is used to define the EBNF syntax for expressing the xcpj file grammar. The grammar is presented in bottom up order (i.e. there is a tendency to define non-terminals before they are referenced)
Let stringLiteral stand for a double quoted string literal and intLiteral for an integer literal.
targetType =
'"Application"' |
'"Static Library"' |
'"Console Application"' |
'"Dynamic-Link Library"' |
'"Utility Project"';
compilerName =
'"vc6"' | '"vc8"' | '"vc9"';
(* E.g. "Debug" *)
configName = stringLiteral;
(* E.g. "Win32" *)
platformName = stringLiteral;
(* E.g. "Debug|Win32" *)
configAndPlatform = stringLiteral;
(* E.g. "WinCE" *)
tagName = stringLiteral;
(* E.g. "Debug|Win32" ["Unicode"] *)
singleConfigDef =
configAndPlatform,
[
'[', {tagName}, ']'
];
configsDef =
'config',
'{',
{ singleConfigDef },
'}';
(* E.g. "Debug|WinCE|vc8"
Each string between the | must be either a
tagName, configName, platformName,
compilerName or targetType
*)
configRef = stringLiteral;
(* E.g. ("Debug|WinCE|vc8", "Win32") *)
configRefList =
'(',
[configRef, { ',', configRef } ],
')';
cppBoolSwitch1 =
'/GR' | '/GL' | '/GS' | '/Gy' | '/fp:except';
cppBoolSwitch2 =
'/nologo' | '/Oi' | '/Op' | '/Oy' | '/GT' |
'/X' | '/C' | '/GF' | '/Gm' | '/RTCc' |
'/Za' | '/J' | '/openmp' | '/Fx' | '/doc' |
'/WX' | '/Wp64' | '/showIncludes' | '/u' |
'/FC' | '/Zl' | '/Zc:wchar_t' |
'/Zc:forScope' | '/QRinterwork' | '/QRfpe';
cppEnumSwitch =
'/Od' | '/O1' | '/O2' | '/Ox' |
'/Ob1' | '/Ob2' |
'/Ot' | '/Os' |
'/EHsc' | '/EHa' | '/GX' |
'/RTCs' | '/RTCu' | '/RTC1' | '/RTCsu' |
'/GZ' |
'/MT' | '/MTd' | '/MD' | '/MDd' |
'/Zp1' | '/Zp2' | '/Zp4' | '/Zp8' | '/Zp16' |
'/QRarch4' | '/QRarch5' | '/QRarch4t' |
'/QRarch5t' |
'/TC' | '/TP' |
'/arch:SSE' | '/arch:SSE2' |
'/fp:precise' | '/fp:strict' | '/fp:fast' |
'/FA' | '/FAcs' | '/FAc' | '/FAs' |
'/FR' | '/Fr' |
'/W0' | '/W1' | '/W2' | '/W3' | '/W4' |
'/Z7' | '/Zi' | '/ZI' |
'/Gd' | '/Gr' | '/Gz' |
'/errorReport:prompt' |
'/errorReport:queue' |
'/clr' | '/clr:pure' | '/clr:safe' |
'/clr:noAssembly' | '/clr:oldSyntax';
cppStrArgSwitch =
'/Fd' | '/Fe' | '/Fo' | '/Fp' | '/FR';
cppListStrArgSwitch =
'/I' | '/D' | '/FI' | '/FU' | '/U';
cppPchSwitch =
'/Yc' | '/Yu' | '/YX';
cppCompilerSwitch =
cppBoolSwitch1, ['-'] |
cppBoolSwitch2 |
cppEnumSwitch |
cppStrArgSwitch, stringLiteral |
cppListStrArgSwitch, stringLiteral |
cppPchSwitch [stringLiteral];
rcBoolSwitch =
'/x' | '/v';
rcStrArgSwitch =
'/fo';
rcListStrArgSwitch =
'/I' | '/d' | '/u';
rcCompilerSwitch =
rcBoolSwitch |
rcStrArgSwitch, stringLiteral |
rcListStrArgSwitch, stringLiteral;
linkBoolSwitch =
'/NOLOGO' | '/NOENTRY' | '/IGNOREIDL' |
'/NOASSEMBLY' | '/DELAY:UNLOAD' | '/RELEASE' |
'/DEBUG' | '/SWAPRUN:CD' | '/SWAPRUN:NET' |
'/PROFILE' | '/MAPINFO:EXPORTS' | '/MAP' |
'/NODEFAULTLIB' | '/DELAYSIGN' |
'/CLRUNMANAGEDCODECHECK';
machine =
'X86' | 'IX86' | 'I386' | 'AM33' |
'ARM' | 'EBC' | 'IA64' | 'M32R' |
'MIPS' | 'MIPS16' | 'MIPSFPU' |
'MIPSFPU16' | 'MIPSR41XX' | 'SH3' |
'SH3DSP' | 'SH4' | 'SH5' | 'THUMB' |
'X64';
subsystem =
'CONSOLE' | 'WINDOWS' |
'NATIVE' | 'EFI_APPLICATION' |
'EFI_BOOT_SERVICE_DRIVER' |
'EFI_ROM' | 'EFI_RUNTIME_DRIVER' |
'POSIX' | 'WINDOWSCE';
opt =
'NOREF' | 'REF' | 'NOICF' | 'ICF' |
'NOWIN98' | 'WIN98';
linkEnumSwitch =
'/MACHINE:', machine |
'/SUBSYSTEM:', subsystem |
'/OPT:', opt |
'/DRIVER', [':UPONLY' | ':WDM'] |
'/ASSEMBLYDEBUG', [':DISABLE'] |
'/INCREMENTAL', [':NO'] |
'/MANIFEST', [':NO'] |
'/FIXED', [':NO'] |
'/TSAWARE', [':NO'] |
'/LARGEADDRESSAWARE', [':NO'] |
'/LTCG', [':PGINSTRUMENT' | ':PGOPTIMIZE' | ':PGUPDATE'] |
'/VERBOSE', [':LIB'] |
'/ALLOWISOLATION:NO' |
'/CLRTHREADATTRIBUTE:', ('MTA' | 'STA') |
'/CLRIMAGETYPE:', ('IJW' | 'PURE' | 'SAFE') |
'/ERRORREPORT:', ('NONE' | 'PROMPT' | 'QUEUE');
linkStrArgSwitch =
'/DEF' | '/BASE' | '/ENTRY' | '/IDLOUT' |
'/TLBOUT' | '/TLBID' | '/PGD' | '/ORDER' |
'/MANIFESTFILE' | '/OUT' | '/VERSION' |
'/IMPLIB' | '/PDB' | '/PDBSTRIPPED' |
'/MIDL' | '/KEYFILE' | '/KEYCONTAINER' |
'/MAP';
linkListStrArgSwitch =
'/MANIFESTDEPENDENCY' |
'/ASSEMBLYMODULE' | '/ASSEMBLYRESOURCE' |
'/ASSEMBLYLINKRESOURCE' |
'/INCLUDE' | '/DELAYLOAD' |
'/NODEFAULTLIB' | '/LIBPATH';
reserve = intLiteral;
commit = intLiteral;
libraryName = stringLiteral;
linkSwitch =
linkBoolSwitch |
linkEnumSwitch |
linkStrArgSwitch, ':', stringLiteral |
linkListStrArgSwitch, ':', stringLiteral |
('/HEAP:' | '/STACK'), reserve, [',', commit] |
libraryName;
This part of the grammar concerns the incremental addition or removal of compiler or linker switches, either to all configurations or else to specified configurations.
cppSpec =
('+' | '-'),
'cpp',
[ configRefList ],
'{',
{ cppCompilerSwitch },
'}';
rcSpec =
('+' | '-'),
'rc',
[ configRefList ],
'{',
{ rcCompilerSwitch },
'}';
linkSpec =
('+' | '-'),
'link',
[ configRefList ],
'{',
{ linkSwitch },
'}';
This is the relevant part of the grammar involved with specifying the files that comprise the project. It supports nested directories, wild cards, recursion, flattening, renaming.
pattern = stringLiteral;
directoryName = stringLiteral;
folderName = stringLiteral;
(* E.g. +["*.cpp" "*.h"] *)
nameFilter =
['-' | '+'],
pattern | '[', {pattern}, ']';
(* E.g. directories -[] *)
directoriesFilterDef =
'directories', nameFilter;
(* E.g. +cpp{/O1} *)
fileOpt =
'exclude' |
cppSpec |
rcSpec;
(* E.g. "*.cpp" flat * : +cpp{/D "BLAH"} *)
filesSpec =
nameFilter,
[ ['flat'], '*' ],
[ ':', fileOpt, {',', fileOpt} ];
dirElement =
filesSpec |
directoryName, ['as', folderName],
directoryStructure;
directoryStructure =
'{', {dirElement}, '}';
varName = identifier;
varValue = stringLiteral;
path = stringLiteral;
logicalPathToProjDir = path;
subProjSpec =
'subproj',
'{',
{ logicalPathToProjDir },
'}';
toolFilesSpec =
'toolFiles',
'{',
{ path },
'}';
description = stringLiteral;
command = stringLiteral;
eventSpec =
('prebuildevent' | 'prelinkevent' |
'postbuildevent'),
[ configRefList ],
'{',
description,
command,
'}';
genKey =
'OutputDirectory' |
'IntermediateDirectory' |
'DeleteExtensionsOnClean' |
'BuildLogFile' |
'InheritedPropertySheets' |
'ConfigurationType' |
'UseOfMFC' |
'UseOfATL' |
'ATLMinimizesCRunTimeLibraryUsage' |
'CharacterSet' |
'ManagedExtensions' |
'WholeProgramOptimization';
genSettingsSpec =
'general',
[ configRefList ],
'{',
{ genKey, '=', stringLiteral },
'}';
xcpjElement =
'xcpp' |
'export' |
'$', varName, '=', varValue |
'@import', path |
cppSpec |
rcSpec
LinkSpec
subProjSpec |
configsDef |
directoriesFilterDef |
toolFilesSpec |
eventSpec;
xcpjFile =
'$TARGET_TYPE', '=', targetType,
'$ROOT_TO_PROJDIR', '=', logicalPathToProjDir,
{ xcpjElement },
directoryStructure;