Exemplo n.º 1
0
        /// <summary>
        /// Parses text that can have escape characters and cleans up the string
        /// by removing double \t, \n and spaces
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        public string ParseAndCleanTextWithEscape(TomeStream stream)
        {
            StringBuilder sb = new StringBuilder();

            // this will get all the text up to a star which is the delimiter
            while (stream.PeekChar() != '*')
            {
                // just in case i'll keep this here but i may remove it later
                // i actually need this to delimit the star
                if (stream.PeekChar() == '\\')
                {
                    sb.Append(stream.NextChar());
                    // add whatever is next regardless of what it is
                    sb.Append(stream.NextChar());
                }
                else
                {
                    sb.Append(stream.NextChar());
                }
            }

            // this is slower but also safer
            string clean   = CleanString(sb.ToString());
            string decoded = DecodeString(clean);

            return(decoded);
        }
Exemplo n.º 2
0
 public static void EatWhitespace(TomeStream stream)
 {
     while (Char.IsWhiteSpace(stream.PeekChar()))
     {
         stream.NextChar();
     }
 }
Exemplo n.º 3
0
        public static BrigitGraph Parse(TomeStream stream)
        {
            BrigitParser parser = new BrigitParser(stream);
            var          bg     = parser.ParseBrigitGraph(stream);

            // TODO stuff here
            return(bg);
        }
Exemplo n.º 4
0
 private bool ParseArrow(TomeStream stream)
 {
     if (stream.PeekChar() == '-')
     {
         stream.NextChar();
         return(AssertChar(stream, '>'));
     }
     return(false);
 }
Exemplo n.º 5
0
        // starts at ( and eats away the closing paren
        public AttributeManager ParseAttributes(TomeStream stream)
        {
            AttributeManager am = new AttributeManager();

            // since we're in here we assume this is the [ character
            AssertChar(stream, '[');

            string attributesString = GrabSubstringToParse(stream);

            // nothing was found for some reason
            if (attributesString == string.Empty)
            {
                AssertChar(stream, ']');
                // just return a new manager with nothing in it
                return(am);
            }

            string[] attributes = attributesString.Split(',');

            // looking for keywords
            foreach (string s in attributes)
            {
                string[] KeywordAndValue = s.Split(':');
                string   keyword         = KeywordAndValue[0];
                string   value           = KeywordAndValue[1];

                if (keyword.StartsWith(REQFLAGS) || keyword.StartsWith(" " + REQFLAGS))
                {
                    am.Expression = ParseRequiredFlags(value);
                }
                else if (keyword.StartsWith(TRUEFLAGS) || keyword.StartsWith(" " + TRUEFLAGS))
                {
                    string[] flagsToSetTrue = value.Split(null);
                    SetFlagArrayTo(Flag.True, flagsToSetTrue, am);
                }
                else if (keyword.StartsWith(FALSEFLAGS) || keyword.StartsWith(" " + FALSEFLAGS))
                {
                    string[] falseFlags = value.Split(null);
                    SetFlagArrayTo(Flag.False, falseFlags, am);
                }
                else if (keyword.StartsWith(DONTCARE) || keyword.StartsWith(" " + DONTCARE))
                {
                    string[] dontCareFlags = value.Split(null);
                    SetFlagArrayTo(Flag.DontCare, dontCareFlags, am);
                }
                else
                {
                    // TODO make these better
                    throw new Exception("Keyword " + keyword + " is not valid");
                }
            }

            AssertChar(stream, ']');

            return(am);
        }
Exemplo n.º 6
0
        public TomeStream GetStream(string testFileName)
        {
            string path = Path.Combine(Config.TomePath, testFileName);

            string[]   tome           = File.ReadAllLines(path);
            string[]   tomeNoComments = CommentRemover.RemoveComments(tome);
            TomeStream stream         = new TomeStream(tomeNoComments);

            return(stream);
        }
Exemplo n.º 7
0
        // only parses a-zA-Z and returns it as a string
        /// <summary>
        /// Parses a-zA-Z0-9 but nothing else
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        public string ParseOnlyTextNoEscape(TomeStream stream)
        {
            StringBuilder sb = new StringBuilder();

            while (Char.IsLetterOrDigit(stream.PeekChar()))
            {
                sb.Append(stream.NextChar());
            }

            return(sb.ToString());
        }
Exemplo n.º 8
0
        // this uses the same method from the parse speech
        private Choice ParseChoice(TomeStream stream, ref ParsingState state)
        {
            Choice choice = new Choice();
            // the biggest difference these two have is the pointer to the index
            SpeechText st = ParseSpeechText(stream, ref state);

            choice.Text       = st.Text;
            choice.Attributes = st.Attributes;

            return(choice);
        }
Exemplo n.º 9
0
 private bool AssertChar(TomeStream stream, char c)
 {
     if (stream.PeekChar() != c)
     {
         String msg = String.Format("Expected {0} symbol but found {1}, at position {2}",
                                    c, stream.PeekChar(), stream.Position);
         throw new Exception(msg);
     }
     stream.NextChar();
     return(true);
 }
Exemplo n.º 10
0
        private static string GrabSubstringToParse(TomeStream stream)
        {
            StringBuilder sb = new StringBuilder();

            while (stream.PeekChar() != ']')
            {
                sb.Append(stream.NextChar());
            }

            return(sb.ToString());
        }
Exemplo n.º 11
0
        private bool AssertAlphaDigitString(TomeStream stream, string str)
        {
            string name = ParseOnlyTextNoEscape(stream);

            if (name != str)
            {
                String msg = String.Format("Expected {0} symbol but found {1}, at position {2}",
                                           str, name, stream.Position);
                throw new Exception(msg);
            }
            return(true);
        }
Exemplo n.º 12
0
        public BrigitGraph ParseBranch(TomeStream stream, ref string name)
        {
            BrigitGraph branchGraph = new BrigitGraph();

            // parse away the > and the name
            AssertChar(stream, '>');
            // getting the name
            name = ParseOnlyTextNoEscape(stream);

            // whitespace can be between the name and the opener
            EatWhitespace(stream);
            AssertChar(stream, '{');

            // parse like an ordinary tome after ward
            branchGraph = ParseBrigitGraph(stream);

            return(branchGraph);
        }
Exemplo n.º 13
0
        private SpeechText ParseSpeechText(TomeStream stream, ref ParsingState state)
        {
            SpeechText st = new SpeechText();

            state = ParsingState.ExpectingMore;

            // parse text here
            string text = ParseAndCleanTextWithEscape(stream);

            // make sure the text ends in a star
            if (stream.PeekChar() == '*')
            {
                stream.NextChar();
            }
            else
            {
                String msg = String.Format("Expected * to end speech parsing but found {0} at {1}",
                                           stream.PeekChar(), stream.Position);
                throw new Exception(msg);
            }

            // parse the attribute
            if (stream.PeekChar() == '[')
            {
                // this closes the paren for us if there is any
                st.Attributes = ParseAttributes(stream);
            }

            EatWhitespace(stream);

            // check if it ended
            // at this point we know there is at least 1 star
            // if this is true then this will be the last speech text
            if (stream.PeekChar() == '}')
            {
                stream.NextChar();
                state = ParsingState.Complete;
            }

            st.Text = text;

            return(st);
        }
Exemplo n.º 14
0
        public Node ParseDialog(TomeStream stream)
        {
            Node node = new Node();
            var  data = new Dialog();

            // first things first, parse character name and then semicolon
            data.Character = ParseCharacterName(stream);

            // check for colon
            if (stream.PeekChar() != '{')
            {
                String msg = String.Format("Expected : or {, found {0}, at {1}", stream.PeekChar(), stream.Position);
                throw new Exception(msg);
            }
            else
            {
                stream.NextChar();
            }

            // parsing the text then attributes of the text
            // getting rid of the starting whitespace
            EatWhitespace(stream);

            ParsingState state = ParsingState.ExpectingMore;

            while (state == ParsingState.ExpectingMore)
            {
                var text = ParseSpeechText(stream, ref state);
                data.Text.Add(text);
            }

            if (stream.PeekChar() == '[')
            {
                data.Attributes = ParseAttributes(stream);
            }

            // everything has been completed for this section.
            // ParseSpeechText will eat the final *
            node.Data = data;

            return(node);
        }
Exemplo n.º 15
0
        /// <summary>
        /// Parse a character name. Allows for spaces, dashes, single quotes and dots
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        public string ParseCharacterName(TomeStream stream)
        {
            StringBuilder  sb           = new StringBuilder();
            HashSet <char> charsToAllow = new HashSet <char>(new char[] { '.', '\'', '-', '(', ')', ' ' });

            while (stream.PeekChar() != '{')
            {
                if (Char.IsLetterOrDigit(stream.PeekChar()) || charsToAllow.Contains(stream.PeekChar()))
                {
                    sb.Append(stream.NextChar());
                }
                else
                {
                    throw new Exceptions.InvalidCharacterNameException(String.Format("Character name cannot contain: '{0}'. Location: {1}", stream.PeekChar(), stream.Position));
                }
            }

            // for now just remove spaces at the end of the string
            if (!char.IsLetterOrDigit(sb[sb.Length - 1]))
            {
            }

            return(sb.ToString());
        }
Exemplo n.º 16
0
        // public for testing purpose
        // this chooses what is parsed next, IE a branch, a dialog or descision
        public BrigitGraph ParseBrigitGraph(TomeStream stream)
        {
            BrigitGraph ll = new BrigitGraph();

            while (!(stream.Complete() || stream.PeekChar() == '}'))
            {
                // getting rid of some beginning whitespace
                EatWhitespace(stream);

                // the real parsing starts here
                // can't use switch need to use if elses
                char c = stream.PeekChar();
                if (Char.IsLetterOrDigit(c))
                {
                    // start parsing as a dialog
                    // this one is simple. parse the dialog. then add
                    // it to the list
                    Node n = ParseDialog(stream);

                    // for the new AddInBetween function
                    // this will only work for whatever comes next. This isn't very good
                    // if there's multiple branches to place
                    // TODO make this functionality work better with dummy tail in the subgraphs
                    foreach (KeyValuePair <string, OpenChoice> kvp in BranchesToPlace)
                    {
                        if (kvp.Value.TailNode == null)
                        {
                            kvp.Value.TailNode = n;
                            break;
                        }
                    }

                    ll.AddNode(n);
                }
                else if (c == '@')
                {
                    // naybe use a struct here?
                    Dictionary <string, OpenChoice> branchesToNode = new Dictionary <string, OpenChoice>();
                    // TODO change signature of ParseDescision to (obj stream, Dict brachesToNode)
                    BrigitGraph subGraph = ParseDescision(stream, branchesToNode);

                    foreach (KeyValuePair <string, OpenChoice> kvp in branchesToNode)
                    {
                        BranchesToPlace.Add(kvp.Key, kvp.Value);
                    }

                    // adding the dictionary entries to this
                    ll.AddGraph(subGraph);
                }
                else if (c == '{')
                {
                    // this is a branch selector
                    // we can just pass in the big dictionary
                    BrigitGraph subGraph = ParseBranchSelector(BranchesToPlace);
                    ll.AddGraph(subGraph);
                }
                else if (c == '>')
                {
                    // this is a branch name
                    // TODO change signature of ParseBranch to ParseBranch(stream, ref string branchName)
                    // TODO i'll probably need a wrapper for the Node and Ch entires
                    string      branchName = String.Empty;
                    BrigitGraph subGraph   = ParseBranch(stream, ref branchName);
                    if (BranchesToPlace.ContainsKey(branchName))
                    {
                        OpenChoice openCh = BranchesToPlace[branchName];
                        Node       n      = openCh.EnclosingNode;
                        Choice     ch     = openCh.BranchingChoice;

                        ll.AddInBetween(n, new List <Node>()
                        {
                            openCh.TailNode
                        }, subGraph);
                        ch.NextNode = n.Next.Count - 1;
                    }
                    else
                    {
                        String msg = String.Format("{0} not found in dictionary, could the name be mispelled?",
                                                   branchName);
                        throw new Exception(msg);
                    }
                }
                else
                {
                    // panic here
                    String msg = String.Format("Expected beginning of character name, branch or chioce but found {0} at {1}",
                                               stream.PeekChar(), stream.Position);
                    throw new Exception(msg);
                }

                EatWhitespace(stream);
            }

            if (!stream.Complete())
            {
                AssertChar(stream, '}');
            }

            return(ll);
        }
Exemplo n.º 17
0
        public BrigitGraph ParseDescision(TomeStream stream, Dictionary <string, OpenChoice> branchEndings)
        {
            Decision    descision = new Decision();
            BrigitGraph ll        = new BrigitGraph();
            Node        root      = new Node()
            {
                Data = descision
            };

            ll.AddNode(root);

            // first parse away the @player:
            AssertChar(stream, '@');
            AssertAlphaDigitString(stream, "player");
            AssertChar(stream, '{');
            EatWhitespace(stream);

            ParsingState state = ParsingState.ExpectingMore;

            while (state == ParsingState.ExpectingMore)
            {
                // parse the choice (same as parse text with esacape)
                // parse attributes if there are any
                Choice ch = ParseChoice(stream, ref state);
                // -1 is the place holder for now. will be set to an actual number
                // or to the size of list
                ch.NextNode = -1;
                descision.Choices.Add(ch);

                // at this point either the parsing is complete
                // or there is an arrow pointing to a sub branch or a branch name

                // Parseing.Expecting more implies that the arrow maybe still be here
                // Some branches have multiple "nexts" where the next either points to the same node
                // or to two different ones within the same branching pattern.
                //  It's the addition of the nodes that's wrong
                if (ParseArrow(stream))
                {
                    // whitespace
                    EatWhitespace(stream);
                    // either it's a branch
                    if (stream.PeekChar() == '{')
                    {
                        AssertChar(stream, '{');
                        // parse the subbranch if there is one
                        // parse the branch name is there is one, and we didn't parse a sub branch
                        // add the subbranch to the next list if there is none set their "next" to -1
                        BrigitGraph subGraph = ParseBrigitGraph(stream);

                        ll.AddBranch(root, subGraph);
                        ch.NextNode = root.Next.Count - 1;
                    }
                    // or a branch name
                    else
                    {
                        string     BranchName = ParseOnlyTextNoEscape(stream);
                        OpenChoice openCh     = new OpenChoice(root, ch);
                        branchEndings.Add(BranchName, openCh);
                    }

                    // this means it has reach the end
                    if (stream.PeekChar() == '}')
                    {
                        state = ParsingState.Complete;
                        stream.NextChar();
                    }
                }
            }

            // any next nodes in descision that are -1 should be set
            // to the count of the list
            foreach (Choice c in descision.Choices)
            {
                if (c.NextNode == -1)
                {
                    c.NextNode = root.Next.Count;
                }
            }

            return(ll);
        }
Exemplo n.º 18
0
 // Constructor
 // this class needs a stream so there will be no default constructor
 public BrigitParser(TomeStream stream)
 {
     Stream = stream;
 }