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 -> - 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(), NumberParser(), 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 Choice( from token in IdentifierParser() from _ in Delimiter("[") from expressions in ExpressionsParser() from _1 in Delimiter("]") select new VariableNode(token, expressions), from token in IdentifierParser() select new VariableNode(token) ); } 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 ConstValueParser() { return Choice( from _ in Operator("-") from num in NumberParser() select new UnaryOperatorNode(UnaryOperatorType.Minus, num), from _ in Operator("+") from num in NumberParser() select new UnaryOperatorNode(UnaryOperatorType.Plus, num), NumberParser(), CharParser(), TrueParser(), FalseParser() ); } public static IParser ConstDeclarationParser() { return from identifier in Satisfy(token => token.TokenType == LexicalTokenType.Identifier) from _ in Operator("=") from node in ConstValueParser() select new ConstantNode(identifier, node); } public static IParser ConstDeclarationsParser() { return (from _ in Keyword("const") from tokens in ConstDeclarationParser().SeparatedOrEndBy1(Delimiter(";")) select new BlockNode(tokens)).Try(new BlockNode([])); } public static IParser ArrayTypeParser() { IParser> arrayRangeParser = ( from left in IntegerParser() from _ in Delimiter("..") from right in IntegerParser() select new ArrayRange(left.Value, right.Value)).SeparatedBy1(Delimiter(",")); return from _ in Keyword("array") from _1 in Delimiter("[") from ranges in arrayRangeParser from _2 in Delimiter("]") from _3 in Keyword("of") from typeToken in BasicTypeParser() select new TypeNode(typeToken, ranges); } public static IParser TypeParser() { return Choice(ArrayTypeParser(), from token in BasicTypeParser() select new TypeNode(token)); } public static IParser VariableDeclarationParser() { return from tokens in Satisfy( token => token.TokenType == LexicalTokenType.Identifier).SeparatedBy1(Delimiter(",")) from _1 in Delimiter(":") from type in TypeParser() select new VariableDeclarationNode(tokens, type.Convert()); } public static IParser VariableDeclarationsParser() { return (from _ in Keyword("var") from nodes in VariableDeclarationParser().SeparatedOrEndBy1(Delimiter(";")) select new BlockNode(nodes)).Try(new BlockNode([])); } public static IParser ProgramBodyParser() { return from constant in ConstDeclarationsParser() from variables in VariableDeclarationsParser() from block in CompoundStatementParser() select new ProgramBody(constant.Convert(), variables, 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); } }