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); }
public Operator(TerminalSymbol terminalSymbol, int precedence, string symbol, bool rightAssociative, bool unary) { TerminalSymbol = terminalSymbol; Precedence = precedence; Symbol = symbol; RightAssociative = rightAssociative; Unary = unary; }
/// <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); }
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; }
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 }; }
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); } } }
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(); }
/// <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); }
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 }; }
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)); }
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; }
/// <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); }
public Operator(TerminalSymbol terminalSymbol, int precedence, string symbol) { TerminalSymbol = terminalSymbol; Precedence = precedence; Symbol = symbol; }