Exemplo n.º 1
0
        /**
         * Commit changes to all loaded grammars and all changes of grammar since
         * the last commitChange
         *
         * @throws JSGFGrammarParseException
         * @throws JSGFGrammarException
         */
        public virtual void CommitChanges()
        {
            try
            {
                if (LoadGrammar)
                {
                    if (Manager == null)
                    {
                        GetGrammarManager();
                    }
                    _ruleGrammar = LoadNamedGrammar(GrammarName);
                    LoadImports(_ruleGrammar);
                    LoadGrammar = false;
                }

                Manager.LinkGrammars();
                RuleStack = new RuleStack();
                NewGrammar();

                FirstNode = CreateGrammarNode("<sil>");
                GrammarNode finalNode = CreateGrammarNode("<sil>");
                finalNode.SetFinalNode(true);

                // go through each rule and create a network of GrammarNodes
                // for each of them

                foreach (String ruleName in _ruleGrammar.GetRuleNames())
                {
                    if (_ruleGrammar.IsRulePublic(ruleName))
                    {
                        String       fullName        = GetFullRuleName(ruleName);
                        GrammarGraph publicRuleGraph = new GrammarGraph(this);
                        RuleStack.Push(fullName, publicRuleGraph);
                        JSGFRule     rule  = _ruleGrammar.GetRule(ruleName);
                        GrammarGraph graph = ProcessRule(rule);
                        RuleStack.Pop();

                        FirstNode.Add(publicRuleGraph.StartNode, 0.0f);
                        publicRuleGraph.EndNode.Add(finalNode, 0.0f);
                        publicRuleGraph.StartNode.Add(graph.StartNode,
                                                      0.0f);
                        graph.EndNode.Add(publicRuleGraph.EndNode, 0.0f);
                    }
                }
                PostProcessGrammar();
                if (Logger.Level == LogLevel.All)
                {
                    DumpGrammar();
                }
            }
            catch (UriFormatException mue)
            {
                throw new IOException("bad base grammar URL " + BaseUrl + ' ' + mue);
            }
        }
Exemplo n.º 2
0
        /**
         * Parses the given RuleSequence into a network of GrammarNodes.
         *
         * @param ruleSequence
         *            the RuleSequence to parse
         * @return the first and last GrammarNodes of the network
         */
        private GrammarGraph ProcessRuleSequence(JSGFRuleSequence ruleSequence)
        {
            GrammarNode startNode = null;
            GrammarNode endNode   = null;

            this.LogInfo("parseRuleSequence: " + ruleSequence);

            List <JSGFRule> rules = ruleSequence.Rules;

            GrammarNode lastGrammarNode = null;

            // expand and connect each rule in the sequence serially
            for (int i = 0; i < rules.Count; i++)
            {
                JSGFRule     rule     = rules[i];
                GrammarGraph newNodes = ProcessRule(rule);

                // first node
                if (i == 0)
                {
                    startNode = newNodes.StartNode;
                }

                // last node
                if (i == (rules.Count - 1))
                {
                    endNode = newNodes.EndNode;
                }

                if (i > 0)
                {
                    lastGrammarNode.Add(newNodes.StartNode, 0.0f);
                }
                lastGrammarNode = newNodes.EndNode;
            }

            return(new GrammarGraph(startNode, endNode, this));
        }
Exemplo n.º 3
0
        public TestLanguage()
        {
            this.LanguageName = "Lispish";
            // The scanner will understand tokens in the sentence "(one foo baz   )", for example.
            // Incidentally, it will also understand them in "())( zab (((()", but that's not the scanner's problem.
            ScannerProductions = new Dictionary<string, GrammarNode>();
            ScannerNames = new List<string>();
            GrammarNode SPName = new GrammarNode(GrammarNodeType.TERMINAL, "[a-z]", MatchType.REGEX);
            SPName.GNTQuantifier = GrammarNodeTypeQuantifier.ONE_OR_MORE;
            AddProduction("scanner", "name", SPName);

            GrammarNode SPLParen = new GrammarNode(GrammarNodeType.TERMINAL, "(", MatchType.VALUE);
            SPLParen.GNTQuantifier = GrammarNodeTypeQuantifier.ONE;
            AddProduction("scanner", "lparen", SPLParen);

            GrammarNode SPRParen = new GrammarNode(GrammarNodeType.TERMINAL, ")", MatchType.VALUE);
            SPLParen.GNTQuantifier = GrammarNodeTypeQuantifier.ONE;
            AddProduction("scanner", "rparen", SPRParen);

            GrammarNode SPWhiteSpace = new GrammarNode(GrammarNodeType.ALTERNATION, "", MatchType.RECURSE);
            SPWhiteSpace.GNTQuantifier = GrammarNodeTypeQuantifier.ONE_OR_MORE;
            GrammarNode SPSpace = new GrammarNode(GrammarNodeType.TERMINAL, " ", MatchType.VALUE);
            SPSpace.GNTQuantifier = GrammarNodeTypeQuantifier.ONE;
            GrammarNode SPReturn = new GrammarNode(GrammarNodeType.TERMINAL, "\r", MatchType.REGEX);
            SPReturn.GNTQuantifier = GrammarNodeTypeQuantifier.ONE;
            GrammarNode SPNewline = new GrammarNode(GrammarNodeType.TERMINAL, "\n", MatchType.REGEX);
            SPNewline.GNTQuantifier = GrammarNodeTypeQuantifier.ONE;
            SPWhiteSpace.Add(SPSpace);
            SPWhiteSpace.Add(SPReturn);
            SPWhiteSpace.Add(SPNewline);
            AddProduction("scanner", "whitespace", SPWhiteSpace);

            GrammarNode SPEOF = new GrammarNode(GrammarNodeType.TERMINAL, "EOF", MatchType.TYPE);
            SPEOF.GNTQuantifier = GrammarNodeTypeQuantifier.ONE;
            AddProduction("scanner", "EOF", SPEOF);

            // The parser will understand sentences of the form "(foo baz bar   one   )", for example.
            // It will also understand "(foo (baz bar)   one )". That is, recursive lists of simple alphabetic string atoms.

            ParserProductions = new Dictionary<string, GrammarNode>();
            ParserNames = new List<string>();
            //GrammarNode PWhitespace = new GrammarNode(GrammarNodeType.TERMINAL, "whitespace", MatchType.TYPE);
            //PWhitespace.GNTQuantifier = GrammarNodeTypeQuantifier.ONE;
            //GrammarNode PWSZeroOrOne = new GrammarNode(GrammarNodeType.TERMINAL, "whitespace", MatchType.TYPE);
            //PWSZeroOrOne.GNTQuantifier = GrammarNodeTypeQuantifier.ZERO_OR_ONE;

            GrammarNode PLBegin = new GrammarNode(GrammarNodeType.SEQUENCE, "", MatchType.RECURSE);
            PLBegin.GNTQuantifier = GrammarNodeTypeQuantifier.ONE;

            GrammarNode PLParen = new GrammarNode(GrammarNodeType.TERMINAL, "lparen", MatchType.TYPE);
            PLParen.GNTQuantifier = GrammarNodeTypeQuantifier.ONE;

            PLBegin.Add(PLParen);
            //PLBegin.Add(PWSZeroOrOne);

            GrammarNode PName = new GrammarNode(GrammarNodeType.TERMINAL, "name", MatchType.TYPE);
            PName.GNTQuantifier = GrammarNodeTypeQuantifier.ONE;

            GrammarNode PList = new GrammarNode(GrammarNodeType.SEQUENCE, "", MatchType.RECURSE);
            PList.GNTQuantifier = GrammarNodeTypeQuantifier.ONE;

            GrammarNode PListElement = new GrammarNode(GrammarNodeType.ALTERNATION, "", MatchType.RECURSE);
            PListElement.GNTQuantifier = GrammarNodeTypeQuantifier.ZERO_OR_MORE;

            PListElement.Add(PName);
            PListElement.Add(PList);

            //GrammarNode PConsequent = new GrammarNode(GrammarNodeType.SEQUENCE, "", MatchType.RECURSE);
            //PConsequent.GNTQuantifier = GrammarNodeTypeQuantifier.ZERO_OR_MORE;

            //PConsequent.Add(PWhitespace);
            //PConsequent.Add(PInitial);

            GrammarNode PLEnd = new GrammarNode(GrammarNodeType.SEQUENCE, "", MatchType.RECURSE);
            PLEnd.GNTQuantifier = GrammarNodeTypeQuantifier.ONE;

            GrammarNode PRParen = new GrammarNode(GrammarNodeType.TERMINAL, "rparen", MatchType.TYPE);
            PRParen.GNTQuantifier = GrammarNodeTypeQuantifier.ONE;

            //PLEnd.Add(PWSZeroOrOne);
            PLEnd.Add(PRParen);

            PList.Add(PLBegin);
            PList.Add(PListElement);
            //PList.Add(PConsequent);
            PList.Add(PLEnd);

            GrammarNode EOF = new GrammarNode(GrammarNodeType.TERMINAL, "EOF", MatchType.EOF);

            //AddProduction("parser","whitespace", PWhitespace);
            AddProduction("parser", "list", PList);
            AddProduction("parser", "EOF", EOF);

            // The scanner will suppress whitespace, which will simplify parsing.
            Ignore = new Dictionary<string, string>();

            Ignore.Add("whitespace", "whitespace"); // It's only the key that matters.
        }
Exemplo n.º 4
0
        public EBNF()
        {
            LanguageName = "EBNF";
            ScannerNames = new List<string>();
            ScannerProductions = new Dictionary<string, GrammarNode>();

            GrammarNode name = new GrammarNode(GrammarNodeType.SEQUENCE, "", MatchType.RECURSE);
            GrammarNode name_initial = new GrammarNode(GrammarNodeType.TERMINAL, "[a-z]", MatchType.REGEX);
            GrammarNode name_subsequent = new GrammarNode(GrammarNodeType.TERMINAL, "[a-z0-9_]", MatchType.REGEX, GrammarNodeTypeQuantifier.ZERO_OR_MORE);

            name.Add(name_initial);
            name.Add(name_subsequent);
            // TODO: Reserved words require lookahead for robust performance.
            //GrammarNode environment_name = new GrammarNode(GrammarNodeType.ALTERNATION, "", MatchType.RECURSE);
            //GrammarNode scanner_name = Language.ToSequence("scanner", GrammarNodeTypeQuantifier.ONE);
            //GrammarNode parser_name = Language.ToSequence("parser", GrammarNodeTypeQuantifier.ONE);
            //environment_name.Add(scanner_name);
            //environment_name.Add(parser_name);
            // On hold pending decision on and implementation of lookahead.
            //GrammarNode ignore_production_name = ToSequence("ignore", GrammarNodeTypeQuantifier.ONE);

            GrammarNode assignment = new GrammarNode(GrammarNodeType.SEQUENCE, "", MatchType.RECURSE);
            GrammarNode colon = new GrammarNode(GrammarNodeType.TERMINAL, ":", MatchType.VALUE);
            GrammarNode equal = new GrammarNode(GrammarNodeType.TERMINAL, "=", MatchType.VALUE);
            assignment.Add(colon);
            assignment.Add(equal);

            GrammarNode whitespace = new GrammarNode(GrammarNodeType.TERMINAL, @"\s", MatchType.REGEX, GrammarNodeTypeQuantifier.ONE_OR_MORE);

            // regex:= /\/([^\/]|(?<\\)\/)+\//;
            GrammarNode regex = new GrammarNode(GrammarNodeType.SEQUENCE, "", MatchType.RECURSE);
            GrammarNode regex_initial = new GrammarNode(GrammarNodeType.TERMINAL, "/", MatchType.VALUE);
            GrammarNode regex_terminal = new GrammarNode(GrammarNodeType.TERMINAL, "/", MatchType.VALUE);
            GrammarNode regex_piece = new GrammarNode(GrammarNodeType.ALTERNATION, "", MatchType.RECURSE, GrammarNodeTypeQuantifier.ONE_OR_MORE);
            GrammarNode not_slashes = new GrammarNode(GrammarNodeType.TERMINAL, @"[^\\/]", MatchType.REGEX, GrammarNodeTypeQuantifier.ONE);
            GrammarNode escape = new GrammarNode(GrammarNodeType.SEQUENCE, "", MatchType.RECURSE, GrammarNodeTypeQuantifier.ONE);
            GrammarNode regex_backslash = new GrammarNode(GrammarNodeType.TERMINAL, @"\", MatchType.VALUE, GrammarNodeTypeQuantifier.ONE);
            GrammarNode regex_thing_escaped = new GrammarNode(GrammarNodeType.TERMINAL, @"\S", MatchType.REGEX, GrammarNodeTypeQuantifier.ONE);

            // assemble production 'regex'
            regex.Add(regex_initial);
            regex.Add(regex_piece);
            regex.Add(regex_terminal);

            // assemble label 'regex_piece'
            regex_piece.Add(escape);
            regex_piece.Add(not_slashes);

            // assemble label 'escape'
            escape.Add(regex_backslash); // escape sequences start with a backslash...
            escape.Add(regex_thing_escaped); // ...and are followed by the thing escaped.

            GrammarNode terminator = new GrammarNode(GrammarNodeType.TERMINAL, ";", MatchType.VALUE);

            GrammarNode ebnf_string = new GrammarNode(GrammarNodeType.SEQUENCE, "", MatchType.RECURSE);
            GrammarNode quote = new GrammarNode(GrammarNodeType.TERMINAL, "\"", MatchType.VALUE);
            //string_element:= /[^\\"]/ | /\\\"/| /\\\\/;
            GrammarNode string_element = new GrammarNode(GrammarNodeType.ALTERNATION, "", MatchType.RECURSE, GrammarNodeTypeQuantifier.ZERO_OR_MORE);
            GrammarNode not_slash_or_quote = new GrammarNode(GrammarNodeType.TERMINAL, @"[^\\" + "\"]", MatchType.REGEX);
            string_element.Add(not_slash_or_quote);
            string_element.Add(escape);
            ebnf_string.Add(quote);
            ebnf_string.Add(string_element);
            ebnf_string.Add(quote);

            GrammarNode quantifier = new GrammarNode(GrammarNodeType.ALTERNATION, "", MatchType.RECURSE);
            GrammarNode zero_or_one = new GrammarNode(GrammarNodeType.TERMINAL, "?", MatchType.VALUE);
            GrammarNode zero_or_more = new GrammarNode(GrammarNodeType.TERMINAL, "*", MatchType.VALUE);
            GrammarNode one_or_more = new GrammarNode(GrammarNodeType.TERMINAL, "+", MatchType.VALUE);
            quantifier.Add(zero_or_more);
            quantifier.Add(zero_or_one);
            quantifier.Add(one_or_more);

            GrammarNode comment = new GrammarNode(GrammarNodeType.SEQUENCE, "", MatchType.RECURSE);
            GrammarNode slash = new GrammarNode(GrammarNodeType.TERMINAL, "/", MatchType.VALUE);
            comment.Add(slash);
            comment.Add(slash);
            GrammarNode not_newline = new GrammarNode(GrammarNodeType.TERMINAL, @"[^\n\r]", MatchType.REGEX, GrammarNodeTypeQuantifier.ZERO_OR_MORE);
            comment.Add(not_newline);

            GrammarNode pipe = new GrammarNode(GrammarNodeType.TERMINAL, "|", MatchType.VALUE);

            GrammarNode language_name = new GrammarNode(GrammarNodeType.SEQUENCE, "", MatchType.RECURSE, GrammarNodeTypeQuantifier.ONE);
            GrammarNode language_sigil = new GrammarNode(GrammarNodeType.TERMINAL, "%", MatchType.VALUE, GrammarNodeTypeQuantifier.ONE);
            GrammarNode Zor1whitespace = new GrammarNode(GrammarNodeType.ALTERNATION, "", MatchType.RECURSE, GrammarNodeTypeQuantifier.ZERO_OR_ONE);
            Zor1whitespace.Add(whitespace);

            GrammarNode mixed_name = new GrammarNode(GrammarNodeType.SEQUENCE, "", MatchType.RECURSE);
            GrammarNode mixed_initial = new GrammarNode(GrammarNodeType.TERMINAL, "[a-zA-Z]", MatchType.REGEX);
            GrammarNode mixed_subsequent = new GrammarNode(GrammarNodeType.TERMINAL, "[a-zA-Z0-9_]", MatchType.REGEX, GrammarNodeTypeQuantifier.ZERO_OR_MORE);

            // assemble label 'mixed_name'
            mixed_name.Add(mixed_initial);
            mixed_name.Add(mixed_subsequent);

            // assemble production 'language_name'
            language_name.Add(language_sigil);
            language_name.Add(language_sigil);
            language_name.Add(Zor1whitespace);
            language_name.Add(mixed_name);

            GrammarNode environment_name = GrammarNode.SequenceNode();
            environment_name.Add(language_sigil);
            environment_name.Add(Zor1whitespace);
            environment_name.Add(name);

            GrammarNode eof = new GrammarNode(GrammarNodeType.TERMINAL, "EOF", MatchType.EOF);

            AddProduction("scanner", "environment_name", environment_name);
            AddProduction("scanner", "name", name);
            AddProduction("scanner", "assignment", assignment);
            AddProduction("scanner", "whitespace", whitespace);
            AddProduction("scanner", "regex", regex);
            AddProduction("scanner", "terminator", terminator);
            AddProduction("scanner", "string", ebnf_string);
            AddProduction("scanner", "quantifier", quantifier);
            AddProduction("scanner", "comment", comment);
            AddProduction("scanner", "pipe", pipe);
            AddProduction("scanner", "language_name", language_name);
            AddProduction("scanner", "EOF", eof);

            // The scanner won't send these off to the parser.
            this.Ignore = new Dictionary<string, string>();
            Ignore.Add("whitespace", "whitespace");
            Ignore.Add("comment", "comment");

            ParserNames = new List<string>();
            ParserProductions = new Dictionary<string, GrammarNode>();

            //language_specifier:= language_name;
            GrammarNode P_language_spec = new GrammarNode(GrammarNodeType.TERMINAL, "language_name", MatchType.TYPE);

            GrammarNode P_environment_name = new GrammarNode(GrammarNodeType.TERMINAL, "environment_name", MatchType.TYPE);

            //production:= production_name assignment sequence alternation_subsequent* terminator;
            GrammarNode production = new GrammarNode(GrammarNodeType.SEQUENCE, "", MatchType.RECURSE);
            GrammarNode P_name = GrammarNode.TerminalNodeByType("name");
            GrammarNode P_assignment = GrammarNode.TerminalNodeByType("assignment");
            GrammarNode P_sequence = new GrammarNode(GrammarNodeType.SEQUENCE, "", MatchType.RECURSE);
            GrammarNode P_alternation_subsequent = new GrammarNode(GrammarNodeType.SEQUENCE, "", MatchType.RECURSE, GrammarNodeTypeQuantifier.ZERO_OR_MORE);
            GrammarNode P_terminator = new GrammarNode(GrammarNodeType.TERMINAL, "terminator", MatchType.TYPE);

            // assemble production 'production'
            production.Add(P_name);
            production.Add(P_assignment);
            production.Add(P_sequence);
            production.Add(P_alternation_subsequent);
            production.Add(P_terminator);

            //sequence:= sequence_atom+;
            GrammarNode P_sequence_atom = new GrammarNode(GrammarNodeType.ALTERNATION, "", MatchType.RECURSE, GrammarNodeTypeQuantifier.ONE_OR_MORE);
            P_sequence.Add(P_sequence_atom);

            //sequence_atom:= quantified_name | quantified_string | regex;
            GrammarNode P_quantified_name = GrammarNode.SequenceNode();
            GrammarNode P_quantified_string = new GrammarNode(GrammarNodeType.SEQUENCE, "", MatchType.RECURSE);
            GrammarNode P_regex = GrammarNode.TerminalNodeByType("regex");
            P_sequence_atom.Add(P_quantified_name);
            P_sequence_atom.Add(P_quantified_string);
            P_sequence_atom.Add(P_regex);

            //quantified_name:= name quantifier?;
            GrammarNode P_quantifier = GrammarNode.TerminalNodeByType("quantifier");
            P_quantifier.GNTQuantifier = GrammarNodeTypeQuantifier.ZERO_OR_ONE;
            P_quantified_name.Add(P_name);
            P_quantified_name.Add(P_quantifier);

            //quantified_string:= string quantifier?;
            GrammarNode P_string = GrammarNode.TerminalNodeByType("string");
            P_quantified_string.Add(P_string);
            P_quantified_string.Add(P_quantifier);

            //alternation_subsequent:= pipe sequence;
            GrammarNode P_pipe = GrammarNode.TerminalNodeByType("pipe");
            P_alternation_subsequent.Add(P_pipe);
            P_alternation_subsequent.Add(P_sequence);

            AddProduction("parser", "production", production);
            AddProduction("parser", "language_specifier", P_language_spec);
            AddProduction("parser", "environment_specifier", P_environment_name);
            AddProduction("parser", "EOF", eof);
        }