static void TestEfficientRemoveKth() { Console.WriteLine("Efficient Remove Kth:"); LNode list = LLUtilities.BuildLinkedList(6); Console.WriteLine($"Before: {list.ToString()}"); list = Remove.EfficientRemoveKth(list, 4); Console.WriteLine($"After: {list.ToString()}"); }
public override Pred CodeToTerminalPred(LNode expr, ref string errorMsg) { bool isInt = false; PGIntSet set; if (expr.IsIdNamed(_underscore)) { set = PGIntSet.AllExceptEOF; } else if (expr.IsIdNamed(_EOF)) { set = PGIntSet.EOF; } else if (expr.Calls(S.DotDot, 2)) { int? from = ConstValue(expr.Args[0], ref isInt); int? to = ConstValue(expr.Args[1], ref isInt); if (from == null || to == null) { errorMsg = "Expected int32 or character literal on each side of «..»"; return null; } set = PGIntSet.WithRanges(from.Value, to.Value); } else if (expr.Value is string) { return Pred.Seq((string)expr.Value); } else { int? num = ConstValue(expr, ref isInt); if (num == null) { errorMsg = "Unrecognized expression. Expected int32 or character literal instead of: " + expr.ToString(); // warning return null; } set = PGIntSet.With(num.Value); } set.IsCharSet = !isInt; return new TerminalPred(expr, set, true); }
static void Main(string[] args) { Console.WriteLine( "Welcome to the LLLPG-with-Loyc-trees calculator demo.\n" + "Please type an expression like pi * 2 or «exit» to quit.\n" + "Mathy-looking expressions like 2(x-1)x^2 are also accepted.\n" + "This calculator has only six built-in operators: + - * / ^ =\n" + "The = operator lets you save a result in a variable: x = 10\n"); Vars[GSymbol.Get("pi")] = Math.PI; Vars[GSymbol.Get("e")] = Math.E; string line; while ((line = Console.ReadLine()) != "exit") { while (line.EndsWith(" ")) // user can add additional lines this way { line += "\n" + Console.ReadLine(); } try { var parser = MyParser.New(line); LNode tree = parser.Start(); Console.WriteLine("Syntax tree: " + tree.ToString()); Console.WriteLine("Computed result: " + Compute(tree)); } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.WriteLine(); } }
protected override void Stmt(string text, LNode expected, Action <EcsPrinterOptions> configure = null, Mode mode = Mode.Both) { bool exprMode = (mode & Mode.Expression) != 0; if ((mode & (Mode.ParserTest | Mode.ExpectAndDropParserError)) == 0) { return; } var sink = (mode & Mode.ExpectAndDropParserError) != 0 ? new MessageHolder() : (IMessageSink)ConsoleMessageSink.Value; using (Token.SetToStringStrategy(TokenExt.ToString)) // debugging aid { // This is the easy way: // LNode result = EcsLanguageService.Value.ParseSingle(text, sink, exprMode ? ParsingMode.Expressions : ParsingMode.Statements, preserveComments: true); // But to make debugging easier, I'll do it the long way: ILexer <Token> lexer = EcsLanguageService.Value.Tokenize(new UString(text), "", sink); var preprocessed = new EcsPreprocessor(lexer, true); var treeified = new TokensToTree(preprocessed, false); var parser = new EcsParser(treeified.Buffered(), lexer.SourceFile, sink, null); LNodeList results = exprMode ? LNode.List(parser.ExprStart(false)) : LNode.List(parser.ParseStmtsGreedy()); // Inject comments var injector = new EcsTriviaInjector(preprocessed.TriviaList, preprocessed.SourceFile, (int)TokenType.Newline, "/*", "*/", "//", (mode & Mode.Expression) == 0); results = LNode.List(injector.Run(results.GetEnumerator()).ToList()); LNode result = results.AsLNode(S.Splice); AreEqual(TokenType.EOF, parser.LT0.Type(), string.Format("Parser stopped before EOF at [{0}] in {1}", parser.LT0.StartIndex, text)); if ((mode & Mode.IgnoreTrivia) != 0) { result = result.ReplaceRecursive(n => n.IsTrivia ? Maybe <LNode> .NoValue : n, LNode.ReplaceOpt.ProcessAttrs).Value; } if (sink is MessageHolder) { ((MessageHolder)sink).WriteListTo(TraceMessageSink.Value); GreaterOrEqual(((MessageHolder)sink).List.Count(m => m.Severity >= Severity.Error), 1, "Expected an error but got none for " + text); if (expected == null) { return; } } if (!expected.Equals(result, LNode.CompareMode.TypeMarkers)) { if ((mode & Mode.CompareAsLes) != 0) { using (LNode.SetPrinter(Syntax.Les.Les3LanguageService.Value)) AreEqual(expected.ToString(), result.ToString()); } else { AreEqual(expected, result); } Fail("{0} has a different type marker than {1}", expected, result); } } }
private static LNode RegisterSimpleMacro(LNodeList attrs, LNode pattern, LNode body, IMacroContext context) { if (DecodeSubstitutionExpr(pattern, out _, out _, out _) != null) { return(Reject(context, pattern, "Defining a macro that could match everything is not allowed.")); } MacroMode modes = GetMacroMode(ref attrs, pattern); LNode macroName = pattern.Target ?? pattern; LNode replacement = body.AsList(S.Braces).AsLNode(S.Splice); if (pattern.IsCall) { WarnAboutMissingDollarSigns(pattern.Args, context, pattern, replacement); } // Note: we could fill out the macro's Syntax and Description with the // pattern and replacement converted to strings, but it's generally a // waste of CPU time as those strings are usually not requested. // Compromise: provide syntax pattern only var syntax = pattern.ToString(); var lma = new LexicalMacroAttribute(syntax, "User-defined macro at {0}".Localized(pattern.Range.Start), macroName.Name.Name) { Mode = modes }; if ((modes & (MacroMode.MatchEveryLiteral | MacroMode.MatchEveryCall | MacroMode.MatchEveryIdentifier)) != 0) { lma = new LexicalMacroAttribute(syntax, lma.Description) { Mode = modes } } ; var macroInfo = new MacroInfo(null, lma, UserDefinedMacro); macroInfo.Mode |= MacroMode.UseLogicalNameInErrorMessages; context.RegisterMacro(macroInfo); return(F.Splice()); // delete the `define` node from the output LNode UserDefinedMacro(LNode candidate, IMacroContext context2) { MMap <Symbol, LNode> captures = new MMap <Symbol, LNode>(); if (candidate.MatchesPattern(pattern, ref captures, out LNodeList unmatchedAttrs)) { LNode replacement2 = WithUniqueIdentifiers(replacement, context.IncrementTempCounter, out _); return(ReplaceCaptures(replacement2, captures).PlusAttrsBefore(unmatchedAttrs)); } return(null); } }
void CheckIsComplexIdentifier(bool? result, LNode expr) { var np = new EcsNodePrinter(expr, null); _testNum++; var isCI = EcsValidators.IsComplexIdentifier(expr); if (result == null && !isCI) return; else if (result == isCI) return; Assert.Fail(string.Format( "IsComplexIdentifier: fail on test #{0} '{1}'. Expected {2}, got {3}", _testNum, expr.ToString(), result, isCI)); }
void CheckIsComplexIdentifier(bool?result, LNode expr) { _testNum++; var isCI = EcsValidators.IsComplexIdentifier(expr, ICI.Default, EcsValidators.Pedantics.Strict); if (result == null && !isCI) { return; } else if (result == isCI) { return; } Assert.Fail(string.Format( "IsComplexIdentifier: fail on test #{0} '{1}'. Expected {2}, got {3}", _testNum, expr.ToString(), result, isCI)); }
void CheckIsComplexIdentifier(bool?result, LNode expr) { var np = new EcsNodePrinter(expr, null); _testNum++; var isCI = EcsValidators.IsComplexIdentifier(expr); if (result == null && !isCI) { return; } else if (result == isCI) { return; } Assert.Fail(string.Format( "IsComplexIdentifier: fail on test #{0} '{1}'. Expected {2}, got {3}", _testNum, expr.ToString(), result, isCI)); }
public override Pred CodeToTerminalPred(LNode expr, ref string errorMsg) { Debug.Assert(!expr.IsIdNamed(EOF.Name) || expr.Equals(EOF)); if (expr.IsCall && expr.Name != S.Dot && expr.Name != S.Of) { errorMsg = "Unrecognized expression. Treating this as a terminal: " + expr.ToString(); // warning } var expr2 = ResolveAlias(expr); PGNodeSet set; if (expr2.IsIdNamed(_underscore)) { set = PGNodeSet.AllExceptEOF; } else { set = new PGNodeSet(expr2); } // bug fix 2015-07: must use expr, not expr2, as TerminalPred's Basis // (wrong Basis breaks error locations, and $A in code blocks if A is an alias) return(new TerminalPred(expr, set, true)); }
void WhereClausesOpt(ref LNode name) { TokenType la0; #line 1163 "EcsParserGrammar.les" var list = new BMultiMap<Symbol,LNode>(); #line default // Line 1164: (WhereClause)* for (;;) { la0 = LA0; if (la0 == TT.ContextualKeyword) list.Add(WhereClause()); else break; } #line 1165 "EcsParserGrammar.les" if ((list.Count != 0)) { if ((!name.CallsMin(S.Of, 2))) { Error("'{0}' is not generic and cannot use 'where' clauses.", name.ToString()); } else { var tparams = name.Args.ToRWList(); for (int i = 1; i < tparams.Count; i++) { var wheres = list[TParamSymbol(tparams[i])]; tparams[i] = tparams[i].PlusAttrs(wheres); wheres.Clear(); } name = name.WithArgs(tparams.ToRVList()); if ((list.Count > 0)) { Error(list[0].Value, "There is no type parameter named '{0}'", list[0].Key); } } } #line default }
public override Pred CodeToPred(LNode expr, ref string errorMsg) { Debug.Assert(!expr.IsIdNamed(EOF.Name) || expr.Equals(EOF)); if (expr.IsCall && expr.Name != S.Dot && expr.Name != S.Of) { errorMsg = "Unrecognized expression. Treating this as a terminal: " + expr.ToString(); // warning } expr = ResolveAlias(expr); PGNodeSet set; if (expr.IsIdNamed(_underscore)) { set = PGNodeSet.AllExceptEOF; } else { set = new PGNodeSet(expr); } return(new TerminalPred(expr, set, true)); }
public override Pred CodeToPred(LNode expr, ref string errorMsg) { bool isInt = false; PGIntSet set; if (expr.IsIdNamed(_underscore)) { set = PGIntSet.AllExceptEOF; } else if (expr.IsIdNamed(_EOF)) { set = PGIntSet.EOF; } else if (expr.Calls(S.DotDot, 2)) { int?from = ConstValue(expr.Args[0], ref isInt); int?to = ConstValue(expr.Args[1], ref isInt); if (from == null || to == null) { errorMsg = "Expected int32 or character literal on each side of «..»"; return(null); } set = PGIntSet.WithRanges(from.Value, to.Value); } else if (expr.Value is string) { return(Pred.Seq((string)expr.Value)); } else { int?num = ConstValue(expr, ref isInt); if (num == null) { errorMsg = "Unrecognized expression. Expected int32 or character literal instead of: " + expr.ToString(); // warning return(null); } set = PGIntSet.With(num.Value); } set.IsCharSet = !isInt; return(new TerminalPred(expr, set, true)); }
void CheckIsComplexIdentifier(bool? result, LNode expr) { var np = new EcsNodePrinter(expr, null); _testNum++; var is1 = np.IsComplexIdentifier(expr); var is2 = np.IsComplexIdentifierOrNull(expr.Target); if (result == null && !is1 && is2) return; else if (result == is1 && result == is2) return; Assert.Fail(string.Format( "IsComplexIdentifier: fail on test #{0} '{1}'. Expected {2}, got {3}/{4}", _testNum, expr.ToString(), result, is1, is2)); }
void CheckIsComplexIdentifier(bool? result, LNode expr) { _testNum++; var isCI = EcsValidators.IsComplexIdentifier(expr, ICI.Default, EcsValidators.Pedantics.Strict); if (result == null && !isCI) return; else if (result == isCI) return; Assert.Fail(string.Format( "IsComplexIdentifier: fail on test #{0} '{1}'. Expected {2}, got {3}", _testNum, expr.ToString(), result, isCI)); }
/// <summary> /// Gets a pretty string representation for a node. /// </summary> /// <param name="node">The node to print.</param> /// <returns>A string representation.</returns> public static string Print(LNode node) { // TODO: maybe figure out a better way to do this? return(node.ToString().TrimEnd(';')); }