示例#1
0
        internal override GrammarExpressionTuple GenerateGrammar(GrammarType grammarType, int grammarNumber,
                                                                 ref int index, ref int additionalGrammarNumber, Action <GrammarPostReport> onIterate, params GrammarExpressionWithOriginal[] dependencies)
        {
            CheckDependencies(dependencies);

            NonTerminalSymbol target = new NonTerminalSymbol(new Label(new SingleLabel(Grammar._DefaultNonTerminalSymbol, index++)));
            TerminalSymbol    symbol = new TerminalSymbol(Character);

            GrammarExpressionTuple grammarExpressionTuple =
                new GrammarExpressionTuple(
                    this,
                    new Grammar(
                        EnumerateHelper.Sequence(
                            new Rule(EnumerateHelper.Sequence(new Chain(EnumerateHelper.Sequence(symbol))), target)
                            ),
                        target
                        ),
                    grammarNumber
                    );

            if (onIterate != null)
            {
                onIterate(new GrammarPostReport(grammarExpressionTuple, dependencies));
            }

            return(grammarExpressionTuple);
        }
示例#2
0
 public Operator(TerminalSymbol terminalSymbol, int precedence, string symbol, bool rightAssociative, bool unary)
 {
     TerminalSymbol   = terminalSymbol;
     Precedence       = precedence;
     Symbol           = symbol;
     RightAssociative = rightAssociative;
     Unary            = unary;
 }
示例#3
0
        /// <summary>
        ///  Scans the source
        /// </summary>
        /// <returns></returns>
        internal IEnumerable <Token> Scan(string source)
        {
            int currentIndex  = 0;
            int currentRow    = 0;
            int currentColumn = 0;

            while (currentIndex < source.Length)
            {
                TerminalSymbol matched       = null;
                int            matchedLength = -1;
                foreach (var terminal in _terminals)
                {
                    var match = terminal.Regex.Match(source, currentIndex);

                    if (match.Success && (match.Index - currentIndex) == 0)
                    {
                        if (match.Length > matchedLength)
                        {
                            matched       = terminal;
                            matchedLength = match.Length;
                            if (_scannerMatchMode == ScannerMatchMode.FirstMatch)
                            {
                                break;
                            }
                        }
                    }
                }

                if (matched == null)
                {
                    throw new ArgumentException($"Unrecognized symbol '{source[currentIndex]}' at {new Position(currentIndex, currentRow, currentColumn, 1)}.");
                }
                else
                {
                    var value = source.Substring(currentIndex, matchedLength);

                    if (!matched.Ignore)
                    {
                        yield return(new Token(matched, value, new Position(currentIndex, currentRow, currentColumn, matchedLength)));
                    }

                    var isEndOfLine = UsefulRegex.NewLine.Match(value);
                    if (isEndOfLine.Success && isEndOfLine.Index == 0)
                    {
                        currentRow   += 1;
                        currentColumn = 0;
                    }
                    else
                    {
                        currentColumn += matchedLength;
                    }
                    currentIndex += matchedLength;
                }
            }
            yield break;
        }
    public bool RecusiveDescent(BnfNonterminal t)
    {
        int rulesCount = t.RulesCount;

        bool [] success = new bool [rulesCount];
        int     i       = 0;

        foreach (var rule in t.Rules)
        {
            var currentPosition = r.Position;
            success [i] = true;
            foreach (var sym in rule.Parts)
            {
                if (sym is NonterminalSymbol)
                {
                    if (RecusiveDescent(sym as BnfNonterminal) == false)
                    {
                        success [i] = false;
                        break;
                    }
                }
                else
                {
                    var inputSymbol = r.GetSymbol();
                    if (TerminalSymbol.Compare(sym as TerminalSymbol, inputSymbol) == 0)
                    {
                        continue;
                    }
                    else
                    {
                        success [i] = false;
                        break;
                    }
                }
            }
            if (success [i] == false)
            {
                r.Position = currentPosition;
            }
            i++;
        }
        int total = 0;

        foreach (var b in success)
        {
            if (b)
            {
                total++;
            }
        }
        if (total > 1)
        {
            throw new ApplicationException();
        }
        return(total == 1);
    }
示例#5
0
        internal Token(TerminalSymbol tokenType, string value, Position position)
        {
            Debug.Assert(tokenType != null, "Token Type Null.");
            Debug.Assert(!string.IsNullOrWhiteSpace(value), "Empty Token Value");
            Debug.Assert(position != null, "Null position.");

            TokenType = tokenType;
            Value     = value;
            Position  = position;
        }
示例#6
0
        public MainWindow()
        {
            InitializeComponent();
            Number_Of_Lines = 10;


            TerminalSymbol.AppendText("=====>");

            cmbFontFamily.ItemsSource = Fonts.SystemFontFamilies.OrderBy(f => f.Source);
            cmbFontSize.ItemsSource   = new List <double>()
            {
                8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72
            };
        }
示例#7
0
 private void AppendTokenCondition(Symbols symbols, StringBuilder sb, string indent)
 {
     for (int i = 0; i < symbols.Count; i++)
     {
         TerminalSymbol s = (TerminalSymbol)symbols[i];
         if (i == 0)
         {
             sb.Append("tok.Type == TokenType." + s.Name);
         }
         else
         {
             sb.Append(Environment.NewLine + indent + "    || tok.Type == TokenType." + s.Name);
         }
     }
 }
示例#8
0
        public static Node Parse(GrammarDefinition grammar, string source)
        {
            FullLalrState lalrState = new FullLalrState();

            lalrState.StateStack.Add(grammar.Table[0]); //push state 0
            foreach (var tk in Lexer.Lex(grammar, source))
            {
                var currentSymbol = new TerminalSymbol(tk.Name);
DontConsumeToken:
                {
                    var currentState = lalrState.StateStack[lalrState.StateStack.Count - 1];

                    if (!currentState.ContainsKey(currentSymbol))
                    {
                        throw new GrammarException(tk.Location, $"token inesperado {tk.Source}");
                    }

                    var action = currentState[currentSymbol].First();
                    if (action is LalrShift)
                    {
                        var s = action as LalrShift;
                        lalrState.NodeStack.Add(Node.FromToken(tk));
                        lalrState.StateStack.Add(s.State);
                    }
                    else if (action is LalrReduce)
                    {
                        var prod = ((LalrReduce)action).Production;
                        Reduce(grammar, prod, lalrState);
                        currentState = lalrState.StateStack[lalrState.StateStack.Count - 1];
                        lalrState.StateStack.Add(((LalrGoto)currentState[prod.Head].First()).State);
                        goto DontConsumeToken;
                    }
                    else
                    {
                        //accept
                        SetParent(lalrState.NodeStack.First(), null);
                        return(lalrState.NodeStack.First());
                    }
                }
            }

            //should never get here
            throw new InvalidOperationException();
        }
示例#9
0
        /// <summary>
        /// 終端記号ごとに区切った文字列にタイプを割り当て、終端記号のリストを取得する。
        /// </summary>
        /// <param name="terminalSymbolListStr">終端記号ごとに区切った文字列のリスト</param>
        /// <returns>終端記号のリスト</returns>
        private static List <TerminalSymbol> assignTerminalSymbolList(List <string> terminalSymbolListStr)
        {
            var terminalSymbolList = new List <TerminalSymbol>();

            int n = terminalSymbolListStr.Count;

            terminalSymbolListStr.Add(null);
            TerminalSymbol prevTerminalSymbol = new TerminalSymbol(null, TerminalSymbolType.None);

            for (int i = 0; i < n; i++)
            {
                TerminalSymbol terminalSymbol;
                bool           assignResult = assignTerminalSymbol(prevTerminalSymbol, terminalSymbolListStr[i], terminalSymbolListStr[i + 1], out terminalSymbol);
                if (!assignResult)
                {
                    throw new ArgumentException("終端記号タイプの割り当てに失敗しました。");
                }
                prevTerminalSymbol = terminalSymbol;
                terminalSymbolList.Add(terminalSymbol);
            }
            return(terminalSymbolList);
        }
示例#10
0
        public override void EnterLexerRuleSpec([NotNull] ANTLRv4Parser.LexerRuleSpecContext context)
        {
            int i;

            for (i = 0; i < context.ChildCount; ++i)
            {
                if (!(context.GetChild(i) is TerminalNodeImpl))
                {
                    continue;
                }

                TerminalNodeImpl c = context.GetChild(i) as TerminalNodeImpl;
                if (c.Symbol.Type == ANTLRv4Lexer.TOKEN_REF)
                {
                    break;
                }
            }
            if (i == context.ChildCount)
            {
                return;
            }

            TerminalNodeImpl token_ref = context.GetChild(i) as TerminalNodeImpl;
            string           id        = token_ref.GetText();
            ISymbol          sym       = new TerminalSymbol(id, token_ref.Symbol);

            _pd.RootScope.define(ref sym);
            CombinedScopeSymbol s = (CombinedScopeSymbol)sym;

            _pd.Attributes[context] = new List <CombinedScopeSymbol>()
            {
                s
            };
            _pd.Attributes[context.GetChild(i)] = new List <CombinedScopeSymbol>()
            {
                s
            };
        }
示例#11
0
        public override void EnterTerminal([NotNull] ANTLRv4Parser.TerminalContext context)
        {
            TerminalNodeImpl first = context.GetChild(0) as TerminalNodeImpl;

            if (first.Symbol.Type == ANTLRv4Parser.TOKEN_REF)
            {
                string          id   = first.GetText();
                IList <ISymbol> list = _pd.RootScope.LookupType(id);
                if (!list.Any())
                {
                    ISymbol sym = new TerminalSymbol(id, first.Symbol);
                    _pd.RootScope.define(ref sym);
                }
                List <CombinedScopeSymbol> new_attrs = new List <CombinedScopeSymbol>();
                foreach (ISymbol sym in list)
                {
                    CombinedScopeSymbol s = new RefSymbol(first.Symbol, sym);
                    new_attrs.Add(s);
                }
                _pd.Attributes[context]             = new_attrs;
                _pd.Attributes[context.GetChild(0)] = new_attrs;
            }
        }
        public static Lexical create(TerminalSymbol terminalSymbol, int parenthesisDepth)
        {
            switch (terminalSymbol.type)
            {
            case TerminalSymbolType.Integer:
                var literalInteger = new LiteralInteger();
                literalInteger.value = terminalSymbol.value;
                return(literalInteger);

            case TerminalSymbolType.Decimal:
                var literalDecimal = new LiteralDecimal();
                literalDecimal.value = terminalSymbol.value;
                return(literalDecimal);

            case TerminalSymbolType.LogicTrue:
                var literalTrue = new LiteralTrue();
                literalTrue.value = terminalSymbol.value;
                return(literalTrue);

            case TerminalSymbolType.LogicFalse:
                var literalFalse = new LiteralFalse();
                literalFalse.value = terminalSymbol.value;
                return(literalFalse);

            case TerminalSymbolType.Variable:
                var literalVariable = new LiteralVariable();
                literalVariable.value = terminalSymbol.value;
                return(literalVariable);

            case TerminalSymbolType.OpAdd:
                var binaryOperatorAdd = new BinaryOperatorAdd();
                binaryOperatorAdd.parenthesisDepth = parenthesisDepth;
                return(binaryOperatorAdd);

            case TerminalSymbolType.OpDiff:
                var binaryOperatorDiff = new BinaryOperatorDiff();
                binaryOperatorDiff.parenthesisDepth = parenthesisDepth;
                return(binaryOperatorDiff);

            case TerminalSymbolType.OpProd:
                var binaryOperatorProd = new BinaryOperatorProd();
                binaryOperatorProd.parenthesisDepth = parenthesisDepth;
                return(binaryOperatorProd);

            case TerminalSymbolType.OpDivide:
                var binaryOperatorDivide = new BinaryOperatorDivide();
                binaryOperatorDivide.parenthesisDepth = parenthesisDepth;
                return(binaryOperatorDivide);

            case TerminalSymbolType.OpMod:
                var binaryOperatorMod = new BinaryOperatorMod();
                binaryOperatorMod.parenthesisDepth = parenthesisDepth;
                return(binaryOperatorMod);

            case TerminalSymbolType.OpPow:
                var binaryOperatorPow = new BinaryOperatorPow();
                binaryOperatorPow.parenthesisDepth = parenthesisDepth;
                return(binaryOperatorPow);

            case TerminalSymbolType.OpNeg:
                var unaryOperatorNegative = new UnaryOperatorNegative();
                unaryOperatorNegative.parenthesisDepth = parenthesisDepth;
                return(unaryOperatorNegative);

            case TerminalSymbolType.OpLt:
                var binaryOperatorLt = new BinaryOperatorLt();
                binaryOperatorLt.parenthesisDepth = parenthesisDepth;
                return(binaryOperatorLt);

            case TerminalSymbolType.OpLtEq:
                var binaryOperatorLtEq = new BinaryOperatorLtEq();
                binaryOperatorLtEq.parenthesisDepth = parenthesisDepth;
                return(binaryOperatorLtEq);

            case TerminalSymbolType.OpGt:
                var binaryOperatorGt = new BinaryOperatorGt();
                binaryOperatorGt.parenthesisDepth = parenthesisDepth;
                return(binaryOperatorGt);

            case TerminalSymbolType.OpGtEq:
                var binaryOperatorGtEq = new BinaryOperatorGtEq();
                binaryOperatorGtEq.parenthesisDepth = parenthesisDepth;
                return(binaryOperatorGtEq);

            case TerminalSymbolType.OpEq:
                var binaryOperatorEqual = new BinaryOperatorEqual();
                binaryOperatorEqual.parenthesisDepth = parenthesisDepth;
                return(binaryOperatorEqual);

            case TerminalSymbolType.OpNotEq:
                var binaryOperatorNotEqual = new BinaryOperatorNotEqual();
                binaryOperatorNotEqual.parenthesisDepth = parenthesisDepth;
                return(binaryOperatorNotEqual);

            case TerminalSymbolType.OpNot:
                var unaryOperatorNot = new UnaryOperatorNot();
                unaryOperatorNot.parenthesisDepth = parenthesisDepth;
                return(unaryOperatorNot);

            case TerminalSymbolType.OpAnd:
                var binaryOperatorAnd = new BinaryOperatorAnd();
                binaryOperatorAnd.parenthesisDepth = parenthesisDepth;
                return(binaryOperatorAnd);

            case TerminalSymbolType.OpOr:
                var binaryOperatorOr = new BinaryOperatorOr();
                binaryOperatorOr.parenthesisDepth = parenthesisDepth;
                return(binaryOperatorOr);

            case TerminalSymbolType.Function:
                var unaryOperatorFunction = new UnaryOperatorFunction();
                // 演算子の中で、関数だけ変数名を登録する必要がある。
                unaryOperatorFunction.functionName     = terminalSymbol.value;
                unaryOperatorFunction.parenthesisDepth = parenthesisDepth;
                return(unaryOperatorFunction);

            case TerminalSymbolType.Comma:
                var binaryOperatorComma = new BinaryOperatorComma();
                binaryOperatorComma.parenthesisDepth = parenthesisDepth;
                return(binaryOperatorComma);

            default:
                throw new ApplicationException("品詞に変換できない終端記号が指定されました。");
            }
        }
 public static int Compare(TerminalSymbol sym, TerminalSymbol inputSymbol)
 {
     return(string.Compare(sym.c, inputSymbol.c));
 }
示例#14
0
 public LexemeResult(TerminalSymbol terminalSymbol)
 {
     Successful     = true;
     TerminalSymbol = terminalSymbol;
 }
 internal AbstractSyntaxTerminalNode(TerminalSymbol terminalSymbol, string value, Position position, string content) : base(position, content)
 {
     Debug.Assert(terminalSymbol != null, "Terminal Symbol is required.");
     TerminalSymbol = terminalSymbol;
     Value          = value ?? string.Empty;
 }
示例#16
0
        /// <summary>
        /// 文字列に終端記号を割り当てる。
        /// </summary>
        /// <param name="prevExpr">評価対象の前の終端記号。</param>
        /// <param name="expr">評価対象の文字列。</param>
        /// <param name="nextExpr">評価対象の次の文字列。
        /// <param name="terminalSymbol">結果を保存する変数。
        /// exprに終端記号を割り当てて返却する。</param>
        /// 評価対象の文字列が式の最後の場合は、nullを指定する。</param>
        /// <returns>終端記号割り当てに成功した場合、trueを返却する。</returns>
        private static bool assignTerminalSymbol(TerminalSymbol prevExpr, string expr, string nextExpr, out TerminalSymbol terminalSymbol)
        {
            terminalSymbol = new TerminalSymbol(null, TerminalSymbolType.None);
            if (expr.Length == 0)
            {
                return(false);
            }

            switch (expr)
            {
            case "+":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.OpAdd);
                return(true);

            case "-":
                TerminalSymbolType hyphenTerminalSymbolType = getHyphenTerminalSymbolType(prevExpr.type);
                if (hyphenTerminalSymbolType == TerminalSymbolType.None)
                {
                    return(false);
                }
                terminalSymbol = new TerminalSymbol(expr, hyphenTerminalSymbolType);
                return(true);

            case "*":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.OpProd);
                return(true);

            case "/":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.OpDivide);
                return(true);

            case "%":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.OpMod);
                return(true);

            case "^":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.OpPow);
                return(true);

            case "<":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.OpLt);
                return(true);

            case "<=":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.OpLtEq);
                return(true);

            case ">":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.OpGt);
                return(true);

            case ">=":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.OpGtEq);
                return(true);

            case "==":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.OpEq);
                return(true);

            case "!=":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.OpNotEq);
                return(true);

            case "!":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.OpNot);
                return(true);

            case "&&":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.OpAnd);
                return(true);

            case "||":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.OpOr);
                return(true);

            case ",":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.Comma);
                return(true);

            case "(":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.LeftP);
                return(true);

            case ")":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.RightP);
                return(true);
            }
            if (expr == "true")
            {
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.LogicTrue);
                return(true);
            }
            else if (expr == "false")
            {
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.LogicFalse);
                return(true);
            }
            else if (checkDigit(expr[0]))
            {
                // 数値であることを判定する。
                int countDot = 0;
                for (int i = 1; i < expr.Length; i++)
                {
                    if (expr[i] == '.')
                    {
                        countDot++;
                    }
                    else if (!checkDigit(expr[i]))
                    {
                        return(false);
                    }
                }
                if (countDot == 0)
                {
                    terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.Integer);
                    return(true);
                }
                else if (countDot == 1)
                {
                    terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.Decimal);
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            else if (Char.IsLetter(expr[0]))
            {
                // 全ての文字が関数・変数で利用可能であることを確認する。
                for (int i = 1; i < expr.Length; i++)
                {
                    if (!checkVarNameChar(expr[i]))
                    {
                        return(false);
                    }
                }
                // 次のexprの種類によって関数又は変数が決まる。
                // funcになるパターンは、次の終端記号が整数、小数、変数、関数、左括弧のどれかの場合。
                // true/falseが続く場合は文法エラーなので除外すると、以下の条件式で識別できる。
                if (nextExpr == null)
                {
                    terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.Variable);
                    return(true);
                }
                else
                {
                    if (nextExpr.Length == 0)
                    {
                        return(false);
                    }
                    if (checkVarNameChar(nextExpr[0]) || nextExpr == "(")
                    {
                        terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.Function);
                        return(true);
                    }
                    else
                    {
                        terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.Variable);
                        return(true);
                    }
                }
            }
            return(false);
        }
示例#17
0
 public Operator(TerminalSymbol terminalSymbol, int precedence, string symbol)
 {
     TerminalSymbol = terminalSymbol;
     Precedence     = precedence;
     Symbol         = symbol;
 }