using CanonSharp.Combinator.Abstractions; using CanonSharp.Combinator.Extensions; using static CanonSharp.Combinator.ParserBuilder; using CanonSharp.Pascal.Scanner; using CanonSharp.Pascal.SyntaxTree; namespace CanonSharp.Pascal.Parser; public sealed class GrammarParser : GrammarParserBuilder { public static IParser FactorParser() { // factor -> true | false | num IParser trueParser = from _ in Keyword("true") select new BooleanValueNode(true); IParser falseParser = from _ in Keyword("false") select new BooleanValueNode(false); IParser integerParser = from token in Satisfy(x => x.TokenType == LexicalTokenType.ConstInteger) select new IntegerValueNode(int.Parse(token.LiteralValue)); IParser floatParser = from token in Satisfy(x => x.TokenType == LexicalTokenType.ConstFloat) select new FloatValueNode(double.Parse(token.LiteralValue)); // factor -> - factor | + factor IParser minusParser = from _ in Operator("-") from node in FactorParser() select new UnaryOperatorNode(UnaryOperatorType.Minus, node); IParser plusParser = from _ in Operator("+") from node in FactorParser() select new UnaryOperatorNode(UnaryOperatorType.Plus, node); IParser notParser = from _ in Keyword("not") from node in FactorParser() select new UnaryOperatorNode(UnaryOperatorType.Not, node); IParser parenthesisParser = from _1 in Delimiter("(") from node in ExpressionParser() from _2 in Delimiter(")") select node; return Choice( trueParser, falseParser, integerParser, floatParser, minusParser, plusParser, notParser, VariableParser(), parenthesisParser ); } private static IParser TermRecursively(SyntaxNodeBase left) { // MultiplyOperator -> * | / | div | mod | and IParser multiplyOperator = Choice( from _ in Operator("*") select BinaryOperatorType.Multiply, from _ in Operator("/") select BinaryOperatorType.Divide, from _ in Keyword("div") select BinaryOperatorType.IntegerDivide, from _ in Keyword("mod") select BinaryOperatorType.Mod, from _ in Keyword("and") select BinaryOperatorType.And); return multiplyOperator.Next(op => { return FactorParser().Map(right => new BinaryOperatorNode(op, left, right)) .Bind(TermRecursively); }, left); } public static IParser TermParser() { // Term -> Factor | Term MultiplyOperator Factor // 消除左递归为 // Term -> Factor Term' // Term' -> MultiplyOperator Factor Term' | ε return FactorParser().Bind(TermRecursively); } private static IParser SimpleExpressionRecursively(SyntaxNodeBase left) { // AddOperator -> + | - | or IParser addOperator = Choice( from _ in Operator("+") select BinaryOperatorType.Add, from _ in Operator("-") select BinaryOperatorType.Subtract, from _ in Keyword("or") select BinaryOperatorType.Or); return addOperator.Next(op => { return TermParser().Map(right => new BinaryOperatorNode(op, left, right)) .Bind(SimpleExpressionRecursively); }, left); } public static IParser SimpleExpressionParser() { // SimpleExpression -> Term | SimpleExpression AddOperator Term // 消除左递归为 // SimpleExpression -> Term SimpleExpression' // SimpleExpression' -> AddOperator Term SimpleExpression' | ε return TermParser().Bind(SimpleExpressionRecursively); } public static IParser ExpressionParser() { // RelationOperator -> = | <> | < | <= | > | >= IParser relationOperator = Choice( from _ in Operator("=") select BinaryOperatorType.Equal, from _ in Operator("<>") select BinaryOperatorType.NotEqual, from _ in Operator("<") select BinaryOperatorType.Less, from _ in Operator("<=") select BinaryOperatorType.LessEqual, from _ in Operator(">") select BinaryOperatorType.Greater, from _ in Operator(">=") select BinaryOperatorType.GreaterEqual); // Expression -> SimpleExpression | SimpleExpression RelationOperator SimpleExpression return Choice( from left in SimpleExpressionParser() from op in relationOperator from right in SimpleExpressionParser() select new BinaryOperatorNode(op, left, right), SimpleExpressionParser() ); } /// /// ExpressionList Parser /// ExpressionList -> Expression | ExpressionList , Expression /// /// public static IParser> ExpressionsParser() => ExpressionParser().SeparatedBy1(Delimiter(",")); public static IParser VariableParser() { return from token in Satisfy(token => token.TokenType == LexicalTokenType.Identifier) select new VariableNode(token.LiteralValue); } public static IParser StatementParser() { return Choice( from variable in VariableParser() from _ in Operator(":=") from expression in ExpressionParser() select new AssignNode(variable, expression) ); } public static IParser CompoundStatementParser() { return from _1 in Keyword("begin") from statements in StatementParser().SeparatedOrEndBy(Delimiter(";")) from _2 in Keyword("end") select new BlockNode(statements); } public static IParser ProgramBodyParser() { return from block in CompoundStatementParser() select new ProgramBody(block); } public static IParser ProgramHeadParser() { return from _ in Keyword("program") from token in Satisfy(token => token.TokenType == LexicalTokenType.Identifier) select new ProgramHead(token); } public static IParser ProgramParser() { return from head in ProgramHeadParser() from _1 in Delimiter(";") from body in ProgramBodyParser() from _2 in Delimiter(".") select new Program(head, body); } }