示例#1
0
        public Production(bool isInitial, NonTerminal lvalue, BnfTermList rvalues)
        {
            LValue = lvalue;

            foreach (GrammarTerm rv in rvalues)
            {
                if (rv != Grammar.Empty)
                {
                    RValues.Add(rv);
                }
            }

            foreach (GrammarTerm term in RValues)
            {
                Terminal terminal = term as Terminal;
                if (terminal == null)
                {
                    continue;
                }
                HasTerminals = true;
                if (terminal.Category == TokenCategory.Error)
                {
                    IsError = true;
                }
            }

            for (int p = 0; p <= RValues.Count; p++)
            {
                LR0Items.Add(new LR0Item(this, p));
            }
        }
示例#2
0
 public NonTerminal Star()
 {
   if (_star != null) return _star;
   string name = this.Name + "*";
   _star = new NonTerminal(name);
   _star.SetOption(TermOptions.IsList);
   _star.Rule = Grammar.Empty | _star + this;
   return _star;
 }
示例#3
0
        public NonTerminal Star()
        {
            if (_star != null)
            {
                return(_star);
            }
            string name = this.Name + "*";

            _star = new NonTerminal(name);
            _star.SetOption(TermOptions.IsList);
            _star.Rule = Grammar.Empty | _star + this;
            return(_star);
        }
示例#4
0
    public Production(bool isInitial, NonTerminal lvalue, BnfTermList rvalues)
    {
      LValue = lvalue;
      
      foreach (GrammarTerm rv in rvalues)
        if (rv != Grammar.Empty)
          RValues.Add(rv);

      foreach (GrammarTerm term in RValues)
      {
        Terminal terminal = term as Terminal;
        if (terminal == null) continue;
        HasTerminals = true;
        if (terminal.Category == TokenCategory.Error) IsError = true;
      }

      for (int p = 0; p <= RValues.Count; p++)
        LR0Items.Add(new LR0Item(this, p));
    }
示例#5
0
    private void CreateGrammar(bool expressionGrammar)
    {
      #region 1. Terminals
      NumberLiteral n = new NumberLiteral();
      IdentifierTerminal v = new IdentifierTerminal();
      Terminal s = new StringLiteral();

      Terminal @ref = SymbolTerminal.GetSymbol("ref");
      Terminal @out = SymbolTerminal.GetSymbol("out");

      Terminal @is = SymbolTerminal.GetSymbol("is");
      Terminal dot = SymbolTerminal.GetSymbol(".");
      Terminal less = SymbolTerminal.GetSymbol("<");
      Terminal greater = SymbolTerminal.GetSymbol(">");
      Terminal arrow = SymbolTerminal.GetSymbol("->");
      Terminal LSb = SymbolTerminal.GetSymbol("[");
      Terminal RSb = SymbolTerminal.GetSymbol("]");
      Terminal LCb = SymbolTerminal.GetSymbol("(");
      Terminal RCb = SymbolTerminal.GetSymbol(")");
      Terminal RFb = SymbolTerminal.GetSymbol("}");
      Terminal LFb = SymbolTerminal.GetSymbol("{");
      Terminal LMb = SymbolTerminal.GetSymbol("<!");
      Terminal RMb = SymbolTerminal.GetSymbol("!>");
      Terminal LGb = SymbolTerminal.GetSymbol("<|");
      Terminal RGb = SymbolTerminal.GetSymbol("|>");
      Terminal comma = SymbolTerminal.GetSymbol(",");
      Terminal semicolon = SymbolTerminal.GetSymbol(";");
      Terminal colon = SymbolTerminal.GetSymbol(":");

      ITerminal Comment = new CommentTerminal("Comment", "/*", "*/");
      NonGrammarTerminals.Add(Comment);
      ITerminal LineComment = new CommentTerminal("LineComment", "//", "\n");
      NonGrammarTerminals.Add(LineComment);
      #endregion

      #region 2. Non-terminals
      #region 2.1 Expressions
      NonTerminal Expr = new NonTerminal("Expr", typeof(ScriptExpr));
      NonTerminal ConstExpr = new NonTerminal("ConstExpr", typeof(ScriptConstExpr));
      NonTerminal BinExpr = new NonTerminal("BinExpr", typeof(ScriptBinExpr));
      NonTerminal UnaryExpr = new NonTerminal("UnaryExpr", typeof(ScriptUnaryExpr));
      NonTerminal AssignExpr = new NonTerminal("AssignExpr", typeof(ScriptAssignExpr));
      NonTerminal TypeConvertExpr = new NonTerminal("TypeConvertExpr", typeof(ScriptTypeConvertExpr));
      NonTerminal IsExpr = new NonTerminal("IsExpr", typeof(ScriptIsExpr));
      NonTerminal MetaExpr = new NonTerminal("MetaExpr", typeof(ScriptMetaExpr));
      NonTerminal FuncDefExpr = new NonTerminal("FuncDefExpr", typeof(ScriptFunctionDefinition));  //typeof(ScriptFunctionDefExpression));

      NonTerminal RefExpr = new NonTerminal("RefExpr", typeof(ScriptRefExpr));
      NonTerminal VarExpr = new NonTerminal("VarExpr", typeof(ScriptVarExpr));
      NonTerminal TypeExpr = new NonTerminal("TypeExpr", typeof(ScriptTypeExpr));
      NonTerminal TypeConstructor = new NonTerminal("TypeConstructor", typeof(ScriptTypeConstructor));
      NonTerminal FunctionCall = new NonTerminal("FunctionCall", typeof(ScriptFunctionCall));
      NonTerminal ArrayResolution = new NonTerminal("ArrayResolution", typeof(ScriptArrayResolution));

      NonTerminal BinOp = new NonTerminal("BinOp");
      NonTerminal LUnOp = new NonTerminal("LUnOp");
      NonTerminal RUnOp = new NonTerminal("RUnOp");

      NonTerminal ArrayConstructor = new NonTerminal("ArrayConstructor", typeof(ScriptArrayConstructor));
      NonTerminal MObjectConstructor = new NonTerminal("MObjectConstructor", typeof(ScriptMObject));
      NonTerminal MObjectPart = new NonTerminal("MObjectPart", typeof(ScriptMObjectPart));
      NonTerminal MObjectParts = new NonTerminal("MObjectPart", typeof(ScriptAst));

      NonTerminal TypeList = new NonTerminal("TypeList", typeof(ScriptTypeExprList));
      #endregion

      #region 2.2 QualifiedName
      //Expression List:  expr1, expr2, expr3, ..
      NonTerminal ExprList = new NonTerminal("ExprList", typeof(ScriptExprList));

      //A name in form: a.b.c().d[1,2].e ....
      NonTerminal NewStmt = new NonTerminal("NewStmt", typeof(ScriptNewStmt));
      NonTerminal NewArrStmt = new NonTerminal("NewArrStmt", typeof(ScriptNewArrStmt));
      NonTerminal QualifiedName = new NonTerminal("QualifiedName", typeof(ScriptQualifiedName));
      NonTerminal GenericsPostfix = new NonTerminal("GenericsPostfix", typeof(ScriptGenericsPostfix));

      NonTerminal GlobalList = new NonTerminal("GlobalList", typeof(ScriptGlobalList));
      #endregion

      #region 2.3 Statement
      NonTerminal Condition = new NonTerminal("Condition", typeof(ScriptCondition));
      NonTerminal Statement = new NonTerminal("Statement", typeof(ScriptStatement));

      NonTerminal IfStatement = new NonTerminal("IfStatement", typeof(ScriptIfStatement));
      NonTerminal WhileStatement = new NonTerminal("WhileStatement", typeof(ScriptWhileStatement));
      NonTerminal ForStatement = new NonTerminal("ForStatement", typeof(ScriptForStatement));
      NonTerminal ForEachStatement = new NonTerminal("ForEachStatement", typeof(ScriptForEachStatement));
      NonTerminal OptionalExpression = new NonTerminal("OptionalExpression", typeof(ScriptExpr));
      NonTerminal SwitchStatement = new NonTerminal("SwitchStatement", typeof(ScriptSwitchRootStatement));
      NonTerminal SwitchStatements = new NonTerminal("SwitchStatements", typeof(ScriptSwitchStatement));
      NonTerminal SwitchCaseStatement = new NonTerminal("SwitchCaseStatement", typeof(ScriptSwitchCaseStatement));
      NonTerminal SwitchDefaultStatement = new NonTerminal("SwitchDefaultStatement", typeof(ScriptSwitchDefaultStatement));
      NonTerminal UsingStatement = new NonTerminal("UsingStatement", typeof(ScriptUsingStatement));
      NonTerminal TryCatchFinallyStatement = new NonTerminal("TryCatchFinallyStatement", typeof(ScriptTryCatchFinallyStatement));
      NonTerminal FlowControlStatement = new NonTerminal("FlowControl", typeof(ScriptFlowControlStatement));
      NonTerminal ExprStatement = new NonTerminal("ExprStatement", typeof(ScriptStatement));

      //Block
      NonTerminal BlockStatement = new NonTerminal("BlockStatement", typeof(ScriptStatement));
      NonTerminal Statements = new NonTerminal("Statements(Compound)", typeof(ScriptCompoundStatement));
      #endregion

      #region 2.4 Program and Functions
      NonTerminal Prog = new NonTerminal("Prog", typeof(ScriptProg));
      NonTerminal Element = new NonTerminal("Element", typeof(ScriptAst));
      NonTerminal Elements = new NonTerminal("Elements", typeof(ScriptElements));
      NonTerminal FuncDef = new NonTerminal("FuncDef", typeof(ScriptFunctionDefinition));
      NonTerminal FuncContract = new NonTerminal("FuncContract", typeof(ScriptFuncContract));
      NonTerminal ParameterList = new NonTerminal("ParamaterList", typeof(ScriptFuncParameters));

      NonTerminal FuncContractPre = new NonTerminal("Pre Conditions", typeof(ScriptFuncContractPre));
      NonTerminal FuncContractPost = new NonTerminal("Post Conditions", typeof(ScriptFuncContractPost));
      NonTerminal FuncContractInv = new NonTerminal("Invariant Conditions", typeof(ScriptFuncContractInv));
      #endregion

      #endregion

      #region 3. BNF rules
      #region 3.1 Expressions
      ConstExpr.Rule = SymbolTerminal.GetSymbol("true")
                      | "false"
                      | "null"
                      | s
                      | n;

      BinExpr.Rule = Expr + BinOp + Expr
                     | IsExpr;

      UnaryExpr.Rule = LUnOp + Expr;

      IsExpr.Rule = Expr + @is + TypeExpr;

      TypeConvertExpr.Rule = LCb + Expr + RCb + Expr.Q();

      AssignExpr.Rule = QualifiedName + "=" + Expr
                       | VarExpr + "=" + Expr
                       | QualifiedName + "++"
                       | QualifiedName + "--"
                       | QualifiedName + ":=" + Expr
                       | QualifiedName + "+=" + Expr
                       | QualifiedName + "-=" + Expr;

      //TODO: MetaFeatures;
      // <[    ] + > because of conflict a[1]>2
      MetaExpr.Rule = LMb + Elements + RMb;

      GlobalList.Rule = "global" + LCb + ParameterList + RCb;

      FuncDefExpr.Rule = "function" + LCb + ParameterList + RCb
        + GlobalList.Q()
        + FuncContract.Q()
        + BlockStatement;

      Expr.Rule = ConstExpr
                  | BinExpr
                  | UnaryExpr
                  | QualifiedName
                  | AssignExpr
                  | NewStmt
                  | FuncDefExpr
                  | NewArrStmt
                  | ArrayConstructor
                  | MObjectConstructor
                  | TypeConvertExpr
                  | MetaExpr
        //NOTE: ref, out
                  | RefExpr
                  | VarExpr
                  ;

      VarExpr.Rule = "var" + v;

      RefExpr.Rule = (@ref | @out) + v;

      NewStmt.Rule = "new" + TypeConstructor;
      NewArrStmt.Rule = "new" + TypeExpr + ArrayResolution;
      BinOp.Rule = SymbolTerminal.GetSymbol("+") | "-" | "*" | "/" | "%" | "^" | "&" | "|"
                  | "&&" | "||" | "==" | "!=" | greater | less
                  | ">=" | "<=";

      LUnOp.Rule = SymbolTerminal.GetSymbol("~") | "-" | "!" | "$";

      ArrayConstructor.Rule = LSb + ExprList + RSb;

      MObjectPart.Rule = v + arrow + Expr;
      MObjectParts.Rule = MakePlusRule(MObjectParts, comma, MObjectPart);
      MObjectConstructor.Rule = LSb + MObjectParts + RSb;

      OptionalExpression.Rule = Expr.Q();
      #endregion

      #region 3.2 QualifiedName
      TypeExpr.Rule = //MakePlusRule(TypeExpr, dot, v);
          v + GenericsPostfix.Q()
          | TypeExpr + dot + (v + GenericsPostfix.Q());

      GenericsPostfix.Rule = LGb + TypeList + RGb;
      FunctionCall.Rule = LCb + ExprList.Q() + RCb;
      ArrayResolution.Rule = LSb + ExprList + RSb;

      QualifiedName.Rule = v + (GenericsPostfix | ArrayResolution | FunctionCall).Star()
                          | QualifiedName + dot + v + (GenericsPostfix | ArrayResolution | FunctionCall).Star();

      ExprList.Rule = MakePlusRule(ExprList, comma, Expr);
      TypeList.Rule = MakePlusRule(TypeList, comma, TypeExpr);
      TypeConstructor.Rule = TypeExpr + FunctionCall;
      #endregion

      #region 3.3 Statement
      Condition.Rule = LCb + Expr + RCb;
      IfStatement.Rule = "if" + Condition + Statement + ("else" + Statement).Q();
      WhileStatement.Rule = "while" + Condition + Statement;
      ForStatement.Rule = "for" + LCb + OptionalExpression + semicolon + OptionalExpression + semicolon + OptionalExpression + RCb + Statement;
      ForEachStatement.Rule = "foreach" + LCb + v + "in" + Expr + RCb + Statement;
      UsingStatement.Rule = "using" + LCb + Expr + RCb + BlockStatement;
      TryCatchFinallyStatement.Rule = "try" + BlockStatement + "catch" + LCb + v + RCb + BlockStatement + "finally" + BlockStatement;
      SwitchStatement.Rule = "switch" + LCb + Expr + RCb + LFb + SwitchStatements + RFb;
      ExprStatement.Rule = Expr + semicolon;
      FlowControlStatement.Rule = "break" + semicolon
                                | "continue" + semicolon
                                | "return" + Expr + semicolon
                                | "throw" + Expr + semicolon;

      Statement.Rule = semicolon
                      | IfStatement                 //1. If
                      | WhileStatement              //2. While
                      | ForStatement                //3. For
                      | ForEachStatement            //4. ForEach
                      | UsingStatement              //5. Using
                      | SwitchStatement             //6. Switch
                      | BlockStatement              //7. Block
                      | TryCatchFinallyStatement    //8. TryCatch
                      | ExprStatement               //9. Expr
                      | FlowControlStatement;       //10. FlowControl

      Statements.SetOption(TermOptions.IsList);
      Statements.Rule = Statements + Statement | Empty;
      BlockStatement.Rule = LFb + Statements + RFb;

      SwitchStatements.Rule = SwitchCaseStatement.Star() + SwitchDefaultStatement.Q();
      SwitchCaseStatement.Rule = SymbolTerminal.GetSymbol("case") + Expr + colon + Statements;
      SwitchDefaultStatement.Rule = "default" + colon + Statements;
      #endregion

      #region 3.4 Prog
      FuncContract.Rule = LSb +
                           FuncContractPre + semicolon +
                           FuncContractPost + semicolon +
                           FuncContractInv + semicolon +
                          RSb;
      FuncContractPre.Rule = "pre" + LCb + ExprList.Q() + RCb;
      FuncContractPost.Rule = "post" + LCb + ExprList.Q() + RCb;
      FuncContractInv.Rule = "invariant" + LCb + ExprList.Q() + RCb;

      ParameterList.Rule = MakeStarRule(ParameterList, comma, v);
      FuncDef.Rule = "function" + v + LCb + ParameterList + RCb
        + GlobalList.Q()
        + FuncContract.Q()
        + BlockStatement;

      Element.Rule = Statement | FuncDef;
      Elements.SetOption(TermOptions.IsList);
      Elements.Rule = Elements + Element | Empty;

      Prog.Rule = Elements + Eof;
      #endregion
      #endregion

      #region 4. Set starting symbol
      if (!expressionGrammar)
        Root = Prog; // Set grammar root
      else
        Root = Expr;
      #endregion

      #region 5. Operators precedence
      SymbolTerminal.RegisterOperators(1, "=", "+=", "-=", ":=");
      SymbolTerminal.RegisterOperators(2, "|", "||");
      SymbolTerminal.RegisterOperators(3, "&", "&&");
      SymbolTerminal.RegisterOperators(4, "==", "!=", ">", "<", ">=", "<=");
      SymbolTerminal.RegisterOperators(5, "is");
      SymbolTerminal.RegisterOperators(6, "+", "-");
      SymbolTerminal.RegisterOperators(7, "*", "/", "%");
      SymbolTerminal.RegisterOperators(8, Associativity.Right, "^");
      SymbolTerminal.RegisterOperators(9, "~", "!", "$", "++", "--");
      SymbolTerminal.RegisterOperators(10, ".");

      //RegisterOperators(10, Associativity.Right, ".",",", ")", "(", "]", "[", "{", "}");
      //RegisterOperators(11, Associativity.Right, "else");
      #endregion

      #region 6. Punctuation symbols
      SymbolTerminal.RegisterPunctuation("(", ")", "[", "]", "{", "}", ",", ";");
      #endregion
    }
示例#6
0
 public GrammarExpression MakeStarRule(NonTerminal listNonTerminal, GrammarTerm delimiter, GrammarTerm listMember)
 {
   if (delimiter == null)
   {
     //it is much simpler case
     listNonTerminal.SetOption(TermOptions.IsList);
     listNonTerminal.Rule = Empty | listNonTerminal + listMember;
     return listNonTerminal.Rule;
   }
   NonTerminal tmp = new NonTerminal(listMember.Name + "+");
   MakePlusRule(tmp, delimiter, listMember);
   listNonTerminal.Rule = Empty | tmp;
   listNonTerminal.SetOption(TermOptions.IsStarList);
   return listNonTerminal.Rule;
 }
示例#7
0
 public GrammarExpression MakePlusRule(NonTerminal listNonTerminal, GrammarTerm delimiter, GrammarTerm listMember)
 {
   listNonTerminal.SetOption(TermOptions.IsList);
   if (delimiter == null)
     listNonTerminal.Rule = listMember | listNonTerminal + listMember;
   else
     listNonTerminal.Rule = listMember | listNonTerminal + delimiter + listMember;
   return listNonTerminal.Rule;
 }
示例#8
0
    private void CollectAllElementsRecursive(GrammarTerm element)
    {
      Terminal terminal = element as Terminal;
      if (terminal != null && !_data.Terminals.Contains(terminal) && !_grammar.IsPseudoTerminal(terminal))
      {
        _data.Terminals.Add(terminal);
        return;
      }

      NonTerminal nonTerminal = element as NonTerminal;
      if (nonTerminal == null || _data.NonTerminals.Contains(nonTerminal))
        return;

      if (nonTerminal.Name == null)
      {
        if (nonTerminal.Rule != null && !string.IsNullOrEmpty(nonTerminal.Rule.Name))
          nonTerminal.Name = nonTerminal.Rule.Name;
        else
          nonTerminal.Name = "NT" + (_unnamedCount++);
      }

      _data.NonTerminals.Add(nonTerminal);
      
      if (nonTerminal.Rule == null)
      {
        Cancel(string.Format("Non-terminal {0} has uninitialized Rule property.", nonTerminal.Name));
      }

      foreach (BnfTermList elemList in nonTerminal.Rule.Data)
        for (int i = 0; i < elemList.Count; i++)
        {
          GrammarTerm child = elemList[i];
          if (child == null)
            Cancel(string.Format("Rule for NonTerminal {0} contains null as an operand in position {1} in one of productions.", nonTerminal, i));
      
          GrammarExpression expr = child as GrammarExpression;
          if (expr != null)
          {
            child = new NonTerminal(null) { Rule = expr };
            elemList[i] = child;
          }

          CollectAllElementsRecursive(child);
        }
    }
示例#9
0
    private bool CalculateNullability(NonTerminal nonTerminal, NonTerminalList undecided)
    {
      foreach (Production prod in nonTerminal.Productions)
      {
        if (prod.HasTerminals) continue;
        if (prod.IsEmpty())
        {
          nonTerminal.Nullable = true;
          return true;
        }

        bool allNullable = true;
        foreach (GrammarTerm term in prod.RValues)
        {
          NonTerminal nt = term as NonTerminal;
          if (nt != null)
            allNullable &= nt.Nullable;
        }

        if (allNullable)
        {
          nonTerminal.Nullable = true;
          return true;
        }
      }
      return false;
    }