예제 #1
0
/* ParseMultiRule() - parse multiple rules of a single non-terminal.
 *
 *
 */
void    TParser::ParseMultirule(TSymbol* LeftHandSide)
    {
    DUMP("ParseMultirule(%s)\n", LeftHandSide->Name().c_str());
    // the lhs nonterminal and colon have already been eaten.
    
    do  {
        // compose name for new rule
        string RuleName = LeftHandSide->Name();
        if(CurrentToken.Type == TToken::DOTIDENT)
            RuleName   += CurrentToken;
        else
            RuleName   += "." + std::to_string(LeftHandSide->Derives.size());
        auto Rule = SymbolTable->NewRule(RuleName, CurrentToken.Index);

        LeftHandSide->AddSymbol(Rule, CurrentToken.Index);
        Match(CurrentToken.Type);   // match '|' or ':' or DOTIDENT

        while(CurrentToken.Type == TToken::IDENT || CurrentToken.Type == TToken::QUOTED)
            {
            if(CurrentToken.Type == TToken::IDENT)
                {
                auto Next    = PeekNextToken();
                if(Next.Type == TToken::COLON)
                    break;
                }
            Match(CurrentToken.Type);
            }
        } while(CurrentToken.Type == TToken::ORBAR || CurrentToken.Type == TToken::DOTIDENT);
    DUMP("ParseMultirule() returns\n");
    }
예제 #2
0
void   TParser::ParseGrammar()
    {
    printf("ParseGrammar( '%10.10s'[%d])\n", CurrentToken.Text, CurrentToken.Type);
    printf("TokenCursor=%d\n", TokenCursor);
    auto  Next = PeekNextToken();

    printf("TokenCursor=%d\n", TokenCursor);
    // while we see another non-terminal
    while(CurrentToken.Type == TToken::IDENT && Next.Type == TToken::COLON)
        {
        TTokenIndex NontermTokenId  = CurrentToken.Index;

        auto LeftHandSide = SymbolTable->Find(CurrentToken);
        if(LeftHandSide && LeftHandSide->IsTerminal())
//        if(auto Terminal = SymbolTable->Find(CurrentToken))
            Error("SYNTAX_EXPECTING_NONTERM_NOT_TERM",
                "Colon",    TokenCursor+1, //??? wrong??
                "SymRef",   NontermTokenId,
                "SymDef",   LeftHandSide->FirstUse()
            );
        // if LHS was not already a defined symbol
        if(!LeftHandSide)
            LeftHandSide  = SymbolTable->NewNonterminal(CurrentToken.Index);

        Match(TToken::IDENT);   // eat the lhs nonterminal
        assert(CurrentToken.Type == TToken::COLON);
        Next    = PeekNextToken();
        if(Next.Type == TToken::DOTIDENT)
            Match(TToken::COLON);
        ParseMultirule(LeftHandSide);
        if(CurrentToken.Type == TToken::SEMICOLON)
            Match(TToken::SEMICOLON);
        Next    = PeekNextToken();
        }
    DUMP("ParseGrammar() returns\n");
    }
예제 #3
0
void SymbolParserThread::ParseFileSymbols(wxInputStream& input, std::vector<Symbol*>& symbols)
{

    if (!input.IsOk())
    {
        return;
    }

    wxString token;

    unsigned int lineNumber = 1;

    Symbol *return_symbol = nullptr;

    wxStack<Symbol *> symStack;
    symStack.push(nullptr);

    std::vector<Token> tokens;
    while (GetToken(input, token, lineNumber))
    {
      tokens.emplace_back(token, lineNumber);
    }

    for (unsigned current_token = 0; current_token < tokens.size(); ++current_token)
    {
      token = tokens[current_token].token;
      lineNumber = tokens[current_token].lineNumber;

      if (token == "function")
      {
        unsigned int defLineNumber = lineNumber;
        Symbol *function = nullptr;

        // Lua functions can have these forms:
        //    function (...)
        //    function Name (...)
        //    function Module.Function (...)
        //    function Class:Method (...)

        wxString t1;
        if (!GetNextToken(tokens, t1, lineNumber, current_token)) break;

        if (t1 == "(")
        {
          // The form function (...) which doesn't have a name. If we
          // were being really clever we could check to see what is being
          // done with this value, but we're not.
          continue;
        }

        wxString t2;

        if (!GetNextToken(tokens, t2, lineNumber, current_token)) break;

        if (t2 == "(")
        {
          function = new Symbol(symStack.top(), t1, defLineNumber);

          if (return_symbol)
          {
            function->typeSymbol = return_symbol;
            return_symbol = nullptr;
          }

          // The form function Name (...).
          symbols.push_back(function);
        }
        else
        {

          wxString t3;
          if (!GetNextToken(tokens, t3, lineNumber, current_token)) break;

          if (t2 == "." || t2 == ":")
          {
            Symbol *module = GetSymbol(t1, symbols);
            if (module == nullptr)
            {
              module = new Symbol(symStack.top(), t1, defLineNumber, SymbolType::Module);
              symbols.push_back(module);
            }

            function = new Symbol(module, t3, defLineNumber);
            if (return_symbol)
            {
              function->typeSymbol = return_symbol;
              return_symbol = nullptr;
            }

            symbols.push_back(function);
          }

        }


        if (function)
          symStack.push(function);

      }
      else if (token == "decodadef")
      {
        //A decodadef will be in the form:
        //decodadef name { Definitions }
        //decodadef name ret

        unsigned int defLineNumber = lineNumber;

        wxString moduleName;
        if (!GetNextToken(tokens, moduleName, lineNumber, current_token)) break;

        wxString t1 = PeekNextToken(tokens, current_token, lineNumber);
        if (t1 == "{")
        {
          if (!GetNextToken(tokens, t1, lineNumber, current_token)) break;
          //outputWin->OutputMessage("Processing " + moduleName);

          Symbol *module = GetSymbol(moduleName, symbols);
          if (module == nullptr)
          {
            module = new Symbol(symStack.top(), moduleName, lineNumber, SymbolType::Type);
            symbols.push_back(module);
          }

          DecodaDefRecursive(symbols, lineNumber, module, tokens, current_token);
        }
        else
        {
          DecodaDefFunction(symbols, lineNumber, nullptr, tokens, current_token, moduleName);
        }
      }
      else if (token == "end")
      {
        if (symStack.size() > 1)
          symStack.pop();
      }
      else if (token == "decodaprefix")
      {
        //A decodaprefix will be in the form:
        //decodaprefix Module name

        /*
        decodaprefix this __FILENAME__
        decodaprefix this { Weapon nil }

        */

        unsigned int defLineNumber = lineNumber;

        wxString moduleName;
        if (!GetNextToken(tokens, moduleName, lineNumber, current_token)) break;


        Symbol *module = GetSymbol(moduleName, symbols, SymbolType::Prefix);
        if (module == nullptr)
        {
          module = new Symbol(nullptr, moduleName, defLineNumber, SymbolType::Prefix);
          symbols.push_back(module);
        }

        wxString t1;
        if (!GetNextToken(tokens, t1, lineNumber, current_token)) break;

        //List of 
        if (t1 == "{")
        {
          DecodaPrefixRecursive(symbols, lineNumber, module, tokens, current_token);
        }
        else
        {
          Symbol *sym_prefix = new Symbol(module, t1, defLineNumber, SymbolType::Prefix);
          sym_prefix->requiredModule = moduleName;
          symbols.push_back(sym_prefix);
        }
      }
      else if (token == "decodareturn")
      {
        //A decodaprefix will be in the form:
        //decodareturn Module

        unsigned int defLineNumber = lineNumber;

        wxString moduleName;
        if (!GetNextToken(tokens, moduleName, lineNumber, current_token)) break;

        Symbol *module = GetSymbol(moduleName, symbols);
        if (module == nullptr)
        {
          module = new Symbol(symStack.top(), moduleName, lineNumber, SymbolType::Type);
          symbols.push_back(module);
        }

        return_symbol = module;
      }
      else if (token == "=")
      {
        unsigned int defLineNumber = lineNumber;

        //If we find an equal sign, we need to find the left and right hand side
        unsigned start = current_token;

        //First handle +=, -=, *=, /=
        wxString prev = PeekPrevToken(tokens, current_token, lineNumber);
        if (prev == "+" || prev == "-" || prev == "*" || prev == "/")
          GetPrevToken(tokens, prev, lineNumber, current_token);

        wxStack<wxString> lhs_stack;
        wxString lhs;
        if (!GetPrevToken(tokens, lhs, lineNumber, current_token)) break;
        
        lhs_stack.push(lhs);

        int currentLine = lineNumber;

        prev = PeekPrevToken(tokens, current_token, lineNumber);
        while ((prev == "." || prev == ":" || prev == ")" || prev == "]") && lineNumber == currentLine)
        {
          if (prev == "." || prev == ":")
          {
            GetPrevToken(tokens, prev, lineNumber, current_token);
            lhs_stack.push(prev);

            wxString part;
            if (!GetPrevToken(tokens, part, lineNumber, current_token)) return;
            if (part == ")" || part == "]")
            {
              current_token++;
              prev = part;
              continue;
            }

            lhs_stack.push(part);
          }
          else if (prev == ")" || prev == "]")
          {
            GetPrevToken(tokens, prev, lineNumber, current_token);
            lhs_stack.push(prev);

            wxString open;
            wxString close;

            if (prev == ")")
            {
              open = "(";
              close = ")";
            }
            else if (prev == "]")
            {
              open = "[";
              close = "]";
            }


            int parenStack = 0;
            wxString part;
            if (!GetPrevToken(tokens, part, lineNumber, current_token)) return;
            for (;;)
            {
              if (part == close)
                parenStack++;
              if (part == open)
              {
                if (parenStack == 0)
                  break;
                parenStack--;
              }

              lhs_stack.push(part);
              if (!GetPrevToken(tokens, part, lineNumber, current_token)) return;
            }
            lhs_stack.push(part);

            if (!GetPrevToken(tokens, part, lineNumber, current_token)) return;
            lhs_stack.push(part);
          }

          prev = PeekPrevToken(tokens, current_token, lineNumber);
        }

        //Parse rhs
        current_token = start;

        //First handle +=, -=, *=, /=
        wxString next = PeekNextToken(tokens, current_token, lineNumber);
        bool valid = true;
        for (int i = 0; i < next.size(); ++i)
        {
          if (IsSymbol(next[i]) || IsSpace(next[i]))
          {
            valid = false;
            break;
          }
        }

        wxString rhs;

        if (valid)
        {
          GetNextToken(tokens, next, lineNumber, current_token);
          rhs.Append(next);

          next = PeekNextToken(tokens, current_token, lineNumber);
          while ((next == "." || next == ":" || next == "(" || next == "[") && lineNumber == currentLine)
          {
            if (next == "." || next == ":")
            {
              GetNextToken(tokens, next, lineNumber, current_token);
              rhs.Append(next);

              wxString part;
              if (!GetNextToken(tokens, part, lineNumber, current_token)) return;
              rhs.Append(part);
            }
            else if (next == "(" || next == "[")
            {
              GetNextToken(tokens, next, lineNumber, current_token);
              rhs.Append(next);

              wxString open;
              wxString close;

              if (next == "(")
              {
                open = "(";
                close = ")";
              }
              else if (next == "[")
              {
                open = "[";
                close = "]";
              }


              int parenStack = 0;
              wxString part;
              if (!GetNextToken(tokens, part, lineNumber, current_token)) return;
              for (;;)
              {
                if (part == open)
                  parenStack++;
                if (part == close)
                {
                  if (parenStack == 0)
                    break;
                  parenStack--;
                }

                rhs.Append(part);
                if (!GetNextToken(tokens, part, lineNumber, current_token)) return;
              }
              rhs.Append(part);
            }

            next = PeekNextToken(tokens, current_token, lineNumber);
          }
        }

        //Build up the strings with the stacks
        if (lhs_stack.size() > 0 && rhs.size() > 0)
        {
          lhs.Empty();

          while (!lhs_stack.empty())
          {
            lhs.Append(lhs_stack.top());
            lhs_stack.pop();
          }

          Symbol *assignment = new Symbol(symStack.top(), lhs, defLineNumber, SymbolType::Assignment);
          assignment->rhs = rhs;
          symbols.push_back(assignment);
        }

        //Reset token
        current_token = start;
      }
    }
}