preprocessor
preprocessor copied to clipboard
Simple C Preprocessor
Simple C-lang Preprocessor
This implementation of a preprocessor based in part on ISO/IEC 9899:TC2.
Requirements
- PHP >= 7.4
Installation
Library is available as composer repository and can be installed using the following command in a root of your project.
$ composer require ffi/preprocessor
Usage
use FFI\Preprocessor\Preprocessor;
$pre = new Preprocessor();
echo $pre->process('
#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object;
#if !defined(VK_DEFINE_NON_DISPATCHABLE_HANDLE)
#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object;
#else
#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object;
#endif
#endif
VK_DEFINE_HANDLE(VkInstance)
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSemaphore)
');
//
// Expected Output:
//
// typedef struct VkInstance_T* VkInstance;
// typedef uint64_t VkSemaphore;
//
Directives
Supported Directives
- [x]
#include "file.h"local-first include - [x]
#include <file.h>global-first include - [x]
#define namedefining directives- [x]
#define name valueobject-like macro - [x]
#define name(arg) valuefunction-like macro - [x]
#define name(arg) xxx##argconcatenation - [x]
#define name(arg) #argstringizing
- [x]
- [x]
#undef nameremoving directives - [x]
#ifdef name"if directive defined" condition - [x]
#ifndef name"if directive not defined" condition - [x]
#if EXPRESSIONif condition - [x]
#elif EXPRESSIONelse if condition - [x]
#elseelse condition - [x]
#endifcompletion of a condition - [x]
#error messageerror message directive - [x]
#warning messagewarning message directive - [ ]
#line 66 "filename"line and file override - [ ]
#pragma XXXcompiler control- [ ]
#pragma once
- [ ]
- [ ]
#assert XXXcompiler assertion- [ ]
#unassert XXXcompiler assertion
- [ ]
- [ ]
#ident XXX- [ ]
#sccs XXX
- [ ]
Expression Grammar
Comparison Operators
- [x]
A > Bgreater than - [x]
A < Bless than - [x]
A == Bequal - [x]
A != Bnot equal - [x]
A >= Bgreater than or equal - [x]
A <= Bless than or equal
Logical Operators
- [x]
! Alogical NOT - [x]
A && Bconjunction - [x]
A || Bdisjunction - [x]
(...)grouping
Arithmetic Operators
- [x]
A + Bmath addition - [x]
A - Bmath subtraction - [x]
A * Bmath multiplication - [x]
A / Bmath division - [x]
A % Bmodulo - [ ]
A++increment- [x]
++Aprefix form
- [x]
- [ ]
A--decrement- [x]
--Aprefix form
- [x]
- [x]
+Aunary plus - [x]
-Aunary minus - [ ]
&Aunary addr - [ ]
*Aunary pointer
Bitwise Operators
- [x]
~Abitwise NOT - [x]
A & Bbitwise AND - [x]
A | Bbitwise OR - [x]
A ^ Bbitwise XOR - [x]
A << Bbitwise left shift - [x]
A >> Bbitwise right shift
Other Operators
- [x]
defined(X)defined macro - [ ]
A ? B : Cternary - [ ]
sizeof VALUEsizeof- [ ]
sizeof(TYPE)sizeof type
- [ ]
Literals
- [x]
true,falseboolean - [x]
42decimal integer literal- [x]
42u,42Uunsigned int - [x]
42l,42Llong int - [x]
42ul,42ULunsigned long int - [x]
42ll,42LLlong long int - [x]
42ull,42ULLunsigned long long int
- [x]
- [x]
042octal integer literal - [x]
0x42hexadecimal integer literal - [x]
0b42binary integer literal - [x]
"string"string (char array)- [x]
L"string"string (wide char array) - [x]
"\•"escape sequences in strings - [ ]
"\•••"arbitrary octal value in strings - [ ]
"\X••"arbitrary hexadecimal value in strings
- [x]
- [ ]
'x'char literal- [ ]
'\•'escape sequences - [ ]
'\•••'arbitrary octal value - [ ]
'\X••'arbitrary hexadecimal value - [ ]
L'x'wide character literal
- [ ]
- [ ]
42.0double- [ ]
42f,42Ffloat - [ ]
42l,42Llong double - [ ]
42Eexponential form - [ ]
0.42e23exponential form
- [ ]
- [ ]
NULLnull macro
Type Casting
- [x]
(char)42 - [x]
(short)42 - [x]
(int)42 - [x]
(long)42 - [x]
(float)42 - [x]
(double)42 - [x]
(bool)42(Out of ISO/IEC 9899:TC2 specification) - [x]
(string)42(Out of ISO/IEC 9899:TC2 specification) - [ ]
(void)42 - [ ]
(long type)42Casting to a long type (long int,long double, etc) - [ ]
(const type)42Casting to a constant type (const char, etc) - [ ]
(unsigned type)42Casting to unsigned type (unsigned int,unsigned long, etc) - [ ]
(signed type)42Casting to signed type (signed int,signed long, etc) - [ ] Pointers (
void *, etc) - [ ] References (
unsigned int,unsigned long, etc)
Object Like Directive
use FFI\Preprocessor\Preprocessor;
use FFI\Preprocessor\Directive\ObjectLikeDirective;
$pre = new Preprocessor();
// #define A
$pre->define('A');
// #define B 42
$pre->define('B', '42');
// #define С 42
$pre->define('С', new ObjectLikeDirective('42'));
Function Like Directive
use FFI\Preprocessor\Preprocessor;
use FFI\Preprocessor\Directive\FunctionLikeDirective;
$pre = new Preprocessor();
// #define C(object) object##_T* object;
$pre->define('C', function (string $arg) {
return "${arg}_T* ${arg};";
});
// #define D(object) object##_T* object;
$pre->define('D', new FunctionLikeDirective(['object'], 'object##_T* object'));
Include Directories
use FFI\Preprocessor\Preprocessor;
$pre = new Preprocessor();
$pre->include('/path/to/directory');
$pre->exclude('some');
Message Handling
use FFI\Preprocessor\Preprocessor;
$logger = new Psr3LoggerImplementation();
$pre = new Preprocessor($logger);
$pre->process('
#error Error message
// Will be sent to the logger:
// - LoggerInterface::error("Error message")
#warning Warning message
// Will be sent to the logger:
// - LoggerInterface::warning("Warning message")
');