@@ -47,8 +47,6 @@ keyword = "alignas" | "alignof" | "auto" | "bool"
47
47
48
48
universal_character_name = "\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}";
49
49
50
- identifier = "[_a-zA-Z]\w*";
51
-
52
50
constant =
53
51
| integer_constant
54
52
| floating_constant
@@ -447,7 +445,6 @@ iteration_statement =
447
445
448
446
jump_statement = (("goto" identifier) | "continue" | "break" | ("return" expression?)) ";";
449
447
450
- ##root translation_unit
451
448
translation_unit = external_declaration;
452
449
453
450
external_declaration = function_definition | declaration;
@@ -460,3 +457,158 @@ n_char_sequence = {digit | nondigit};
460
457
n_wchar_sequence = {digit | nondigit};
461
458
d_char_sequence = {digit | nondigit};
462
459
d_wchar_sequence = {digit | nondigit};
460
+
461
+ group_part =
462
+ | control_line
463
+ | if_section
464
+ | text_line
465
+ | ("#" non_directive);
466
+
467
+ if_section = if_group elif_group* else_group? endif_line;
468
+
469
+ if_group =
470
+ | ("#if\b" constant_expression group_part*)
471
+ | ("#ifdef\b" identifier group_part*)
472
+ | ("#ifndef\b" identifier group_part*);
473
+ ##groups if_group %#if %#ifdef %#ifndef
474
+
475
+ elif_group =
476
+ | ("#elif\b" constant_expression group_part*)
477
+ | ("#elifdef\b" identifier group_part*)
478
+ | ("#elifndef\b" identifier group_part*);
479
+ ##groups elif_group %#elif %#elifdef %#elifndef
480
+
481
+ else_group = "#else\b" group_part*;
482
+
483
+ endif_line = "#endif\b";
484
+
485
+ control_line = "#" (
486
+ | ("include\b" header_name)
487
+ | ("embed\b" header_name)
488
+ | ("define\b" identifier replacement_list)
489
+ | ("define\b" identifier "\(" identifier_list? "\)" replacement_list)
490
+ | ("define\b" identifier "\(" "\.\.\." "\)" replacement_list)
491
+ | ("define\b" identifier "\(" identifier_list "," "\.\.\." "\)" replacement_list)
492
+ | ("undef\b" identifier)
493
+ | ("line\b" pp_tokens)
494
+ | ("error\b" preprocessing_token*)
495
+ | ("warning\b" preprocessing_token*)
496
+ | ("pragma\b" preprocessing_token*)
497
+ );
498
+
499
+ text_line = pp_tokens;
500
+
501
+ non_directive = pp_tokens;
502
+
503
+ # a ( character not immediately preceded by white space
504
+ # TODO: Actually do a look-behind and use this
505
+ # lparen = "\(";
506
+
507
+ replacement_list = preprocessing_token*;
508
+
509
+ pp_tokens = preprocessing_token preprocessing_token*;
510
+
511
+ identifier_list = identifier {"," identifier};
512
+
513
+ pp_parameter = pp_parameter_name pp_parameter_clause?;
514
+
515
+ pp_parameter_name = pp_standard_parameter | pp_prefixed_parameter;
516
+
517
+ pp_standard_parameter = identifier;
518
+
519
+ pp_prefixed_parameter = identifier "::" identifier;
520
+
521
+ pp_parameter_clause = "\(" pp_balanced_token* "\)";
522
+
523
+ pp_balanced_token =
524
+ | __pp_token_no_grouping
525
+ | ("\(" pp_balanced_token* "\)")
526
+ | ("\[" pp_balanced_token* "\]")
527
+ | ("\{" pp_balanced_token* "\}");
528
+
529
+ # any pp_token other than a parenthesis, a bracket, or a brace
530
+ __pp_token_no_grouping =
531
+ | __pp_token_base
532
+ | __punctuator_base
533
+ | __punctuator_angle_brackets;
534
+
535
+ embed_parameter_sequence = pp_parameter*;
536
+
537
+ defined_macro_expression = "defined\b" (identifier | ("\(" identifier "\)"));
538
+
539
+ # any preprocessing_token other than >
540
+ h_preprocessing_token =
541
+ | __pp_token_base
542
+ | __punctuator_base
543
+ | __punctuator_grouping;
544
+
545
+ h_pp_tokens = h_preprocessing_token*;
546
+
547
+ header_name_tokens = string_literal | ("<" h_pp_tokens ">");
548
+
549
+ has_include_expression = "__has_include\b" "\(" (header_name | header_name_tokens) "\)";
550
+
551
+ has_embed_expression =
552
+ | ("__has_embed\b" "\(" (header_name embed_parameter_sequence?) "\)")
553
+ | ("__has_embed\b" "\(" (header_name_tokens pp_balanced_token*) "\)");
554
+
555
+ has_c_attribute_express = "__has_c_attribute\b" "\(" pp_tokens "\)";
556
+
557
+ va_opt_replacement = "__VA_OPT__\b" "\(" preprocessing_token* "\)";
558
+
559
+ standard_pragma = "#" "pragma\b" "STDC\b" (
560
+ | ("FP_CONTRACT\b" on_off_switch)
561
+ | ("FENV_ACCESS\b" on_off_switch)
562
+ | ("FENV_DEC_ROUND\b" dec_direction)
563
+ | ("FENV_ROUND\b" direction)
564
+ | ("CX_LIMITED_RANGE\b" on_off_switch)
565
+ );
566
+
567
+ on_off_switch = "ON\b" | "OFF\b" | "DEFAULT\b";
568
+
569
+ direction =
570
+ | "FE_DOWNWARD\b"
571
+ | "FE_TONEAREST\b"
572
+ | "FE_TONEARESTFROMZERO\b"
573
+ | "FE_TOWARDZERO\b"
574
+ | "FE_UPWARD\b"
575
+ | "FE_DYNAMIC\b";
576
+
577
+ dec_direction =
578
+ | "FE_DEC_DOWNWARD\b"
579
+ | "FE_DEC_TONEAREST\b"
580
+ | "FE_DEC_TONEARESTFROMZERO\b"
581
+ | "FE_DEC_TOWARDZERO\b"
582
+ | "FE_DEC_UPWARD\b"
583
+ | "FE_DEC_DYNAMIC\b";
584
+
585
+ preprocessing_token = __pp_token_base | punctuator;
586
+ #| each universal_character_name that cannot be one of the above
587
+ #| each non_white_space character that cannot be one of the above
588
+
589
+ __pp_token_base =
590
+ | header_name
591
+ | identifier
592
+ | pp_number
593
+ | character_constant
594
+ | string_literal;
595
+
596
+ header_name = __header_name | string_literal;
597
+
598
+ __header_name = '<[^\n>]*>|"[^\n\"]*"';
599
+
600
+ # header_name = ("<" h_char_sequence ">") | ('"' q_char_sequence '"');
601
+
602
+ # h_char_sequence = h_char*;
603
+
604
+ # # any member of the source character set except the character and >
605
+ # h_char = digit | nondigit | __punctuator_base | __punctuator_grouping | __punctuator_left_angle_brackets;
606
+
607
+ # q_char_sequence = q_char*;
608
+
609
+ # # any member of the source character set except the character and "
610
+ # q_char = digit | nondigit | punctuator;
611
+
612
+ pp_number = "\.?[0-9](['\w]|(e|E|p|P)(\+|-)|\.)*";
613
+
614
+ identifier = "[_a-zA-Z]\w*";
0 commit comments