jhjourdan / C11parser

A correct C89/C90/C99/C11/C18 parser written using Menhir and OCaml
Other
190 stars 16 forks source link

Grammar railroad diagram #20

Closed mingodad closed 3 years ago

mingodad commented 3 years ago

I've done a experimental tool to convert bison grammars to a kind of EBNF understood by https://www.bottlecaps.de/rr/ui to generate railroad diagrams see bellow the converted parser.mly and with some hand made changes to allow view it at https://www.bottlecaps.de/rr/ui the order of the rules could be changed to a better view of the railroad diagrams. Copy and paste the EBNF bellow on https://www.bottlecaps.de/rr/ui tab Edit Grammar then switch to the tab View Diagram.

/*
From https://github.com/jhjourdan/C11parser/blob/master/parser.mly
*/

translation_unit_file ::=  external_declaration translation_unit_file | external_declaration EOF
external_declaration ::=  function_definition | declaration
function_definition ::=  function_definition1 declaration_list? compound_statement
declaration_list ::=  declaration | declaration_list declaration
function_definition1 ::=  declaration_specifiers declarator_varname
jump_statement ::=  "goto" general_identifier ";" | "continue" ";" | "break" ";" | "return" expression? ";"
iteration_statement ::=  "while" "(" expression ")" scoped | "do" scoped "while" "(" expression ")" ";" | "for" "(" expression? ";" expression? ";" expression? ")" scoped | "for" "(" declaration expression? ";" expression? ")" scoped
selection_statement ::=  "if" "(" expression ")" scoped "else" scoped | "if" "(" expression ")" scoped | "switch" "(" expression ")" scoped
expression_statement ::=  expression? ";"
block_item ::=  declaration | statement
block_item_list ::=  block_item_list? block_item
compound_statement ::=  "{" block_item_list? "}"
labeled_statement ::=  general_identifier ":" statement | "case" constant_expression ":" statement | "default" ":" statement
statement ::=  labeled_statement | scoped | expression_statement | scoped | scoped | jump_statement
static_assert_declaration ::=  "_Static_assert" "(" constant_expression "," STRING_LITERAL ")" ";"
designator ::=  "[" constant_expression "]" | "." general_identifier
designator_list ::=  designator_list? designator
designation ::=  designator_list "="
initializer_list ::=  designation? c_initializer | initializer_list "," designation? c_initializer
c_initializer ::=  assignment_expression | "{" initializer_list ","? "}"
direct_abstract_declarator ::=  "(" save_context abstract_declarator ")" | direct_abstract_declarator? "[" ioption assignment_expression? "]" | direct_abstract_declarator? "[" "static" type_qualifier_list? assignment_expression "]" | direct_abstract_declarator? "[" type_qualifier_list "static" assignment_expression "]" | direct_abstract_declarator? "[" "*" "]" | ioption "(" scoped? ")"
abstract_declarator ::=  pointer | ioption direct_abstract_declarator
type_name ::=  specifier_qualifier_list abstract_declarator?
identifier_list ::=  var_name | identifier_list "," var_name
parameter_declaration ::=  declaration_specifiers declarator_varname | declaration_specifiers abstract_declarator?
parameter_list ::=  parameter_declaration | parameter_list "," parameter_declaration
parameter_type_list ::=  parameter_list option save_context
type_qualifier_list ::=  type_qualifier_list? type_qualifier
pointer ::=  "*" type_qualifier_list? pointer?
direct_declarator ::=  general_identifier | "(" save_context declarator ")" | direct_declarator "[" type_qualifier_list? assignment_expression? "]" | direct_declarator "[" "static" type_qualifier_list? assignment_expression "]" | direct_declarator "[" type_qualifier_list "static" assignment_expression "]" | direct_declarator "[" type_qualifier_list? "*" "]" | direct_declarator "(" scoped ")" | direct_declarator "(" save_context identifier_list? ")"
declarator ::=  ioption direct_declarator
alignment_specifier ::=  "_Alignas" "(" type_name ")" | "_Alignas" "(" constant_expression ")"
function_specifier ::=  "inline" | "_Noreturn"
type_qualifier ::=  "const" | "restrict" | "volatile" | "_Atomic"
atomic_type_specifier ::=  "_Atomic" "(" type_name ")" | "_Atomic" ATOMIC_LPAREN type_name ")"
enumeration_constant ::=  general_identifier
enumerator ::=  enumeration_constant | enumeration_constant "=" constant_expression
enumerator_list ::=  enumerator | enumerator_list "," enumerator
enum_specifier ::=  "enum" general_identifier? "{" enumerator_list ","? "}" | "enum" general_identifier
struct_declarator ::=  declarator | declarator? ":" constant_expression
struct_declarator_list ::=  struct_declarator | struct_declarator_list "," struct_declarator
specifier_qualifier_list ::=  list_eq1 | list_ge1
struct_declaration ::=  specifier_qualifier_list struct_declarator_list? ";" | static_assert_declaration
struct_declaration_list ::=  struct_declaration | struct_declaration_list struct_declaration
struct_or_union ::=  "struct" | "union"
struct_or_union_specifier ::=  struct_or_union general_identifier? "{" struct_declaration_list "}" | struct_or_union general_identifier
type_specifier_unique ::=  "void" | "_Bool" | atomic_type_specifier | struct_or_union_specifier | enum_specifier | typedef_name_spec
type_specifier_nonunique ::=  "char" | "short" | "int" | "long" | "float" | "double" | "signed" | "unsigned" | "_Complex"
storage_class_specifier ::=  "extern" | "static" | "_Thread_local" | "auto" | "register"
init_declarator ::=  declarator | declarator "=" c_initializer
init_declarator_list ::=  init_declarator | init_declarator_list "," init_declarator
declaration_specifiers_typedef ::=  list_eq1_eq1 | list_eq1_ge1
declaration_specifiers ::=  list_eq1 | list_ge1
declaration_specifier ::=  storage_class_specifier | type_qualifier | function_specifier | alignment_specifier
declaration ::=  declaration_specifiers init_declarator_list? ";" | declaration_specifiers_typedef init_declarator_list? ";" | static_assert_declaration
constant_expression ::=  conditional_expression
expression ::=  assignment_expression | expression "," assignment_expression
assignment_operator ::=  "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "<<=" | ">>=" | "&=" | "^=" | "|="
assignment_expression ::=  conditional_expression | unary_expression assignment_operator assignment_expression
conditional_expression ::=  logical_or_expression | logical_or_expression "?" expression ":" conditional_expression
logical_or_expression ::=  logical_and_expression | logical_or_expression "||" logical_and_expression
logical_and_expression ::=  inclusive_or_expression | logical_and_expression "&&" inclusive_or_expression
inclusive_or_expression ::=  exclusive_or_expression | inclusive_or_expression "|" exclusive_or_expression
exclusive_or_expression ::=  and_expression | exclusive_or_expression "^" and_expression
and_expression ::=  equality_expression | and_expression "&" equality_expression
equality_expression ::=  relational_expression | equality_expression equality_operator relational_expression
equality_operator ::=  "==" | "!="
relational_expression ::=  shift_expression | relational_expression relational_operator shift_expression
relational_operator ::=  "<" | ">" | "<=" | ">="
shift_expression ::=  additive_expression | shift_expression shift_operator additive_expression
shift_operator ::=  "<<" | ">>"
additive_expression ::=  multiplicative_expression | additive_expression additive_operator multiplicative_expression
additive_operator ::=  "+" | "-"
multiplicative_expression ::=  cast_expression | multiplicative_expression multiplicative_operator cast_expression
multiplicative_operator ::=  "*" | "/" | "%"
cast_expression ::=  unary_expression | "(" type_name ")" cast_expression
unary_operator ::=  "&" | "*" | "+" | "-" | "~" | "!"
unary_expression ::=  postfix_expression | "++" unary_expression | "--" unary_expression | unary_operator cast_expression | "sizeof" unary_expression | "sizeof" "(" type_name ")" | "_Alignof" "(" type_name ")"
argument_expression_list ::=  assignment_expression | argument_expression_list "," assignment_expression
postfix_expression ::=  primary_expression | postfix_expression "[" expression "]" | postfix_expression "(" argument_expression_list? ")" | postfix_expression "." general_identifier | postfix_expression "->" general_identifier | postfix_expression "++" | postfix_expression "--" | "(" type_name ")" "{" initializer_list ","? "}"
generic_association ::=  type_name ":" assignment_expression | "default" ":" assignment_expression
generic_assoc_list ::=  generic_association | generic_assoc_list "," generic_association
generic_selection ::=  "_Generic" "(" assignment_expression "," generic_assoc_list ")"
primary_expression ::=  var_name | CONSTANT | STRING_LITERAL | "(" expression ")" | generic_selection
declarator_typedefname ::=  declarator
declarator_varname ::=  declarator
scoped ::=  save_context X
save_context ::=  /* empty */
general_identifier ::=  typedef_name | var_name
typedef_name_spec ::=  typedef_name
var_name ::=  NAME VARIABLE
typedef_name ::=  NAME TYPE
list_eq1_ge1 ::=  A list_ge1 | B list_eq1 | B list_eq1_ge1 | C list_eq1_ge1
list_eq1_eq1 ::=  A list_eq1 | B list_eq1 | C list_eq1_eq1
list_ge1 ::=  A B* | A list_ge1 | B list_ge1
list_eq1 ::=  A B* | B list_eq1
list ::=  /* empty */ | X list
option ::=  ioption
ioption ::=  /* empty */ | X

// Tokens

ELLIPSIS ::= "..."
ADD_ASSIGN ::= "+="
SUB_ASSIGN ::= "-="
MUL_ASSIGN ::= "*="
DIV_ASSIGN ::= "/="
MOD_ASSIGN ::= "%="
OR_ASSIGN ::= "|="
AND_ASSIGN ::= "&="
XOR_ASSIGN ::= "^="
LEFT_ASSIGN ::= "<<="
RIGHT_ASSIGN ::= ">>="
LEFT ::= "<<"
RIGHT ::= ">>"
EQEQ ::= "=="
NEQ ::= "!="
LEQ ::= "<="
GEQ ::= ">="
EQ ::= "="
LT ::= "<"
GT ::= ">"
INC ::= "++"
DEC ::= "--"
PTR ::= "->"
PLUS ::= "+"
MINUS ::= "-"
STAR ::= "*"
SLASH ::= "/"
PERCENT ::= "%"
BANG ::= "!"
ANDAND ::= "&&"
BARBAR ::= "||"
AND ::= "&"
BAR ::= "|"
HAT ::= "^"
QUESTION ::= "?"
COLON ::= ":"
TILDE ::= "~"
LBRACE ::= "{"|"<%"
RBRACE ::= "}"|"%>"
LBRACK ::= "["|"<:"
RBRACK ::= "]"|":>"
LPAREN ::= "("
RPAREN ::= ")"
SEMICOLON ::= ";"
COMMA ::= ","
DOT ::= "."
ALIGNAS ::= "_Alignas"
ALIGNOF ::= "_Alignof"
ATOMIC ::= "_Atomic"
BOOL ::= "_Bool"
COMPLEX ::= "_Complex"
GENERIC ::= "_Generic"
IMAGINARY ::= "_Imaginary"
NORETURN ::= "_Noreturn"
STATIC_ASSERT ::= "_Static_assert"
THREAD_LOCAL ::= "_Thread_local"
AUTO ::= "auto"
BREAK ::= "break"
CASE ::= "case"
CHAR ::= "char"
CONST ::= "const"
CONTINUE ::= "continue"
DEFAULT ::= "default"
DO ::= "do"
DOUBLE ::= "double"
ELSE ::= "else"
ENUM ::= "enum"
EXTERN ::= "extern"
FLOAT ::= "float"
FOR ::= "for"
GOTO ::= "goto"
IF ::= "if"
INLINE ::= "inline"
INT ::= "int"
LONG ::= "long"
REGISTER ::= "register"
RESTRICT ::= "restrict"
RETURN ::= "return"
SHORT ::= "short"
SIGNED ::= "signed"
SIZEOF ::= "sizeof"
STATIC ::= "static"
STRUCT ::= "struct"
SWITCH ::= "switch"
TYPEDEF ::= "typedef"
UNION ::= "union"
UNSIGNED ::= "unsigned"
VOID ::= "void"
VOLATILE ::= "volatile"
WHILE ::= "while"
jhjourdan commented 3 years ago

Dear @mingodad,

I appreciate that you inform us that this tool exists and produces beautiful railroad grammars for the our grammar for C11, but please do not use Github issues for things which are not issues.

I am closing this.