using System.Collections.Immutable;
using AST;
using static Parsing.ParserCombinator;
namespace Parsing {
public partial class CParsers {
///
/// statement
/// : labeled-statement
/// | compound-statement
/// | expression-statement
/// | selection-statement
/// | iteration-statement
/// | jump-statement
///
public static NamedParser
Statement = new NamedParser("statement");
///
/// jump-statement
/// : 'goto' identifier ';'
/// | 'continue' ';'
/// | 'break' ';'
/// | 'return' [expression]? ';'
///
public static NamedParser
JumpStatement = new NamedParser("jump-statement");
///
/// compound-statement
/// : '{' [declaration-list]? [statement-list]? '}'
///
public static NamedParser
CompoundStatement = new NamedParser("compound-statement");
///
/// declaration-list
/// : [declaration]+
///
public static NamedParser>
DeclarationList = new NamedParser>("declaration-list");
///
/// statement-list
/// : [statement]+
///
public static NamedParser>
StatementList = new NamedParser>("statement-list");
///
/// expression-statement
/// : [expression]? ';'
///
public static NamedParser
ExpressionStatement = new NamedParser("expression-statement");
///
/// iteration-statement
/// : 'while' '(' expression ')' statement
/// | 'do' statement 'while' '(' expression ')' ';'
/// | 'for' '(' [expression]? ';' [expression]? ';' [expression]? ')' statement
///
public static NamedParser
IterationStatement = new NamedParser("iteration-statement");
///
/// selection-statement
/// : 'if' '(' expression ')' statement 'else' statement
/// | 'if' '(' expression ')' statement
/// | 'switch' '(' expression ')' statement
///
public static NamedParser
SelectionStatement = new NamedParser("selection-statement");
///
/// labeled-statement
/// : identifier ':' statement
/// | 'case' constant-expression ':' statement
/// | 'default' ':' statement
///
public static NamedParser
LabeledStatement = new NamedParser("labeled-statement");
public static void SetStatementRules() {
// statement
// : labeled-statement
// | compound-statement
// | expression-statement
// | selection-statement
// | iteration-statement
// | jump-statement
Statement.Is(
Either(LabeledStatement)
.Or(CompoundStatement)
.Or(ExpressionStatement)
.Or(SelectionStatement)
.Or(IterationStatement)
.Or(JumpStatement)
);
// jump-statement
// : 'goto' identifier ';'
// | 'continue' ';'
// | 'break' ';'
// | 'return' [expression]? ';'
JumpStatement.Is(
(
Either(
(Goto).Then(Identifier).Then(GotoStmt.Create)
).Or(Continue)
.Or(Break)
.Or((Return).Then(Expression.Optional()).Then(ReturnStmt.Create))
)
.Then(Semicolon)
);
// compound-statement
// : '{' [declaration-list]? [statement-list]? '}'
CompoundStatement.Is(
(LeftCurlyBrace)
.TransformEnvironment(env => env.InScope())
.Then(DeclarationList.Optional(ImmutableList.Empty))
.Then(StatementList.Optional(ImmutableList.Empty))
.Then(RightCurlyBrace)
.TransformEnvironment(env => env.OutScope())
.Then(CompoundStmt.Create)
);
// declaration-list
// : [declaration]+
DeclarationList.Is(
Declaration.OneOrMore()
);
// statement-list
// : [statement]+
StatementList.Is(
Statement.OneOrMore()
);
// expression-statement
// : [expression]? ';'
ExpressionStatement.Is(
Expression.Optional()
.Then(Semicolon)
.Then(ExprStmt.Create)
);
// iteration-statement
// : 'while' '(' expression ')' statement
// | 'do' statement 'while' '(' expression ')' ';'
// | 'for' '(' [expression]? ';' [expression]? ';' [expression]? ')' statement
IterationStatement.Is(
Either(
(While)
.Then(LeftParen)
.Then(Expression)
.Then(RightParen)
.Then(Statement)
.Then(WhileStmt.Create)
).Or(
(Do)
.Then(Statement)
.Then(While)
.Then(LeftParen)
.Then(Expression)
.Then(RightParen)
.Then(Semicolon)
.Then(DoWhileStmt.Create)
).Or(
(For)
.Then(LeftParen)
.Then(Expression.Optional())
.Then(Semicolon)
.Then(Expression.Optional())
.Then(Semicolon)
.Then(Expression.Optional())
.Then(RightParen)
.Then(Statement)
.Then(ForStmt.Create)
)
);
// selection-statement
// : 'if' '(' expression ')' statement 'else' statement
// | 'if' '(' expression ')' statement
// | 'switch' '(' expression ')' statement
SelectionStatement.Is(
Either(
(If)
.Then(LeftParen)
.Then(Expression)
.Then(RightParen)
.Then(Statement)
.Then(
Either(
Given()
.Then(Else)
.Then(Statement)
.Then(IfElseStmt.Create)
).Or(
Given()
.Then(IfStmt.Create)
)
)
).Or(
(Switch)
.Then(LeftParen)
.Then(Expression)
.Then(RightParen)
.Then(Statement)
.Then(SwitchStmt.Create)
)
);
// labeled-statement
// : identifier ':' statement
// | 'case' constant-expression ':' statement
// | 'default' ':' statement
LabeledStatement.Is(
Either(
(Identifier)
.Then(Colon)
.Then(Statement)
.Then(LabeledStmt.Create)
)
.Or(
(Case)
.Then(ConstantExpression)
.Then(Colon)
.Then(Statement)
.Then(CaseStmt.Create)
).Or(
(Default)
.Then(Colon)
.Then(Statement)
.Then(DefaultStmt.Create)
)
);
}
}
}