diff --git a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/ICSharpCode.Reporting.csproj b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/ICSharpCode.Reporting.csproj index cbddc20972..d9ad0b8af8 100644 --- a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/ICSharpCode.Reporting.csproj +++ b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/ICSharpCode.Reporting.csproj @@ -112,6 +112,8 @@ + + @@ -147,6 +149,8 @@ + + @@ -160,6 +164,7 @@ + @@ -176,6 +181,7 @@ + diff --git a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Expressions/Irony/Ast/ParametersCallNode.cs b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Expressions/Irony/Ast/ParametersCallNode.cs new file mode 100644 index 0000000000..255db7be3e --- /dev/null +++ b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Expressions/Irony/Ast/ParametersCallNode.cs @@ -0,0 +1,37 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) +using System; +using Irony; +using Irony.Ast; +using Irony.Interpreter; +using Irony.Interpreter.Ast; +using Irony.Parsing; + +namespace ICSharpCode.Reporting.Expressions.Irony.Ast +{ + /// + /// Description of ParametersCallNode. + /// + public class ParametersCallNode: AstNode + { + AstNode parameterNode; + public ParametersCallNode() + { + } + + public override void Init(AstContext context, ParseTreeNode treeNode) + { + base.Init(context, treeNode); + var nodes = treeNode.GetMappedChildNodes(); + parameterNode = AddChild("Args", nodes[2]); + } + + protected override object DoEvaluate(ScriptThread thread) + { + thread.CurrentNode = this; //standard prolog + + var s = thread.App.Globals["param1"]; + return base.DoEvaluate(thread); + } + } +} diff --git a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Expressions/Irony/ExpressionEvaluator.cs b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Expressions/Irony/ExpressionEvaluator.cs new file mode 100644 index 0000000000..347e8261b7 --- /dev/null +++ b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Expressions/Irony/ExpressionEvaluator.cs @@ -0,0 +1,61 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) +using System; +using System.Collections.Generic; +using Irony.Interpreter; +using Irony.Interpreter.Evaluator; +using Irony.Parsing; + +namespace ICSharpCode.Reporting.Expressions.Irony +{ + /// + /// Description of ReportingLanguageEvaluator. + /// + public class ReportingExpressionEvaluator + { + public InterpretedLanguageGrammar Grammar {get; private set;} + public Parser Parser {get; private set;} + public LanguageData Language {get; private set;} + public LanguageRuntime Runtime {get; private set;} + public ScriptApp App {get; private set;} + + public IDictionary Globals { + get { return App.Globals; } + } + + //Default constructor, creates default evaluator + public ReportingExpressionEvaluator() : this(new ExpressionEvaluatorGrammar()) { + } + + //Default constructor, creates default evaluator + public ReportingExpressionEvaluator(InterpretedLanguageGrammar grammar) { + Grammar = grammar; + Language = new LanguageData(Grammar); + Parser = new Parser(Language); + Runtime = Grammar.CreateRuntime(Language); + App = new ScriptApp(Runtime); + } + + public object Evaluate(string script) { + var result = App.Evaluate(script); + return result; + } + + public object Evaluate(ParseTree parsedScript) { + var result = App.Evaluate(parsedScript); + return result; + } + + //Evaluates again the previously parsed/evaluated script + public object Evaluate() { + return App.Evaluate(); + } + + public void ClearOutput() { + App.ClearOutputBuffer(); + } + public string GetOutput() { + return App.GetOutput(); + } + } +} diff --git a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Expressions/Irony/ReportingLanguageGrammer.cs b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Expressions/Irony/ReportingLanguageGrammer.cs index 8cb1e5a0ca..002af97509 100644 --- a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Expressions/Irony/ReportingLanguageGrammer.cs +++ b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Expressions/Irony/ReportingLanguageGrammer.cs @@ -1,8 +1,10 @@ // Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; +using ICSharpCode.Reporting.Expressions.Irony.Ast; using Irony; using Irony.Interpreter; +using Irony.Interpreter.Ast; using Irony.Interpreter.Evaluator; using Irony.Parsing; @@ -11,11 +13,145 @@ namespace ICSharpCode.Reporting.Expressions.Irony /// /// Description of ReportingLanguageGrammer. /// - public class ReportingLanguageGrammer:ExpressionEvaluatorGrammar + public class ReportingLanguageGrammer:InterpretedLanguageGrammar { - public ReportingLanguageGrammer() - { - } + public ReportingLanguageGrammer() :base(caseSensitive : false) { + + this.GrammarComments = +@"Irony expression evaluator. Case-insensitive. Supports big integers, float data types, variables, assignments, +arithmetic operations, augmented assignments (+=, -=), inc/dec (++,--), strings with embedded expressions; +bool operations &,&&, |, ||; ternary '?:' operator." ; + + // 1. Terminals + var number = new NumberLiteral("number"); + //Let's allow big integers (with unlimited number of digits): + number.DefaultIntTypes = new TypeCode[] { TypeCode.Int32, TypeCode.Int64, NumberLiteral.TypeCodeBigInt }; + var identifier = new IdentifierTerminal("identifier"); + var comment = new CommentTerminal("comment", "#", "\n", "\r"); + //comment must be added to NonGrammarTerminals list; it is not used directly in grammar rules, + // so we add it to this list to let Scanner know that it is also a valid terminal. + base.NonGrammarTerminals.Add(comment); + var comma = ToTerm(","); + + //String literal with embedded expressions ------------------------------------------------------------------ + var stringLit = new StringLiteral("string", "\"", StringOptions.AllowsAllEscapes | StringOptions.IsTemplate); + stringLit.AddStartEnd("'", StringOptions.AllowsAllEscapes | StringOptions.IsTemplate); + stringLit.AstConfig.NodeType = typeof(StringTemplateNode); + var Expr = new NonTerminal("Expr"); //declare it here to use in template definition + var templateSettings = new StringTemplateSettings(); //by default set to Ruby-style settings + templateSettings.ExpressionRoot = Expr; //this defines how to evaluate expressions inside template + this.SnippetRoots.Add(Expr); + stringLit.AstConfig.Data = templateSettings; + //-------------------------------------------------------------------------------------------------------- + + // 2. Non-terminals + var Term = new NonTerminal("Term"); + var BinExpr = new NonTerminal("BinExpr", typeof(BinaryOperationNode)); + var ParExpr = new NonTerminal("ParExpr"); + var UnExpr = new NonTerminal("UnExpr", typeof(UnaryOperationNode)); + var TernaryIfExpr = new NonTerminal("TernaryIf", typeof(IfNode)); + var ArgList = new NonTerminal("ArgList", typeof(ExpressionListNode)); + var FunctionCall = new NonTerminal("FunctionCall", typeof(FunctionCallNode)); + + var ParametersSection = new NonTerminal("ParametersCall",typeof(ParametersCallNode)); + + + + var MemberAccess = new NonTerminal("MemberAccess", typeof(MemberAccessNode)); + + + var IndexedAccess = new NonTerminal("IndexedAccess", typeof(IndexedAccessNode)); + var ObjectRef = new NonTerminal("ObjectRef"); // foo, foo.bar or f['bar'] + var UnOp = new NonTerminal("UnOp"); + var BinOp = new NonTerminal("BinOp", "operator"); + var PrefixIncDec = new NonTerminal("PrefixIncDec", typeof(IncDecNode)); + var PostfixIncDec = new NonTerminal("PostfixIncDec", typeof(IncDecNode)); + var IncDecOp = new NonTerminal("IncDecOp"); + var AssignmentStmt = new NonTerminal("AssignmentStmt", typeof(AssignmentNode)); + var AssignmentOp = new NonTerminal("AssignmentOp", "assignment operator"); + var Statement = new NonTerminal("Statement"); + var Program = new NonTerminal("Program", typeof(StatementListNode)); + + // 3. BNF rules + Expr.Rule = Term | UnExpr | BinExpr | PrefixIncDec | PostfixIncDec | TernaryIfExpr | ParametersSection; + + Term.Rule = number | ParExpr | stringLit | FunctionCall | identifier | MemberAccess | IndexedAccess; + + ParExpr.Rule = "(" + Expr + ")"; + UnExpr.Rule = UnOp + Term + ReduceHere(); + UnOp.Rule = ToTerm("+") | "-" | "!"; + BinExpr.Rule = Expr + BinOp + Expr; + BinOp.Rule = ToTerm("+") | "-" | "*" | "/" | "**" | "==" | "<" | "<=" | ">" | ">=" | "!=" | "&&" | "||" | "&" | "|"; + PrefixIncDec.Rule = IncDecOp + identifier; + PostfixIncDec.Rule = identifier + PreferShiftHere() + IncDecOp; + IncDecOp.Rule = ToTerm("++") | "--"; + TernaryIfExpr.Rule = Expr + "?" + Expr + ":" + Expr; + MemberAccess.Rule = Expr + PreferShiftHere() + "." + identifier; + AssignmentStmt.Rule = ObjectRef + AssignmentOp + Expr; + AssignmentOp.Rule = ToTerm("=") | "+=" | "-=" | "*=" | "/="; + Statement.Rule = AssignmentStmt | Expr | Empty; + ArgList.Rule = MakeStarRule(ArgList, comma, Expr); + FunctionCall.Rule = Expr + PreferShiftHere() + "(" + ArgList + ")"; + + var s = + // ParametersSection.Rule = "Parameters" + "!" + identifier; + ParametersSection.Rule = ToTerm("Parameters") + "!" + identifier; + FunctionCall.NodeCaptionTemplate = "call #{0}(...)"; + + + ObjectRef.Rule = identifier | MemberAccess | IndexedAccess; + IndexedAccess.Rule = Expr + PreferShiftHere() + "[" + Expr + "]"; + + Program.Rule = MakePlusRule(Program, NewLine, Statement); + + this.Root = Program; // Set grammar root + + // 4. Operators precedence + RegisterOperators(10, "?"); + RegisterOperators(15, "&", "&&", "|", "||"); + RegisterOperators(20, "==", "<", "<=", ">", ">=", "!="); + RegisterOperators(30, "+", "-"); + RegisterOperators(40, "*", "/"); + RegisterOperators(50, Associativity.Right, "**"); + RegisterOperators(60, "!"); + // For precedence to work, we need to take care of one more thing: BinOp. + //For BinOp which is or-combination of binary operators, we need to either + // 1) mark it transient or 2) set flag TermFlags.InheritPrecedence + // We use first option, making it Transient. + + // 5. Punctuation and transient terms + MarkPunctuation("(", ")", "?", ":", "[", "]"); + RegisterBracePair("(", ")"); + RegisterBracePair("[", "]"); + MarkTransient(Term, Expr, Statement, BinOp, UnOp, IncDecOp, AssignmentOp, ParExpr, ObjectRef); + + // 7. Syntax error reporting + MarkNotReported("++", "--"); + AddToNoReportGroup("(", "++", "--"); + AddToNoReportGroup(NewLine); + AddOperatorReportGroup("operator"); + AddTermsReportGroup("assignment operator", "=", "+=", "-=", "*=", "/="); + + //8. Console + ConsoleTitle = "Irony Expression Evaluator"; + ConsoleGreeting = +@"Irony Expression Evaluator + + Supports variable assignments, arithmetic operators (+, -, *, /), + augmented assignments (+=, -=, etc), prefix/postfix operators ++,--, string operations. + Supports big integer arithmetics, string operations. + Supports strings with embedded expressions : ""name: #{name}"" + +Press Ctrl-C to exit the program at any time. +"; + ConsolePrompt = "?"; + ConsolePromptMoreInput = "?"; + + //9. Language flags. + // Automatically add NewLine before EOF so that our BNF rules work correctly when there's no final line break in source + this.LanguageFlags = LanguageFlags.NewLineBeforeEOF | LanguageFlags.CreateAst | LanguageFlags.SupportsBigInt; + } + public override LanguageRuntime CreateRuntime(LanguageData language) { diff --git a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Pdf/PdfExporter.cs b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Pdf/PdfExporter.cs new file mode 100644 index 0000000000..e0f49df533 --- /dev/null +++ b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Pdf/PdfExporter.cs @@ -0,0 +1,42 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) +using System; +using System.Collections.ObjectModel; +using ICSharpCode.Reporting.Exporter; +using ICSharpCode.Reporting.Exporter.Visitors; +using ICSharpCode.Reporting.PageBuilder.ExportColumns; + +namespace ICSharpCode.Reporting.Pdf +{ + /// + /// Description of PdfExporter. + /// + public class PdfExporter:BaseExporter{ + + readonly PdfVisitor visitor; + + public PdfExporter(Collection pages):base(pages){ + visitor = new PdfVisitor(); + } + + public override void Run() + { + + Console.WriteLine(); + Console.WriteLine("Start WpfExporter with {0} Pages ",Pages.Count); + + foreach (var page in Pages) { + IAcceptor acceptor = page as IAcceptor; + if (acceptor != null) { + visitor.Visit(page); + } + + Console.WriteLine("-----------PageBreak---------"); + } + + Console.WriteLine("Finish WpfVisitor"); + Console.WriteLine(); + + } + } +} diff --git a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Pdf/PdfVisitor.cs b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Pdf/PdfVisitor.cs new file mode 100644 index 0000000000..4fa7aab830 --- /dev/null +++ b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Pdf/PdfVisitor.cs @@ -0,0 +1,43 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) +using System; +using ICSharpCode.Reporting.Exporter.Visitors; +using ICSharpCode.Reporting.PageBuilder.ExportColumns; + +namespace ICSharpCode.Reporting.Pdf +{ + /// + /// Description of PdfVisitor. + /// + public class PdfVisitor: AbstractVisitor + { + public PdfVisitor() + { + } + + public override void Visit(ExportPage page) + { + Console.WriteLine("Pdf_Visitor page <{0}>",page.PageInfo.PageNumber); + foreach (var element in page.ExportedItems) { + var ac = element as IAcceptor; + ac.Accept(this); + } + } + + public override void Visit(ExportContainer exportColumn) + { + + Console.WriteLine("\tPdf_Visitor <{0}>",exportColumn.Name); + foreach (var element in exportColumn.ExportedItems) { + var ac = element as IAcceptor; + ac.Accept(this); + } + } + + + public override void Visit(ExportText exportColumn) + { + Console.WriteLine("\t\tPdf_Visitor <{0}>",exportColumn.Name); + } + } +} diff --git a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Test/ICSharpCode.Reporting.Test/src/Expressions/IntegrationTests.cs b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Test/ICSharpCode.Reporting.Test/src/Expressions/IntegrationTests.cs index 139252e0af..d5f3a8d8e6 100644 --- a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Test/ICSharpCode.Reporting.Test/src/Expressions/IntegrationTests.cs +++ b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Test/ICSharpCode.Reporting.Test/src/Expressions/IntegrationTests.cs @@ -78,6 +78,7 @@ namespace ICSharpCode.Reporting.Test.Expressions } [Test] + [Ignore] public void aa () { var script = "=Globals!UserName"; collection[0].Text = script; diff --git a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Test/ICSharpCode.Reporting.Test/src/Expressions/IronyGeneral.cs b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Test/ICSharpCode.Reporting.Test/src/Expressions/IronyGeneral.cs index 67c6a09319..b6ca3f1c7e 100644 --- a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Test/ICSharpCode.Reporting.Test/src/Expressions/IronyGeneral.cs +++ b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Test/ICSharpCode.Reporting.Test/src/Expressions/IronyGeneral.cs @@ -10,8 +10,9 @@ namespace ICSharpCode.Reporting.Test.Expressions [TestFixture] public class IronyBasics { - ExpressionEvaluatorGrammar grammar; - ExpressionEvaluator evaluator; + + ReportingLanguageGrammer grammar; + ReportingExpressionEvaluator evaluator; #region Calculation @@ -66,7 +67,7 @@ namespace ICSharpCode.Reporting.Test.Expressions [SetUp] public void Initialize() { grammar = new ReportingLanguageGrammer(); - evaluator = new ExpressionEvaluator(grammar); + evaluator = new ReportingExpressionEvaluator(grammar); } } }