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(o(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(signed)) --> ['__signed__'].
348type_specifier(type(unsigned)) --> [unsigned].
349type_specifier(type('_Bool')) --> ['_Bool'].
350type_specifier(type('_Complex')) --> ['_Complex'].
351type_specifier(type('__uint128_t')) --> ['__uint128_t'].
352type_specifier(type('__int128_t')) --> ['__int128_t'].
353type_specifier(type('_Float16')) --> ['_Float16'].
354type_specifier(type('_Float32')) --> ['_Float32'].
355type_specifier(type('_Float32x')) --> ['_Float32x'].
356type_specifier(type('_Float64')) --> ['_Float64'].
357type_specifier(type('_Float64x')) --> ['_Float64x'].
358type_specifier(type('_Float80')) --> ['_Float80'].
359type_specifier(type('_Float128')) --> ['_Float128'].
360type_specifier(type('__builtin_va_list')) --> ['__builtin_va_list'].
361type_specifier(type('__gnuc_va_list')) --> ['__gnuc_va_list'].
362type_specifier(type(Type)) --> [struct], struct_specifier(Type).
363type_specifier(type(Type)) --> [union], union_specifier(Type).
364type_specifier(type(Type)) --> [enum], enum_specifier(Type).
365type_specifier(type(Type)) --> [id(Name)], {typedef_name(Name, Type)}.
366
367struct_specifier(struct(Id, Fields)) -->
368 opt_id(struct, Id),
369 ['{'], struct_declaration_list(Fields), ['}'].
370struct_specifier(struct(Id)) -->
371 [ id(Id) ].
372
373union_specifier(union(Id, Fields)) -->
374 opt_id(union, Id),
375 ['{'], struct_declaration_list(Fields), ['}'].
376union_specifier(union(Id)) -->
377 [ id(Id) ].
378
379opt_id(_, Id) --> [id(Id)], !.
380opt_id(Sort, Id) -->
381 { anon_id(Sort, Id) }.
382
383struct_declaration_list([H|T]) -->
384 struct_declaration(H), !,
385 struct_declaration_list(T).
386struct_declaration_list([]) --> [].
387
388struct_declaration(f(QL, DL, GCC)) -->
389 specifier_qualifier_list(QL),
390 struct_declarator_list_opt(DL), 391 gcc_attributes_opt(GCC),
392 [;].
393
394specifier_qualifier_list([H|T]) -->
395 specifier_qualifier(H), !,
396 specifier_qualifier_list(T).
397specifier_qualifier_list([]) --> [].
398
399specifier_qualifier(SQ) --> type_specifier(SQ).
400specifier_qualifier(SQ) --> type_qualifier(SQ).
401
402struct_declarator_list_opt(List) -->
403 struct_declarator_list(List), !.
404struct_declarator_list_opt([]) --> [].
405
406struct_declarator_list([H|T]) -->
407 struct_declarator(H),
408 ( [',']
409 -> struct_declarator_list(T)
410 ; {T=[]}
411 ).
412
413struct_declarator(SD) -->
414 declarator(D),
415 ( [:]
416 -> constant_expression(E),
417 {SD = bitfield(D, E)}
418 ; {SD = d(D)}
419 ).
420struct_declarator(SD) -->
421 [:], constant_expression(E),
422 {SD = bitfield(-, E)}.
423
424enum_specifier(enum(ID, EL)) -->
425 opt_id(enum, ID),
426 ['{'], enumerator_list(EL), opt_comma, ['}'].
427enum_specifier(enum(ID)) -->
428 [id(ID)].
429
430enumerator_list([H|T]) -->
431 enumerator(H), !,
432 ( [','], \+ ['}']
433 -> enumerator_list(T)
434 ; {T=[]}
435 ).
436
437enumerator(enum_value(H, V)) -->
438 enumeration_constant(H),
439 gcc_attributes_opt(_),
440 ( [=]
441 -> constant_expression(V)
442 ; {V = (-)}
443 ).
444
445enumeration_constant(Id) -->
446 [id(Id)].
447
448opt_comma --> [','], !.
449opt_comma --> [].
450
451type_qualifier(const) --> [const].
452type_qualifier(restrict) --> [restrict].
453type_qualifier(volatile) --> [volatile].
454type_qualifier('__restrict__') --> ['__restrict__']. 455type_qualifier('__extension__') --> ['__extension__']. 456type_qualifier('_Nonnull') --> ['_Nonnull']. 457type_qualifier('_Nullable') --> ['_Nullable']. 458
459function_specifier(inline) --> [inline].
460
461declarator(declarator(P, DD)) --> pointer(P), !, direct_declarator(DD).
462declarator(declarator(-, DD)) --> direct_declarator(DD).
463
464direct_declarator(Decl) -->
465 gcc_attributes(_), 466 !,
467 direct_declarator(Decl).
468direct_declarator(dd(Id, DDS)) -->
469 [id(Id)], !,
470 direct_declarator_suffix_opt(DDS).
471direct_declarator(dd(D, DDS)) -->
472 ['('], declarator(D), [')'],
473 direct_declarator_suffix_opt(DDS).
474
475direct_declarator_suffix_opt(DDS) -->
476 direct_declarator_suffix(DDS), !.
477direct_declarator_suffix_opt(-) --> [].
478
479direct_declarator_suffix(DDS) -->
480 ['['], array_direct_declarator_suffix(DDS), [']'].
481direct_declarator_suffix(DDS) -->
482 ['('], param_direct_declarator_suffix(DDS), [')'].
483
484array_direct_declarator_suffix(dds(TQL, Ass)) -->
485 type_qualifier_list_opt(TQL), assignment_expression_opt(Ass).
486array_direct_declarator_suffix(dds(TQL, Ass)) -->
487 [static],
488 type_qualifier_list_opt(TQL), assignment_expression(Ass).
489array_direct_declarator_suffix(dds(TQL, Ass)) -->
490 type_qualifier_list(TQL), [static], assignment_expression(Ass).
491array_direct_declarator_suffix(dds(TQL, *)) -->
492 type_qualifier_list_opt(TQL), ptr.
493
494param_direct_declarator_suffix(dds(PTL)) -->
495 parameter_type_list(PTL), !.
496param_direct_declarator_suffix(dds(IDList)) -->
497 identifier_list_opt(IDList), !.
498
499
500pointer([ptr(TQL)|T]) -->
501 ptr, type_qualifier_list_opt(TQL),
502 pointers(T).
503
504pointers([ptr(TQL)|T]) -->
505 ptr, type_qualifier_list_opt(TQL), !,
506 pointers(T).
507pointers([]) --> [].
508
509ptr --> [*].
510ptr --> [^]. 511
512type_qualifier_list([H|T]) -->
513 type_qualifier(H), !,
514 type_qualifier_list_opt(T).
515
516type_qualifier_list_opt([H|T]) -->
517 type_qualifier(H), !,
518 type_qualifier_list_opt(T).
519type_qualifier_list_opt([]) --> [].
520
521parameter_type_list(List) -->
522 parameter_list(List, T),
523 ( [',', '...']
524 -> {T=[param([], '...')]}
525 ; {T=[]}
526 ).
527
528parameter_type_list_opt(List) -->
529 parameter_type_list(List).
530parameter_type_list_opt([]) --> [].
531
532parameter_list([H|T0], T) -->
533 parameter_declaration(H),
534 ( [','], \+ ['...']
535 -> parameter_list(T0, T)
536 ; {T=T0}
537 ).
538
539parameter_declaration(param(S,D)) -->
540 declaration_specifiers(S),
541 ( declarator(D)
542 -> gcc_attributes_opt(_)
543 ; abstract_declarator_opt(D)
544 ).
545
546identifier_list([H|T]) -->
547 [id(H)],
548 ( [',']
549 -> identifier_list(T)
550 ; {T=[]}
551 ).
552
553identifier_list_opt(IDL) -->
554 identifier_list(IDL), !.
555identifier_list_opt([]) --> [].
556
557type_name(type_name(QL, D)) -->
558 specifier_qualifier_list(QL), abstract_declarator_opt(D).
559
560abstract_declarator(ad(AD,DAD)) -->
561 pointer_or_block(AD), !,
562 ( direct_abstract_declarator(DAD)
563 -> []
564 ; {DAD = (-)}
565 ).
566abstract_declarator(ad(-,DAD)) -->
567 direct_abstract_declarator(DAD).
568
569pointer_or_block(AD) -->
570 pointer(AD), !.
571pointer_or_block(AD) -->
572 block(AD).
580block([block(TQL)|T]) -->
581 [^], type_qualifier_list_opt(TQL),
582 blocks(T).
583
584blocks([block(TQL)|T]) -->
585 [^], type_qualifier_list_opt(TQL), !,
586 blocks(T).
587blocks([]) --> [].
588
589abstract_declarator_opt(AD) -->
590 abstract_declarator(AD), !.
591abstract_declarator_opt(ad(-,-)) --> [].
592
593direct_abstract_declarator(dad(AD,S)) -->
594 ( ['('], abstract_declarator(AD), [')']
595 -> []
596 ; {AD = (-)}
597 ),
598 direct_abstract_declarator_suffix(S).
599
600direct_abstract_declarator_suffix(dads(TQL, Ass)) -->
601 ['['],
602 type_qualifier_list_opt(TQL), assignment_expression_opt(Ass),
603 [']'], !.
604direct_abstract_declarator_suffix(dads(TQL, Ass)) -->
605 ['[', static],
606 type_qualifier_list_opt(TQL), assignment_expression(Ass),
607 [']'], !.
608direct_abstract_declarator_suffix(dads(TQL, Ass)) -->
609 ['['],
610 type_qualifier_list(TQL), [static], assignment_expression(Ass),
611 [']'], !.
612direct_abstract_declarator_suffix(dads(*)) -->
613 ['[',*,']'], !.
614direct_abstract_declarator_suffix(dads(PTL)) -->
615 ['('], parameter_type_list_opt(PTL), [')'], !.
616direct_abstract_declarator_suffix(-) -->
617 [].
618
619typedef_name(Name, Type) :-
620 defined_type(Name),
621 Type = user_type(Name).
622
623initializer(init(E)) -->
624 assignment_expression(E).
625initializer(init(IL)) -->
626 ['{'], initializer_list(IL), opt_comma, ['}'], !.
627
628initializer_list([H|T]) -->
629 initializer1(H), !,
630 ( [',']
631 -> initializer_list(T)
632 ; []
633 ).
634initializer_list([]) --> [].
635
636initializer1(init(D,I)) -->
637 designation(D), !,
638 initializer(I).
639initializer1(init(-,I)) -->
640 initializer(I).
641
642designation(D) -->
643 designator_list(D), [=], !.
644
645designator_list([H|T]) -->
646 designator(H),
647 designator_list_opt(T).
648
649designator_list_opt([H|T]) -->
650 designator(H), !,
651 designator_list_opt(T).
652designator_list_opt([]) --> [].
653
654designator([E]) -->
655 constant_expression(E).
656designator(.(Id)) -->
657 [id(Id)].
664gcc_attributes_opt([H|T]) -->
665 gcc_attributes(H), !,
666 gcc_attributes_opt(T).
667gcc_attributes_opt([]) --> [].
668
669gcc_attributes(gcc_attributes(List)) -->
670 ['__attribute__', '(', '('], gcc_attribute_list(List), [')', ')'].
671gcc_attributes(ASM) -->
672 asm(ASM).
673
674gcc_attribute_list(List) -->
675 [','], !,
676 gcc_attribute_list(List).
677gcc_attribute_list([H|T]) -->
678 gcc_attribute(H),
679 ( [',']
680 -> gcc_attribute_list(T)
681 ; {T=[]}
682 ).
683
684gcc_attribute(H) -->
685 gcc_attribute_name(Name),
686 ( ['(']
687 -> gcc_attribute_param_list(Params), [')'],
688 { H =.. [Name|Params] }
689 ; { H = Name }
690 ).
691
692gcc_attribute_name(H) --> [id(H)].
693gcc_attribute_name(H) --> [H], {atom(H)}.
694
695gcc_attribute_param_list([]), [')'] -->
696 [')'], !.
697gcc_attribute_param_list([H|T]) -->
698 gcc_attribute_param(Name),
699 ( {Name == introduced}, 700 [=],
701 version(V)
702 -> {H = (Name=V)}
703 ; {atom(Name)},
704 [=],
705 constant_expression(V)
706 -> {H = (Name=V)}
707 ; {H = Name}
708 ),
709 ( [',']
710 -> gcc_attribute_param_list(T)
711 ; {T=[]}
712 ).
713
714gcc_attribute_param(H) -->
715 gcc_attribute_name(H).
716gcc_attribute_param(H) -->
717 constant_expression(H).
718gcc_attribute_param(alignof(Decl)) -->
719 ['__alignof__', '('], declaration_specifiers(Decl), [')'].
720
721version(String) -->
722 [double(D), '.', i(I)],
723 !,
724 { format(string(String), '~w.~d', [D, I]) }.
725version(String) -->
726 [double(D)],
727 !,
728 { format(string(String), '~w', [D]) }.
729
730asm(ASM) -->
731 ['__asm__', '('], asm_list(Statements), [')'],
732 { ASM = asm(Statements) }.
733
734asm_list([H|T]) -->
735 [ str(H) ], !,
736 asm_list(T).
737asm_list([]) --> [].
738
739
740 743
744statement(S) --> labeled_statement(S).
745statement(S) --> compound_statement(S).
746statement(S) --> expression_statement(S).
747statement(S) --> selection_statement(S).
748statement(S) --> iteration_statement(S).
749statement(S) --> jump_statement(S).
750
751labeled_statement(label(L, Statement)) -->
752 [id(L), :], !, statement(Statement).
753labeled_statement(case(V, Statement)) -->
754 [case], constant_expression(V), [:], !, statement(Statement).
755labeled_statement(default(Statement)) -->
756 [default, :], !, statement(Statement).
757
758compound_statement(block(Statements)) -->
759 ['{'], block_item_list_opt(Statements), ['}'].
760
761block_item_list_opt([H|T]) -->
762 block_item(H), !,
763 block_item_list_opt(T).
764block_item_list_opt([]) --> [].
765
766block_item(H) --> declaration(H).
767block_item(H) --> statement(H).
768
769expression_statement(E) -->
770 expression_opt(E), [;], !.
771
772expression_opt(E) -->
773 expression(E), !.
774expression_opt(void) -->
775 [].
776
777selection_statement(if(Cond, If, Then)) -->
778 [if, '('], expression(Cond), [')'],
779 statement(If),
780 ( [else]
781 -> statement(Then)
782 ; {Then = void}
783 ).
784selection_statement(switch(Expr, Statement)) -->
785 [switch, '('], expression(Expr), [')'],
786 statement(Statement).
787
788iteration_statement(while(Expr, Statement)) -->
789 [while, '('], expression(Expr), [')'], statement(Statement).
790iteration_statement(do_while(Expr, Statement)) -->
791 [do], statement(Statement), [while, '('], expression(Expr), [')', ';'].
792iteration_statement(for(Init, Cond, Iter, Statement)) -->
793 [for, '('], expression_opt(Init), [;], expression_opt(Cond), [;],
794 expression_opt(Iter), [')'], statement(Statement).
795iteration_statement(for2(Decl, Expr1, Expr2, Statement)) -->
796 [for, '('], declaration(Decl), expression_opt(Expr1), [;],
797 expression_opt(Expr2), [')'], statement(Statement).
798
799jump_statement(goto(Id)) -->
800 [ goto, id(Id), ';' ].
801jump_statement(continue) -->
802 [ continue, ';' ].
803jump_statement(break) -->
804 [ break, ';' ].
805jump_statement(return(Expr)) -->
806 [ return ], expression_statement(Expr).
807
808 811
812translation_unit([H|T]) -->
813 external_declaration(H), !,
814 { update_types(H),
815 ( debugging(c99(unit))
816 -> print_term(H, [output(user_error)]), nl(user_error)
817 ; true
818 )
819 },
820 translation_unit(T).
821translation_unit(List) -->
822 skip_unit, !,
823 translation_unit(List).
824translation_unit([]) --> [].
825
826external_declaration(D) -->
827 declaration_specifiers(DS), !,
828 ( specifiers_declaration(DS, D)
829 ; function_definition(DS, D)
830 ).
831external_declaration(D) --> pp(D).
832
833function_definition(Specifiers,
834 function(Specifiers, Declarator, Params, Body)) -->
835 declarator(Declarator),
836 declaration_list_opt(Params),
837 compound_statement(Body).
838
839declaration_list_opt([H|T]) -->
840 declaration(H), !,
841 declaration_list_opt(T).
842declaration_list_opt([]) --> [].
843
844pp(pp(Line)) -->
845 [pp(Line)].
846
847 850
851skip_unit -->
852 here(Start),
853 skip_unit([]),
854 here(End),
855 { diff(Start, End, Skipped),
856 ( memberchk('__extension__', Skipped)
857 -> ( debugging(c99(extension))
858 -> print_message(informational, ffi(skipped_header(Skipped)))
859 ; true
860 )
861 ; print_message(warning, ffi(skipped_header(Skipped)))
862 )
863 }.
864
865skip_unit(Stack) --> open_bracket(Close), !, skip_unit([Close|Stack]).
866skip_unit(['}']) --> ['}'], !.
867skip_unit([Close|Stack]) --> [Close], !, skip_unit(Stack).
868skip_unit([]) --> [';'], !.
869skip_unit(Stack) --> [_], skip_unit(Stack).
870
871here(List, List, List).
872
873diff(Start, End, Skipped) :- Start == End, !, Skipped = [].
874diff([H|T0], End, [H|T]) :- diff(T0, End, T).
875
876open_bracket(')') --> ['('].
877open_bracket(']') --> ['['].
878open_bracket('}') --> ['{'].
879
880
881 884
885:- thread_local
886 typedef/1,
887 anon/2. 888
889init_state :-
890 retractall(typedef(_)),
891 retractall(anon(_,_)).
892
893defined_type(Name) :-
894 typedef(Name).
895
896update_types(decl(What, As, _GCC)) :-
897 memberchk(storage(typedef), What), !,
898 forall(( member(A, As),
899 declarator_name(A, Name)
900 ),
901 assertz(typedef(Name))).
902update_types(_).
903
904anon_id(Sort, Id) :-
905 ( retract(anon(Sort, I0))
906 -> I is I0+1
907 ; I = 1
908 ),
909 asserta(anon(Sort, I)),
910 atomic_list_concat(['_:', Sort, '_', I], Id).
911
912
913 916
917declarator_name(declarator(_Ptr, dd(Name, _)), Name) :-
918 atom(Name), !.
920declarator_name(declarator(_Ptr, dd(Declarator,_)), Name) :-
921 declarator_name(Declarator, Name).
922
923
924 927
928:- multifile
929 prolog:message//1. 930
931prolog:message(ffi(Msg)) -->
932 message(Msg).
933
934message(skipped_header(Tokens)) -->
935 [ 'FFI: Could not parse ~p'-[Tokens] ]