Exemplo n.º 1
0
        protected internal virtual ParserAction GetNextAction()
        {
            var currState = Context.CurrentParserState;
            var currInput = Context.CurrentParserInput;

            if (currState.DefaultAction != null)
            {
                return(currState.DefaultAction);
            }
            ParserAction action;
            //First try as keyterm/key symbol; for example if token text = "while", then first try it as a keyword "while";
            // if this does not work, try as an identifier that happens to match a keyword but is in fact identifier
            Token inputToken = currInput.Token;

            if (inputToken != null && inputToken.KeyTerm != null)
            {
                var keyTerm = inputToken.KeyTerm;
                if (currState.Actions.TryGetValue(keyTerm, out action))
                {
                    #region comments
                    // Ok, we found match as a key term (keyword or special symbol)
                    // Backpatch the token's term. For example in most cases keywords would be recognized as Identifiers by Scanner.
                    // Identifier would also check with SymbolTerms table and set AsSymbol field to SymbolTerminal if there exist
                    // one for token content. So we first find action by Symbol if there is one; if we find action, then we
                    // patch token's main terminal to AsSymbol value.  This is important for recognizing keywords (for colorizing),
                    // and for operator precedence algorithm to work when grammar uses operators like "AND", "OR", etc.
                    //TODO: This might be not quite correct action, and we can run into trouble with some languages that have keywords that
                    // are not reserved words. But proper implementation would require substantial addition to parser code:
                    // when running into errors, we need to check the stack for places where we made this "interpret as Symbol"
                    // decision, roll back the stack and try to reinterpret as identifier
                    #endregion
                    inputToken.SetTerminal(keyTerm);
                    currInput.Term          = keyTerm;
                    currInput.Precedence    = keyTerm.Precedence;
                    currInput.Associativity = keyTerm.Associativity;
                    return(action);
                }
            }
            //Try to get by main Terminal, only if it is not the same as symbol
            if (currState.Actions.TryGetValue(currInput.Term, out action))
            {
                return(action);
            }
            //If input is EOF and NewLineBeforeEof flag is set, try using NewLine to find action
            if (currInput.Term == _grammar.Eof && _grammar.LanguageFlags.IsSet(LanguageFlags.NewLineBeforeEOF) &&
                currState.Actions.TryGetValue(_grammar.NewLine, out action))
            {
                //There's no action for EOF but there's action for NewLine. Let's add newLine token as input, just in case
                // action code wants to check input - it should see NewLine.
                var newLineToken = new Token(_grammar.NewLine, currInput.Token.Location, "\r\n", null);
                var newLineNode  = new ParseTreeNode(newLineToken)
                {
                    Tokens = Context.ComputeTokenSubList()
                };
                Context.CurrentParserInput = newLineNode;
                return(action);
            }//if
            return(null);
        }
Exemplo n.º 2
0
 private void CheckReservedWord(Token token)
 {
     if (!Grammar.KeyTerms.TryGetValue(token.Text, out KeyTerm keyTerm))
     {
         return;
     }
     token.KeyTerm = keyTerm;
     //if it is reserved word, then overwrite terminal
     if (keyTerm.Flags.IsSet(TermFlags.IsReservedWord))
     {
         token.SetTerminal(keyTerm);
     }
 }