コード例 #1
0
        protected Symbol MatchGerundSignature(string gerund, ParseForest forest, ParseTreeVisitor visitor, SemanticContext context, bool isSubject)
        {
            string root = gerund.FormOf(Inflections.plural);

            "  Found gerund for".Log(root);
            var context2 = new SemanticContext {
                InvocationBeingDefined = new Invocation(root), SignatureBeingDefined = new Signature(root),
            };

            CreateSymbol(forest, visitor.Right(), context2);
            context2.InvocationBeingDefined.SuppliedArguments = context2.SignatureBeingDefined.parms;
            Scope.Current.ResolveMultimethodSymbolByArguments(context2.InvocationBeingDefined);
            if (context2.InvocationBeingDefined.FunctionSymbol == null)
            {
                throw new Backtrack("Signature of parameter-function \"" + context2.SignatureBeingDefined + "\" doesn't match any existing functions.");
            }

            var newSymbol = new Symbol
            {
                Name         = context2.SignatureBeingDefined.verb, // todo: might the name & type be backward? It's usually the other way but the logging looks better this way: it's more precise
                Type         = context2.SignatureBeingDefined.ToString(),
                Category     = Categories.Variable,                 // local variable
                PartOfSpeech = NonTerminalSymbol.GP,
            };

            context.SignatureBeingDefined[context.prepFound] = newSymbol;
            context.SignatureBeingDefined.HasSubject        |= isSubject;
            "  Higher-order function".Log("\"" + context.SignatureBeingDefined + "\" has a parameter \"" + context2.SignatureBeingDefined + "\" which could accept any \"" + context2.InvocationBeingDefined.FunctionSymbol.Signature + "\"");
            return(context2.InvocationBeingDefined.FunctionSymbol);
        }
コード例 #2
0
        protected string WithAlternates(ParseForest forest, ParseTreeVisitor resetVisitor, SemanticContext context, string retryScope = null)
        {
            string             errors = "";
            ParseTreeNodeMatch c      = resetVisitor.currentNode;

            for (; errors != null && c != null; c = c.next)
            {
                try
                {
                    var visitor = new ParseTreeVisitor(resetVisitor)
                    {
                        currentNode = c
                    };
                    visitor.Right();                     // does this need be here? what if we want Left?  Should i pass in these two lines as delegate?
                    CreateSymbol(forest, visitor, context);
                    errors = null;
                }
                catch (Backtrack b)
                {
                    "--BACKTRACK".Log();
                    errors += b.Message + Environment.NewLine;
                    if (retryScope == null)
                    {
                        continue;
                    }
                    Scope.Abandon();
                    Scope.EnterNew(retryScope);
                }
            }
            if (errors != null && c == null)
            {
                if (retryScope != null)
                {
                    Scope.Abandon();
                }
                return(errors);
            }
            return(null);
        }
コード例 #3
0
        protected void DefineTemporalConstraint(ParseForest forest, SemanticContext context)
        {
            var DCvisitor = new ParseTreeVisitor(forest);
            var MCvisitor = new ParseTreeVisitor(DCvisitor);

            if (DCvisitor.currentNode.B == NonTerminalSymbol.DC)
            {
                DCvisitor.Left(); MCvisitor.Right();
            }
            else
            {
                DCvisitor.Right(); MCvisitor.Left();
            }

            context.SignatureBeingDefined.verb = "??constraint";
            context.InvocationBeingDefined     = new Invocation("");

            context.FunctionBeingDefined = new Symbol
            {
                Category     = Categories.Constraint,
                PartOfSpeech = NonTerminalSymbol.TR,
            };
            Scope.EnterNew(context.SignatureBeingDefined.verb);
            DefineImpInvSymbol(forest, context, MCvisitor);
            "  MAIN CLAUSE:".Log(context.SignatureBeingDefined.verb);

            DefineImpInvSymbol(forest, context, DCvisitor);
            "  DEPENDENT CLAUSE:".Log(context.SignatureBeingDefined.verb);

            "DEFINED constraint:".Log(context.SignatureBeingDefined);

            context.FunctionBeingDefined.Name      = context.SignatureBeingDefined.ToString();
            context.FunctionBeingDefined.Type      = context.SignatureBeingDefined.verb;
            context.FunctionBeingDefined.Signature = context.SignatureBeingDefined;
            Scope.Current.Define(context.FunctionBeingDefined);
            EndPreviousFunctionBody(context);
        }
コード例 #4
0
        protected void CreateSymbol(ParseForest forest, ParseTreeVisitor visitor, SemanticContext context)
        {
            if (visitor == null)
            {
                return;
            }
            ParseTreeVisitor visitor2;

            switch (visitor.currentType)
            {
            case NonTerminalSymbol.G:
                // the problem with lone gerunds like "giving" is that you don't know if its GP or aGP so look to see what the container is
                if (visitor.parentNode.B == NonTerminalSymbol.IV)
                {                           // aGP
                    MatchGerundSignature(forest.a[visitor.i], forest, visitor, context, false);
                }
                else if (visitor.parentNode.B == NonTerminalSymbol.VO || visitor.parentNode.B == NonTerminalSymbol.SVO)
                {                           // GP
                    //if (visitor.currentNode != null && visitor.currentNode.B == NonTerminalSymbol.G)
                    MatchGerundSignature(forest.a[visitor.i], forest, visitor, context, false);
                    //else
                    //	FillParameterWith_NP(forest, visitor, context); // the G -- G is an argument
                }
                else
                {
                    throw new Exception("Unknown context for lone gerund.");
                }
                break;

            case NonTerminalSymbol.NPPP:
            case NonTerminalSymbol.SV:
            case NonTerminalSymbol.SVO:
            case NonTerminalSymbol.VO:
            case NonTerminalSymbol.IsHas:
            case NonTerminalSymbol.NPs:
            case NonTerminalSymbol.ConjNP:
            case NonTerminalSymbol.aSVO:
            case NonTerminalSymbol.aNPPP:
                visitor2 = new ParseTreeVisitor(visitor);
                CreateSymbol(forest, visitor.Left(), context);
                CreateSymbol(forest, visitor2.Right(), context);
                break;

            case NonTerminalSymbol.XYZ:
                CreateSymbol(forest, visitor.Right(), context);
                break;

            case NonTerminalSymbol.Conj:
            case NonTerminalSymbol.comma:
            case NonTerminalSymbol.colon:
                break;

            case NonTerminalSymbol.aSV:
                if (visitor.currentNode != null && visitor.currentNode.B == NonTerminalSymbol.G)
                {
                    MatchGerundSignature(forest.a[visitor.i], forest, visitor.Left(), context, true);
                }
                else
                {
                    CreateParameterFrom_aNP(forest, visitor.Left(), context, true);
                }
                break;

            case NonTerminalSymbol.aVO:
                if (visitor.currentNode != null && visitor.currentNode.B == NonTerminalSymbol.G)
                {
                    MatchGerundSignature(forest.a[visitor.i], forest, visitor.Right(), context, false);
                }
                else
                {
                    CreateParameterFrom_aNP(forest, visitor.Right(), context, true);
                }
                break;

            case NonTerminalSymbol.aGP:
            case NonTerminalSymbol.aNP:
                if (visitor.currentNode != null && visitor.currentNode.B == NonTerminalSymbol.G)
                {
                    MatchGerundSignature(forest.a[visitor.i], forest, visitor, context, false);
                }
                else
                {
                    CreateParameterFrom_aNP(forest, visitor, context);
                }
                break;

            case NonTerminalSymbol.aPP:
            case NonTerminalSymbol.PP:
                context.prepFound = "";
                visitor2          = new ParseTreeVisitor(visitor);
                CreateSymbol(forest, visitor.Left(), context);
                CreateSymbol(forest, visitor2.Right(), context);
                break;

            case NonTerminalSymbol.P:
                context.prepFound = forest.a[visitor.i];
                break;

            case NonTerminalSymbol.GP:
                MatchGerundSignature(forest.a[visitor.i], forest, visitor, context, false);
                break;

            case NonTerminalSymbol.NP:
                // is this NP actually a gerund phrase?
                if (visitor.currentNode != null && visitor.currentNode.B == NonTerminalSymbol.G)
                {
                    MatchGerundSignature(forest.a[visitor.i], forest, visitor, context, false);
                }
                else
                {
                    FillParameterWith_NP(forest, visitor, context);
                }
                break;

            case NonTerminalSymbol.V:
            case NonTerminalSymbol.VP:
                if (context.InvocationBeingDefined == null)
                {
                    context.InvocationBeingDefined = new Invocation(forest.a[visitor.i]);
                }
                else
                {
                    context.InvocationBeingDefined.verb = forest.a[visitor.i];
                }
                break;

            case NonTerminalSymbol.Ops:
                //AppendToFunctionBody(context);
                visitor2 = new ParseTreeVisitor(visitor);
                CreateSymbol(forest, visitor.Left(), context);
                CreateSymbol(forest, visitor2.Right(), context);
                break;

            case NonTerminalSymbol.ConjOp:
                AppendToFunctionBody(context);
                visitor2 = new ParseTreeVisitor(visitor);
                CreateSymbol(forest, visitor.Left(), context);
                CreateSymbol(forest, visitor2.Right(), context);
                break;

            case NonTerminalSymbol.body:
                CreateSymbol(forest, visitor.Right(), context);
                AppendToFunctionBody(context);
                break;

            case NonTerminalSymbol.DeObj:
            case NonTerminalSymbol.DeVar:
                var whichCase = visitor.currentType;
                visitor2 = new ParseTreeVisitor(visitor);
                if (visitor.currentNode.B == NonTerminalSymbol.G)
                {
                    throw new Exception("Can't use a gerund phrase yet");
                }
                Symbol ident = CreateSymbolFromNP(forest, visitor.Left(), context);
                using (Scope.EnterNew("of " + ident.Name))
                {
                    CreateSymbol(forest, visitor2.Right(), context);
                    if (whichCase == NonTerminalSymbol.DeVar && context.SignatureBeingDefined.parms.Count == 1)
                    {
                        ident.Type = context.SignatureBeingDefined.parms[0].aNP.Type;
                    }
                }
                break;

            default:
                visitor.currentType.ToString().Log("isn't known by the big switch statement in CreateSymbol");
                return;
            }
        }