add: constant parser and variable parser.

This commit is contained in:
2024-08-16 17:07:53 +08:00
parent bdcc59a2ab
commit ed36546b30
10 changed files with 244 additions and 24 deletions

View File

@@ -10,21 +10,6 @@ public sealed class GrammarParser : GrammarParserBuilder
{
public static IParser<LexicalToken, SyntaxNodeBase> FactorParser()
{
// factor -> true | false | num
IParser<LexicalToken, SyntaxNodeBase> trueParser = from _ in Keyword("true")
select new BooleanValueNode(true);
IParser<LexicalToken, SyntaxNodeBase> falseParser = from _ in Keyword("false")
select new BooleanValueNode(false);
IParser<LexicalToken, SyntaxNodeBase> integerParser =
from token in Satisfy<LexicalToken>(x => x.TokenType == LexicalTokenType.ConstInteger)
select new IntegerValueNode(int.Parse(token.LiteralValue));
IParser<LexicalToken, SyntaxNodeBase> floatParser =
from token in Satisfy<LexicalToken>(x => x.TokenType == LexicalTokenType.ConstFloat)
select new FloatValueNode(double.Parse(token.LiteralValue));
// factor -> - factor | + factor
IParser<LexicalToken, SyntaxNodeBase> minusParser =
from _ in Operator("-")
@@ -48,10 +33,9 @@ public sealed class GrammarParser : GrammarParserBuilder
select node;
return Choice(
trueParser,
falseParser,
integerParser,
floatParser,
TrueParser(),
FalseParser(),
NumberParser(),
minusParser,
plusParser,
notParser,
@@ -166,7 +150,7 @@ public sealed class GrammarParser : GrammarParserBuilder
from _ in Operator(":=")
from expression in ExpressionParser()
select new AssignNode(variable, expression)
);
);
}
public static IParser<LexicalToken, BlockNode> CompoundStatementParser()
@@ -177,10 +161,66 @@ public sealed class GrammarParser : GrammarParserBuilder
select new BlockNode(statements);
}
public static IParser<LexicalToken, SyntaxNodeBase> 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<LexicalToken, SyntaxNodeBase> ConstDeclarationParser()
{
return from identifier in Satisfy<LexicalToken>(token =>
token.TokenType == LexicalTokenType.Identifier)
from _ in Operator("=")
from node in ConstValueParser()
select new ConstantNode(identifier, node);
}
public static IParser<LexicalToken, SyntaxNodeBase> ConstDeclarationsParser()
{
return (from _ in Keyword("const")
from tokens in ConstDeclarationParser().SeparatedOrEndBy1(Delimiter(";"))
select new BlockNode(tokens)).Try(new BlockNode([]));
}
public static IParser<LexicalToken, SyntaxNodeBase> TypeParser()
{
return from token in BasicTypeParser()
select new TypeNode(token);
}
public static IParser<LexicalToken, VariableDeclarationNode> VariableDeclarationParser()
{
return from tokens in Satisfy<LexicalToken>(
token => token.TokenType == LexicalTokenType.Identifier).SeparatedBy1(Delimiter(","))
from _1 in Delimiter(":")
from type in TypeParser()
select new VariableDeclarationNode(tokens, type.Convert<TypeNode>());
}
public static IParser<LexicalToken, BlockNode> VariableDeclarationsParser()
{
return (from _ in Keyword("var")
from nodes in VariableDeclarationParser().SeparatedOrEndBy1(Delimiter(";"))
select new BlockNode(nodes)).Try(new BlockNode([]));
}
public static IParser<LexicalToken, ProgramBody> ProgramBodyParser()
{
return from block in CompoundStatementParser()
select new ProgramBody(block);
return from constant in ConstDeclarationsParser()
from variables in VariableDeclarationsParser()
from block in CompoundStatementParser()
select new ProgramBody(constant.Convert<BlockNode>(), variables, block);
}
public static IParser<LexicalToken, ProgramHead> ProgramHeadParser()

View File

@@ -1,5 +1,7 @@
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;
@@ -14,4 +16,42 @@ public abstract class GrammarParserBuilder
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, 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")
);
}
}