CanonSharp/CanonSharp.Pascal/Parser/GrammarParserBase.cs

71 lines
2.7 KiB
C#
Raw Normal View History

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<LexicalToken, LexicalToken> Keyword(string value)
=> Satisfy<LexicalToken>(token =>
token.TokenType == LexicalTokenType.Keyword &&
token.LiteralValue.Equals(value, StringComparison.OrdinalIgnoreCase));
protected static IParser<LexicalToken, LexicalToken> Operator(string value)
=> Satisfy<LexicalToken>(token => token.TokenType == LexicalTokenType.Operator && token.LiteralValue == value);
protected static IParser<LexicalToken, LexicalToken> Delimiter(string value)
=> Satisfy<LexicalToken>(token => token.TokenType == LexicalTokenType.Delimiter && token.LiteralValue == value);
protected static IParser<LexicalToken, BooleanValueNode> TrueParser()
{
return from _ in Keyword("true")
select new BooleanValueNode(true);
}
protected static IParser<LexicalToken, BooleanValueNode> FalseParser()
{
return from _ in Keyword("false")
select new BooleanValueNode(false);
}
protected static IParser<LexicalToken, IntegerValueNode> IntegerParser()
{
return from token in Satisfy<LexicalToken>(token => token.TokenType == LexicalTokenType.ConstInteger)
select new IntegerValueNode(int.Parse(token.LiteralValue));
}
protected static IParser<LexicalToken, SyntaxNodeBase> NumberParser()
{
return Choice<LexicalToken, SyntaxNodeBase>(
from token in Satisfy<LexicalToken>(x => x.TokenType == LexicalTokenType.ConstInteger)
select new IntegerValueNode(int.Parse(token.LiteralValue)),
from token in Satisfy<LexicalToken>(x => x.TokenType == LexicalTokenType.ConstFloat)
select new FloatValueNode(double.Parse(token.LiteralValue))
);
}
protected static IParser<LexicalToken, CharValueNode> CharParser()
{
return Satisfy<LexicalToken>(token => token.TokenType == LexicalTokenType.Character)
.Map(x => new CharValueNode(char.Parse(x.LiteralValue)));
}
protected static IParser<LexicalToken, LexicalToken> BasicTypeParser()
{
return Choice(
Keyword("integer"),
Keyword("real"),
Keyword("boolean"),
Keyword("char")
);
}
protected static IParser<LexicalToken, LexicalToken> IdentifierParser()
{
return Satisfy<LexicalToken>(token => token.TokenType == LexicalTokenType.Identifier);
}
}