2024-08-15 16:18:32 +08:00
|
|
|
|
using CanonSharp.Combinator.Abstractions;
|
2024-08-16 17:07:53 +08:00
|
|
|
|
using CanonSharp.Combinator.Extensions;
|
2024-08-15 16:18:32 +08:00
|
|
|
|
using CanonSharp.Pascal.Scanner;
|
2024-08-16 17:07:53 +08:00
|
|
|
|
using CanonSharp.Pascal.SyntaxTree;
|
2024-08-15 16:18:32 +08:00
|
|
|
|
using static CanonSharp.Combinator.ParserBuilder;
|
|
|
|
|
|
|
|
|
|
namespace CanonSharp.Pascal.Parser;
|
|
|
|
|
|
|
|
|
|
public abstract class GrammarParserBuilder
|
|
|
|
|
{
|
|
|
|
|
protected static IParser<LexicalToken, LexicalToken> Keyword(string value)
|
2024-08-17 15:44:58 +08:00
|
|
|
|
=> Satisfy<LexicalToken>(token =>
|
|
|
|
|
token.TokenType == LexicalTokenType.Keyword &&
|
|
|
|
|
token.LiteralValue.Equals(value, StringComparison.OrdinalIgnoreCase));
|
2024-08-15 16:18:32 +08:00
|
|
|
|
|
|
|
|
|
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);
|
2024-08-16 17:07:53 +08:00
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-17 17:50:28 +08:00
|
|
|
|
protected static IParser<LexicalToken, IntegerValueNode> IntegerParser()
|
|
|
|
|
{
|
|
|
|
|
return from token in Satisfy<LexicalToken>(token => token.TokenType == LexicalTokenType.ConstInteger)
|
|
|
|
|
select new IntegerValueNode(int.Parse(token.LiteralValue));
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-16 17:07:53 +08:00
|
|
|
|
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")
|
|
|
|
|
);
|
|
|
|
|
}
|
2024-08-17 17:50:28 +08:00
|
|
|
|
|
|
|
|
|
protected static IParser<LexicalToken, LexicalToken> IdentifierParser()
|
|
|
|
|
{
|
|
|
|
|
return Satisfy<LexicalToken>(token => token.TokenType == LexicalTokenType.Identifier);
|
|
|
|
|
}
|
2024-08-15 16:18:32 +08:00
|
|
|
|
}
|