Skip to content

Instantly share code, notes, and snippets.

@marionette-of-u
Created August 8, 2015 13:31
Show Gist options
  • Save marionette-of-u/b214118027f821691570 to your computer and use it in GitHub Desktop.
Save marionette-of-u/b214118027f821691570 to your computer and use it in GitHub Desktop.
C++03によるパーサジェネレータのブートストラップの記述例
https://github.com/marionette-of-u/kp19pp/blob/stable/scanner.cpp
フォーマット解説 :
DECL_SEQSマクロでBNF表現ルールを記述
DECL_SEQS_EPSはε還元を含むルールを追加する以外DECL_SEQSと同機能
L = Ra1 Ra2 Ra3 [ActA] | Rb1 Rb2 Rb3 [ActB];
を記述するには始めに左辺Lをマクロの引数に取る
Rはa, bと複数個あるのでここでBOOST_PP_SEQ形式(Ra)(ActA)(Rb)(ActB)の形を取る
セマンティックアクションActA, ActBが付くので必ず偶数個の要素数になる
RnもBOOST_PP_SEQ形式で記述される
Ra, RbはそれぞれRa1 Ra2 Ra3, Rb1 Rb2 Rb3なので
((Ra1)(Ra2)(Ra3)) (ActA)
((Rb1)(Rb2)(Rb3)) (ActB)
と記述する
終端記号はスネークケースのterm(=int)値
非終端記号は規則を保持するクラスなのでキャメルケースで記述して区別する
lhsというメンバ変数でterm(=int)値として扱う
括弧が多くてややこしい上にマクロを展開する仕組みも複雑でコンパイル時間が長くイマイチ
DECL_SEQS(
IdentifierSeq,
((identifier)(SymbolType_opt.lhs)) (identifier_seq_a)
((IdentifierSeq.lhs)(comma)(identifier)(SymbolType_opt.lhs)) (identifier_seq_b)
);
DECL_SEQS(
NonDelimIdentifierSeq,
((identifier)(ReferenceSpecifier_opt.lhs)) (make_non_delim_identifier_seq_a)
((NonDelimIdentifierSeq.lhs)(identifier)(ReferenceSpecifier_opt.lhs))
(make_non_delim_identifier_seq_b)
((ReferenceSpecifier.lhs)) (make_non_delim_identifier_seq_c)
);
DECL_SEQS(
Type,
((DoubleColon_opt.lhs)(NonDelimIdentifierSeq.lhs)(Template_opt.lhs)(NestIdentifier_opt.lhs))
(make_type_a)
((Type.lhs)(NonDelimIdentifierSeq.lhs)) (make_type_b)
);
DECL_SEQS(
ReferenceSpecifier,
((asterisk)) (make_reference_specifier)
((ampersand)) (make_reference_specifier)
);
DECL_SEQS_EPS(
ReferenceSpecifier_opt,
((ReferenceSpecifier.lhs)) (make_reference_specifier_opt)
);
DECL_SEQS_EPS(
DoubleColon_opt,
((double_colon)) (make_double_colon_opt)
);
DECL_SEQS_EPS(
NestIdentifier_opt,
((NestIdentifier.lhs)) (make_nest_identifier_opt)
);
DECL_SEQS(
NestIdentifier,
((double_colon)(identifier)(Template_opt.lhs)) (make_nest_identifier_a)
((dot)(identifier)(Template_opt.lhs)) (make_nest_identifier_a)
((NestIdentifier.lhs)(double_colon)(identifier)(Template_opt.lhs)) (make_nest_identifier_b)
((NestIdentifier.lhs)(dot)(identifier)(Template_opt.lhs)) (make_nest_identifier_b)
);
DECL_SEQS(
Template,
((l_bracket)(TemplateArg_opt.lhs)(r_bracket)) (make_template)
);
DECL_SEQS_EPS(
Template_opt,
((Template.lhs)) (make_template_opt)
);
DECL_SEQS_EPS(
TemplateArg_opt,
((TypeSeq.lhs)) (make_template_arg)
);
DECL_SEQS(
TypeSeq,
((Type.lhs)) (make_type_seq)
((Type.lhs)(TypeSeqRest.lhs)) (make_type_seq)
);
DECL_SEQS(
TypeSeqRest,
((comma)(Type.lhs)) (make_type_seq)
((TypeSeqRest.lhs)(comma)(Type.lhs)) (make_type_seq)
);
DECL_SEQS_EPS(
SymbolType_opt,
((l_bracket)(Type.lhs)(r_bracket)) (make_symbol_type)
);
DECL_SEQS(
LinkDir,
((l_bracket)(identifier)(r_bracket)) (make_link_dir)
);
DECL_SEQS(
BlockWithLinkDir,
((LinkDir.lhs)(l_curly_bracket)(SeqStatements.lhs)(r_curly_bracket))(make_block_with_linkdir)
);
DECL_SEQS(
SeqStatements,
((SeqStatementsElement.lhs)(semicolon)) (make_seq_statements_a)
((semicolon)) (eat)
((SeqStatements.lhs)(SeqStatementsElement.lhs)(semicolon)) (make_seq_statements_b)
((SeqStatements.lhs)(semicolon)) (eat)
);
DECL_SEQS(
SeqStatementsElement,
((IdentifierSeq.lhs)) (make_seq_statements_element)
);
DECL_SEQS(
TopLevelSeqStatements,
((TopLevelSeqStatementsElement.lhs)) (make_top_level_seq_statements_a)
((semicolon)) (eat)
((TopLevelSeqStatements.lhs)(TopLevelSeqStatementsElement.lhs)) (make_top_level_seq_statements_b)
((TopLevelSeqStatements.lhs)(semicolon)) (eat)
);
DECL_SEQS(
TopLevelSeqStatementsElement,
((IdentifierSeq.lhs)(semicolon)) (make_top_level_seq_statements_element_a)
((BlockWithLinkDir.lhs)) (make_top_level_seq_statements_element_b)
);
DECL_SEQS_EPS(
Arg_opt,
((l_round_pare)(value)(r_round_pare)) (make_arg)
);
DECL_SEQS(
SemanticAction,
((l_square_bracket)(SemanticActionElement_opt.lhs)(r_square_bracket))
(make_semantic_action)
);
DECL_SEQS_EPS(
SemanticActionElement_opt,
((identifier)) (make_semantic_action_opt)
);
DECL_SEQS_EPS(
Tag_opt,
((l_bracket)(identifier)(r_bracket)) (make_tag)
);
DECL_SEQS(
RHSSeq,
((identifier)(Arg_opt.lhs)) (make_rhs_seq)
((RHSSeq.lhs)(identifier)(Arg_opt.lhs)) (make_rhs_seq_last)
);
DECL_SEQS_EPS(
RHSSeq_opt,
((RHSSeq.lhs)) (make_rhs_seq_opt)
);
DECL_SEQS(
RHS,
((SemanticAction.lhs)(Tag_opt.lhs)(RHSSeq_opt.lhs)) (make_rhs)
((RHS.lhs)(symbol_or)(SemanticAction.lhs)(Tag_opt.lhs)(RHSSeq_opt.lhs))
(make_rhs)
);
DECL_SEQS(
LHS,
((identifier)(LHSType.lhs)) (make_lhs)
);
DECL_SEQS(
LHSType,
((l_bracket)(Type.lhs)(r_bracket)) (make_lhs_type)
);
DECL_SEQS(
Exp,
((LHS.lhs)(symbol_colon)(RHS.lhs)) (make_expression)
);
DECL_SEQS(
ExpStatements,
((Exp.lhs)(semicolon)) (make_exp_statements_a)
((semicolon)) (eat)
((ExpStatements.lhs)(Exp.lhs)(semicolon)) (make_exp_statements_b)
((ExpStatements.lhs)(semicolon)) (eat)
);
DECL_SEQS_EPS(
TokenHeaderRest_opt,
((comma)(identifier)) (make_token_header_rest)
)
DECL_SEQS(
TokenHeader,
((l_bracket)(identifier)(TokenHeaderRest_opt.lhs)(r_bracket)) (make_header)
);
DECL_SEQS(
TokenBody,
((l_curly_bracket)(TopLevelSeqStatements.lhs)(r_curly_bracket)) (make_token_body)
);
DECL_SEQS(
GrammarHeader,
((l_bracket)(identifier)(r_bracket)) (make_header)
);
DECL_SEQS_EPS(
DefaultSemanticAction_opt,
((l_square_bracket)(identifier)(r_square_bracket)) (make_default_semantic_action)
)
DECL_SEQS(
GrammarBody,
((l_curly_bracket)(DefaultSemanticAction_opt.lhs)(ExpStatements.lhs)(r_curly_bracket))
(make_grammar_body)
);
DECL_SEQS_EPS(
TokenNamespace,
((identifier)) (make_token_namespace)
);
DECL_SEQS(
GrammarNamespace,
((identifier)) (make_grammar_namespace)
);
DECL_SEQS(
Start,
((TokenHeader.lhs)(TokenNamespace.lhs)(TokenBody.lhs)(GrammarHeader.lhs)(GrammarNamespace.lhs)(GrammarBody.lhs))
(eat)
);
DECL_SEQS(
StartPrime,
((Start.lhs)) (eat)
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment