IFPSTools.NET/LibIFPSCC/Parser/CParsers.cs
zc e16c00799d ifpscc: initial commit
libifpscc: initial commit
readme: document ifpscc/libifpscc
license: add credits for ifpscc/libifpscc (derived from code also MIT licensed)
libifps: make additional fields/types public for libifpscc
libifps: fix field documentation for some opcodes
libifps: fix loading functions that are not exported
libifps: allow saving a nonexistant primitive type if the same primitive type was added already
libifps: fix parsing Extended constants
libifps: fix ushort/short being mapped to the wrong types in one table
csproj: set Prefer32Bit=false for release builds
2023-03-28 17:24:19 +01:00

117 lines
4.8 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using LexicalAnalysis;
using AST;
using static Parsing.ParserCombinator;
using System.Collections.Immutable;
namespace Parsing {
public partial class CParsers {
static CParsers() {
SetExpressionRules();
SetDeclarationRules();
SetExternalDefinitionRules();
SetStatementRules();
}
public static IParserResult<TranslnUnit> Parse(IEnumerable<Token> tokens) =>
TranslationUnit.Parse(new ParserInput(new ParserEnvironment(), tokens));
public class ConstCharParser : IParser<Expr> {
public RuleCombining Combining => RuleCombining.NONE;
public IParserResult<Expr> Parse(ParserInput input) {
var token = input.Source.First() as TokenCharConst;
if (token == null) {
return new ParserFailed<Expr>(input);
}
return ParserSucceeded.Create(new IntLiteral(token.Value, TokenInt.IntSuffix.NONE), input.Environment, input.Source.Skip(1));
}
}
public class ConstIntParser : IParser<Expr> {
public RuleCombining Combining => RuleCombining.NONE;
public IParserResult<Expr> Parse(ParserInput input) {
var token = input.Source.First() as TokenInt;
if (token == null) {
return new ParserFailed<Expr>(input);
}
return ParserSucceeded.Create(new IntLiteral(token.Val, token.Suffix), input.Environment, input.Source.Skip(1));
}
}
public class ConstFloatParser : IParser<Expr> {
public RuleCombining Combining => RuleCombining.NONE;
public IParserResult<Expr> Parse(ParserInput input) {
var token = input.Source.First() as TokenFloat;
if (token == null) {
return new ParserFailed<Expr>(input);
}
return ParserSucceeded.Create(new FloatLiteral(token.Value, token.Suffix), input.Environment, input.Source.Skip(1));
}
}
public class StringLiteralParser : IParser<Expr> {
public RuleCombining Combining => RuleCombining.NONE;
public IParserResult<Expr> Parse(ParserInput input) {
var token = input.Source.First() as TokenString;
if (token == null) {
return new ParserFailed<Expr>(input);
}
return ParserSucceeded.Create(new StringLiteral(token.Val), input.Environment, input.Source.Skip(1));
}
}
public class UnicodeStringLiteralParser : IParser<Expr>
{
public RuleCombining Combining => RuleCombining.NONE;
public IParserResult<Expr> Parse(ParserInput input)
{
var token = input.Source.First() as TokenUnicodeString;
if (token == null)
{
return new ParserFailed<Expr>(input);
}
return ParserSucceeded.Create(new UnicodeStringLiteral(token.Val), input.Environment, input.Source.Skip(1));
}
}
public class BinaryOperatorBuilder {
public BinaryOperatorBuilder(IConsumer operatorConsumer, Func<Expr, Expr, Expr> nodeCreator) {
this.OperatorConsumer = operatorConsumer;
this.NodeCreator = nodeCreator;
}
public static BinaryOperatorBuilder Create(IConsumer operatorConsumer, Func<Expr, Expr, Expr> nodeCreator) =>
new BinaryOperatorBuilder(operatorConsumer, nodeCreator);
public IConsumer OperatorConsumer { get; }
public Func<Expr, Expr, Expr> NodeCreator { get; }
}
// TODO: create a dedicated class for this.
public static IParser<Expr> BinaryOperator(IParser<Expr> operandParser, params BinaryOperatorBuilder[] builders) {
ImmutableList<ITransformer<Expr, Expr>> transformers = builders.Select(builder =>
Given<Expr>()
.Then(builder.OperatorConsumer)
.Then(operandParser)
.Then(builder.NodeCreator)
).ToImmutableList();
return operandParser.Then((new OrTransformer<Expr, Expr>(transformers)).ZeroOrMore());
}
public static IParser<Expr> AssignmentOperator(
IParser<Expr> lhsParser,
IParser<Expr> rhsParser,
params BinaryOperatorBuilder[] builders
) {
var transformers = builders.Select(builder =>
Given<Expr>()
.Then(builder.OperatorConsumer)
.Then(rhsParser)
.Then(builder.NodeCreator)
).ToImmutableList();
return lhsParser.Then((new OrTransformer<Expr, Expr>(transformers)).OneOrMore());
}
}
}