34
35:- module(c99_grammar,
36 [ c99_parse//1, 37 c99_parse_cont//1
38 ]). 39:- use_module(library(debug)). 40:- use_module(ctokens). 41:- use_module(library(pprint)). 42
43c99_parse(AST) -->
44 { init_state },
45 c99_parse_cont(AST).
46
47c99_parse_cont(AST) -->
48 c99_tokens(Tokens),
49 { phrase(translation_unit(AST), Tokens) }.
50
51
52 55
56primary_expression(E) --> opt_extension, [id(E)].
57primary_expression(E) --> constant(E).
58primary_expression(E) --> string_literal(E).
59primary_expression(E) --> ['('], expression(E), [')'].
60primary_expression(E) --> opt_extension, ['('],
61 compound_statement(E), [')']. 62
63opt_extension --> ['__extension__'], !.
64opt_extension --> [].
65
66constant(i(I)) --> [i(I)].
67constant(l(I)) --> [l(I)].
68constant(ll(I)) --> [ll(I)].
69constant(u(I)) --> [u(I)].
70constant(ul(I)) --> [ul(I)].
71constant(ull(I)) --> [ull(I)].
72constant(float(F)) --> [float(F)].
73constant(double(D)) --> [double(D)].
74constant(enum_value(Name)) --> [enum_value(Name)].
75constant(char(Codes)) --> [char(Codes)].
76constant(wchar(Codes)) --> [wchar(Codes)].
77
78string_literal(str(S)) --> [str(S)].
79string_literal(wstr(S)) --> [wstr(S)].
80
81postfix_expression(Expr) -->
82 primary_expression(P),
83 expression_postfixes(P, Expr).
84
85expression_postfixes(P, Expr) -->
86 expression_postfix(P, Expr0), !,
87 expression_postfixes(Expr0, Expr).
88expression_postfixes(Expr, Expr) --> [].
89
90expression_postfix(E0, array(E0,I)) -->
91 ['['], expression(I), [']'].
92expression_postfix(E0, call(E0, List)) -->
93 ['('], argument_expression_list_opt(List), [')'].
94expression_postfix(E0, member(E0, Id)) -->
95 [ '.', id(Id) ].
96expression_postfix(E0, member_ptr(E0, Id)) -->
97 [ '->', id(Id) ].
98expression_postfix(E0, post_incr(E0)) -->
99 [++].
100expression_postfix(E0, post_decr(E0)) -->
101 [--].
102expression_postfix(E0, cast(E0, Type, Init)) -->
103 ['('], type_name(Type), [')', '{'],
104 initializer_list(Init), opt_comma, ['}'].
105
106argument_expression_list([H|T]) -->
107 assignment_expression(H),
108 ( [',']
109 -> argument_expression_list(T)
110 ; {T=[]}
111 ).
112
113argument_expression_list_opt(List) -->
114 argument_expression_list(List), !.
115argument_expression_list_opt([]) --> [].
116
117unary_expression(E) -->
118 postfix_expression(E).
119unary_expression(++(UE)) -->
120 [++], unary_expression(UE).
121unary_expression(--(UE)) -->
122 [--], unary_expression(UE).
123unary_expression(op(Op, Expr)) -->
124 unary_operator(Op),
125 cast_expression(Expr).
126unary_expression(sizeof(Expr)) -->
127 [sizeof], unary_expression(Expr).
128unary_expression(sizeof(type(Type))) -->
129 [sizeof, '('], type_name(Type), [')'].
130
131unary_operator(&) --> [&].
132unary_operator(*) --> [*].
133unary_operator(+) --> [+].
134unary_operator(-) --> [-].
135unary_operator(~) --> [~].
136unary_operator(!) --> [!].
137
138cast_expression(cast(Type, Expr)) -->
139 ['('], type_name(Type), [')'], cast_expression(Expr).
140cast_expression(Expr) -->
141 unary_expression(Expr).
142
143multiplicative_expression(Expr) -->
144 cast_expression(A),
145 ( multiplicative_op(Op)
146 -> multiplicative_expression(B),
147 { re_nest(Op, A, B, Expr) }
148 ; { Expr = A }
149 ).
150
151multiplicative_op(*) --> [*].
152multiplicative_op(/) --> [/].
153multiplicative_op('%') --> ['%'].
154
155re_nest(Op, A, o(Op2, B, C), Expr) :-
156 re_nest(Op2, o(Op,A,B), C, Expr).
157re_nest(Op, A, B, o(Op, A, B)).
158
159additive_expression(Expr) -->
160 multiplicative_expression(A),
161 ( additive_op(Op)
162 -> additive_expression(B),
163 { re_nest(Op, A, B, Expr) }
164 ; { Expr = A }
165 ).
166
167additive_op(+) --> [+].
168additive_op(-) --> [-].
169
170shift_expression(Expr) -->
171 additive_expression(A),
172 ( shift_op(Op)
173 -> shift_expression(B),
174 { re_nest(Op, A, B, Expr) }
175 ; { Expr = A }
176 ).
177
178shift_op(<<) --> [<<].
179shift_op(>>) --> [>>].
180
181relational_expression(Expr) -->
182 shift_expression(A),
183 ( relational_op(Op)
184 -> relational_expression(B),
185 { re_nest(Op, A, B, Expr) }
186 ; { Expr = A }
187 ).
188
189relational_op(<) --> [<].
190relational_op(>) --> [>].
191relational_op(>=) --> [>=].
192relational_op(<=) --> [<=].
193
194equality_expression(Expr) -->
195 relational_expression(A),
196 ( equality_op(Op)
197 -> equality_expression(B),
198 { re_nest(Op, A, B, Expr) }
199 ; { Expr = A }
200 ).
201
202equality_op(==) --> [==].
203equality_op('!=') --> ['!='].
204
205and_expression(Expr) -->
206 equality_expression(A),
207 ( [&]
208 -> and_expression(B),
209 { re_nest(&, A, B, Expr) }
210 ; { Expr = A }
211 ).
212
213exclusive_or_expression(Expr) -->
214 and_expression(A),
215 ( [^]
216 -> exclusive_or_expression(B),
217 { re_nest(^, A, B, Expr) }
218 ; { Expr = A }
219 ).
220
221
222inclusive_or_expression(Expr) -->
223 exclusive_or_expression(A),
224 ( ['|']
225 -> inclusive_or_expression(B),
226 { re_nest('|', A, B, Expr) }
227 ; { Expr = A }
228 ).
229
230logical_and_expression(Expr) -->
231 inclusive_or_expression(A),
232 ( [&&]
233 -> logical_and_expression(B),
234 { re_nest(&&, A, B, Expr) }
235 ; { Expr = A }
236 ).
237
238logical_or_expression(Expr) -->
239 logical_and_expression(A),
240 ( ['||']
241 -> logical_or_expression(B),
242 { re_nest('||', A, B, Expr) }
243 ; { Expr = A }
244 ).
245
246conditional_expression(Expr) -->
247 logical_or_expression(A),
248 ( [?]
249 -> expression(If),
250 [:],
251 conditional_expression(Then),
252 { Expr = cond(A, If, Then) }
253 ; { Expr = A }
254 ).
255
256assignment_expression(assign(Op, UE, AE)) -->
257 unary_expression(UE),
258 assignment_operator(Op),
259 assignment_expression(AE).
260assignment_expression(Expr) -->
261 conditional_expression(Expr).
262
263assignment_expression_opt(Expr) -->
264 assignment_expression(Expr).
265assignment_expression_opt(-) --> [].
266
267assignment_operator(=) --> [=].
268assignment_operator(*=) --> [*=].
269assignment_operator(/=) --> [/=].
270assignment_operator('%=') --> ['%='].
271assignment_operator(+=) --> [+=].
272assignment_operator(-=) --> [-=].
273assignment_operator(<<=) --> [<<=].
274assignment_operator(>>=) --> [>>=].
275assignment_operator(&=) --> [&=].
276assignment_operator(^=) --> [^=].
277assignment_operator('|=') --> ['|='].
278
279expression(Expr) -->
280 assignment_expression(A),
281 ( [',']
282 -> expression(B),
283 { re_nest(=, A, B, Expr) }
284 ; { Expr = A }
285 ).
286
287constant_expression(E) -->
288 conditional_expression(E).
289
290
291 294
295declaration(Decl) -->
296 declaration_specifiers(DS),
297 specifiers_declaration(DS, Decl).
298
299specifiers_declaration(DS, decl(DS, I, GCC)) -->
300 init_declarator_list(I),
301 gcc_attributes_opt(GCC),
302 [;].
303
304declaration_specifiers([H|T]) -->
305 declaration_specifier(H), !,
306 declaration_specifiers(T).
307declaration_specifiers([]) --> [].
308
309declaration_specifier(DS) --> storage_class_specifier(DS).
310declaration_specifier(DS) --> type_specifier(DS).
311declaration_specifier(DS) --> type_qualifier(DS).
312declaration_specifier(DS) --> function_specifier(DS).
313declaration_specifier(DS) --> gcc_attributes(DS).
314
315init_declarator_list([H|T]) -->
316 init_declarator(H),
317 !,
318 ( [',']
319 -> init_declarator_list(T)
320 ; { T = [] }
321 ).
322init_declarator_list([]) --> [].
323
324init_declarator(ID) -->
325 declarator(D),
326 ( [=]
327 -> initializer(I),
328 {ID = (D=I)}
329 ; {ID = D}
330 ).
331
332storage_class_specifier(storage(typedef)) --> [typedef].
333storage_class_specifier(storage(extern)) --> [extern].
334storage_class_specifier(storage(static)) --> [static].
335storage_class_specifier(storage(auto)) --> [auto].
336storage_class_specifier(storage(register)) --> [register].
337
338type_specifier(type(void)) --> [void].
339type_specifier(type(char)) --> [char].
340type_specifier(type(short)) --> [short].
341type_specifier(type(int)) --> [int].
342type_specifier(type(long)) --> [long].
343type_specifier(type(size_t)) --> [size_t]. 344type_specifier(type(float)) --> [float].
345type_specifier(type(double)) --> [double].
346type_specifier(type(signed)) --> [signed].
347type_specifier(type(unsigned)) --> [unsigned].
348type_specifier(type('_Bool')) --> ['_Bool'].
349type_specifier(type('_Complex')) --> ['_Complex'].
350type_specifier(type('_Float128')) --> ['_Float128'].
351type_specifier(type('__builtin_va_list')) --> ['__builtin_va_list'].
352type_specifier(type('__gnuc_va_list')) --> ['__gnuc_va_list'].
353type_specifier(type(Type)) --> [struct], struct_specifier(Type).
354type_specifier(type(Type)) --> [union], union_specifier(Type).
355type_specifier(type(Type)) --> [enum], enum_specifier(Type).
356type_specifier(type(Type)) --> [id(Name)], {typedef_name(Name, Type)}.
357
358struct_specifier(struct(Id, Fields)) -->
359 opt_id(struct, Id),
360 ['{'], struct_declaration_list(Fields), ['}'].
361struct_specifier(struct(Id)) -->
362 [ id(Id) ].
363
364union_specifier(union(Id, Fields)) -->
365 opt_id(union, Id),
366 ['{'], struct_declaration_list(Fields), ['}'].
367union_specifier(union(Id)) -->
368 [ id(Id) ].
369
370opt_id(_, Id) --> [id(Id)], !.
371opt_id(Sort, Id) -->
372 { anon_id(Sort, Id) }.
373
374struct_declaration_list([H|T]) -->
375 struct_declaration(H), !,
376 struct_declaration_list(T).
377struct_declaration_list([]) --> [].
378
379struct_declaration(f(QL, DL, GCC)) -->
380 specifier_qualifier_list(QL),
381 struct_declarator_list_opt(DL), 382 gcc_attributes_opt(GCC),
383 [;].
384
385specifier_qualifier_list([H|T]) -->
386 specifier_qualifier(H), !,
387 specifier_qualifier_list(T).
388specifier_qualifier_list([]) --> [].
389
390specifier_qualifier(SQ) --> type_specifier(SQ).
391specifier_qualifier(SQ) --> type_qualifier(SQ).
392
393struct_declarator_list_opt(List) -->
394 struct_declarator_list(List), !.
395struct_declarator_list_opt([]) --> [].
396
397struct_declarator_list([H|T]) -->
398 struct_declarator(H),
399 ( [',']
400 -> struct_declarator_list(T)
401 ; {T=[]}
402 ).
403
404struct_declarator(SD) -->
405 declarator(D),
406 ( [:]
407 -> constant_expression(E),
408 {SD = bitfield(D, E)}
409 ; {SD = d(D)}
410 ).
411struct_declarator(SD) -->
412 [:], constant_expression(E),
413 {SD = bitfield(-, E)}.
414
415enum_specifier(enum(ID, EL)) -->
416 opt_id(enum, ID),
417 ['{'], enumerator_list(EL), opt_comma, ['}'].
418enum_specifier(enum(ID)) -->
419 [id(ID)].
420
421enumerator_list([H|T]) -->
422 enumerator(H), !,
423 ( [','], \+ ['}']
424 -> enumerator_list(T)
425 ; {T=[]}
426 ).
427
428enumerator(enum_value(H, V)) -->
429 enumeration_constant(H),
430 gcc_attributes_opt(_),
431 ( [=]
432 -> constant_expression(V)
433 ; {V = (-)}
434 ).
435
436enumeration_constant(Id) -->
437 [id(Id)].
438
439opt_comma --> [','], !.
440opt_comma --> [].
441
442type_qualifier(const) --> [const].
443type_qualifier(restrict) --> [restrict].
444type_qualifier(volatile) --> [volatile].
445type_qualifier('__restrict__') --> ['__restrict__']. 446type_qualifier('__extension__') --> ['__extension__']. 447type_qualifier('_Nonnull') --> ['_Nonnull']. 448type_qualifier('_Nullable') --> ['_Nullable']. 449
450function_specifier(inline) --> [inline].
451
452declarator(declarator(P, DD)) --> pointer(P), !, direct_declarator(DD).
453declarator(declarator(-, DD)) --> direct_declarator(DD).
454
455direct_declarator(Decl) -->
456 gcc_attributes(_), 457 !,
458 direct_declarator(Decl).
459direct_declarator(dd(Id, DDS)) -->
460 [id(Id)], !,
461 direct_declarator_suffix_opt(DDS).
462direct_declarator(dd(D, DDS)) -->
463 ['('], declarator(D), [')'],
464 direct_declarator_suffix_opt(DDS).
465
466direct_declarator_suffix_opt(DDS) -->
467 direct_declarator_suffix(DDS), !.
468direct_declarator_suffix_opt(-) --> [].
469
470direct_declarator_suffix(DDS) -->
471 ['['], array_direct_declarator_suffix(DDS), [']'].
472direct_declarator_suffix(DDS) -->
473 ['('], param_direct_declarator_suffix(DDS), [')'].
474
475array_direct_declarator_suffix(dds(TQL, Ass)) -->
476 type_qualifier_list_opt(TQL), assignment_expression_opt(Ass).
477array_direct_declarator_suffix(dds(TQL, Ass)) -->
478 [static],
479 type_qualifier_list_opt(TQL), assignment_expression(Ass).
480array_direct_declarator_suffix(dds(TQL, Ass)) -->
481 type_qualifier_list(TQL), [static], assignment_expression(Ass).
482array_direct_declarator_suffix(dds(TQL, *)) -->
483 type_qualifier_list_opt(TQL), ptr.
484
485param_direct_declarator_suffix(dds(PTL)) -->
486 parameter_type_list(PTL), !.
487param_direct_declarator_suffix(dds(IDList)) -->
488 identifier_list_opt(IDList), !.
489
490
491pointer([ptr(TQL)|T]) -->
492 ptr, type_qualifier_list_opt(TQL),
493 pointers(T).
494
495pointers([ptr(TQL)|T]) -->
496 ptr, type_qualifier_list_opt(TQL), !,
497 pointers(T).
498pointers([]) --> [].
499
500ptr --> [*].
501ptr --> [^]. 502
503type_qualifier_list([H|T]) -->
504 type_qualifier(H), !,
505 type_qualifier_list_opt(T).
506
507type_qualifier_list_opt([H|T]) -->
508 type_qualifier(H), !,
509 type_qualifier_list_opt(T).
510type_qualifier_list_opt([]) --> [].
511
512parameter_type_list(List) -->
513 parameter_list(List, T),
514 ( [',', '...']
515 -> {T=[param([], '...')]}
516 ; {T=[]}
517 ).
518
519parameter_type_list_opt(List) -->
520 parameter_type_list(List).
521parameter_type_list_opt([]) --> [].
522
523parameter_list([H|T0], T) -->
524 parameter_declaration(H),
525 ( [','], \+ ['...']
526 -> parameter_list(T0, T)
527 ; {T=T0}
528 ).
529
530parameter_declaration(param(S,D)) -->
531 declaration_specifiers(S),
532 ( declarator(D)
533 -> gcc_attributes_opt(_)
534 ; abstract_declarator_opt(D)
535 ).
536
537identifier_list([H|T]) -->
538 [id(H)],
539 ( [',']
540 -> identifier_list(T)
541 ; {T=[]}
542 ).
543
544identifier_list_opt(IDL) -->
545 identifier_list(IDL), !.
546identifier_list_opt([]) --> [].
547
548type_name(type_name(QL, D)) -->
549 specifier_qualifier_list(QL), abstract_declarator_opt(D).
550
551abstract_declarator(ad(AD,DAD)) -->
552 pointer_or_block(AD), !,
553 ( direct_abstract_declarator(DAD)
554 -> []
555 ; {DAD = (-)}
556 ).
557abstract_declarator(ad(-,DAD)) -->
558 direct_abstract_declarator(DAD).
559
560pointer_or_block(AD) -->
561 pointer(AD), !.
562pointer_or_block(AD) -->
563 block(AD).
571block([block(TQL)|T]) -->
572 [^], type_qualifier_list_opt(TQL),
573 blocks(T).
574
575blocks([block(TQL)|T]) -->
576 [^], type_qualifier_list_opt(TQL), !,
577 blocks(T).
578blocks([]) --> [].
579
580abstract_declarator_opt(AD) -->
581 abstract_declarator(AD), !.
582abstract_declarator_opt(ad(-,-)) --> [].
583
584direct_abstract_declarator(dad(AD,S)) -->
585 ( ['('], abstract_declarator(AD), [')']
586 -> []
587 ; {AD = (-)}
588 ),
589 direct_abstract_declarator_suffix(S).
590
591direct_abstract_declarator_suffix(dads(TQL, Ass)) -->
592 ['['],
593 type_qualifier_list_opt(TQL), assignment_expression_opt(Ass),
594 [']'], !.
595direct_abstract_declarator_suffix(dads(TQL, Ass)) -->
596 ['[', static],
597 type_qualifier_list_opt(TQL), assignment_expression(Ass),
598 [']'], !.
599direct_abstract_declarator_suffix(dads(TQL, Ass)) -->
600 ['['],
601 type_qualifier_list(TQL), [static], assignment_expression(Ass),
602 [']'], !.
603direct_abstract_declarator_suffix(dads(*)) -->
604 ['[',*,']'], !.
605direct_abstract_declarator_suffix(dads(PTL)) -->
606 ['('], parameter_type_list_opt(PTL), [')'], !.
607direct_abstract_declarator_suffix(-) -->
608 [].
609
610typedef_name(Name, Type) :-
611 defined_type(Name),
612 Type = user_type(Name).
613
614initializer(init(E)) -->
615 assignment_expression(E).
616initializer(init(IL)) -->
617 ['{'], initializer_list(IL), opt_comma, ['}'], !.
618
619initializer_list([H|T]) -->
620 initializer1(H), !,
621 ( [',']
622 -> initializer_list(T)
623 ; []
624 ).
625initializer_list([]) --> [].
626
627initializer1(init(D,I)) -->
628 designation(D), !,
629 initializer(I).
630initializer1(init(-,I)) -->
631 initializer(I).
632
633designation(D) -->
634 designator_list(D), [=], !.
635
636designator_list([H|T]) -->
637 designator(H),
638 designator_list_opt(T).
639
640designator_list_opt([H|T]) -->
641 designator(H), !,
642 designator_list_opt(T).
643designator_list_opt([]) --> [].
644
645designator([E]) -->
646 constant_expression(E).
647designator(.(Id)) -->
648 [id(Id)].
655gcc_attributes_opt([H|T]) -->
656 gcc_attributes(H), !,
657 gcc_attributes_opt(T).
658gcc_attributes_opt([]) --> [].
659
660gcc_attributes(gcc_attributes(List)) -->
661 ['__attribute__', '(', '('], gcc_attribute_list(List), [')', ')'].
662gcc_attributes(ASM) -->
663 asm(ASM).
664
665gcc_attribute_list(List) -->
666 [','], !,
667 gcc_attribute_list(List).
668gcc_attribute_list([H|T]) -->
669 gcc_attribute(H),
670 ( [',']
671 -> gcc_attribute_list(T)
672 ; {T=[]}
673 ).
674
675gcc_attribute(H) -->
676 gcc_attribute_name(Name),
677 ( ['(']
678 -> gcc_attribute_param_list(Params), [')'],
679 { H =.. [Name|Params] }
680 ; { H = Name }
681 ).
682
683gcc_attribute_name(H) --> [id(H)].
684gcc_attribute_name(H) --> [H], {atom(H)}.
685
686gcc_attribute_param_list([]), [')'] -->
687 [')'], !.
688gcc_attribute_param_list([H|T]) -->
689 gcc_attribute_param(Name),
690 ( {Name == introduced}, 691 [=],
692 version(V)
693 -> {H = (Name=V)}
694 ; {atom(Name)},
695 [=],
696 constant_expression(V)
697 -> {H = (Name=V)}
698 ; {H = Name}
699 ),
700 ( [',']
701 -> gcc_attribute_param_list(T)
702 ; {T=[]}
703 ).
704
705gcc_attribute_param(H) -->
706 gcc_attribute_name(H).
707gcc_attribute_param(H) -->
708 constant_expression(H).
709gcc_attribute_param(alignof(Decl)) -->
710 ['__alignof__', '('], declaration_specifiers(Decl), [')'].
711
712version(String) -->
713 [double(D), '.', i(I)],
714 !,
715 { format(string(String), '~w.~d', [D, I]) }.
716version(String) -->
717 [double(D)],
718 !,
719 { format(string(String), '~w', [D]) }.
720
721asm(ASM) -->
722 ['__asm__', '('], asm_list(Statements), [')'],
723 { ASM = asm(Statements) }.
724
725asm_list([H|T]) -->
726 [ str(H) ], !,
727 asm_list(T).
728asm_list([]) --> [].
729
730
731 734
735statement(S) --> labeled_statement(S).
736statement(S) --> compound_statement(S).
737statement(S) --> expression_statement(S).
738statement(S) --> selection_statement(S).
739statement(S) --> iteration_statement(S).
740statement(S) --> jump_statement(S).
741
742labeled_statement(label(L, Statement)) -->
743 [id(L), :], !, statement(Statement).
744labeled_statement(case(V, Statement)) -->
745 [case], constant_expression(V), [:], !, statement(Statement).
746labeled_statement(default(Statement)) -->
747 [default, :], !, statement(Statement).
748
749compound_statement(block(Statements)) -->
750 ['{'], block_item_list_opt(Statements), ['}'].
751
752block_item_list_opt([H|T]) -->
753 block_item(H), !,
754 block_item_list_opt(T).
755block_item_list_opt([]) --> [].
756
757block_item(H) --> declaration(H).
758block_item(H) --> statement(H).
759
760expression_statement(E) -->
761 expression_opt(E), [;], !.
762
763expression_opt(E) -->
764 expression(E), !.
765expression_opt(void) -->
766 [].
767
768selection_statement(if(Cond, If, Then)) -->
769 [if, '('], expression(Cond), [')'],
770 statement(If),
771 ( [else]
772 -> statement(Then)
773 ; {Then = void}
774 ).
775selection_statement(switch(Expr, Statement)) -->
776 [switch, '('], expression(Expr), [')'],
777 statement(Statement).
778
779iteration_statement(while(Expr, Statement)) -->
780 [while, '('], expression(Expr), [')'], statement(Statement).
781iteration_statement(do_while(Expr, Statement)) -->
782 [do], statement(Statement), [while, '('], expression(Expr), [')', ';'].
783iteration_statement(for(Init, Cond, Iter, Statement)) -->
784 [for, '('], expression_opt(Init), [;], expression_opt(Cond), [;],
785 expression_opt(Iter), [')'], statement(Statement).
786iteration_statement(for2(Decl, Expr1, Expr2, Statement)) -->
787 [for, '('], declaration(Decl), expression_opt(Expr1), [;],
788 expression_opt(Expr2), [')'], statement(Statement).
789
790jump_statement(goto(Id)) -->
791 [ goto, id(Id), ';' ].
792jump_statement(continue) -->
793 [ continue, ';' ].
794jump_statement(break) -->
795 [ break, ';' ].
796jump_statement(return(Expr)) -->
797 [ return ], expression_statement(Expr).
798
799 802
803translation_unit([H|T]) -->
804 external_declaration(H), !,
805 { update_types(H),
806 ( debugging(c99(unit))
807 -> print_term(H, [output(user_error)]), nl(user_error)
808 ; true
809 )
810 },
811 translation_unit(T).
812translation_unit(List) -->
813 skip_unit, !,
814 translation_unit(List).
815translation_unit([]) --> [].
816
817external_declaration(D) -->
818 declaration_specifiers(DS), !,
819 ( specifiers_declaration(DS, D)
820 ; function_definition(DS, D)
821 ).
822external_declaration(D) --> pp(D).
823
824function_definition(Specifiers,
825 function(Specifiers, Declarator, Params, Body)) -->
826 declarator(Declarator),
827 declaration_list_opt(Params),
828 compound_statement(Body).
829
830declaration_list_opt([H|T]) -->
831 declaration(H), !,
832 declaration_list_opt(T).
833declaration_list_opt([]) --> [].
834
835pp(pp(Line)) -->
836 [pp(Line)].
837
838 841
842skip_unit -->
843 here(Start),
844 skip_unit([]),
845 here(End),
846 { diff(Start, End, Skipped),
847 ( memberchk('__extension__', Skipped)
848 -> ( debugging(c99(extension))
849 -> print_message(informational, ffi(skipped_header(Skipped)))
850 ; true
851 )
852 ; print_message(warning, ffi(skipped_header(Skipped)))
853 )
854 }.
855
856skip_unit(Stack) --> open_bracket(Close), !, skip_unit([Close|Stack]).
857skip_unit(['}']) --> ['}'], !.
858skip_unit([Close|Stack]) --> [Close], !, skip_unit(Stack).
859skip_unit([]) --> [';'], !.
860skip_unit(Stack) --> [_], skip_unit(Stack).
861
862here(List, List, List).
863
864diff(Start, End, Skipped) :- Start == End, !, Skipped = [].
865diff([H|T0], End, [H|T]) :- diff(T0, End, T).
866
867open_bracket(')') --> ['('].
868open_bracket(']') --> ['['].
869open_bracket('}') --> ['{'].
870
871
872 875
876:- thread_local
877 typedef/1,
878 anon/2. 879
880init_state :-
881 retractall(typedef(_)),
882 retractall(anon(_,_)).
883
884defined_type(Name) :-
885 typedef(Name).
886
887update_types(decl(What, As, _GCC)) :-
888 memberchk(storage(typedef), What), !,
889 forall(( member(A, As),
890 declarator_name(A, Name)
891 ),
892 assertz(typedef(Name))).
893update_types(_).
894
895anon_id(Sort, Id) :-
896 ( retract(anon(Sort, I0))
897 -> I is I0+1
898 ; I = 1
899 ),
900 asserta(anon(Sort, I)),
901 atomic_list_concat(['_:', Sort, '_', I], Id).
902
903
904 907
908declarator_name(declarator(_Ptr, dd(Name, _)), Name) :-
909 atom(Name), !.
911declarator_name(declarator(_Ptr, dd(Declarator,_)), Name) :-
912 declarator_name(Declarator, Name).
913
914
915 918
919:- multifile
920 prolog:message//1. 921
922prolog:message(ffi(Msg)) -->
923 message(Msg).
924
925message(skipped_header(Tokens)) -->
926 [ 'FFI: Could not parse ~p'-[Tokens] ]