Aller au contenu

Grammaire C¤

Yacc (Yet Another COmpiler-Compiler) est un logiciel utilisé pour écrire des analyseurs syntaxiques de code. Il prend en entrée une grammaire.

Parce que les informaticiens ont de l'humour, Yacc à son pendant GNU Bison plus récent (1985) mais toujours activement développé.

Voici à titre d'information la définition formelle du langage C99 :

%{
#include "ast.h"
#include <stdio.h>
void yyerror(const char *s);
int yylex(void);
extern int yylineno;
ASTNode *root;
%}

%token IDENTIFIER I_CONSTANT F_CONSTANT STRING_LITERAL FUNC_NAME SIZEOF
%token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
%token AND_OP OR_OP MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
%token SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
%token XOR_ASSIGN OR_ASSIGN
%token TYPEDEF_NAME ENUMERATION_CONSTANT

%token TYPEDEF EXTERN STATIC AUTO REGISTER INLINE
%token CONST RESTRICT VOLATILE
%token BOOL CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE VOID
%token COMPLEX IMAGINARY
%token STRUCT UNION ENUM ELLIPSIS

%token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN

%token ALIGNAS ALIGNOF ATOMIC GENERIC NORETURN STATIC_ASSERT THREAD_LOCAL

%start translation_unit
%%

primary_expression
    : IDENTIFIER {
        $$ = create_identifier_node($1);
    }
    | constant {
        $$ = $1;
    }
    | string {
        $$ = $1;
    }
    | '(' expression ')' {
        $$ = $2;
    }
    | generic_selection {
        $$ = $1;
    }
    ;

constant
    : I_CONSTANT {
        $$ = create_constant_node($1);
    }
    | F_CONSTANT {
        $$ = create_constant_node($1);
    }
    | ENUMERATION_CONSTANT {
        $$ = create_identifier_node($1);
    }
    ;

string
    : STRING_LITERAL {
        $$ = create_string_node($1);
    }
    | FUNC_NAME {
        $$ = create_string_node($1);
    }
    ;

generic_selection
    : GENERIC '(' assignment_expression ',' generic_assoc_list ')' {
        // Créez le nœud correspondant
    }
    ;

generic_assoc_list
    : generic_association
    | generic_assoc_list ',' generic_association
    ;

generic_association
    : type_name ':' assignment_expression
    | DEFAULT ':' assignment_expression
    ;

postfix_expression
    : primary_expression {
        $$ = $1;
    }
    | postfix_expression '[' expression ']' {
        // Créez le nœud correspondant
    }
    | postfix_expression '(' ')' {
        // Créez le nœud correspondant
    }
    | postfix_expression '(' argument_expression_list ')' {
        // Créez le nœud correspondant
    }
    | postfix_expression '.' IDENTIFIER {
        // Créez le nœud correspondant
    }
    | postfix_expression PTR_OP IDENTIFIER {
        // Créez le nœud correspondant
    }
    | postfix_expression INC_OP {
        $$ = create_unary_op_node(INC_OP, $1);
    }
    | postfix_expression DEC_OP {
        $$ = create_unary_op_node(DEC_OP, $1);
    }
    | '(' type_name ')' '{' initializer_list '}' {
        // Créez le nœud correspondant
    }
    | '(' type_name ')' '{' initializer_list ',' '}' {
        // Créez le nœud correspondant
    }
    ;

argument_expression_list
    : assignment_expression {
        // Créez le nœud correspondant
    }
    | argument_expression_list ',' assignment_expression {
        // Créez le nœud correspondant
    }
    ;

unary_expression
    : postfix_expression {
        $$ = $1;
    }
    | INC_OP unary_expression {
        $$ = create_unary_op_node(INC_OP, $2);
    }
    | DEC_OP unary_expression {
        $$ = create_unary_op_node(DEC_OP, $2);
    }
    | unary_operator cast_expression {
        $$ = create_unary_op_node($1, $2);
    }
    | SIZEOF unary_expression {
        // Créez le nœud correspondant
    }
    | SIZEOF '(' type_name ')' {
        // Créez le nœud correspondant
    }
    | ALIGNOF '(' type_name ')' {
        // Créez le nœud correspondant
    }
    ;

unary_operator
    : '&' {
        $$ = '&';
    }
    | '*' {
        $$ = '*';
    }
    | '+' {
        $$ = '+';
    }
    | '-' {
        $$ = '-';
    }
    | '~' {
        $$ = '~';
    }
    | '!' {
        $$ = '!';
    }
    ;

cast_expression
    : unary_expression {
        $$ = $1;
    }
    | '(' type_name ')' cast_expression {
        // Créez le nœud correspondant
    }
    ;

multiplicative_expression
    : cast_expression {
        $$ = $1;
    }
    | multiplicative_expression '*' cast_expression {
        $$ = create_binary_op_node('*', $1, $3);
    }
    | multiplicative_expression '/' cast_expression {
        $$ = create_binary_op_node('/', $1, $3);
    }
    | multiplicative_expression '%' cast_expression {
        $$ = create_binary_op_node('%', $1, $3);
    }
    ;

additive_expression
    : multiplicative_expression {
        $$ = $1;
    }
    | additive_expression '+' multiplicative_expression {
        $$ = create_binary_op_node('+', $1, $3);
    }
    | additive_expression '-' multiplicative_expression {
        $$ = create_binary_op_node('-', $1, $3);
    }
    ;

shift_expression
    : additive_expression {
        $$ = $1;
    }
    | shift_expression LEFT_OP additive_expression {
        // Créez le nœud correspondant
    }
    | shift_expression RIGHT_OP additive_expression {
        // Créez le nœud correspondant
    }
    ;

relational_expression
    : shift_expression {
        $$ = $1;
    }
    | relational_expression '<' shift_expression {
        // Créez le nœud correspondant
    }
    | relational_expression '>' shift_expression {
        // Créez le nœud correspondant
    }
    | relational_expression LE_OP shift_expression {
        // Créez le nœud correspondant
    }
    | relational_expression GE_OP shift_expression {
        // Créez le nœud correspondant
    }
    ;

equality_expression
    : relational_expression {
        $$ = $1;
    }
    | equality_expression EQ_OP relational_expression {
        // Créez le nœud correspondant
    }
    | equality_expression NE_OP relational_expression {
        // Créez le nœud correspondant
    }
    ;

and_expression
    : equality_expression {
        $$ = $1;
    }
    | and_expression '&' equality_expression {
        // Créez le nœud correspondant
    }
    ;

exclusive_or_expression
    : and_expression {
        $$ = $1;
    }
    | exclusive_or_expression '^' and_expression {
        // Créez le nœud correspondant
    }
    ;

inclusive_or_expression
    : exclusive_or_expression {
        $$ = $1;
    }
    | inclusive_or_expression '|' exclusive_or_expression {
        // Créez le nœud correspondant
    }
    ;

logical_and_expression
    : inclusive_or_expression {
        $$ = $1;
    }
    | logical_and_expression AND_OP inclusive_or_expression {
        // Créez le nœud correspondant
    }
    ;

logical_or_expression
    : logical_and_expression {
        $$ = $1;
    }
    | logical_or_expression OR_OP logical_and_expression {
        // Créez le nœud correspondant
    }
    ;

conditional_expression
    : logical_or_expression {
        $$ = $1;
    }
    | logical_or_expression '?' expression ':' conditional_expression {
        // Créez le nœud correspondant
    }
    ;

assignment_expression
    : conditional_expression {
        $$ = $1;
    }
    | unary_expression assignment_operator assignment_expression {
        // Créez le nœud correspondant
    }
    ;

assignment_operator
    : '=' {
        $$ = '=';
    }
    | MUL_ASSIGN {
        $$ = MUL_ASSIGN;
    }
    | DIV_ASSIGN {
        $$ = DIV_ASSIGN;
    }
    | MOD_ASSIGN {
        $$ = MOD_ASSIGN;
    }
    | ADD_ASSIGN {
        $$ = ADD_ASSIGN;
    }
    | SUB_ASSIGN {
        $$ = SUB_ASSIGN;
    }
    | LEFT_ASSIGN {
        $$ = LEFT_ASSIGN;
    }
    | RIGHT_ASSIGN {
        $$ = RIGHT_ASSIGN;
    }
    | AND_ASSIGN {
        $$ = AND_ASSIGN;
    }
    | XOR_ASSIGN {
        $$ = XOR_ASSIGN;
    }
    | OR_ASSIGN {
        $$ = OR_ASSIGN;
    }
    ;

expression
    : assignment_expression {
        $$ = $1;
    }
    | expression ',' assignment_expression {
        // Créez le nœud correspondant
    }
    ;

constant_expression
    : conditional_expression {
        $$ = $1;
    }
    ;

declaration
    : declaration_specifiers ';' {
        // Créez le nœud correspondant
    }
    | declaration_specifiers init_declarator_list ';' {
        // Créez le nœud correspondant
    }
    | static_assert_declaration {
        // Créez le nœud correspondant
    }
    ;

declaration_specifiers
    : storage_class_specifier declaration_specifiers {
        // Créez le nœud correspondant
    }
    | storage_class_specifier {
        // Créez le nœud correspondant
    }
    | type_specifier declaration_specifiers {
        // Créez le nœud correspondant
    }
    | type_specifier {
        // Créez le nœud correspondant
    }
    | type_qualifier declaration_specifiers {
        // Créez le nœud correspondant
    }
    | type_qualifier {
        // Créez le nœud correspondant
    }
    | function_specifier declaration_specifiers {
        // Créez le nœud correspondant
    }
    | function_specifier {
        // Créez le nœud correspondant
    }
    | alignment_specifier declaration_specifiers {
        // Créez le nœud correspondant
    }
    | alignment_specifier {
        // Créez le nœud correspondant
    }
    ;

init_declarator_list
    : init_declarator {
        // Créez le nœud correspondant
    }
    | init_declarator_list ',' init_declarator {
        // Créez le nœud correspondant
    }
    ;

init_declarator
    : declarator '=' initializer {
        // Créez le nœud correspondant
    }
    | declarator {
        // Créez le nœud correspondant
    }
    ;

storage_class_specifier
    : TYPEDEF {
        // Créez le nœud correspondant
    }
    | EXTERN {
        // Créez le nœud correspondant
    }
    | STATIC {
        // Créez le nœud correspondant
    }
    | THREAD_LOCAL {
        // Créez le nœud correspondant
    }
    | AUTO {
        // Créez le nœud correspondant
    }
    | REGISTER {
        // Créez le nœud correspondant
    }
    ;

type_specifier
    : VOID {
        // Créez le nœud correspondant
    }
    | CHAR {
        // Créez le nœud correspondant
    }
    | SHORT {
        // Créez le nœud correspondant
    }
    | INT {
        // Créez le nœud correspondant
    }
    | LONG {
        // Créez le nœud correspondant
    }
    | FLOAT {
        // Créez le nœud correspondant
    }
    | DOUBLE {
        // Créez le nœud correspondant
    }
    | SIGNED {
        // Créez le nœud correspondant
    }
    | UNSIGNED {
        // Créez le nœud correspondant
    }
    | BOOL {
        // Créez le nœud correspondant
    }
    | COMPLEX {
        // Créez le nœud correspondant
    }
    | IMAGINARY {
        // Créez le nœud correspondant
    }
    | atomic_type_specifier {
        // Créez le nœud correspondant
    }
    | struct_or_union_specifier {
        // Créez le nœud correspondant
    }
    | enum_specifier {
        // Créez le nœud correspondant
    }
    | TYPEDEF_NAME {
        // Créez le nœud correspondant
    }
    ;

struct_or_union_specifier
    : struct_or_union '{' struct_declaration_list '}' {
        // Créez le nœud correspondant
    }
    | struct_or_union IDENTIFIER '{' struct_declaration_list '}' {
        // Créez le nœud correspondant
    }
    | struct_or_union IDENTIFIER {
        // Créez le nœud correspondant
    }
    ;

struct_or_union
    : STRUCT {
        // Créez le nœud correspondant
    }
    | UNION {
        // Créez le nœud correspondant
    }
    ;

struct_declaration_list
    : struct_declaration {
        // Créez le nœud correspondant
    }
    | struct_declaration_list struct_declaration {
        // Créez le nœud correspondant
    }
    ;

struct_declaration
    : specifier_qualifier_list ';' {
        // Créez le nœud correspondant
    }
    | specifier_qualifier_list struct_declarator_list ';' {
        // Créez le nœud correspondant
    }
    | static_assert_declaration {
        // Créez le nœud correspondant
    }
    ;

specifier_qualifier_list
    : type_specifier specifier_qualifier_list {
        // Créez le nœud correspondant
    }
    | type_specifier {
        // Créez le nœud correspondant
    }
    | type_qualifier specifier_qualifier_list {
        // Créez le nœud correspondant
    }
    | type_qualifier {
        // Créez le nœud correspondant
    }
    ;

struct_declarator_list
    : struct_declarator {
        // Créez le nœud correspondant
    }
    | struct_declarator_list ',' struct_declarator {
        // Créez le nœud correspondant
    }
    ;

struct_declarator
    : ':' constant_expression {
        // Créez le nœud correspondant
    }
    | declarator ':' constant_expression {
        // Créez le nœud correspondant
    }
    | declarator {
        // Créez le nœud correspondant
    }
    ;

enum_specifier
    : ENUM '{' enumerator_list '}' {
        // Créez le nœud correspondant
    }
    | ENUM '{' enumerator_list ',' '}' {
        // Créez le nœud correspondant
    }
    | ENUM IDENTIFIER '{' enumerator_list '}' {
        // Créez le nœud correspondant
    }
    | ENUM IDENTIFIER '{' enumerator_list ',' '}' {
        // Créez le nœud correspondant
    }
    | ENUM IDENTIFIER {
        // Créez le nœud correspondant
    }
    ;

enumerator_list
    : enumerator {
        // Créez le nœud correspondant
    }
    | enumerator_list ',' enumerator {
        // Créez le nœud correspondant
    }
    ;

enumerator
    : enumeration_constant '=' constant_expression {
        // Créez le nœud correspondant
    }
    | enumeration_constant {
        // Créez le nœud correspondant
    }
    ;

atomic_type_specifier
    : ATOMIC '(' type_name ')' {
        // Créez le nœud correspondant
    }
    ;

type_qualifier
    : CONST {
        // Créez le nœud correspondant
    }
    | RESTRICT {
        // Créez le nœud correspondant
    }
    | VOLATILE {
        // Créez le nœud correspondant
    }
    | ATOMIC {
        // Créez le nœud correspondant
    }
    ;

function_specifier
    : INLINE {
        // Créez le nœud correspondant
    }
    | NORETURN {
        // Créez le nœud correspondant
    }
    ;

alignment_specifier
    : ALIGNAS '(' type_name ')' {
        // Créez le nœud correspondant
    }
    | ALIGNAS '(' constant_expression ')' {
        // Créez le nœud correspondant
    }
    ;

declarator
    : pointer direct_declarator {
        // Créez le nœud correspondant
    }
    | direct_declarator {
        // Créez le nœud correspondant
    }
    ;

direct_declarator
    : IDENTIFIER {
        $$ = create_identifier_node($1);
    }
    | '(' declarator ')' {
        $$ = $2;
    }
    | direct_declarator '[' ']' {
        // Créez le nœud correspondant
    }
    | direct_declarator '[' '*' ']' {
        // Créez le nœud correspondant
    }
    | direct_declarator '[' STATIC type_qualifier_list assignment_expression ']' {
        // Créez le nœud correspondant
    }
    | direct_declarator '[' STATIC assignment_expression ']' {
        // Créez le nœud correspondant
    }
    | direct_declarator '[' type_qualifier_list '*' ']' {
        // Créez le nœud correspondant
    }
    | direct_declarator '[' type_qualifier_list STATIC assignment_expression ']' {
        // Créez le nœud correspondant
    }
    | direct_declarator '[' type_qualifier_list assignment_expression ']' {
        // Créez le nœud correspondant
    }
    | direct_declarator '[' type_qualifier_list ']' {
        // Créez le nœud correspondant
    }
    | direct_declarator '[' assignment_expression ']' {
        // Créez le nœud correspondant
    }
    | direct_declarator '(' parameter_type_list ')' {
        // Créez le nœud correspondant
    }
    | direct_declarator '(' ')' {
        // Créez le nœud correspondant
    }
    | direct_declarator '(' identifier_list ')' {
        // Créez le nœud correspondant
    }
    ;

pointer
    : '*' type_qualifier_list pointer {
        // Créez le nœud correspondant
    }
    | '*' type_qualifier_list {
        // Créez le nœud correspondant
    }
    | '*' pointer {
        // Créez le nœud correspondant
    }
    | '*' {
        // Créez le nœud correspondant
    }
    ;

type_qualifier_list
    : type_qualifier {
        // Créez le nœud correspondant
    }
    | type_qualifier_list type_qualifier {
        // Créez le nœud correspondant
    }
    ;

parameter_type_list
    : parameter_list ',' ELLIPSIS {
        // Créez le nœud correspondant
    }
    | parameter_list {
        // Créez le nœud correspondant
    }
    ;

parameter_list
    : parameter_declaration {
        // Créez le nœud correspondant
    }
    | parameter_list ',' parameter_declaration {
        // Créez le nœud correspondant
    }
    ;

parameter_declaration
    : declaration_specifiers declarator {
        // Créez le nœud correspondant
    }
    | declaration_specifiers abstract_declarator {
        // Créez le nœud correspondant
    }
    | declaration_specifiers {
        // Créez le nœud correspondant
    }
    ;

identifier_list
    : IDENTIFIER {
        $$ = create_identifier_node($1);
    }
    | identifier_list ',' IDENTIFIER {
        // Créez le nœud correspondant
    }
    ;

type_name
    : specifier_qualifier_list abstract_declarator {
        // Créez le nœud correspondant
    }
    | specifier_qualifier_list {
        // Créez le nœud correspondant
    }
    ;

abstract_declarator
    : pointer direct_abstract_declarator {
        // Créez le nœud correspondant
    }
    | pointer {
        // Créez le nœud correspondant
    }
    | direct_abstract_declarator {
        // Créez le nœud correspondant
    }
    ;

direct_abstract_declarator
    : '(' abstract_declarator ')' {
        // Créez le nœud correspondant
    }
    | '[' ']' {
        // Créez le nœud correspondant
    }
    | '[' '*' ']' {
        // Créez le nœud correspondant
    }
    | '[' STATIC type_qualifier_list assignment_expression ']' {
        // Créez le nœud correspondant
    }
    | '[' STATIC assignment_expression ']' {
        // Créez le nœud correspondant
    }
    | '[' type_qualifier_list STATIC assignment_expression ']' {
        // Créez le nœud correspondant
    }
    | '[' type_qualifier_list assignment_expression ']' {
        // Créez le nœud correspondant
    }
    | '[' type_qualifier_list ']' {
        // Créez le nœud correspondant
    }
    | '[' assignment_expression ']' {
        // Créez le nœud correspondant
    }
    | direct_abstract_declarator '[' ']' {
        // Créez le nœud correspondant
    }
    | direct_abstract_declarator '[' '*' ']' {
        // Créez le nœud correspondant
    }
    | direct_abstract_declarator '[' STATIC type_qualifier_list assignment_expression ']' {
        // Créez le nœud correspondant
    }
    | direct_abstract_declarator '[' STATIC assignment_expression ']' {
        // Créez le nœud correspondant
    }
    | direct_abstract_declarator '[' type_qualifier_list assignment_expression ']' {
        // Créez le nœud correspondant
    }
    | direct_abstract_declarator '[' type_qualifier_list STATIC assignment_expression ']' {
        // Créez le nœud correspondant
    }
    | direct_abstract_declarator '[' type_qualifier_list ']' {
        // Créez le nœud correspondant
    }
    | direct_abstract_declarator '[' assignment_expression ']' {
        // Créez le nœud correspondant
    }
    | '(' ')' {
        // Créez le nœud correspondant
    }
    | '(' parameter_type_list ')' {
        // Créez le nœud correspondant
    }
    | direct_abstract_declarator '(' ')' {
        // Créez le nœud correspondant
    }
    | direct_abstract_declarator '(' parameter_type_list ')' {
        // Créez le nœud correspondant
    }
    ;

initializer
    : '{' initializer_list '}' {
        // Créez le nœud correspondant
    }
    | '{' initializer_list ',' '}' {
        // Créez le nœud correspondant
    }
    | assignment_expression {
        // Créez le nœud correspondant
    }
    ;

initializer_list
    : designation initializer {
        // Créez le nœud correspondant
    }
    | initializer {
        // Créez le nœud correspondant
    }
    | initializer_list ',' designation initializer {
        // Créez le nœud correspondant
    }
    | initializer_list ',' initializer {
        // Créez le nœud correspondant
    }
    ;

designation
    : designator_list '=' {
        // Créez le nœud correspondant
    }
    ;

designator_list
    : designator {
        // Créez le nœud correspondant
    }
    | designator_list designator {
        // Créez le nœud correspondant
    }
    ;

designator
    : '[' constant_expression ']' {
        // Créez le nœud correspondant
    }
    | '.' IDENTIFIER {
        // Créez le nœud correspondant
    }
    ;

static_assert_declaration
    : STATIC_ASSERT '(' constant_expression ',' STRING_LITERAL ')' ';' {
        // Créez le nœud correspondant
    }
    ;

statement
    : labeled_statement {
        // Créez le nœud correspondant
    }
    | compound_statement {
        // Créez le nœud correspondant
    }
    | expression_statement {
        // Créez le nœud correspondant
    }
    | selection_statement {
        // Créez le nœud correspondant
    }
    | iteration_statement {
        // Créez le nœud correspondant
    }
    | jump_statement {
        // Créez le nœud correspondant
    }
    ;

labeled_statement
    : IDENTIFIER ':' statement {
        // Créez le nœud correspondant
    }
    | CASE constant_expression ':' statement {
        // Créez le nœud correspondant
    }
    | DEFAULT ':' statement {
        // Créez le nœud correspondant
    }
    ;

compound_statement
    : '{' '}' {
        // Créez le nœud correspondant
    }
    | '{' block_item_list '}' {
        // Créez le nœud correspondant
    }
    ;

block_item_list
    : block_item {
        // Créez le nœud correspondant
    }
    | block_item_list block_item {
        // Créez le nœud correspondant
    }
    ;

block_item
    : declaration {
        // Créez le nœud correspondant
    }
    | statement {
        // Créez le nœud correspondant
    }
    ;

expression_statement
    : ';' {
        // Créez le nœud correspondant
    }
    | expression ';' {
        // Créez le nœud correspondant
    }
    ;

selection_statement
    : IF '(' expression ')' statement ELSE statement {
        // Créez le nœud correspondant
    }
    | IF '(' expression ')' statement {
        // Créez le nœud correspondant
    }
    | SWITCH '(' expression ')' statement {
        // Créez le nœud correspondant
    }
    ;

iteration_statement
    : WHILE '(' expression ')' statement {
        // Créez le nœud correspondant
    }
    | DO statement WHILE '(' expression ')' ';' {
        // Créez le nœud correspondant
    }
    | FOR '(' expression_statement expression_statement ')' statement {
        // Créez le nœud correspondant
    }
    | FOR '(' expression_statement expression_statement expression ')' statement {
        // Créez le nœud correspondant
    }
    | FOR '(' declaration expression_statement ')' statement {
        // Créez le nœud correspondant
    }
    | FOR '(' declaration expression_statement expression ')' statement {
        // Créez le nœud correspondant
    }
    ;

jump_statement
    : GOTO IDENTIFIER ';' {
        // Créez le nœud correspondant
    }
    | CONTINUE ';' {
        // Créez le nœud correspondant
    }
    | BREAK ';' {
        // Créez le nœud correspondant
    }
    | RETURN ';' {
        // Créez le nœud correspondant
    }
    | RETURN expression ';' {
        // Créez le nœud correspondant
    }
    ;

translation_unit
    : external_declaration {
        root = $1;
    }
    | translation_unit external_declaration {
        // Créez le nœud correspondant
    }
    ;

external_declaration
    : function_definition {
        // Créez le nœud correspondant
    }
    | declaration {
        // Créez le nœud correspondant
    }
    ;

function_definition
    : declaration_specifiers declarator declaration_list compound_statement {
        // Créez le nœud correspondant
    }
    | declaration_specifiers declarator compound_statement {
        // Créez le nœud correspondant
    }
    ;

declaration_list
    : declaration {
        // Créez le nœud correspondant
    }
    | declaration_list declaration {
        // Créez le nœud correspondant
    }
    ;

%%
#include <stdio.h>

void yyerror(const char *s) {
    fprintf(stderr, "Error: %s at line %d\n", s, yylineno);
}

int yylex(void);

int main(int argc, char **argv) {
    if (argc > 1) {
        FILE *file = fopen(argv[1], "r");
        if (!file) {
            fprintf(stderr, "Could not open file %s\n", argv[1]);
            return 1;
        }
        yyin = file;
    }
    yyparse();
    if (root) {
        print_ast(root);
    }
    return 0;
}

A partir de cette grammaire, Bison génère un fichier c99.tab.c qui contient le code C de l'analyseur syntaxique.

Pour la créer vous-même, vous pouvez utiliser la commande suivante :

bison -d -o c99.tab.c c99.y