using CanonSharp.Combinator.Abstractions; using CanonSharp.Combinator.Extensions; using CanonSharp.Pascal.Scanner; using CanonSharp.Pascal.SyntaxTree; using static CanonSharp.Combinator.ParserBuilder; namespace CanonSharp.Pascal.Parser; public abstract class GrammarParserBuilder { protected static IParser Keyword(string value) => Satisfy(token => token.TokenType == LexicalTokenType.Keyword && token.LiteralValue.Equals(value, StringComparison.OrdinalIgnoreCase)); protected static IParser Operator(string value) => Satisfy(token => token.TokenType == LexicalTokenType.Operator && token.LiteralValue == value); protected static IParser Delimiter(string value) => Satisfy(token => token.TokenType == LexicalTokenType.Delimiter && token.LiteralValue == value); protected static IParser TrueParser() { return from _ in Keyword("true") select new BooleanValueNode(true); } protected static IParser FalseParser() { return from _ in Keyword("false") select new BooleanValueNode(false); } protected static IParser IntegerParser() { return from token in Satisfy(token => token.TokenType == LexicalTokenType.ConstInteger) select new IntegerValueNode(int.Parse(token.LiteralValue)); } protected static IParser NumberParser() { return Choice( from token in Satisfy(x => x.TokenType == LexicalTokenType.ConstInteger) select new IntegerValueNode(int.Parse(token.LiteralValue)), from token in Satisfy(x => x.TokenType == LexicalTokenType.ConstFloat) select new FloatValueNode(double.Parse(token.LiteralValue)) ); } protected static IParser CharParser() { return Satisfy(token => token.TokenType == LexicalTokenType.Character) .Map(x => new CharValueNode(char.Parse(x.LiteralValue))); } protected static IParser BasicTypeParser() { return Choice( Keyword("integer"), Keyword("real"), Keyword("boolean"), Keyword("char") ); } protected static IParser IdentifierParser() { return Satisfy(token => token.TokenType == LexicalTokenType.Identifier); } }