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) ) ); } } }