Created
September 25, 2017 13:16
-
-
Save bit-hack/a18ccf9f8ec1acca98e26bc132db0786 to your computer and use it in GitHub Desktop.
Auto generated recursive ascent parser skeleton
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Auto Generated From ANSI C BNF using grammar adapted from Section A13 of The | |
// C programming language, 2nd edition, by Brian W. Kernighan and Dennis M. | |
// Ritchie, Prentice Hall, 1988. | |
#include <cassert> | |
#include <array> | |
#include <vector> | |
struct ast_node_t {}; | |
bool match(int index, int token); | |
template <typename node_t> | |
ast_node_t * emit(int num_tokens) { | |
return nullptr; | |
} | |
bool run_match(ast_node_t * (*matcher)(void)) { | |
return nullptr != matcher(); | |
} | |
// terminals | |
enum { | |
eIDENTIFIER, | |
eFLOATING_CONSTANT, | |
eSTRING, | |
eCHARACTER_CONSTANT, | |
eENUMERATION_CONSTANT, | |
eINTEGER_CONSTANT, | |
eGTEQUALS, | |
eSHIFTR, | |
eVARARG, | |
eINT, | |
eINCREMENT, | |
eSHIFTL, | |
eFLOAT, | |
eWHILE, | |
eUNSIGNED, | |
eMODASSIGN, | |
eSTATIC, | |
eDIV, | |
eSIZEOF, | |
eNOTEQUALS, | |
eIF, | |
eNOT, | |
eTYPEDEF, | |
eMOD, | |
eSTRUCT, | |
eSHIFTLASSIGN, | |
eAND, | |
eRPAREN, | |
eLPAREN, | |
eADD, | |
eMUL, | |
eSUB, | |
eCOMMA, | |
eLONG, | |
eDOT, | |
eSWITCH, | |
eSHIFTRASSIGN, | |
eVOLATILE, | |
eXORASSIGN, | |
eSEMICOLON, | |
eCOLON, | |
eASSIGN, | |
eLOGOR, | |
eTERNARY, | |
eGT, | |
eMULASSIGN, | |
eBITORASSIGN, | |
eRETURN, | |
eGOTO, | |
eDO, | |
eEQUALS, | |
eAUTO, | |
eVOID, | |
eENUM, | |
eBITANDASSIGN, | |
eELSE, | |
eBREAK, | |
eLOGAND, | |
eEXTERN, | |
eCONST, | |
eLSUBSCRIPT, | |
eRSUBSCRIPT, | |
eXOR, | |
eCASE, | |
eCHAR, | |
eSHORT, | |
eFOR, | |
eDEFAULT, | |
eDOUBLE, | |
eDECREMENT, | |
eREGISTER, | |
eRBRACE, | |
eSIGNED, | |
eLT, | |
eUNION, | |
eDIVASSIGN, | |
eCONTINUE, | |
eSUBASSIGN, | |
eLBRACE, | |
eARROW, | |
ELTEQUALS, | |
eBITOR, | |
eADDASSIGN, | |
eBITNOT, | |
_END_OF_TERMINALS | |
}; | |
// non-terminals | |
enum { | |
eSTORAGE_CLASS_SPECIFIER = _END_OF_TERMINALS, | |
eEXPRESSION_STATEMENT, | |
eTYPE_NAME, | |
eCONSTANT, | |
eUNARY_EXPRESSION, | |
eCONDITIONAL_EXPRESSION, | |
eSTRUCT_OR_UNION_SPECIFIER, | |
eEXCLUSIVE_OR_EXPRESSION, | |
eINITIALIZER, | |
eENUMERATOR_LIST, | |
eSTRUCT_DECLARATION, | |
eITERATION_STATEMENT, | |
eAND_EXPRESSION, | |
eEXTERNAL_DECLARATION, | |
eTYPE_SPECIFIER, | |
eSPECIFIER_QUALIFIER, | |
eCOMPOUND_STATEMENT, | |
eINCLUSIVE_OR_EXPRESSION, | |
ePOINTER, | |
eSELECTION_STATEMENT, | |
ePOSTFIX_EXPRESSION, | |
eSHIFT_EXPRESSION, | |
eRELATIONAL_EXPRESSION, | |
eSTATEMENT, | |
eCAST_EXPRESSION, | |
eINITIALIZER_LIST, | |
eSTRUCT_DECLARATOR_LIST, | |
eLOGICAL_OR_EXPRESSION, | |
eUNARY_OPERATOR, | |
eASSIGNMENT_OPERATOR, | |
eSTRUCT_OR_UNION, | |
eENUMERATOR, | |
eASSIGNMENT_EXPRESSION, | |
ePARAMETER_TYPE_LIST, | |
ePARAMETER_DECLARATION, | |
eDIRECT_DECLARATOR, | |
eDECLARATOR, | |
eDECLARATION_SPECIFIER, | |
eADDITIVE_EXPRESSION, | |
ePRIMARY_EXPRESSION, | |
eDECLARATION, | |
eLOGICAL_AND_EXPRESSION, | |
eTRANSLATION_UNIT, | |
eTYPEDEF_NAME, | |
eEQUALITY_EXPRESSION, | |
eJUMP_STATEMENT, | |
eSTRUCT_DECLARATOR, | |
eFUNCTION_DEFINITION, | |
ePARAMETER_LIST, | |
eMULTIPLICATIVE_EXPRESSION, | |
eTYPE_QUALIFIER, | |
eLABELED_STATEMENT, | |
eABSTRACT_DECLARATOR, | |
eENUM_SPECIFIER, | |
eCONSTANT_EXPRESSION, | |
eINIT_DECLARATOR, | |
eDIRECT_ABSTRACT_DECLARATOR, | |
eEXPRESSION, | |
}; | |
struct ast_storage_class_specifier_t : public ast_node_t { | |
// auto | |
// register | |
// static | |
// extern | |
// typedef | |
ast_node_t *node; | |
void init(ast_node_t* in, size_t num) { assert(num==1); node = in; } | |
size_t size() const { return 1; } | |
ast_node_t *& operator [] (size_t i) { assert(i==0); return node; } | |
}; | |
struct ast_expression_statement_t : public ast_node_t { | |
// {<expression>}? ; | |
std::array<ast_node_t*, 2> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_selection_statement_t : public ast_node_t { | |
// if ( <expression> ) <statement> | |
// if ( <expression> ) <statement> else <statement> | |
// switch ( <expression> ) <statement> | |
std::array<ast_node_t*, 7> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_constant_t : public ast_node_t { | |
// <integer_constant> | |
// <character_constant> | |
// <floating_constant> | |
// <enumeration_constant> | |
ast_node_t *node; | |
void init(ast_node_t* in, size_t num) { assert(num==1); node = in; } | |
size_t size() const { return 1; } | |
ast_node_t *& operator [] (size_t i) { assert(i==0); return node; } | |
}; | |
struct ast_unary_expression_t : public ast_node_t { | |
// <postfix_expression> | |
// ++ <unary_expression> | |
// -- <unary_expression> | |
// <unary_operator> <cast_expression> | |
// sizeof <unary_expression> | |
// sizeof <type_name> | |
std::array<ast_node_t*, 2> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_struct_or_union_specifier_t : public ast_node_t { | |
// <struct_or_union> <identifier> { {<struct_declaration>}+ | |
// <struct_or_union> { {<struct_declaration>}+ | |
// <struct_or_union> <identifier> | |
std::vector<ast_node_t*> nodes; | |
void init(ast_node_t* in, size_t num) { | |
nodes.resize(num); | |
for (size_t i=0; i<num; ++i) nodes[i] = in + i; | |
} | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_exclusive_or_expression_t : public ast_node_t { | |
// <and_expression> | |
// <exclusive_or_expression> ^ <and_expression> | |
std::array<ast_node_t*, 3> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_initializer_t : public ast_node_t { | |
// <assignment_expression> | |
// { <initializer_list> } | |
// { <initializer_list> , } | |
std::array<ast_node_t*, 4> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_enumerator_list_t : public ast_node_t { | |
// <enumerator> | |
// <enumerator_list> , <enumerator> | |
std::array<ast_node_t*, 3> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_struct_declaration_t : public ast_node_t { | |
// {<specifier_qualifier>}* | |
std::vector<ast_node_t*> nodes; | |
void init(ast_node_t* in, size_t num) { | |
nodes.resize(num); | |
for (size_t i=0; i<num; ++i) nodes[i] = in + i; | |
} | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_pointer_t : public ast_node_t { | |
// * {<type_qualifier>}* | |
std::vector<ast_node_t*> nodes; | |
void init(ast_node_t* in, size_t num) { | |
nodes.resize(num); | |
for (size_t i=0; i<num; ++i) nodes[i] = in + i; | |
} | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_and_expression_t : public ast_node_t { | |
// <equality_expression> | |
// <and_expression> & <equality_expression> | |
std::array<ast_node_t*, 3> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_external_declaration_t : public ast_node_t { | |
// <function_definition> | |
// <declaration> | |
ast_node_t *node; | |
void init(ast_node_t* in, size_t num) { assert(num==1); node = in; } | |
size_t size() const { return 1; } | |
ast_node_t *& operator [] (size_t i) { assert(i==0); return node; } | |
}; | |
struct ast_type_specifier_t : public ast_node_t { | |
// void | |
// char | |
// short | |
// int | |
// long | |
// float | |
// double | |
// signed | |
// unsigned | |
// <struct_or_union_specifier> | |
// <enum_specifier> | |
// <typedef_name> | |
ast_node_t *node; | |
void init(ast_node_t* in, size_t num) { assert(num==1); node = in; } | |
size_t size() const { return 1; } | |
ast_node_t *& operator [] (size_t i) { assert(i==0); return node; } | |
}; | |
struct ast_specifier_qualifier_t : public ast_node_t { | |
// <type_specifier> | |
// <type_qualifier> | |
ast_node_t *node; | |
void init(ast_node_t* in, size_t num) { assert(num==1); node = in; } | |
size_t size() const { return 1; } | |
ast_node_t *& operator [] (size_t i) { assert(i==0); return node; } | |
}; | |
struct ast_compound_statement_t : public ast_node_t { | |
// { {<declaration>}* | |
std::vector<ast_node_t*> nodes; | |
void init(ast_node_t* in, size_t num) { | |
nodes.resize(num); | |
for (size_t i=0; i<num; ++i) nodes[i] = in + i; | |
} | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_inclusive_or_expression_t : public ast_node_t { | |
// <exclusive_or_expression> | |
// <inclusive_or_expression> | <exclusive_or_expression> | |
std::array<ast_node_t*, 3> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_iteration_statement_t : public ast_node_t { | |
// while ( <expression> ) <statement> | |
// do <statement> while ( <expression> ) ; | |
// for ( {<expression>}? ; {<expression>}? ; {<expression>}? ) <statement> | |
std::array<ast_node_t*, 9> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_type_name_t : public ast_node_t { | |
// {<specifier_qualifier>}+ | |
std::vector<ast_node_t*> nodes; | |
void init(ast_node_t* in, size_t num) { | |
nodes.resize(num); | |
for (size_t i=0; i<num; ++i) nodes[i] = in + i; | |
} | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_postfix_expression_t : public ast_node_t { | |
// <primary_expression> | |
// <postfix_expression> [ <expression> ] | |
// <postfix_expression> ( {<assignment_expression>}* | |
// <postfix_expression> . <identifier> | |
// <postfix_expression> -> <identifier> | |
// <postfix_expression> ++ | |
// <postfix_expression> -- | |
std::vector<ast_node_t*> nodes; | |
void init(ast_node_t* in, size_t num) { | |
nodes.resize(num); | |
for (size_t i=0; i<num; ++i) nodes[i] = in + i; | |
} | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_typedef_name_t : public ast_node_t { | |
// <identifier> | |
ast_node_t *node; | |
void init(ast_node_t* in, size_t num) { assert(num==1); node = in; } | |
size_t size() const { return 1; } | |
ast_node_t *& operator [] (size_t i) { assert(i==0); return node; } | |
}; | |
struct ast_enumerator_t : public ast_node_t { | |
// <identifier> | |
// <identifier> = <constant_expression> | |
std::array<ast_node_t*, 3> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_relational_expression_t : public ast_node_t { | |
// <shift_expression> | |
// <relational_expression> < <shift_expression> | |
// <relational_expression> > <shift_expression> | |
// <relational_expression> <= <shift_expression> | |
// <relational_expression> >= <shift_expression> | |
std::array<ast_node_t*, 3> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_statement_t : public ast_node_t { | |
// <labeled_statement> | |
// <expression_statement> | |
// <compound_statement> | |
// <selection_statement> | |
// <iteration_statement> | |
// <jump_statement> | |
ast_node_t *node; | |
void init(ast_node_t* in, size_t num) { assert(num==1); node = in; } | |
size_t size() const { return 1; } | |
ast_node_t *& operator [] (size_t i) { assert(i==0); return node; } | |
}; | |
struct ast_unary_operator_t : public ast_node_t { | |
// & | |
// * | |
// + | |
// - | |
// ~ | |
// ! | |
ast_node_t *node; | |
void init(ast_node_t* in, size_t num) { assert(num==1); node = in; } | |
size_t size() const { return 1; } | |
ast_node_t *& operator [] (size_t i) { assert(i==0); return node; } | |
}; | |
struct ast_cast_expression_t : public ast_node_t { | |
// <unary_expression> | |
// ( <type_name> ) <cast_expression> | |
std::array<ast_node_t*, 4> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_init_declarator_t : public ast_node_t { | |
// <declarator> | |
// <declarator> = <initializer> | |
std::array<ast_node_t*, 3> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_struct_declarator_list_t : public ast_node_t { | |
// <struct_declarator> | |
// <struct_declarator_list> , <struct_declarator> | |
std::array<ast_node_t*, 3> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_logical_or_expression_t : public ast_node_t { | |
// <logical_and_expression> | |
// <logical_or_expression> || <logical_and_expression> | |
std::array<ast_node_t*, 3> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_constant_expression_t : public ast_node_t { | |
// <conditional_expression> | |
ast_node_t *node; | |
void init(ast_node_t* in, size_t num) { assert(num==1); node = in; } | |
size_t size() const { return 1; } | |
ast_node_t *& operator [] (size_t i) { assert(i==0); return node; } | |
}; | |
struct ast_assignment_operator_t : public ast_node_t { | |
// = | |
// *= | |
// /= | |
// %= | |
// += | |
// -= | |
// <<= | |
// >>= | |
// &= | |
// ^= | |
// |= | |
ast_node_t *node; | |
void init(ast_node_t* in, size_t num) { assert(num==1); node = in; } | |
size_t size() const { return 1; } | |
ast_node_t *& operator [] (size_t i) { assert(i==0); return node; } | |
}; | |
struct ast_struct_or_union_t : public ast_node_t { | |
// struct | |
// union | |
ast_node_t *node; | |
void init(ast_node_t* in, size_t num) { assert(num==1); node = in; } | |
size_t size() const { return 1; } | |
ast_node_t *& operator [] (size_t i) { assert(i==0); return node; } | |
}; | |
struct ast_declaration_specifier_t : public ast_node_t { | |
// <storage_class_specifier> | |
// <type_specifier> | |
// <type_qualifier> | |
ast_node_t *node; | |
void init(ast_node_t* in, size_t num) { assert(num==1); node = in; } | |
size_t size() const { return 1; } | |
ast_node_t *& operator [] (size_t i) { assert(i==0); return node; } | |
}; | |
struct ast_assignment_expression_t : public ast_node_t { | |
// <conditional_expression> | |
// <unary_expression> <assignment_operator> <assignment_expression> | |
std::array<ast_node_t*, 3> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_parameter_type_list_t : public ast_node_t { | |
// <parameter_list> | |
// <parameter_list> , ... | |
std::array<ast_node_t*, 3> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_parameter_declaration_t : public ast_node_t { | |
// {<declaration_specifier>}+ | |
// {<declaration_specifier>}+ | |
// {<declaration_specifier>}+ | |
std::vector<ast_node_t*> nodes; | |
void init(ast_node_t* in, size_t num) { | |
nodes.resize(num); | |
for (size_t i=0; i<num; ++i) nodes[i] = in + i; | |
} | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_direct_declarator_t : public ast_node_t { | |
// <identifier> | |
// ( <declarator> ) | |
// <direct_declarator> [ {<constant_expression>}? ] | |
// <direct_declarator> ( <parameter_type_list> ) | |
// <direct_declarator> ( {<identifier>}* | |
std::vector<ast_node_t*> nodes; | |
void init(ast_node_t* in, size_t num) { | |
nodes.resize(num); | |
for (size_t i=0; i<num; ++i) nodes[i] = in + i; | |
} | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_declarator_t : public ast_node_t { | |
// {<pointer>}? <direct_declarator> | |
std::array<ast_node_t*, 2> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_additive_expression_t : public ast_node_t { | |
// <multiplicative_expression> | |
// <additive_expression> + <multiplicative_expression> | |
// <additive_expression> - <multiplicative_expression> | |
std::array<ast_node_t*, 3> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_primary_expression_t : public ast_node_t { | |
// <identifier> | |
// <constant> | |
// <string> | |
// ( <expression> ) | |
std::array<ast_node_t*, 3> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_declaration_t : public ast_node_t { | |
// {<declaration_specifier>}+ | |
std::vector<ast_node_t*> nodes; | |
void init(ast_node_t* in, size_t num) { | |
nodes.resize(num); | |
for (size_t i=0; i<num; ++i) nodes[i] = in + i; | |
} | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_logical_and_expression_t : public ast_node_t { | |
// <inclusive_or_expression> | |
// <logical_and_expression> && <inclusive_or_expression> | |
std::array<ast_node_t*, 3> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_shift_expression_t : public ast_node_t { | |
// <additive_expression> | |
// <shift_expression> << <additive_expression> | |
// <shift_expression> >> <additive_expression> | |
std::array<ast_node_t*, 3> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_equality_expression_t : public ast_node_t { | |
// <relational_expression> | |
// <equality_expression> == <relational_expression> | |
// <equality_expression> != <relational_expression> | |
std::array<ast_node_t*, 3> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_jump_statement_t : public ast_node_t { | |
// goto <identifier> ; | |
// continue ; | |
// break ; | |
// return {<expression>}? ; | |
std::array<ast_node_t*, 3> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_struct_declarator_t : public ast_node_t { | |
// <declarator> | |
// <declarator> : <constant_expression> | |
// : <constant_expression> | |
std::array<ast_node_t*, 3> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_function_definition_t : public ast_node_t { | |
// {<declaration_specifier>}* | |
std::vector<ast_node_t*> nodes; | |
void init(ast_node_t* in, size_t num) { | |
nodes.resize(num); | |
for (size_t i=0; i<num; ++i) nodes[i] = in + i; | |
} | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_parameter_list_t : public ast_node_t { | |
// <parameter_declaration> | |
// <parameter_list> , <parameter_declaration> | |
std::array<ast_node_t*, 3> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_multiplicative_expression_t : public ast_node_t { | |
// <cast_expression> | |
// <multiplicative_expression> * <cast_expression> | |
// <multiplicative_expression> / <cast_expression> | |
// <multiplicative_expression> % <cast_expression> | |
std::array<ast_node_t*, 3> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_type_qualifier_t : public ast_node_t { | |
// const | |
// volatile | |
ast_node_t *node; | |
void init(ast_node_t* in, size_t num) { assert(num==1); node = in; } | |
size_t size() const { return 1; } | |
ast_node_t *& operator [] (size_t i) { assert(i==0); return node; } | |
}; | |
struct ast_labeled_statement_t : public ast_node_t { | |
// <identifier> : <statement> | |
// case <constant_expression> : <statement> | |
// default : <statement> | |
std::array<ast_node_t*, 4> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_abstract_declarator_t : public ast_node_t { | |
// <pointer> | |
// <pointer> <direct_abstract_declarator> | |
// <direct_abstract_declarator> | |
std::array<ast_node_t*, 2> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_enum_specifier_t : public ast_node_t { | |
// enum <identifier> { <enumerator_list> } | |
// enum { <enumerator_list> } | |
// enum <identifier> | |
std::array<ast_node_t*, 5> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_translation_unit_t : public ast_node_t { | |
// {<external_declaration>}* | |
std::vector<ast_node_t*> nodes; | |
void init(ast_node_t* in, size_t num) { | |
nodes.resize(num); | |
for (size_t i=0; i<num; ++i) nodes[i] = in + i; | |
} | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_initializer_list_t : public ast_node_t { | |
// <initializer> | |
// <initializer_list> , <initializer> | |
std::array<ast_node_t*, 3> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_conditional_expression_t : public ast_node_t { | |
// <logical_or_expression> | |
// <logical_or_expression> ? <expression> : <conditional_expression> | |
std::array<ast_node_t*, 5> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_direct_abstract_declarator_t : public ast_node_t { | |
// ( <abstract_declarator> ) | |
// {<direct_abstract_declarator>}? [ {<constant_expression>}? ] | |
// {<direct_abstract_declarator>}? ( {<parameter_type_list>}? ) | |
std::array<ast_node_t*, 4> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
struct ast_expression_t : public ast_node_t { | |
// <assignment_expression> | |
// <expression> , <assignment_expression> | |
std::array<ast_node_t*, 3> nodes; | |
void init(ast_node_t* in, size_t num) { for (size_t i=0; i<num; ++i) nodes[i] = in + i; } | |
size_t size() const { return nodes.size(); } | |
ast_node_t *& operator [] (size_t i) { return nodes[i]; } | |
}; | |
ast_node_t * match_eADDITIVE_EXPRESSION() { | |
// <additive_expression> ::= <additive_expression> "+" <multiplicative_expression> | |
if (match(0, eADDITIVE_EXPRESSION) && | |
match(1, eADD) && | |
match(2, eMULTIPLICATIVE_EXPRESSION)) { | |
return emit<ast_additive_expression_t>(3); | |
} | |
// <additive_expression> ::= <additive_expression> "-" <multiplicative_expression> | |
if (match(0, eADDITIVE_EXPRESSION) && | |
match(1, eSUB) && | |
match(2, eMULTIPLICATIVE_EXPRESSION)) { | |
return emit<ast_additive_expression_t>(3); | |
} | |
// <shift_expression> ::= <additive_expression> | |
if (match(0, eADDITIVE_EXPRESSION)) { | |
return emit<ast_shift_expression_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eMODASSIGN() { | |
// <assignment_operator> ::= "%=" | |
if (match(0, eMODASSIGN)) { | |
return emit<ast_assignment_operator_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eMULTIPLICATIVE_EXPRESSION() { | |
// <multiplicative_expression> ::= <multiplicative_expression> "*" <cast_expression> | |
if (match(0, eMULTIPLICATIVE_EXPRESSION) && | |
match(1, eMUL) && | |
match(2, eCAST_EXPRESSION)) { | |
return emit<ast_multiplicative_expression_t>(3); | |
} | |
// <multiplicative_expression> ::= <multiplicative_expression> "/" <cast_expression> | |
if (match(0, eMULTIPLICATIVE_EXPRESSION) && | |
match(1, eDIV) && | |
match(2, eCAST_EXPRESSION)) { | |
return emit<ast_multiplicative_expression_t>(3); | |
} | |
// <multiplicative_expression> ::= <multiplicative_expression> "%" <cast_expression> | |
if (match(0, eMULTIPLICATIVE_EXPRESSION) && | |
match(1, eMOD) && | |
match(2, eCAST_EXPRESSION)) { | |
return emit<ast_multiplicative_expression_t>(3); | |
} | |
// <additive_expression> ::= <multiplicative_expression> | |
if (match(0, eMULTIPLICATIVE_EXPRESSION)) { | |
return emit<ast_additive_expression_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eSPECIFIER_QUALIFIER() { | |
// <struct_declaration> ::= {<specifier_qualifier>}* <struct_declarator_list> | |
do { | |
int i = 0; | |
for (;match(i, eSPECIFIER_QUALIFIER); ++i); | |
if (!match(i++, eSTRUCT_DECLARATOR_LIST)) | |
break; | |
return emit<ast_struct_declaration_t>(i); | |
} while (0); | |
// <type_name> ::= {<specifier_qualifier>}+ {<abstract_declarator>}? | |
do { | |
int i = 0; | |
if (!match(i++, eSPECIFIER_QUALIFIER)) | |
break; | |
for (;match(i, eSPECIFIER_QUALIFIER); ++i); | |
i += match(i, eABSTRACT_DECLARATOR); | |
return emit<ast_type_name_t>(i); | |
} while (0); | |
return nullptr; | |
} | |
ast_node_t * match_eTYPEDEF() { | |
// <storage_class_specifier> ::= "typedef" | |
if (match(0, eTYPEDEF)) { | |
return emit<ast_storage_class_specifier_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eCONST() { | |
// <type_qualifier> ::= "const" | |
if (match(0, eCONST)) { | |
return emit<ast_type_qualifier_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eSTRUCT() { | |
// <struct_or_union> ::= "struct" | |
if (match(0, eSTRUCT)) { | |
return emit<ast_struct_or_union_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eFLOATING_CONSTANT() { | |
// <constant> ::= <floating_constant> | |
if (match(0, eFLOATING_CONSTANT)) { | |
return emit<ast_constant_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eEXPRESSION_STATEMENT() { | |
// <statement> ::= <expression_statement> | |
if (match(0, eEXPRESSION_STATEMENT)) { | |
return emit<ast_statement_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eLPAREN() { | |
// <cast_expression> ::= "(" <type_name> ")" <cast_expression> | |
if (match(0, eLPAREN) && | |
match(1, eTYPE_NAME) && | |
match(2, eRPAREN) && | |
match(3, eCAST_EXPRESSION)) { | |
return emit<ast_cast_expression_t>(4); | |
} | |
// <direct_declarator> ::= "(" <declarator> ")" | |
if (match(0, eLPAREN) && | |
match(1, eDECLARATOR) && | |
match(2, eRPAREN)) { | |
return emit<ast_direct_declarator_t>(3); | |
} | |
// <primary_expression> ::= "(" <expression> ")" | |
if (match(0, eLPAREN) && | |
match(1, eEXPRESSION) && | |
match(2, eRPAREN)) { | |
return emit<ast_primary_expression_t>(3); | |
} | |
// <direct_abstract_declarator> ::= "(" <abstract_declarator> ")" | |
if (match(0, eLPAREN) && | |
match(1, eABSTRACT_DECLARATOR) && | |
match(2, eRPAREN)) { | |
return emit<ast_direct_abstract_declarator_t>(3); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eUNSIGNED() { | |
// <type_specifier> ::= "unsigned" | |
if (match(0, eUNSIGNED)) { | |
return emit<ast_type_specifier_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eSHIFTRASSIGN() { | |
// <assignment_operator> ::= ">>=" | |
if (match(0, eSHIFTRASSIGN)) { | |
return emit<ast_assignment_operator_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eIDENTIFIER() { | |
// <enumerator> ::= <identifier> "=" <constant_expression> | |
if (match(0, eIDENTIFIER) && | |
match(1, eASSIGN) && | |
match(2, eCONSTANT_EXPRESSION)) { | |
return emit<ast_enumerator_t>(3); | |
} | |
// <labeled_statement> ::= <identifier> ":" <statement> | |
if (match(0, eIDENTIFIER) && | |
match(1, eCOLON) && | |
match(2, eSTATEMENT)) { | |
return emit<ast_labeled_statement_t>(3); | |
} | |
// <typedef_name> ::= <identifier> | |
if (match(0, eIDENTIFIER)) { | |
return emit<ast_typedef_name_t>(1); | |
} | |
// <enumerator> ::= <identifier> | |
if (match(0, eIDENTIFIER)) { | |
return emit<ast_enumerator_t>(1); | |
} | |
// <direct_declarator> ::= <identifier> | |
if (match(0, eIDENTIFIER)) { | |
return emit<ast_direct_declarator_t>(1); | |
} | |
// <primary_expression> ::= <identifier> | |
if (match(0, eIDENTIFIER)) { | |
return emit<ast_primary_expression_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eDO() { | |
// <iteration_statement> ::= "do" <statement> "while" "(" <expression> ")" ";" | |
if (match(0, eDO) && | |
match(1, eSTATEMENT) && | |
match(2, eWHILE) && | |
match(3, eLPAREN) && | |
match(4, eEXPRESSION) && | |
match(5, eRPAREN) && | |
match(6, eSEMICOLON)) { | |
return emit<ast_iteration_statement_t>(7); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eRETURN() { | |
// <jump_statement> ::= "return" {<expression>}? ";" | |
do { | |
int i = 0; | |
if (!match(i++, eRETURN)) | |
break; | |
i += match(i, eEXPRESSION); | |
if (!match(i++, eSEMICOLON)) | |
break; | |
return emit<ast_jump_statement_t>(i); | |
} while (0); | |
return nullptr; | |
} | |
ast_node_t * match_eAUTO() { | |
// <storage_class_specifier> ::= "auto" | |
if (match(0, eAUTO)) { | |
return emit<ast_storage_class_specifier_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eVOID() { | |
// <type_specifier> ::= "void" | |
if (match(0, eVOID)) { | |
return emit<ast_type_specifier_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eBITORASSIGN() { | |
// <assignment_operator> ::= "|=" | |
if (match(0, eBITORASSIGN)) { | |
return emit<ast_assignment_operator_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eSHIFT_EXPRESSION() { | |
// <shift_expression> ::= <shift_expression> "<<" <additive_expression> | |
if (match(0, eSHIFT_EXPRESSION) && | |
match(1, eSHIFTL) && | |
match(2, eADDITIVE_EXPRESSION)) { | |
return emit<ast_shift_expression_t>(3); | |
} | |
// <shift_expression> ::= <shift_expression> ">>" <additive_expression> | |
if (match(0, eSHIFT_EXPRESSION) && | |
match(1, eSHIFTR) && | |
match(2, eADDITIVE_EXPRESSION)) { | |
return emit<ast_shift_expression_t>(3); | |
} | |
// <relational_expression> ::= <shift_expression> | |
if (match(0, eSHIFT_EXPRESSION)) { | |
return emit<ast_relational_expression_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eBREAK() { | |
// <jump_statement> ::= "break" ";" | |
if (match(0, eBREAK) && | |
match(1, eSEMICOLON)) { | |
return emit<ast_jump_statement_t>(2); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eENUM_SPECIFIER() { | |
// <type_specifier> ::= <enum_specifier> | |
if (match(0, eENUM_SPECIFIER)) { | |
return emit<ast_type_specifier_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eASSIGNMENT_EXPRESSION() { | |
// <initializer> ::= <assignment_expression> | |
if (match(0, eASSIGNMENT_EXPRESSION)) { | |
return emit<ast_initializer_t>(1); | |
} | |
// <expression> ::= <assignment_expression> | |
if (match(0, eASSIGNMENT_EXPRESSION)) { | |
return emit<ast_expression_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eSTRUCT_DECLARATOR() { | |
// <struct_declarator_list> ::= <struct_declarator> | |
if (match(0, eSTRUCT_DECLARATOR)) { | |
return emit<ast_struct_declarator_list_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eSTRING() { | |
// <primary_expression> ::= <string> | |
if (match(0, eSTRING)) { | |
return emit<ast_primary_expression_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_ePARAMETER_DECLARATION() { | |
// <parameter_list> ::= <parameter_declaration> | |
if (match(0, ePARAMETER_DECLARATION)) { | |
return emit<ast_parameter_list_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eDECREMENT() { | |
// <unary_expression> ::= "--" <unary_expression> | |
if (match(0, eDECREMENT) && | |
match(1, eUNARY_EXPRESSION)) { | |
return emit<ast_unary_expression_t>(2); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eEXTERNAL_DECLARATION() { | |
// <translation_unit> ::= {<external_declaration>}* | |
do { | |
int i = 0; | |
for (;match(i, eEXTERNAL_DECLARATION); ++i); | |
return emit<ast_translation_unit_t>(i); | |
} while (0); | |
return nullptr; | |
} | |
ast_node_t * match_eEXPRESSION() { | |
// <expression> ::= <expression> "," <assignment_expression> | |
if (match(0, eEXPRESSION) && | |
match(1, eCOMMA) && | |
match(2, eASSIGNMENT_EXPRESSION)) { | |
return emit<ast_expression_t>(3); | |
} | |
// <expression_statement> ::= {<expression>}? ";" | |
do { | |
int i = 0; | |
i += match(i, eEXPRESSION); | |
if (!match(i++, eSEMICOLON)) | |
break; | |
return emit<ast_expression_statement_t>(i); | |
} while (0); | |
return nullptr; | |
} | |
ast_node_t * match_ePRIMARY_EXPRESSION() { | |
// <postfix_expression> ::= <primary_expression> | |
if (match(0, ePRIMARY_EXPRESSION)) { | |
return emit<ast_postfix_expression_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eSUBASSIGN() { | |
// <assignment_operator> ::= "-=" | |
if (match(0, eSUBASSIGN)) { | |
return emit<ast_assignment_operator_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eTYPE_SPECIFIER() { | |
// <specifier_qualifier> ::= <type_specifier> | |
if (match(0, eTYPE_SPECIFIER)) { | |
return emit<ast_specifier_qualifier_t>(1); | |
} | |
// <declaration_specifier> ::= <type_specifier> | |
if (match(0, eTYPE_SPECIFIER)) { | |
return emit<ast_declaration_specifier_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eDECLARATION_SPECIFIER() { | |
// <function_definition> ::= {<declaration_specifier>}* <declarator> {<declaration>}* <compound_statement> | |
do { | |
int i = 0; | |
for (;match(i, eDECLARATION_SPECIFIER); ++i); | |
if (!match(i++, eDECLARATOR)) | |
break; | |
for (;match(i, eDECLARATION); ++i); | |
if (!match(i++, eCOMPOUND_STATEMENT)) | |
break; | |
return emit<ast_function_definition_t>(i); | |
} while (0); | |
// <parameter_declaration> ::= {<declaration_specifier>}+ <declarator> | |
do { | |
int i = 0; | |
if (!match(i++, eDECLARATION_SPECIFIER)) | |
break; | |
for (;match(i, eDECLARATION_SPECIFIER); ++i); | |
if (!match(i++, eDECLARATOR)) | |
break; | |
return emit<ast_parameter_declaration_t>(i); | |
} while (0); | |
// <parameter_declaration> ::= {<declaration_specifier>}+ <abstract_declarator> | |
do { | |
int i = 0; | |
if (!match(i++, eDECLARATION_SPECIFIER)) | |
break; | |
for (;match(i, eDECLARATION_SPECIFIER); ++i); | |
if (!match(i++, eABSTRACT_DECLARATOR)) | |
break; | |
return emit<ast_parameter_declaration_t>(i); | |
} while (0); | |
// <declaration> ::= {<declaration_specifier>}+ {<init_declarator>}* | |
do { | |
int i = 0; | |
if (!match(i++, eDECLARATION_SPECIFIER)) | |
break; | |
for (;match(i, eDECLARATION_SPECIFIER); ++i); | |
for (;match(i, eINIT_DECLARATOR); ++i); | |
return emit<ast_declaration_t>(i); | |
} while (0); | |
// <parameter_declaration> ::= {<declaration_specifier>}+ | |
do { | |
int i = 0; | |
if (!match(i++, eDECLARATION_SPECIFIER)) | |
break; | |
for (;match(i, eDECLARATION_SPECIFIER); ++i); | |
return emit<ast_parameter_declaration_t>(i); | |
} while (0); | |
return nullptr; | |
} | |
ast_node_t * match_eCONDITIONAL_EXPRESSION() { | |
// <constant_expression> ::= <conditional_expression> | |
if (match(0, eCONDITIONAL_EXPRESSION)) { | |
return emit<ast_constant_expression_t>(1); | |
} | |
// <assignment_expression> ::= <conditional_expression> | |
if (match(0, eCONDITIONAL_EXPRESSION)) { | |
return emit<ast_assignment_expression_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eITERATION_STATEMENT() { | |
// <statement> ::= <iteration_statement> | |
if (match(0, eITERATION_STATEMENT)) { | |
return emit<ast_statement_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eSTRUCT_DECLARATOR_LIST() { | |
// <struct_declarator_list> ::= <struct_declarator_list> "," <struct_declarator> | |
if (match(0, eSTRUCT_DECLARATOR_LIST) && | |
match(1, eCOMMA) && | |
match(2, eSTRUCT_DECLARATOR)) { | |
return emit<ast_struct_declarator_list_t>(3); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eTYPE_QUALIFIER() { | |
// <specifier_qualifier> ::= <type_qualifier> | |
if (match(0, eTYPE_QUALIFIER)) { | |
return emit<ast_specifier_qualifier_t>(1); | |
} | |
// <declaration_specifier> ::= <type_qualifier> | |
if (match(0, eTYPE_QUALIFIER)) { | |
return emit<ast_declaration_specifier_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eSIZEOF() { | |
// <unary_expression> ::= "sizeof" <unary_expression> | |
if (match(0, eSIZEOF) && | |
match(1, eUNARY_EXPRESSION)) { | |
return emit<ast_unary_expression_t>(2); | |
} | |
// <unary_expression> ::= "sizeof" <type_name> | |
if (match(0, eSIZEOF) && | |
match(1, eTYPE_NAME)) { | |
return emit<ast_unary_expression_t>(2); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eINITIALIZER_LIST() { | |
// <initializer_list> ::= <initializer_list> "," <initializer> | |
if (match(0, eINITIALIZER_LIST) && | |
match(1, eCOMMA) && | |
match(2, eINITIALIZER)) { | |
return emit<ast_initializer_list_t>(3); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eINCLUSIVE_OR_EXPRESSION() { | |
// <inclusive_or_expression> ::= <inclusive_or_expression> "|" <exclusive_or_expression> | |
if (match(0, eINCLUSIVE_OR_EXPRESSION) && | |
match(1, eBITOR) && | |
match(2, eEXCLUSIVE_OR_EXPRESSION)) { | |
return emit<ast_inclusive_or_expression_t>(3); | |
} | |
// <logical_and_expression> ::= <inclusive_or_expression> | |
if (match(0, eINCLUSIVE_OR_EXPRESSION)) { | |
return emit<ast_logical_and_expression_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eDECLARATOR() { | |
// <init_declarator> ::= <declarator> "=" <initializer> | |
if (match(0, eDECLARATOR) && | |
match(1, eASSIGN) && | |
match(2, eINITIALIZER)) { | |
return emit<ast_init_declarator_t>(3); | |
} | |
// <struct_declarator> ::= <declarator> ":" <constant_expression> | |
if (match(0, eDECLARATOR) && | |
match(1, eCOLON) && | |
match(2, eCONSTANT_EXPRESSION)) { | |
return emit<ast_struct_declarator_t>(3); | |
} | |
// <init_declarator> ::= <declarator> | |
if (match(0, eDECLARATOR)) { | |
return emit<ast_init_declarator_t>(1); | |
} | |
// <struct_declarator> ::= <declarator> | |
if (match(0, eDECLARATOR)) { | |
return emit<ast_struct_declarator_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eAND_EXPRESSION() { | |
// <and_expression> ::= <and_expression> "&" <equality_expression> | |
if (match(0, eAND_EXPRESSION) && | |
match(1, eAND) && | |
match(2, eEQUALITY_EXPRESSION)) { | |
return emit<ast_and_expression_t>(3); | |
} | |
// <exclusive_or_expression> ::= <and_expression> | |
if (match(0, eAND_EXPRESSION)) { | |
return emit<ast_exclusive_or_expression_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eSHIFTLASSIGN() { | |
// <assignment_operator> ::= "<<=" | |
if (match(0, eSHIFTLASSIGN)) { | |
return emit<ast_assignment_operator_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eADD() { | |
// <unary_operator> ::= "+" | |
if (match(0, eADD)) { | |
return emit<ast_unary_operator_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eCONTINUE() { | |
// <jump_statement> ::= "continue" ";" | |
if (match(0, eCONTINUE) && | |
match(1, eSEMICOLON)) { | |
return emit<ast_jump_statement_t>(2); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eVOLATILE() { | |
// <type_qualifier> ::= "volatile" | |
if (match(0, eVOLATILE)) { | |
return emit<ast_type_qualifier_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eCHARACTER_CONSTANT() { | |
// <constant> ::= <character_constant> | |
if (match(0, eCHARACTER_CONSTANT)) { | |
return emit<ast_constant_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eGOTO() { | |
// <jump_statement> ::= "goto" <identifier> ";" | |
if (match(0, eGOTO) && | |
match(1, eIDENTIFIER) && | |
match(2, eSEMICOLON)) { | |
return emit<ast_jump_statement_t>(3); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eENUM() { | |
// <enum_specifier> ::= "enum" <identifier> "{" <enumerator_list> "}" | |
if (match(0, eENUM) && | |
match(1, eIDENTIFIER) && | |
match(2, eLBRACE) && | |
match(3, eENUMERATOR_LIST) && | |
match(4, eRBRACE)) { | |
return emit<ast_enum_specifier_t>(5); | |
} | |
// <enum_specifier> ::= "enum" "{" <enumerator_list> "}" | |
if (match(0, eENUM) && | |
match(1, eLBRACE) && | |
match(2, eENUMERATOR_LIST) && | |
match(3, eRBRACE)) { | |
return emit<ast_enum_specifier_t>(4); | |
} | |
// <enum_specifier> ::= "enum" <identifier> | |
if (match(0, eENUM) && | |
match(1, eIDENTIFIER)) { | |
return emit<ast_enum_specifier_t>(2); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eUNARY_OPERATOR() { | |
// <unary_expression> ::= <unary_operator> <cast_expression> | |
if (match(0, eUNARY_OPERATOR) && | |
match(1, eCAST_EXPRESSION)) { | |
return emit<ast_unary_expression_t>(2); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eBITANDASSIGN() { | |
// <assignment_operator> ::= "&=" | |
if (match(0, eBITANDASSIGN)) { | |
return emit<ast_assignment_operator_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eENUMERATOR() { | |
// <enumerator_list> ::= <enumerator> | |
if (match(0, eENUMERATOR)) { | |
return emit<ast_enumerator_list_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eINCREMENT() { | |
// <unary_expression> ::= "++" <unary_expression> | |
if (match(0, eINCREMENT) && | |
match(1, eUNARY_EXPRESSION)) { | |
return emit<ast_unary_expression_t>(2); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eCOMPOUND_STATEMENT() { | |
// <statement> ::= <compound_statement> | |
if (match(0, eCOMPOUND_STATEMENT)) { | |
return emit<ast_statement_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eEQUALITY_EXPRESSION() { | |
// <equality_expression> ::= <equality_expression> "==" <relational_expression> | |
if (match(0, eEQUALITY_EXPRESSION) && | |
match(1, eEQUALS) && | |
match(2, eRELATIONAL_EXPRESSION)) { | |
return emit<ast_equality_expression_t>(3); | |
} | |
// <equality_expression> ::= <equality_expression> "!=" <relational_expression> | |
if (match(0, eEQUALITY_EXPRESSION) && | |
match(1, eNOTEQUALS) && | |
match(2, eRELATIONAL_EXPRESSION)) { | |
return emit<ast_equality_expression_t>(3); | |
} | |
// <and_expression> ::= <equality_expression> | |
if (match(0, eEQUALITY_EXPRESSION)) { | |
return emit<ast_and_expression_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eLBRACE() { | |
// <initializer> ::= "{" <initializer_list> "," "}" | |
if (match(0, eLBRACE) && | |
match(1, eINITIALIZER_LIST) && | |
match(2, eCOMMA) && | |
match(3, eRBRACE)) { | |
return emit<ast_initializer_t>(4); | |
} | |
// <compound_statement> ::= "{" {<declaration>}* {<statement>}* "}" | |
do { | |
int i = 0; | |
if (!match(i++, eLBRACE)) | |
break; | |
for (;match(i, eDECLARATION); ++i); | |
for (;match(i, eSTATEMENT); ++i); | |
if (!match(i++, eRBRACE)) | |
break; | |
return emit<ast_compound_statement_t>(i); | |
} while (0); | |
// <initializer> ::= "{" <initializer_list> "}" | |
if (match(0, eLBRACE) && | |
match(1, eINITIALIZER_LIST) && | |
match(2, eRBRACE)) { | |
return emit<ast_initializer_t>(3); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eENUMERATOR_LIST() { | |
// <enumerator_list> ::= <enumerator_list> "," <enumerator> | |
if (match(0, eENUMERATOR_LIST) && | |
match(1, eCOMMA) && | |
match(2, eENUMERATOR)) { | |
return emit<ast_enumerator_list_t>(3); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eADDASSIGN() { | |
// <assignment_operator> ::= "+=" | |
if (match(0, eADDASSIGN)) { | |
return emit<ast_assignment_operator_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eENUMERATION_CONSTANT() { | |
// <constant> ::= <enumeration_constant> | |
if (match(0, eENUMERATION_CONSTANT)) { | |
return emit<ast_constant_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eFLOAT() { | |
// <type_specifier> ::= "float" | |
if (match(0, eFLOAT)) { | |
return emit<ast_type_specifier_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eSTRUCT_OR_UNION() { | |
// <struct_or_union_specifier> ::= <struct_or_union> <identifier> "{" {<struct_declaration>}+ "}" | |
do { | |
int i = 0; | |
if (!match(i++, eSTRUCT_OR_UNION)) | |
break; | |
if (!match(i++, eIDENTIFIER)) | |
break; | |
if (!match(i++, eLBRACE)) | |
break; | |
if (!match(i++, eSTRUCT_DECLARATION)) | |
break; | |
for (;match(i, eSTRUCT_DECLARATION); ++i); | |
if (!match(i++, eRBRACE)) | |
break; | |
return emit<ast_struct_or_union_specifier_t>(i); | |
} while (0); | |
// <struct_or_union_specifier> ::= <struct_or_union> "{" {<struct_declaration>}+ "}" | |
do { | |
int i = 0; | |
if (!match(i++, eSTRUCT_OR_UNION)) | |
break; | |
if (!match(i++, eLBRACE)) | |
break; | |
if (!match(i++, eSTRUCT_DECLARATION)) | |
break; | |
for (;match(i, eSTRUCT_DECLARATION); ++i); | |
if (!match(i++, eRBRACE)) | |
break; | |
return emit<ast_struct_or_union_specifier_t>(i); | |
} while (0); | |
// <struct_or_union_specifier> ::= <struct_or_union> <identifier> | |
if (match(0, eSTRUCT_OR_UNION) && | |
match(1, eIDENTIFIER)) { | |
return emit<ast_struct_or_union_specifier_t>(2); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eJUMP_STATEMENT() { | |
// <statement> ::= <jump_statement> | |
if (match(0, eJUMP_STATEMENT)) { | |
return emit<ast_statement_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eLABELED_STATEMENT() { | |
// <statement> ::= <labeled_statement> | |
if (match(0, eLABELED_STATEMENT)) { | |
return emit<ast_statement_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eSELECTION_STATEMENT() { | |
// <statement> ::= <selection_statement> | |
if (match(0, eSELECTION_STATEMENT)) { | |
return emit<ast_statement_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eUNARY_EXPRESSION() { | |
// <assignment_expression> ::= <unary_expression> <assignment_operator> <assignment_expression> | |
if (match(0, eUNARY_EXPRESSION) && | |
match(1, eASSIGNMENT_OPERATOR) && | |
match(2, eASSIGNMENT_EXPRESSION)) { | |
return emit<ast_assignment_expression_t>(3); | |
} | |
// <cast_expression> ::= <unary_expression> | |
if (match(0, eUNARY_EXPRESSION)) { | |
return emit<ast_cast_expression_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eAND() { | |
// <unary_operator> ::= "&" | |
if (match(0, eAND)) { | |
return emit<ast_unary_operator_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eUNION() { | |
// <struct_or_union> ::= "union" | |
if (match(0, eUNION)) { | |
return emit<ast_struct_or_union_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eMUL() { | |
// <pointer> ::= "*" {<type_qualifier>}* {<pointer>}? | |
do { | |
int i = 0; | |
if (!match(i++, eMUL)) | |
break; | |
for (;match(i, eTYPE_QUALIFIER); ++i); | |
i += match(i, ePOINTER); | |
return emit<ast_pointer_t>(i); | |
} while (0); | |
// <unary_operator> ::= "*" | |
if (match(0, eMUL)) { | |
return emit<ast_unary_operator_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eLONG() { | |
// <type_specifier> ::= "long" | |
if (match(0, eLONG)) { | |
return emit<ast_type_specifier_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eDECLARATION() { | |
// <external_declaration> ::= <declaration> | |
if (match(0, eDECLARATION)) { | |
return emit<ast_external_declaration_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_ePOINTER() { | |
// <declarator> ::= {<pointer>}? <direct_declarator> | |
do { | |
int i = 0; | |
i += match(i, ePOINTER); | |
if (!match(i++, eDIRECT_DECLARATOR)) | |
break; | |
return emit<ast_declarator_t>(i); | |
} while (0); | |
// <abstract_declarator> ::= <pointer> <direct_abstract_declarator> | |
if (match(0, ePOINTER) && | |
match(1, eDIRECT_ABSTRACT_DECLARATOR)) { | |
return emit<ast_abstract_declarator_t>(2); | |
} | |
// <abstract_declarator> ::= <pointer> | |
if (match(0, ePOINTER)) { | |
return emit<ast_abstract_declarator_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eCOLON() { | |
// <struct_declarator> ::= ":" <constant_expression> | |
if (match(0, eCOLON) && | |
match(1, eCONSTANT_EXPRESSION)) { | |
return emit<ast_struct_declarator_t>(2); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eDIRECT_ABSTRACT_DECLARATOR() { | |
// <direct_abstract_declarator> ::= {<direct_abstract_declarator>}? "[" {<constant_expression>}? "]" | |
do { | |
int i = 0; | |
i += match(i, eDIRECT_ABSTRACT_DECLARATOR); | |
if (!match(i++, eLSUBSCRIPT)) | |
break; | |
i += match(i, eCONSTANT_EXPRESSION); | |
if (!match(i++, eRSUBSCRIPT)) | |
break; | |
return emit<ast_direct_abstract_declarator_t>(i); | |
} while (0); | |
// <direct_abstract_declarator> ::= {<direct_abstract_declarator>}? "(" {<parameter_type_list>}? ")" | |
do { | |
int i = 0; | |
i += match(i, eDIRECT_ABSTRACT_DECLARATOR); | |
if (!match(i++, eLPAREN)) | |
break; | |
i += match(i, ePARAMETER_TYPE_LIST); | |
if (!match(i++, eRPAREN)) | |
break; | |
return emit<ast_direct_abstract_declarator_t>(i); | |
} while (0); | |
// <abstract_declarator> ::= <direct_abstract_declarator> | |
if (match(0, eDIRECT_ABSTRACT_DECLARATOR)) { | |
return emit<ast_abstract_declarator_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eLOGICAL_AND_EXPRESSION() { | |
// <logical_and_expression> ::= <logical_and_expression> "&&" <inclusive_or_expression> | |
if (match(0, eLOGICAL_AND_EXPRESSION) && | |
match(1, eLOGAND) && | |
match(2, eINCLUSIVE_OR_EXPRESSION)) { | |
return emit<ast_logical_and_expression_t>(3); | |
} | |
// <logical_or_expression> ::= <logical_and_expression> | |
if (match(0, eLOGICAL_AND_EXPRESSION)) { | |
return emit<ast_logical_or_expression_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eLOGICAL_OR_EXPRESSION() { | |
// <conditional_expression> ::= <logical_or_expression> "?" <expression> ":" <conditional_expression> | |
if (match(0, eLOGICAL_OR_EXPRESSION) && | |
match(1, eTERNARY) && | |
match(2, eEXPRESSION) && | |
match(3, eCOLON) && | |
match(4, eCONDITIONAL_EXPRESSION)) { | |
return emit<ast_conditional_expression_t>(5); | |
} | |
// <logical_or_expression> ::= <logical_or_expression> "||" <logical_and_expression> | |
if (match(0, eLOGICAL_OR_EXPRESSION) && | |
match(1, eLOGOR) && | |
match(2, eLOGICAL_AND_EXPRESSION)) { | |
return emit<ast_logical_or_expression_t>(3); | |
} | |
// <conditional_expression> ::= <logical_or_expression> | |
if (match(0, eLOGICAL_OR_EXPRESSION)) { | |
return emit<ast_conditional_expression_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eCAST_EXPRESSION() { | |
// <multiplicative_expression> ::= <cast_expression> | |
if (match(0, eCAST_EXPRESSION)) { | |
return emit<ast_multiplicative_expression_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eTYPEDEF_NAME() { | |
// <type_specifier> ::= <typedef_name> | |
if (match(0, eTYPEDEF_NAME)) { | |
return emit<ast_type_specifier_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eCASE() { | |
// <labeled_statement> ::= "case" <constant_expression> ":" <statement> | |
if (match(0, eCASE) && | |
match(1, eCONSTANT_EXPRESSION) && | |
match(2, eCOLON) && | |
match(3, eSTATEMENT)) { | |
return emit<ast_labeled_statement_t>(4); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eSTATIC() { | |
// <storage_class_specifier> ::= "static" | |
if (match(0, eSTATIC)) { | |
return emit<ast_storage_class_specifier_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_ePOSTFIX_EXPRESSION() { | |
// <postfix_expression> ::= <postfix_expression> "[" <expression> "]" | |
if (match(0, ePOSTFIX_EXPRESSION) && | |
match(1, eLSUBSCRIPT) && | |
match(2, eEXPRESSION) && | |
match(3, eRSUBSCRIPT)) { | |
return emit<ast_postfix_expression_t>(4); | |
} | |
// <postfix_expression> ::= <postfix_expression> "(" {<assignment_expression>}* ")" | |
do { | |
int i = 0; | |
if (!match(i++, ePOSTFIX_EXPRESSION)) | |
break; | |
if (!match(i++, eLPAREN)) | |
break; | |
for (;match(i, eASSIGNMENT_EXPRESSION); ++i); | |
if (!match(i++, eRPAREN)) | |
break; | |
return emit<ast_postfix_expression_t>(i); | |
} while (0); | |
// <postfix_expression> ::= <postfix_expression> "." <identifier> | |
if (match(0, ePOSTFIX_EXPRESSION) && | |
match(1, eDOT) && | |
match(2, eIDENTIFIER)) { | |
return emit<ast_postfix_expression_t>(3); | |
} | |
// <postfix_expression> ::= <postfix_expression> "->" <identifier> | |
if (match(0, ePOSTFIX_EXPRESSION) && | |
match(1, eARROW) && | |
match(2, eIDENTIFIER)) { | |
return emit<ast_postfix_expression_t>(3); | |
} | |
// <postfix_expression> ::= <postfix_expression> "++" | |
if (match(0, ePOSTFIX_EXPRESSION) && | |
match(1, eINCREMENT)) { | |
return emit<ast_postfix_expression_t>(2); | |
} | |
// <postfix_expression> ::= <postfix_expression> "--" | |
if (match(0, ePOSTFIX_EXPRESSION) && | |
match(1, eDECREMENT)) { | |
return emit<ast_postfix_expression_t>(2); | |
} | |
// <unary_expression> ::= <postfix_expression> | |
if (match(0, ePOSTFIX_EXPRESSION)) { | |
return emit<ast_unary_expression_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eSTORAGE_CLASS_SPECIFIER() { | |
// <declaration_specifier> ::= <storage_class_specifier> | |
if (match(0, eSTORAGE_CLASS_SPECIFIER)) { | |
return emit<ast_declaration_specifier_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eDEFAULT() { | |
// <labeled_statement> ::= "default" ":" <statement> | |
if (match(0, eDEFAULT) && | |
match(1, eCOLON) && | |
match(2, eSTATEMENT)) { | |
return emit<ast_labeled_statement_t>(3); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eDOUBLE() { | |
// <type_specifier> ::= "double" | |
if (match(0, eDOUBLE)) { | |
return emit<ast_type_specifier_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eSIGNED() { | |
// <type_specifier> ::= "signed" | |
if (match(0, eSIGNED)) { | |
return emit<ast_type_specifier_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eDIRECT_DECLARATOR() { | |
// <direct_declarator> ::= <direct_declarator> "[" {<constant_expression>}? "]" | |
do { | |
int i = 0; | |
if (!match(i++, eDIRECT_DECLARATOR)) | |
break; | |
if (!match(i++, eLSUBSCRIPT)) | |
break; | |
i += match(i, eCONSTANT_EXPRESSION); | |
if (!match(i++, eRSUBSCRIPT)) | |
break; | |
return emit<ast_direct_declarator_t>(i); | |
} while (0); | |
// <direct_declarator> ::= <direct_declarator> "(" <parameter_type_list> ")" | |
if (match(0, eDIRECT_DECLARATOR) && | |
match(1, eLPAREN) && | |
match(2, ePARAMETER_TYPE_LIST) && | |
match(3, eRPAREN)) { | |
return emit<ast_direct_declarator_t>(4); | |
} | |
// <direct_declarator> ::= <direct_declarator> "(" {<identifier>}* ")" | |
do { | |
int i = 0; | |
if (!match(i++, eDIRECT_DECLARATOR)) | |
break; | |
if (!match(i++, eLPAREN)) | |
break; | |
for (;match(i, eIDENTIFIER); ++i); | |
if (!match(i++, eRPAREN)) | |
break; | |
return emit<ast_direct_declarator_t>(i); | |
} while (0); | |
return nullptr; | |
} | |
ast_node_t * match_eWHILE() { | |
// <iteration_statement> ::= "while" "(" <expression> ")" <statement> | |
if (match(0, eWHILE) && | |
match(1, eLPAREN) && | |
match(2, eEXPRESSION) && | |
match(3, eRPAREN) && | |
match(4, eSTATEMENT)) { | |
return emit<ast_iteration_statement_t>(5); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eEXCLUSIVE_OR_EXPRESSION() { | |
// <exclusive_or_expression> ::= <exclusive_or_expression> "^" <and_expression> | |
if (match(0, eEXCLUSIVE_OR_EXPRESSION) && | |
match(1, eXOR) && | |
match(2, eAND_EXPRESSION)) { | |
return emit<ast_exclusive_or_expression_t>(3); | |
} | |
// <inclusive_or_expression> ::= <exclusive_or_expression> | |
if (match(0, eEXCLUSIVE_OR_EXPRESSION)) { | |
return emit<ast_inclusive_or_expression_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eINITIALIZER() { | |
// <initializer_list> ::= <initializer> | |
if (match(0, eINITIALIZER)) { | |
return emit<ast_initializer_list_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eBITNOT() { | |
// <unary_operator> ::= "~" | |
if (match(0, eBITNOT)) { | |
return emit<ast_unary_operator_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eINT() { | |
// <type_specifier> ::= "int" | |
if (match(0, eINT)) { | |
return emit<ast_type_specifier_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eSTRUCT_OR_UNION_SPECIFIER() { | |
// <type_specifier> ::= <struct_or_union_specifier> | |
if (match(0, eSTRUCT_OR_UNION_SPECIFIER)) { | |
return emit<ast_type_specifier_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eCHAR() { | |
// <type_specifier> ::= "char" | |
if (match(0, eCHAR)) { | |
return emit<ast_type_specifier_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_ePARAMETER_LIST() { | |
// <parameter_type_list> ::= <parameter_list> "," "..." | |
if (match(0, ePARAMETER_LIST) && | |
match(1, eCOMMA) && | |
match(2, eVARARG)) { | |
return emit<ast_parameter_type_list_t>(3); | |
} | |
// <parameter_list> ::= <parameter_list> "," <parameter_declaration> | |
if (match(0, ePARAMETER_LIST) && | |
match(1, eCOMMA) && | |
match(2, ePARAMETER_DECLARATION)) { | |
return emit<ast_parameter_list_t>(3); | |
} | |
// <parameter_type_list> ::= <parameter_list> | |
if (match(0, ePARAMETER_LIST)) { | |
return emit<ast_parameter_type_list_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eINTEGER_CONSTANT() { | |
// <constant> ::= <integer_constant> | |
if (match(0, eINTEGER_CONSTANT)) { | |
return emit<ast_constant_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eIF() { | |
// <selection_statement> ::= "if" "(" <expression> ")" <statement> "else" <statement> | |
if (match(0, eIF) && | |
match(1, eLPAREN) && | |
match(2, eEXPRESSION) && | |
match(3, eRPAREN) && | |
match(4, eSTATEMENT) && | |
match(5, eELSE) && | |
match(6, eSTATEMENT)) { | |
return emit<ast_selection_statement_t>(7); | |
} | |
// <selection_statement> ::= "if" "(" <expression> ")" <statement> | |
if (match(0, eIF) && | |
match(1, eLPAREN) && | |
match(2, eEXPRESSION) && | |
match(3, eRPAREN) && | |
match(4, eSTATEMENT)) { | |
return emit<ast_selection_statement_t>(5); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eNOT() { | |
// <unary_operator> ::= "!" | |
if (match(0, eNOT)) { | |
return emit<ast_unary_operator_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eCONSTANT() { | |
// <primary_expression> ::= <constant> | |
if (match(0, eCONSTANT)) { | |
return emit<ast_primary_expression_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eXORASSIGN() { | |
// <assignment_operator> ::= "^=" | |
if (match(0, eXORASSIGN)) { | |
return emit<ast_assignment_operator_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eSUB() { | |
// <unary_operator> ::= "-" | |
if (match(0, eSUB)) { | |
return emit<ast_unary_operator_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eSWITCH() { | |
// <selection_statement> ::= "switch" "(" <expression> ")" <statement> | |
if (match(0, eSWITCH) && | |
match(1, eLPAREN) && | |
match(2, eEXPRESSION) && | |
match(3, eRPAREN) && | |
match(4, eSTATEMENT)) { | |
return emit<ast_selection_statement_t>(5); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eFUNCTION_DEFINITION() { | |
// <external_declaration> ::= <function_definition> | |
if (match(0, eFUNCTION_DEFINITION)) { | |
return emit<ast_external_declaration_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eASSIGN() { | |
// <assignment_operator> ::= "=" | |
if (match(0, eASSIGN)) { | |
return emit<ast_assignment_operator_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eMULASSIGN() { | |
// <assignment_operator> ::= "*=" | |
if (match(0, eMULASSIGN)) { | |
return emit<ast_assignment_operator_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eEXTERN() { | |
// <storage_class_specifier> ::= "extern" | |
if (match(0, eEXTERN)) { | |
return emit<ast_storage_class_specifier_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eRELATIONAL_EXPRESSION() { | |
// <relational_expression> ::= <relational_expression> "<" <shift_expression> | |
if (match(0, eRELATIONAL_EXPRESSION) && | |
match(1, eLT) && | |
match(2, eSHIFT_EXPRESSION)) { | |
return emit<ast_relational_expression_t>(3); | |
} | |
// <relational_expression> ::= <relational_expression> ">" <shift_expression> | |
if (match(0, eRELATIONAL_EXPRESSION) && | |
match(1, eGT) && | |
match(2, eSHIFT_EXPRESSION)) { | |
return emit<ast_relational_expression_t>(3); | |
} | |
// <relational_expression> ::= <relational_expression> "<=" <shift_expression> | |
if (match(0, eRELATIONAL_EXPRESSION) && | |
match(1, ELTEQUALS) && | |
match(2, eSHIFT_EXPRESSION)) { | |
return emit<ast_relational_expression_t>(3); | |
} | |
// <relational_expression> ::= <relational_expression> ">=" <shift_expression> | |
if (match(0, eRELATIONAL_EXPRESSION) && | |
match(1, eGTEQUALS) && | |
match(2, eSHIFT_EXPRESSION)) { | |
return emit<ast_relational_expression_t>(3); | |
} | |
// <equality_expression> ::= <relational_expression> | |
if (match(0, eRELATIONAL_EXPRESSION)) { | |
return emit<ast_equality_expression_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eSHORT() { | |
// <type_specifier> ::= "short" | |
if (match(0, eSHORT)) { | |
return emit<ast_type_specifier_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eFOR() { | |
// <iteration_statement> ::= "for" "(" {<expression>}? ";" {<expression>}? ";" {<expression>}? ")" <statement> | |
do { | |
int i = 0; | |
if (!match(i++, eFOR)) | |
break; | |
if (!match(i++, eLPAREN)) | |
break; | |
i += match(i, eEXPRESSION); | |
if (!match(i++, eSEMICOLON)) | |
break; | |
i += match(i, eEXPRESSION); | |
if (!match(i++, eSEMICOLON)) | |
break; | |
i += match(i, eEXPRESSION); | |
if (!match(i++, eRPAREN)) | |
break; | |
if (!match(i++, eSTATEMENT)) | |
break; | |
return emit<ast_iteration_statement_t>(i); | |
} while (0); | |
return nullptr; | |
} | |
ast_node_t * match_eREGISTER() { | |
// <storage_class_specifier> ::= "register" | |
if (match(0, eREGISTER)) { | |
return emit<ast_storage_class_specifier_t>(1); | |
} | |
return nullptr; | |
} | |
ast_node_t * match_eDIVASSIGN() { | |
// <assignment_operator> ::= "/=" | |
if (match(0, eDIVASSIGN)) { | |
return emit<ast_assignment_operator_t>(1); | |
} | |
return nullptr; | |
} | |
bool dispatch() { | |
switch (0 /* head */) { | |
case eLBRACE: | |
return run_match(match_eLBRACE); | |
case eLOGICAL_OR_EXPRESSION: | |
return run_match(match_eLOGICAL_OR_EXPRESSION); | |
case eLOGICAL_AND_EXPRESSION: | |
return run_match(match_eLOGICAL_AND_EXPRESSION); | |
case eAND: | |
return run_match(match_eAND); | |
case eSPECIFIER_QUALIFIER: | |
return run_match(match_eSPECIFIER_QUALIFIER); | |
case ePARAMETER_DECLARATION: | |
return run_match(match_ePARAMETER_DECLARATION); | |
case eNOT: | |
return run_match(match_eNOT); | |
case eGOTO: | |
return run_match(match_eGOTO); | |
case eSIZEOF: | |
return run_match(match_eSIZEOF); | |
case eDIVASSIGN: | |
return run_match(match_eDIVASSIGN); | |
case eEQUALITY_EXPRESSION: | |
return run_match(match_eEQUALITY_EXPRESSION); | |
case eREGISTER: | |
return run_match(match_eREGISTER); | |
case eSUB: | |
return run_match(match_eSUB); | |
case eWHILE: | |
return run_match(match_eWHILE); | |
case eEXTERN: | |
return run_match(match_eEXTERN); | |
case ePOSTFIX_EXPRESSION: | |
return run_match(match_ePOSTFIX_EXPRESSION); | |
case eSTRUCT_DECLARATOR_LIST: | |
return run_match(match_eSTRUCT_DECLARATOR_LIST); | |
case eLONG: | |
return run_match(match_eLONG); | |
case eTYPE_QUALIFIER: | |
return run_match(match_eTYPE_QUALIFIER); | |
case eFOR: | |
return run_match(match_eFOR); | |
case eBREAK: | |
return run_match(match_eBREAK); | |
case eCHARACTER_CONSTANT: | |
return run_match(match_eCHARACTER_CONSTANT); | |
case eCONST: | |
return run_match(match_eCONST); | |
case eDIRECT_DECLARATOR: | |
return run_match(match_eDIRECT_DECLARATOR); | |
case eUNARY_EXPRESSION: | |
return run_match(match_eUNARY_EXPRESSION); | |
case eSIGNED: | |
return run_match(match_eSIGNED); | |
case eDEFAULT: | |
return run_match(match_eDEFAULT); | |
case eMUL: | |
return run_match(match_eMUL); | |
case eBITNOT: | |
return run_match(match_eBITNOT); | |
case eINCLUSIVE_OR_EXPRESSION: | |
return run_match(match_eINCLUSIVE_OR_EXPRESSION); | |
case eADDASSIGN: | |
return run_match(match_eADDASSIGN); | |
case eLPAREN: | |
return run_match(match_eLPAREN); | |
case eINITIALIZER: | |
return run_match(match_eINITIALIZER); | |
case eDECLARATION_SPECIFIER: | |
return run_match(match_eDECLARATION_SPECIFIER); | |
case eDO: | |
return run_match(match_eDO); | |
case eCOLON: | |
return run_match(match_eCOLON); | |
case eSWITCH: | |
return run_match(match_eSWITCH); | |
case ePARAMETER_LIST: | |
return run_match(match_ePARAMETER_LIST); | |
case eEXTERNAL_DECLARATION: | |
return run_match(match_eEXTERNAL_DECLARATION); | |
case eENUMERATION_CONSTANT: | |
return run_match(match_eENUMERATION_CONSTANT); | |
case eENUM_SPECIFIER: | |
return run_match(match_eENUM_SPECIFIER); | |
case eMULTIPLICATIVE_EXPRESSION: | |
return run_match(match_eMULTIPLICATIVE_EXPRESSION); | |
case eSTRUCT_OR_UNION_SPECIFIER: | |
return run_match(match_eSTRUCT_OR_UNION_SPECIFIER); | |
case eADD: | |
return run_match(match_eADD); | |
case eCONTINUE: | |
return run_match(match_eCONTINUE); | |
case eCONSTANT: | |
return run_match(match_eCONSTANT); | |
case eSTORAGE_CLASS_SPECIFIER: | |
return run_match(match_eSTORAGE_CLASS_SPECIFIER); | |
case eSTATIC: | |
return run_match(match_eSTATIC); | |
case eSUBASSIGN: | |
return run_match(match_eSUBASSIGN); | |
case eTYPEDEF_NAME: | |
return run_match(match_eTYPEDEF_NAME); | |
case eDOUBLE: | |
return run_match(match_eDOUBLE); | |
case ePRIMARY_EXPRESSION: | |
return run_match(match_ePRIMARY_EXPRESSION); | |
case ePOINTER: | |
return run_match(match_ePOINTER); | |
case eRELATIONAL_EXPRESSION: | |
return run_match(match_eRELATIONAL_EXPRESSION); | |
case eEXCLUSIVE_OR_EXPRESSION: | |
return run_match(match_eEXCLUSIVE_OR_EXPRESSION); | |
case eINT: | |
return run_match(match_eINT); | |
case eVOID: | |
return run_match(match_eVOID); | |
case eFLOAT: | |
return run_match(match_eFLOAT); | |
case eENUMERATOR: | |
return run_match(match_eENUMERATOR); | |
case eSHIFT_EXPRESSION: | |
return run_match(match_eSHIFT_EXPRESSION); | |
case eSELECTION_STATEMENT: | |
return run_match(match_eSELECTION_STATEMENT); | |
case eBITANDASSIGN: | |
return run_match(match_eBITANDASSIGN); | |
case eJUMP_STATEMENT: | |
return run_match(match_eJUMP_STATEMENT); | |
case eDECREMENT: | |
return run_match(match_eDECREMENT); | |
case eAUTO: | |
return run_match(match_eAUTO); | |
case eTYPEDEF: | |
return run_match(match_eTYPEDEF); | |
case eAND_EXPRESSION: | |
return run_match(match_eAND_EXPRESSION); | |
case eLABELED_STATEMENT: | |
return run_match(match_eLABELED_STATEMENT); | |
case eIF: | |
return run_match(match_eIF); | |
case eUNSIGNED: | |
return run_match(match_eUNSIGNED); | |
case eINCREMENT: | |
return run_match(match_eINCREMENT); | |
case eITERATION_STATEMENT: | |
return run_match(match_eITERATION_STATEMENT); | |
case eDECLARATOR: | |
return run_match(match_eDECLARATOR); | |
case eEXPRESSION: | |
return run_match(match_eEXPRESSION); | |
case eUNION: | |
return run_match(match_eUNION); | |
case eSTRUCT_DECLARATOR: | |
return run_match(match_eSTRUCT_DECLARATOR); | |
case eCOMPOUND_STATEMENT: | |
return run_match(match_eCOMPOUND_STATEMENT); | |
case eDECLARATION: | |
return run_match(match_eDECLARATION); | |
case eCAST_EXPRESSION: | |
return run_match(match_eCAST_EXPRESSION); | |
case eEXPRESSION_STATEMENT: | |
return run_match(match_eEXPRESSION_STATEMENT); | |
case eADDITIVE_EXPRESSION: | |
return run_match(match_eADDITIVE_EXPRESSION); | |
case eCHAR: | |
return run_match(match_eCHAR); | |
case eSTRING: | |
return run_match(match_eSTRING); | |
case eSHORT: | |
return run_match(match_eSHORT); | |
case eRETURN: | |
return run_match(match_eRETURN); | |
case eSTRUCT_OR_UNION: | |
return run_match(match_eSTRUCT_OR_UNION); | |
case eINTEGER_CONSTANT: | |
return run_match(match_eINTEGER_CONSTANT); | |
case eBITORASSIGN: | |
return run_match(match_eBITORASSIGN); | |
case eSHIFTLASSIGN: | |
return run_match(match_eSHIFTLASSIGN); | |
case eTYPE_SPECIFIER: | |
return run_match(match_eTYPE_SPECIFIER); | |
case eSHIFTRASSIGN: | |
return run_match(match_eSHIFTRASSIGN); | |
case eFUNCTION_DEFINITION: | |
return run_match(match_eFUNCTION_DEFINITION); | |
case eDIRECT_ABSTRACT_DECLARATOR: | |
return run_match(match_eDIRECT_ABSTRACT_DECLARATOR); | |
case eENUMERATOR_LIST: | |
return run_match(match_eENUMERATOR_LIST); | |
case eCONDITIONAL_EXPRESSION: | |
return run_match(match_eCONDITIONAL_EXPRESSION); | |
case eASSIGN: | |
return run_match(match_eASSIGN); | |
case eENUM: | |
return run_match(match_eENUM); | |
case eSTRUCT: | |
return run_match(match_eSTRUCT); | |
case eINITIALIZER_LIST: | |
return run_match(match_eINITIALIZER_LIST); | |
case eVOLATILE: | |
return run_match(match_eVOLATILE); | |
case eASSIGNMENT_EXPRESSION: | |
return run_match(match_eASSIGNMENT_EXPRESSION); | |
case eFLOATING_CONSTANT: | |
return run_match(match_eFLOATING_CONSTANT); | |
case eMODASSIGN: | |
return run_match(match_eMODASSIGN); | |
case eUNARY_OPERATOR: | |
return run_match(match_eUNARY_OPERATOR); | |
case eIDENTIFIER: | |
return run_match(match_eIDENTIFIER); | |
case eMULASSIGN: | |
return run_match(match_eMULASSIGN); | |
case eCASE: | |
return run_match(match_eCASE); | |
case eXORASSIGN: | |
return run_match(match_eXORASSIGN); | |
default: | |
assert(!"unknown token type"); | |
return false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment