From ff9c6068865793951176439d80f66f38d3f3be46 Mon Sep 17 00:00:00 2001 From: Jorgen Brandt Date: Wed, 17 Feb 2016 01:12:44 +0100 Subject: [PATCH 01/78] Erlang draft. --- .gitignore | 21 +- .travis.yml | 6 - cuneiform-addons/.gitignore | 5 - cuneiform-addons/cuneiform-cfide/.gitignore | 5 - cuneiform-addons/cuneiform-cfide/pom.xml | 55 - .../cuneiform/cfide/editor/DarkStyleConf.java | 24 - .../wbi/cuneiform/cfide/editor/EditPanel.java | 216 -- .../cfide/editor/ErrorTableModel.java | 105 - .../cfide/editor/LightStyleConf.java | 23 - .../wbi/cuneiform/cfide/editor/MainPanel.java | 466 ----- .../cuneiform/cfide/editor/SimpleStyle.java | 115 -- .../cuneiform/cfide/editor/StaticPanel.java | 312 --- .../wbi/cuneiform/cfide/editor/StyleConf.java | 129 -- .../cfide/editor/SyntaxListener.java | 385 ---- .../cuneiform/cfide/editor/SyntaxPanel.java | 121 -- .../wbi/cuneiform/cfide/main/Main.java | 108 - cuneiform-addons/cuneiform-dax/.gitignore | 5 - cuneiform-addons/cuneiform-dax/pom.xml | 67 - .../huberlin/cuneiform/libdax/parser/Dax.g4 | 138 -- .../huberlin/cuneiform/dax/repl/DaxRepl.java | 116 -- .../dax/semanticmodel/DaxFilename.java | 120 -- .../cuneiform/dax/semanticmodel/DaxJob.java | 383 ---- .../dax/semanticmodel/DaxJobUses.java | 62 - .../DaxSemanticModelListener.java | 321 --- .../cuneiform-htcondorcre/.gitignore | 5 - .../cuneiform-htcondorcre/InstallHTCondor.md | 21 - .../cuneiform-htcondorcre/README.md | 11 - .../htcondor_settings/condor_config | 100 - .../cuneiform-htcondorcre/pom.xml | 71 - .../cuneiform/htcondorcre/CondorCreActor.java | 591 ------ .../cuneiform/htcondorcre/CondorWatcher.java | 136 -- .../cuneiform/htcondorcre/StatusMessage.java | 96 - cuneiform-addons/cuneiform-logview/.gitignore | 5 - cuneiform-addons/cuneiform-logview/pom.xml | 63 - .../logview/common/Visualizable.java | 15 - .../cuneiform/logview/graphview/CfEdge.java | 53 - .../logview/graphview/GraphView.java | 163 -- .../wbi/cuneiform/logview/main/Main.java | 118 -- .../parallelismview/ParallelismView.java | 189 -- .../wbi/cuneiform/taskview/FileBrowser.java | 156 -- .../taskview/FileMutableTreeNode.java | 21 - .../cuneiform/taskview/InvocationItem.java | 44 - .../wbi/cuneiform/taskview/TaskBrowser.java | 123 -- .../wbi/cuneiform/taskview/TaskView.java | 109 - .../cuneiform-starlinger/.gitignore | 5 - cuneiform-addons/cuneiform-starlinger/pom.xml | 49 - .../wbi/cuneiform/starlinger/JsonMap.java | 85 - .../starlinger/StarlingerEdgeSet.java | 97 - .../cuneiform/starlinger/StarlingerNode.java | 141 -- .../starlinger/StarlingerNodeSet.java | 40 - .../starlinger/StarlingerNodeVisitor.java | 372 ---- .../starlinger/StarlingerWorkflow.java | 90 - cuneiform-addons/pom.xml | 17 - cuneiform-cmdline/.gitignore | 5 - cuneiform-cmdline/pom.xml | 70 - .../cuneiform/cmdline/main/JsonSummary.java | 90 - .../wbi/cuneiform/cmdline/main/Main.java | 356 ---- cuneiform-core/.gitignore | 5 - cuneiform-core/pom.xml | 99 - .../wbi/cuneiform/core/parser/Cuneiform.g4 | 208 -- .../cuneiform/core/parser/ParseCtlLexer.g4 | 46 - .../src/main/doc/cuneiform-logo.svg | 541 ----- cuneiform-core/src/main/doc/g18225.png | Bin 143604 -> 0 bytes cuneiform-core/src/main/doc/pap-cf-apply.dia | Bin 2776 -> 0 bytes .../wbi/cuneiform/core/actormodel/Actor.java | 139 -- .../cuneiform/core/actormodel/Message.java | 50 - .../wbi/cuneiform/core/cre/BaseCreActor.java | 55 - .../wbi/cuneiform/core/cre/LocalCreActor.java | 130 -- .../wbi/cuneiform/core/cre/LocalThread.java | 434 ---- .../cuneiform/core/cre/TicketReadyMsg.java | 74 - .../cuneiform/core/invoc/BashInvocation.java | 451 ----- .../core/invoc/BeanshellInvocation.java | 273 --- .../wbi/cuneiform/core/invoc/Invocation.java | 886 --------- .../cuneiform/core/invoc/LispInvocation.java | 159 -- .../core/invoc/MatlabInvocation.java | 143 -- .../core/invoc/OctaveInvocation.java | 346 ---- .../core/invoc/PegasusInvocation.java | 22 - .../cuneiform/core/invoc/PerlInvocation.java | 347 ---- .../core/invoc/PythonInvocation.java | 265 --- .../wbi/cuneiform/core/invoc/RInvocation.java | 333 ---- .../cuneiform/core/invoc/ScalaInvocation.java | 281 --- .../core/preprocess/ChannelListener.java | 266 --- .../core/preprocess/ParseException.java | 130 -- .../core/preprocess/PreListener.java | 329 ---- .../core/preprocess/PrePhaseException.java | 43 - .../wbi/cuneiform/core/repl/BaseRepl.java | 441 ----- .../wbi/cuneiform/core/repl/CmdlineRepl.java | 21 - .../core/repl/DynamicNodeVisitor.java | 810 -------- .../cuneiform/core/repl/InteractiveRepl.java | 114 -- .../core/repl/QueryParseCtlLexer.java | 81 - .../core/semanticmodel/ApplyExpr.java | 324 --- .../core/semanticmodel/BaseBlock.java | 182 -- .../core/semanticmodel/BaseNodeVisitor.java | 94 - .../cuneiform/core/semanticmodel/Block.java | 48 - .../cuneiform/core/semanticmodel/CfNode.java | 38 - .../semanticmodel/CfSemanticModelVisitor.java | 692 ------- .../core/semanticmodel/CompoundExpr.java | 327 --- .../core/semanticmodel/CondExpr.java | 111 -- .../core/semanticmodel/CorrelParam.java | 135 -- .../core/semanticmodel/CurryExpr.java | 119 -- .../core/semanticmodel/DataType.java | 65 - .../core/semanticmodel/DrawHelper.java | 66 - .../core/semanticmodel/DrawParam.java | 55 - .../core/semanticmodel/EnumHelper.java | 235 --- .../core/semanticmodel/ForeignLambdaExpr.java | 163 -- .../semanticmodel/HasFailedException.java | 43 - .../core/semanticmodel/HashHelper.java | 58 - .../core/semanticmodel/JsonReportEntry.java | 465 ----- .../core/semanticmodel/LambdaExpr.java | 78 - .../core/semanticmodel/LambdaType.java | 46 - .../core/semanticmodel/NameExpr.java | 142 -- .../core/semanticmodel/NativeLambdaExpr.java | 84 - .../core/semanticmodel/NodeVisitor.java | 61 - .../core/semanticmodel/NotBoundException.java | 42 - .../semanticmodel/NotDerivableException.java | 47 - .../cuneiform/core/semanticmodel/Param.java | 41 - .../core/semanticmodel/Prototype.java | 262 --- .../core/semanticmodel/QualifiedTicket.java | 106 - .../core/semanticmodel/ReduceVar.java | 46 - .../semanticmodel/SemanticModelException.java | 52 - .../core/semanticmodel/SingleExpr.java | 39 - .../core/semanticmodel/StringExpr.java | 97 - .../cuneiform/core/semanticmodel/Ticket.java | 247 --- .../core/semanticmodel/TopLevelContext.java | 119 -- .../cuneiform/core/semanticmodel/Type.java | 37 - .../core/staticreduction/DotNodeVisitor.java | 406 ---- .../staticreduction/StaticNodeVisitor.java | 413 ---- .../core/ticketsrc/NodeVisitorTicketSrc.java | 51 - .../core/ticketsrc/ReplTicketSrc.java | 37 - .../core/ticketsrc/TicketFailedMsg.java | 151 -- .../core/ticketsrc/TicketFinishedMsg.java | 94 - .../core/ticketsrc/TicketSrcActor.java | 334 ---- .../core/invoc/JsonReportEntryTest.java | 70 - .../core/repl/DynamicNodeVisitorTest.java | 209 -- .../cuneiform/core/repl/ReferenceTest.java | 1063 ---------- .../core/semanticmodel/ApplyExprTest.java | 37 - .../core/semanticmodel/CompoundExprTest.java | 111 -- .../core/semanticmodel/CondExprTest.java | 66 - .../core/semanticmodel/EnumHelperTest.java | 210 -- .../core/semanticmodel/HashHelperTest.java | 60 - .../semanticmodel/NativeLambdaExprTest.java | 5 - .../core/semanticmodel/StringExprTest.java | 21 - cuneiform-dist/.gitignore | 5 - cuneiform-dist/pom.xml | 129 -- cuneiform-dist/src/main/assemblies/bin.xml | 51 - .../src/main/cuneiform/variant-call11.cf | 193 -- .../src/main/scripts/log4j.properties | 15 - ebin/cf.app | 8 + ebin/cf.beam | Bin 0 -> 1080 bytes ebin/cf_lexer.beam | Bin 0 -> 68636 bytes ebin/cf_parser.beam | Bin 0 -> 42244 bytes ebin/cf_sup.beam | Bin 0 -> 1144 bytes pom.xml | 137 -- rebar.config | 1 + src/cf.app.src | 12 + src/cf.erl | 47 + src/cf_lexer.erl | 1749 +++++++++++++++++ src/cf_lexer.xrl | 320 +++ src/cf_parser.erl | 1594 +++++++++++++++ src/cf_parser.yrl | 403 ++++ src/cf_sup.erl | 44 + 161 files changed, 4190 insertions(+), 22959 deletions(-) delete mode 100644 .travis.yml delete mode 100644 cuneiform-addons/.gitignore delete mode 100644 cuneiform-addons/cuneiform-cfide/.gitignore delete mode 100644 cuneiform-addons/cuneiform-cfide/pom.xml delete mode 100644 cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/DarkStyleConf.java delete mode 100644 cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/EditPanel.java delete mode 100644 cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/ErrorTableModel.java delete mode 100644 cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/LightStyleConf.java delete mode 100644 cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/MainPanel.java delete mode 100644 cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/SimpleStyle.java delete mode 100644 cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/StaticPanel.java delete mode 100644 cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/StyleConf.java delete mode 100644 cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/SyntaxListener.java delete mode 100644 cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/SyntaxPanel.java delete mode 100644 cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/main/Main.java delete mode 100644 cuneiform-addons/cuneiform-dax/.gitignore delete mode 100644 cuneiform-addons/cuneiform-dax/pom.xml delete mode 100644 cuneiform-addons/cuneiform-dax/src/main/antlr/de/huberlin/cuneiform/libdax/parser/Dax.g4 delete mode 100644 cuneiform-addons/cuneiform-dax/src/main/java/de/huberlin/cuneiform/dax/repl/DaxRepl.java delete mode 100644 cuneiform-addons/cuneiform-dax/src/main/java/de/huberlin/cuneiform/dax/semanticmodel/DaxFilename.java delete mode 100644 cuneiform-addons/cuneiform-dax/src/main/java/de/huberlin/cuneiform/dax/semanticmodel/DaxJob.java delete mode 100644 cuneiform-addons/cuneiform-dax/src/main/java/de/huberlin/cuneiform/dax/semanticmodel/DaxJobUses.java delete mode 100644 cuneiform-addons/cuneiform-dax/src/main/java/de/huberlin/cuneiform/dax/semanticmodel/DaxSemanticModelListener.java delete mode 100644 cuneiform-addons/cuneiform-htcondorcre/.gitignore delete mode 100644 cuneiform-addons/cuneiform-htcondorcre/InstallHTCondor.md delete mode 100644 cuneiform-addons/cuneiform-htcondorcre/README.md delete mode 100644 cuneiform-addons/cuneiform-htcondorcre/htcondor_settings/condor_config delete mode 100644 cuneiform-addons/cuneiform-htcondorcre/pom.xml delete mode 100644 cuneiform-addons/cuneiform-htcondorcre/src/main/java/de/huberlin/wbi/cuneiform/htcondorcre/CondorCreActor.java delete mode 100644 cuneiform-addons/cuneiform-htcondorcre/src/main/java/de/huberlin/wbi/cuneiform/htcondorcre/CondorWatcher.java delete mode 100644 cuneiform-addons/cuneiform-htcondorcre/src/main/java/de/huberlin/wbi/cuneiform/htcondorcre/StatusMessage.java delete mode 100644 cuneiform-addons/cuneiform-logview/.gitignore delete mode 100644 cuneiform-addons/cuneiform-logview/pom.xml delete mode 100644 cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/logview/common/Visualizable.java delete mode 100644 cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/logview/graphview/CfEdge.java delete mode 100644 cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/logview/graphview/GraphView.java delete mode 100644 cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/logview/main/Main.java delete mode 100644 cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/logview/parallelismview/ParallelismView.java delete mode 100644 cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/taskview/FileBrowser.java delete mode 100644 cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/taskview/FileMutableTreeNode.java delete mode 100644 cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/taskview/InvocationItem.java delete mode 100644 cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/taskview/TaskBrowser.java delete mode 100644 cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/taskview/TaskView.java delete mode 100644 cuneiform-addons/cuneiform-starlinger/.gitignore delete mode 100644 cuneiform-addons/cuneiform-starlinger/pom.xml delete mode 100644 cuneiform-addons/cuneiform-starlinger/src/main/java/de/huberlin/wbi/cuneiform/starlinger/JsonMap.java delete mode 100644 cuneiform-addons/cuneiform-starlinger/src/main/java/de/huberlin/wbi/cuneiform/starlinger/StarlingerEdgeSet.java delete mode 100644 cuneiform-addons/cuneiform-starlinger/src/main/java/de/huberlin/wbi/cuneiform/starlinger/StarlingerNode.java delete mode 100644 cuneiform-addons/cuneiform-starlinger/src/main/java/de/huberlin/wbi/cuneiform/starlinger/StarlingerNodeSet.java delete mode 100644 cuneiform-addons/cuneiform-starlinger/src/main/java/de/huberlin/wbi/cuneiform/starlinger/StarlingerNodeVisitor.java delete mode 100644 cuneiform-addons/cuneiform-starlinger/src/main/java/de/huberlin/wbi/cuneiform/starlinger/StarlingerWorkflow.java delete mode 100644 cuneiform-addons/pom.xml delete mode 100644 cuneiform-cmdline/.gitignore delete mode 100644 cuneiform-cmdline/pom.xml delete mode 100644 cuneiform-cmdline/src/main/java/de/huberlin/wbi/cuneiform/cmdline/main/JsonSummary.java delete mode 100644 cuneiform-cmdline/src/main/java/de/huberlin/wbi/cuneiform/cmdline/main/Main.java delete mode 100644 cuneiform-core/.gitignore delete mode 100644 cuneiform-core/pom.xml delete mode 100644 cuneiform-core/src/main/antlr/de/huberlin/wbi/cuneiform/core/parser/Cuneiform.g4 delete mode 100644 cuneiform-core/src/main/antlr/de/huberlin/wbi/cuneiform/core/parser/ParseCtlLexer.g4 delete mode 100644 cuneiform-core/src/main/doc/cuneiform-logo.svg delete mode 100644 cuneiform-core/src/main/doc/g18225.png delete mode 100644 cuneiform-core/src/main/doc/pap-cf-apply.dia delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/actormodel/Actor.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/actormodel/Message.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/cre/BaseCreActor.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/cre/LocalCreActor.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/cre/LocalThread.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/cre/TicketReadyMsg.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/BashInvocation.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/BeanshellInvocation.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/Invocation.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/LispInvocation.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/MatlabInvocation.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/OctaveInvocation.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/PegasusInvocation.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/PerlInvocation.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/PythonInvocation.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/RInvocation.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/ScalaInvocation.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/preprocess/ChannelListener.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/preprocess/ParseException.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/preprocess/PreListener.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/preprocess/PrePhaseException.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/repl/BaseRepl.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/repl/CmdlineRepl.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/repl/DynamicNodeVisitor.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/repl/InteractiveRepl.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/repl/QueryParseCtlLexer.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/ApplyExpr.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/BaseBlock.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/BaseNodeVisitor.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/Block.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CfNode.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CfSemanticModelVisitor.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CompoundExpr.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CondExpr.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CorrelParam.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CurryExpr.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/DataType.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/DrawHelper.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/DrawParam.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/EnumHelper.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/ForeignLambdaExpr.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/HasFailedException.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/HashHelper.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/JsonReportEntry.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/LambdaExpr.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/LambdaType.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/NameExpr.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/NativeLambdaExpr.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/NodeVisitor.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/NotBoundException.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/NotDerivableException.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/Param.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/Prototype.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/QualifiedTicket.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/ReduceVar.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/SemanticModelException.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/SingleExpr.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/StringExpr.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/Ticket.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/TopLevelContext.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/Type.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/staticreduction/DotNodeVisitor.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/staticreduction/StaticNodeVisitor.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/ticketsrc/NodeVisitorTicketSrc.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/ticketsrc/ReplTicketSrc.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/ticketsrc/TicketFailedMsg.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/ticketsrc/TicketFinishedMsg.java delete mode 100644 cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/ticketsrc/TicketSrcActor.java delete mode 100644 cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/invoc/JsonReportEntryTest.java delete mode 100644 cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/repl/DynamicNodeVisitorTest.java delete mode 100644 cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/repl/ReferenceTest.java delete mode 100644 cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/semanticmodel/ApplyExprTest.java delete mode 100644 cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CompoundExprTest.java delete mode 100644 cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CondExprTest.java delete mode 100644 cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/semanticmodel/EnumHelperTest.java delete mode 100644 cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/semanticmodel/HashHelperTest.java delete mode 100644 cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/semanticmodel/NativeLambdaExprTest.java delete mode 100644 cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/semanticmodel/StringExprTest.java delete mode 100644 cuneiform-dist/.gitignore delete mode 100644 cuneiform-dist/pom.xml delete mode 100644 cuneiform-dist/src/main/assemblies/bin.xml delete mode 100644 cuneiform-dist/src/main/cuneiform/variant-call11.cf delete mode 100644 cuneiform-dist/src/main/scripts/log4j.properties create mode 100644 ebin/cf.app create mode 100644 ebin/cf.beam create mode 100644 ebin/cf_lexer.beam create mode 100644 ebin/cf_parser.beam create mode 100644 ebin/cf_sup.beam delete mode 100644 pom.xml create mode 100644 rebar.config create mode 100644 src/cf.app.src create mode 100644 src/cf.erl create mode 100644 src/cf_lexer.erl create mode 100644 src/cf_lexer.xrl create mode 100644 src/cf_parser.erl create mode 100644 src/cf_parser.yrl create mode 100644 src/cf_sup.erl diff --git a/.gitignore b/.gitignore index 4451fb7..b93e9cd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,13 @@ -/target -/bin -/.classpath -/.settings -/.project +.eunit +deps +*.o +*.beam +*.plt +erl_crash.dump +ebin +rel/example_project +.concrete/DEV_MODE +.rebar *~ - -*.iml -.idea -/conf/** \ No newline at end of file +src/cf_lexer.erl +src/cf_parser.erl diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index f1b285a..0000000 --- a/.travis.yml +++ /dev/null @@ -1,6 +0,0 @@ -language: java -jdk: - - oraclejdk8 - - oraclejdk7 - - openjdk7 - diff --git a/cuneiform-addons/.gitignore b/cuneiform-addons/.gitignore deleted file mode 100644 index 6afedc5..0000000 --- a/cuneiform-addons/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/target -/bin -/.classpath -/.settings -/.project diff --git a/cuneiform-addons/cuneiform-cfide/.gitignore b/cuneiform-addons/cuneiform-cfide/.gitignore deleted file mode 100644 index 6afedc5..0000000 --- a/cuneiform-addons/cuneiform-cfide/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/target -/bin -/.classpath -/.settings -/.project diff --git a/cuneiform-addons/cuneiform-cfide/pom.xml b/cuneiform-addons/cuneiform-cfide/pom.xml deleted file mode 100644 index 508478e..0000000 --- a/cuneiform-addons/cuneiform-cfide/pom.xml +++ /dev/null @@ -1,55 +0,0 @@ - - 4.0.0 - - de.hu-berlin.wbi.cuneiform - cuneiform-addons - 2.0.4-SNAPSHOT - - cuneiform-cfide - cuneiform-cfide - - - - de.hu-berlin.wbi.cuneiform - cuneiform-core - ${project.version} - - - de.hu-berlin.wbi.cuneiform - cuneiform-starlinger - ${project.version} - - - - - - - org.apache.maven.plugins - maven-source-plugin - 2.4 - - - attach-sources - - jar - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.10.3 - - - attach-javadocs - - jar - - - - - - - \ No newline at end of file diff --git a/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/DarkStyleConf.java b/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/DarkStyleConf.java deleted file mode 100644 index 519a807..0000000 --- a/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/DarkStyleConf.java +++ /dev/null @@ -1,24 +0,0 @@ -package de.huberlin.wbi.cuneiform.cfide.editor; - -import java.awt.Color; - -public class DarkStyleConf extends StyleConf { - - public DarkStyleConf() { - setCommentStyle( SimpleStyle.createPlainStyle( new Color( 100, 200, 255 ) ) ); - setCallStyle( SimpleStyle.createItStyle() ); - setApplyStyle( SimpleStyle.createUlStyle() ); - setVarnameStyle( SimpleStyle.createPlainStyle( new Color( 100, 180, 140 ) ) ); - setStatStyle( SimpleStyle.createPlainStyle( Color.WHITE ) ); - setKeywordStyle( SimpleStyle.createBfStyle() ); - setDataStyle( SimpleStyle.createPlainStyle( new Color( 255, 255, 150 ) ) ); - setTypeStyle( SimpleStyle.createPlainStyle( new Color( 200, 255, 200 ) ) ); - setForeignStyle( SimpleStyle.createPlainStyle( Color.LIGHT_GRAY ) ); - } - - @Override - public Color getBackgroundColor() { - return new Color( 0, 10, 30 ); - } - -} diff --git a/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/EditPanel.java b/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/EditPanel.java deleted file mode 100644 index 83cfcd7..0000000 --- a/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/EditPanel.java +++ /dev/null @@ -1,216 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.cfide.editor; - -import java.awt.BorderLayout; -import java.awt.Component; -import java.awt.event.KeyEvent; -import java.awt.event.KeyListener; -import java.io.File; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import javax.swing.BorderFactory; -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JSplitPane; -import javax.swing.JTable; -import javax.swing.event.CaretEvent; -import javax.swing.event.CaretListener; -import javax.swing.text.Element; - -public class EditPanel extends SyntaxPanel implements KeyListener, CaretListener { - - private static final long serialVersionUID = -7538677478512722934L; - private static final String TITLE_UNSAVED = "Unsaved*"; - - private JLabel posLabel; - private ErrorTableModel errorTableModel; - private File file; - private String originalContent; - private MainPanel mainPanel; - - public EditPanel( MainPanel mainPanel ) { - this( mainPanel, null, "" ); - } - - public EditPanel( MainPanel mainPanel, File file, String content ) { - - JTable errorTable; - JPanel posPanel; - StaticPanel staticPanel; - ExecutorService es; - JScrollPane errorPane; - JSplitPane editErrorSplitPane, editStaticPane; - Component original; - - setMainPanel( mainPanel ); - setFile( file, content ); - setText( content ); - - original = getComponent( 0 ); - remove( original ); - - addKeyListener( this ); - addCaretListener( this ); - setEditable( true ); - - // error table - errorTableModel = new ErrorTableModel(); - errorTable = new JTable( errorTableModel ); - errorTable.getColumnModel().getColumn( 0 ).setMaxWidth( 60 ); - errorTable.getColumnModel().getColumn( 1 ).setMaxWidth( 60 ); - errorTable.getColumnModel().getColumn( 3 ).setMaxWidth( 60 ); - - // caret position label - posLabel = new JLabel( "1 : 1" ); - - posPanel = new JPanel(); - posPanel.setLayout( new BoxLayout( posPanel, BoxLayout.X_AXIS ) ); - posPanel.add( Box.createHorizontalGlue() ); - posPanel.add( posLabel ); - - add( posPanel, BorderLayout.SOUTH ); - - staticPanel = new StaticPanel( this, errorTableModel ); - es = Executors.newSingleThreadExecutor(); - es.submit( staticPanel ); - es.shutdown(); - - editStaticPane = new JSplitPane( - JSplitPane.HORIZONTAL_SPLIT, staticPanel, original ); - editStaticPane.setDividerLocation( 450 ); - editStaticPane.setResizeWeight( 0 ); - editStaticPane.setOneTouchExpandable( true ); - - errorPane = new JScrollPane( errorTable ); - errorPane.setBorder( BorderFactory.createTitledBorder( "Errors" ) ); - editErrorSplitPane = new JSplitPane( - JSplitPane.VERTICAL_SPLIT, - errorPane, - editStaticPane ); - editErrorSplitPane.setDividerLocation( 100 ); - editErrorSplitPane.setResizeWeight( 0 ); - editErrorSplitPane.setOneTouchExpandable( true ); - - add( editErrorSplitPane, BorderLayout.CENTER ); - } - - @Override - public void caretUpdate( CaretEvent arg0 ) { - - int line, pos, col; - Element root; - - if( posLabel == null ) - return; - - pos = getCaretPosition(); - root = getDocument().getDefaultRootElement(); - - for( line = 0; line < root.getElementCount(); line++ ) - if( root.getElement( line ).getStartOffset() > pos ) - break; - - col = pos-root.getElement( line-1 ).getStartOffset()+1; - - posLabel.setText( line+" : "+col ); - } - - public ErrorTableModel getErrorTableModel() { - return errorTableModel; - } - - public File getFile() { - return file; - } - - public String getTitle() { - - String title; - - if( file == null ) - return TITLE_UNSAVED; - - title = file.getName(); - - if( hasChanged() ) - title += "*"; - - return title; - } - - public boolean hasChanged() { - return !originalContent.equals( getText() ); - } - - public boolean hasFile() { - return file != null; - } - - @Override - public void keyPressed( KeyEvent arg0 ) {} - - @Override - public void keyReleased( KeyEvent arg0 ) { - SyntaxListener.process( getEditPane(), sc ); - mainPanel.updateSelectedEditPanelTitle(); - } - - @Override - public void keyTyped( KeyEvent arg0 ) {} - - public void revert() { - setText( originalContent ); - } - - public void setFile( File file, String content ) { - - if( content == null ) - throw new NullPointerException( "Original content must not be null." ); - - this.file = file; - originalContent = content; - } - - public void setMainPanel( MainPanel mainPanel ) { - - if( mainPanel == null ) - throw new NullPointerException( "Main panel must not be null." ); - - this.mainPanel = mainPanel; - } -} diff --git a/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/ErrorTableModel.java b/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/ErrorTableModel.java deleted file mode 100644 index 126cd42..0000000 --- a/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/ErrorTableModel.java +++ /dev/null @@ -1,105 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.cfide.editor; - -import java.util.LinkedList; -import java.util.List; - -import javax.swing.table.AbstractTableModel; - -import de.huberlin.wbi.cuneiform.core.preprocess.ParseException; - - -public class ErrorTableModel extends AbstractTableModel { - - private static final long serialVersionUID = -5752707318286728959L; - private List errorList; - - public ErrorTableModel() { - errorList = new LinkedList<>(); - } - - public void clear() { - errorList.clear(); - } - - public void add( ParseException entry ) { - - if( entry == null ) - throw new NullPointerException( "Error entry must not be null." ); - - errorList.add( entry ); - } - - @Override - public int getColumnCount() { - return 5; - } - - @Override - public Object getValueAt( int rowIndex, int columnIndex ) { - - ParseException entry; - - entry = errorList.get( rowIndex ); - - switch( columnIndex ) { - case 0 : return entry.hasLine() ? entry.getLine() : ""; - case 1 : return entry.hasCharPositionInLine() ? entry.getCharPositionInLine() : ""; - case 2 : return entry.hasNear() ? entry.getNear() : ""; - case 3 : return "Error"; - case 4 : return entry.getMessage(); - default : - throw new UnsupportedOperationException( - "Invalid column." ); - } - } - - @Override - public int getRowCount() { - return errorList.size(); - } - - @Override - public String getColumnName( int columnIndex ) { - - switch( columnIndex ) { - case 0 : return "Line"; - case 1 : return "Column"; - case 2 : return "Near"; - case 3 : return "Level"; - case 4 : return "Message"; - default : throw new UnsupportedOperationException( "Invalid column." ); - } - } -} diff --git a/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/LightStyleConf.java b/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/LightStyleConf.java deleted file mode 100644 index 36b3b5a..0000000 --- a/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/LightStyleConf.java +++ /dev/null @@ -1,23 +0,0 @@ -package de.huberlin.wbi.cuneiform.cfide.editor; - -import java.awt.Color; - -public class LightStyleConf extends StyleConf { - - public LightStyleConf() { - setCommentStyle( SimpleStyle.createPlainStyle( new Color( 0, 100, 155 ) ) ); - setCallStyle( SimpleStyle.createItStyle() ); - setApplyStyle( SimpleStyle.createUlStyle() ); - setVarnameStyle( SimpleStyle.createPlainStyle( new Color( 0, 80, 40 ) ) ); - setStatStyle( SimpleStyle.createPlainStyle( Color.BLACK ) ); - setKeywordStyle( SimpleStyle.createBfStyle() ); - setDataStyle( SimpleStyle.createPlainStyle( new Color( 100, 100, 0 ) ) ); - setTypeStyle( SimpleStyle.createPlainStyle( new Color( 70, 125, 70 ) ) ); - setForeignStyle( SimpleStyle.createPlainStyle( Color.DARK_GRAY ) ); - } - - @Override - public Color getBackgroundColor() { - return Color.WHITE; - } -} diff --git a/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/MainPanel.java b/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/MainPanel.java deleted file mode 100644 index bc577fc..0000000 --- a/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/MainPanel.java +++ /dev/null @@ -1,466 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.cfide.editor; - -import java.awt.BorderLayout; -import java.awt.Component; -import java.awt.Event; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyEvent; -import java.awt.event.WindowEvent; -import java.awt.event.WindowListener; -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; - -import javax.swing.JFileChooser; -import javax.swing.JFrame; -import javax.swing.JMenu; -import javax.swing.JMenuBar; -import javax.swing.JMenuItem; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JTabbedPane; -import javax.swing.KeyStroke; - -import de.huberlin.wbi.cuneiform.core.repl.BaseRepl; - -public class MainPanel extends JPanel implements ActionListener, WindowListener { - - private static final long serialVersionUID = -8425834761771677470L; - - private static final String LABEL_NEW = "New"; - private static final String LABEL_OPEN = "Open ..."; - private static final String LABEL_CLOSE = "Close"; - private static final String LABEL_SAVE = "Save"; - private static final String LABEL_SAVEAS = "Save as ..."; - private static final String LABEL_QUIT = "Quit"; - private static final String LABEL_ABOUT = "About ..."; - private static final String LABEL_REVERT = "Revert"; - - private JTabbedPane editTabbedPane; - private JFileChooser fc; - private JFrame parent; - private JMenuItem saveItem, closeItem, saveAsItem, revertItem; - - public MainPanel( JFrame parentFrame ) { - - setParent( parentFrame ); - setLayout( new BorderLayout() ); - - fc = new JFileChooser(); - editTabbedPane = new JTabbedPane(); - - - add( editTabbedPane ); - } - - @Override - public void actionPerformed( ActionEvent arg0 ) { - - int returnVal; - File f; - String ac; - EditPanel editPanel; - - - ac = arg0.getActionCommand(); - - if( ac.equals( LABEL_REVERT ) ) { - - editPanel = ( EditPanel )editTabbedPane.getSelectedComponent(); - - if( !editPanel.hasChanged() ) - return; - - returnVal = JOptionPane.showConfirmDialog( parent, "Unsaved changes will be lost.\nAre you sure?", "Revert "+editPanel.getTitle(), JOptionPane.YES_NO_OPTION ); - - if( returnVal == JOptionPane.NO_OPTION ) - return; - - editPanel.revert(); - updateSelectedEditPanelTitle(); - - return; - } - - if( ac.equals( LABEL_ABOUT ) ) { - - JOptionPane.showMessageDialog( parent, "Cuneiform Editor\nversion "+BaseRepl.LABEL_VERSION+" build "+BaseRepl.LABEL_BUILD+"\nJörgen Brandt", "About Cuneiform Editor", JOptionPane.INFORMATION_MESSAGE ); - - return; - } - - if( ac.equals( LABEL_NEW ) ) { - - editPanel = new EditPanel( this ); - editTabbedPane.add( editPanel.getTitle(), editPanel ); - editTabbedPane.setSelectedComponent( editPanel ); - updateMenu(); - - return; - } - - if( ac.equals( LABEL_OPEN ) ) { - - returnVal = fc.showOpenDialog( parent ); - - if( returnVal == JFileChooser.APPROVE_OPTION ) { - - f = fc.getSelectedFile(); - open( f ); - } - - return; - } - - if( ac.equals( LABEL_CLOSE ) ) { - - editPanel = ( EditPanel )editTabbedPane.getSelectedComponent(); - - if( editPanel.hasChanged() ) { - - - if( editPanel.hasFile() ) { - - returnVal = JOptionPane.showConfirmDialog( parent, - "Save changes in "+editPanel.getFile().getName()+"?", - "Save changes", - JOptionPane.YES_NO_CANCEL_OPTION ); - - if( returnVal == JOptionPane.OK_OPTION ) - saveAction( editPanel.getFile() ); - } - else { - - returnVal = JOptionPane.showConfirmDialog( parent, - "Save changes in unsaved file?", - "Save changes", - JOptionPane.YES_NO_CANCEL_OPTION ); - - if( returnVal == JOptionPane.OK_OPTION ) { - - returnVal = saveAsAction(); - - if( returnVal == JFileChooser.CANCEL_OPTION ) - return; - } - else - if( returnVal == JOptionPane.CANCEL_OPTION ) - return; - - - } - - if( returnVal == JOptionPane.CANCEL_OPTION ) - return; - } - - - editTabbedPane.remove( editTabbedPane.getSelectedComponent() ); - updateMenu(); - - return; - } - - if( ac.equals( LABEL_SAVE ) ) { - - editPanel = ( EditPanel )editTabbedPane.getSelectedComponent(); - - if( !editPanel.hasChanged() ) - return; - - if( editPanel.hasFile() ) { - - saveAction( editPanel.getFile() ); - return; - } - - saveAsAction(); - - return; - } - - if( ac.equals( LABEL_SAVEAS ) ) { - - saveAsAction(); - return; - } - - if( ac.equals( LABEL_QUIT ) ) { - quitAction(); - return; - } - - throw new RuntimeException( "Action not recognized: '"+arg0.getActionCommand()+"'." ); - } - - public JMenuBar getMenuBar() { - - JMenuBar menuBar; - JMenu menu; - JMenuItem menuItem; - - menuBar = new JMenuBar(); - - menu = new JMenu( "File" ); - menuBar.add( menu ); - - menuItem = new JMenuItem( LABEL_NEW ); - menuItem.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_N, Event.CTRL_MASK ) ); - menuItem.addActionListener( this ); - menu.add( menuItem ); - - menuItem = new JMenuItem( LABEL_OPEN ); - menuItem.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_O, Event.CTRL_MASK ) ); - menuItem.addActionListener( this ); - menu.add( menuItem ); - - menu.addSeparator(); - - saveItem = new JMenuItem( LABEL_SAVE ); - saveItem.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_S, Event.CTRL_MASK ) ); - saveItem.setEnabled( false ); - saveItem.addActionListener( this ); - menu.add( saveItem ); - - saveAsItem = new JMenuItem( LABEL_SAVEAS ); - saveAsItem.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_S, Event.CTRL_MASK | Event.SHIFT_MASK ) ); - saveAsItem.setEnabled( false ); - saveAsItem.addActionListener( this ); - menu.add( saveAsItem ); - - revertItem = new JMenuItem( LABEL_REVERT ); - revertItem.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_R, Event.CTRL_MASK ) ); - revertItem.setEnabled( false ); - revertItem.addActionListener( this ); - menu.add( revertItem ); - - menu.addSeparator(); - - closeItem = new JMenuItem( LABEL_CLOSE ); - closeItem.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_W, Event.CTRL_MASK ) ); - closeItem.setEnabled( false ); - closeItem.addActionListener( this ); - menu.add( closeItem ); - - - menuItem = new JMenuItem( LABEL_QUIT ); - menuItem.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_Q, Event.CTRL_MASK ) ); - menuItem.addActionListener( this ); - menu.add( menuItem ); - - menu = new JMenu( "Help" ); - menuBar.add( menu ); - - menuItem = new JMenuItem( LABEL_ABOUT ); - menuItem.addActionListener( this ); - menu.add( menuItem ); - - return menuBar; - - } - - public void setParent( JFrame parent ) { - - if( parent == null ) - throw new NullPointerException( "Parent frame must not be null." ); - - this.parent = parent; - } - - public void updateSelectedEditPanelTitle() { - - int i; - EditPanel editPanel; - - i = editTabbedPane.getSelectedIndex(); - editPanel = ( EditPanel )editTabbedPane.getComponent( i ); - editTabbedPane.setTitleAt( i, editPanel.getTitle() ); - } - - public void updateMenu() { - - boolean enabled; - - - enabled = editTabbedPane.getComponentCount() > 0; - - saveItem.setEnabled( enabled ); - saveAsItem.setEnabled( enabled ); - closeItem.setEnabled( enabled ); - revertItem.setEnabled( enabled ); - - } - - - public void open( File f ) { - - EditPanel editPanel; - StringBuffer buf; - String line; - - - try( BufferedReader reader = new BufferedReader( new FileReader( f ) ) ) { - - buf = new StringBuffer(); - - while( ( line = reader.readLine() ) != null ) - buf.append( line ).append( '\n' ); - - editPanel = new EditPanel( this, f, buf.toString() ); - editTabbedPane.add( f.getName(), editPanel ); - editTabbedPane.setSelectedComponent( editPanel ); - updateMenu(); - } - catch( IOException e ) { - JOptionPane.showMessageDialog( parent, - e.getMessage(), - "IOException", - JOptionPane.ERROR_MESSAGE ); - } - } - - @Override - public void windowOpened( WindowEvent e ) {} - - @Override - public void windowClosing( WindowEvent e ) { - quitAction(); - } - - @Override - public void windowClosed( WindowEvent e ) {} - - @Override - public void windowIconified( WindowEvent e ) {} - - @Override - public void windowDeiconified( WindowEvent e ) {} - - @Override - public void windowActivated( WindowEvent e ) {} - - @Override - public void windowDeactivated( WindowEvent e ) {} - - private int saveAsAction() { - - int returnVal; - - returnVal = fc.showSaveDialog( parent ); - - if( returnVal == JFileChooser.APPROVE_OPTION ) { - saveAction( fc.getSelectedFile() ); - } - - return returnVal; - } - - private void saveAction( File f ) { - - EditPanel editPanel; - - editPanel = ( EditPanel )editTabbedPane.getSelectedComponent(); - - try( BufferedWriter writer = new BufferedWriter( new FileWriter( f ) ) ) { - - writer.write( editPanel.getText() ); - editPanel.setFile( f, editPanel.getText() ); - updateSelectedEditPanelTitle(); - - } - catch( IOException e ) { - JOptionPane.showMessageDialog( parent, - e.getMessage(), - "IOException", - JOptionPane.ERROR_MESSAGE ); - } - - } - - private void quitAction() { - - EditPanel editPanel; - int option; - int dialogOption; - - for( Component c : editTabbedPane.getComponents() ) { - - editPanel = ( EditPanel )c; - if( editPanel.hasChanged() ) { - - editTabbedPane.setSelectedComponent( editPanel ); - - if( editPanel.hasFile() ) { - - option = JOptionPane.showConfirmDialog( parent, - "Save changes in "+editPanel.getFile().getName()+"?", - "Save changes", - JOptionPane.YES_NO_CANCEL_OPTION ); - - if( option == JOptionPane.OK_OPTION ) - saveAction( editPanel.getFile() ); - } - else { - - option = JOptionPane.showConfirmDialog( parent, - "Save changes in unsaved file?", - "Save changes", - JOptionPane.YES_NO_CANCEL_OPTION ); - - dialogOption = JFileChooser.APPROVE_OPTION; - - if( option == JOptionPane.OK_OPTION ) - dialogOption = saveAsAction(); - - if( dialogOption == JFileChooser.CANCEL_OPTION ) - return; - - - } - - if( option == JOptionPane.CANCEL_OPTION ) - return; - } - } - - System.exit( 0 ); - } - - -} diff --git a/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/SimpleStyle.java b/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/SimpleStyle.java deleted file mode 100644 index 015f443..0000000 --- a/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/SimpleStyle.java +++ /dev/null @@ -1,115 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.cfide.editor; - -import java.awt.Color; - -import javax.swing.text.Style; -import javax.swing.text.StyleConstants; -import javax.swing.text.StyledDocument; - - -public class SimpleStyle { - - private Boolean it; - private Boolean ul; - private Boolean bf; - private Color col; - - public SimpleStyle( Color col, Boolean it, Boolean bf, Boolean ul ) { - - setIt( it ); - setUl( ul ); - setBf( bf ); - setColor( col ); - } - - public void setIt( Boolean it ) { - this.it = it; - } - - public void setUl( Boolean ul ) { - this.ul = ul; - } - - public void setBf( Boolean bf ) { - this.bf = bf; - } - - public void setColor( Color col ) { - this.col = col; - } - - public void setColor( int r, int g, int b ) { - col = new Color( r, g, b ); - } - - public void addStyleToDoc( StyledDocument doc, String key ) { - - Style style; - - style = doc.addStyle( key, null ); - - if( ul != null ) - StyleConstants.setUnderline( style, ul ); - - if( bf != null ) - StyleConstants.setBold( style, bf ); - - if( it != null ) - StyleConstants.setItalic( style, it ); - - if( col != null ) - StyleConstants.setForeground( style, col ); - } - - public static SimpleStyle createItStyle( Color c ) { - return new SimpleStyle( c, true, null, null ); - } - - public static SimpleStyle createItStyle() { - return new SimpleStyle( null, true, null, null ); - } - - public static SimpleStyle createBfStyle() { - return new SimpleStyle( null, null, true, null ); - } - - public static SimpleStyle createUlStyle() { - return new SimpleStyle( null, null, null, true ); - } - - public static SimpleStyle createPlainStyle( Color c ) { - return new SimpleStyle( c, null, null, null ); - } -} diff --git a/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/StaticPanel.java b/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/StaticPanel.java deleted file mode 100644 index d5aa13b..0000000 --- a/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/StaticPanel.java +++ /dev/null @@ -1,312 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.cfide.editor; - -import java.awt.BorderLayout; -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import javax.imageio.ImageIO; -import javax.swing.BorderFactory; -import javax.swing.ImageIcon; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTabbedPane; -import javax.swing.JTextPane; - -import de.huberlin.wbi.cuneiform.core.preprocess.ChannelListener; -import de.huberlin.wbi.cuneiform.core.preprocess.ParseException; -import de.huberlin.wbi.cuneiform.core.preprocess.PreListener; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CompoundExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CfSemanticModelVisitor; -import de.huberlin.wbi.cuneiform.core.semanticmodel.HasFailedException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NotBoundException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.TopLevelContext; -import de.huberlin.wbi.cuneiform.core.staticreduction.DotNodeVisitor; -import de.huberlin.wbi.cuneiform.core.staticreduction.StaticNodeVisitor; -import de.huberlin.wbi.cuneiform.starlinger.StarlingerNodeVisitor; - - -public class StaticPanel extends JPanel implements Runnable { - - private static final long serialVersionUID = -5302001074704951699L; - - private SyntaxPanel channelPanel, reductionPanel, prePanel, modelPanel; - - private JLabel dagLabel; - private JTextPane dotPane, starlingerPane; - private SyntaxPanel srcPane; - private ErrorTableModel errorTableModel; - private int hash; - - public StaticPanel( SyntaxPanel srcPane, ErrorTableModel errorTableModel ) { - - JTabbedPane tabbedPane; - JPanel panel; - - setSrcPane( srcPane ); - setErrorTableModel( errorTableModel ); - - setLayout( new BorderLayout() ); - - - tabbedPane = new JTabbedPane(); - tabbedPane.setBorder( BorderFactory.createTitledBorder( "Static info" ) ); - add( tabbedPane, BorderLayout.CENTER ); - - prePanel = new SyntaxPanel(); - tabbedPane.addTab( "(i) Pre", prePanel ); - - channelPanel = new SyntaxPanel(); - tabbedPane.addTab( "(ii) Channel", channelPanel ); - - modelPanel = new SyntaxPanel(); - tabbedPane.addTab( "(iii) Model", modelPanel ); - - reductionPanel = new SyntaxPanel(); - tabbedPane.addTab( "(iv) Static red.", reductionPanel ); - - starlingerPane = new JTextPane(); - tabbedPane.addTab( "Starlinger", new JScrollPane( starlingerPane ) ); - - dotPane = new JTextPane(); - tabbedPane.addTab( "Dot", new JScrollPane( dotPane ) ); - - dagLabel = new JLabel(); - - panel = new JPanel(); - panel.setLayout( new BorderLayout() ); - panel.add( new JScrollPane( dagLabel ), BorderLayout.CENTER ); - - - tabbedPane.add( "DAG", panel ); - - - } - - public void setSrcPane( SyntaxPanel srcPane ) { - - if( srcPane == null ) - throw new NullPointerException( "Source pane must not be null." ); - - this.srcPane = srcPane; - } - - public void setErrorTableModel( ErrorTableModel errorTableModel ) { - - if( errorTableModel == null ) - throw new NullPointerException( "Error table model must not be null." ); - - this.errorTableModel = errorTableModel; - } - - @Override - public void run() { - - String afterPre, afterChannel; - TopLevelContext tlc; - String dot; - ImageIcon img; - StaticNodeVisitor staticVisitor; - DotNodeVisitor dotVisitor; - CompoundExpr ce1; - StarlingerNodeVisitor starlingerVisitor; - String starlinger; - String reduction; - - - while( true ) { - - if( srcPane.getText().hashCode() != hash ) - - try { - - hash = srcPane.getText().hashCode(); - - errorTableModel.clear(); - - afterPre = PreListener.process( srcPane.getText() ); - prePanel.setText( afterPre ); - - afterChannel = ChannelListener.process( afterPre ); - channelPanel.setText( afterChannel ); - - tlc = CfSemanticModelVisitor.process( afterChannel ); - modelPanel.setText( tlc.toString() ); - - if( tlc.isTargetListEmpty() ) { - starlinger = "{ 'nodes'=>{},'edges'=>{}}"; - dot = "digraph G {}"; - reduction = ""; - } - else { - - staticVisitor = new StaticNodeVisitor( tlc ); - - ce1 = tlc.visit( staticVisitor ); - reduction = ce1.toString()+";"; - - starlingerVisitor = new StarlingerNodeVisitor(); - - ce1.visit( starlingerVisitor ); - starlinger = starlingerVisitor.toString(); - - dotVisitor = new DotNodeVisitor(); - - ce1.visit( dotVisitor ); - dot = dotVisitor.toString(); - - } - - reductionPanel.setText( reduction ); - starlingerPane.setText( starlinger ); - dotPane.setText( dot ); - - img = runGraphViz( dot ); - dagLabel.setIcon( img ); - - } - catch( ParseException e ) { - errorTableModel.add( e ); - } - catch( RuntimeException e ) { - e.printStackTrace(); - } - catch( HasFailedException e ) { - e.printStackTrace(); - } catch (NotBoundException e) { - e.printStackTrace(); - } - finally { - errorTableModel.fireTableDataChanged(); - } - - try { - Thread.sleep( 2000 ); - } - catch( InterruptedException e ) { - e.printStackTrace(); - } - } - - - } - - private static ImageIcon runGraphViz( String dot ) { - - ImageIcon img; - - - - ProcessBuilder builder; - Process p; - ExecutorService executorService; - BufferedImage rawImage; - - builder = new ProcessBuilder( "/bin/bash", "-c", "dot -T png" ); - - try { - p = builder.start(); - - executorService = Executors.newSingleThreadExecutor(); - executorService.submit( new ProducerThread( p, dot ) ); - executorService.shutdown(); - - try( InputStream inStream = p.getInputStream() ) { - - - rawImage = ImageIO.read( inStream ); - if( rawImage == null ) { - System.err.println( "Cannot produce image. Is graphviz installed properly?" ); - return null; - } - - rawImage.flush(); - - img = new ImageIcon( rawImage ); - - - return img; - } - } - catch( IOException e ) { - e.printStackTrace(); - } - - return null; - - - } - - private static class ProducerThread implements Runnable { - - private Process p; - private String dot; - - public ProducerThread( Process p, String dot ) { - - if( p == null ) - throw new NullPointerException( "Process must not be null." ); - - if( dot == null ) - throw new NullPointerException( "Dot string must not be null." ); - - this.p = p; - this.dot = dot; - } - - @Override - public void run() { - - - - - try( OutputStream outStream = p.getOutputStream() ) { - - outStream.write( dot.getBytes() ); - outStream.close(); - } catch( IOException e ) { - e.printStackTrace(); - } - - } - - - } - -} diff --git a/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/StyleConf.java b/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/StyleConf.java deleted file mode 100644 index fe1bbc3..0000000 --- a/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/StyleConf.java +++ /dev/null @@ -1,129 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.cfide.editor; - -import java.awt.Color; -import java.util.HashMap; -import java.util.Map; - -import javax.swing.text.StyledDocument; - -public abstract class StyleConf { - - - public static final String KEY_KEYWORD = "keyword"; - public static final String KEY_VARNAME = "varname"; - public static final String KEY_COMMENT = "comment"; - public static final String KEY_CALL = "call"; - public static final String KEY_APPLY = "apply"; - public static final String KEY_STAT = "stat"; - public static final String KEY_DATA = "data"; - public static final String KEY_TYPE = "type"; - public static final String KEY_FOREIGN = "foreign"; - - - private Map styleMap; - - public StyleConf() { - styleMap = new HashMap<>(); - } - - public abstract Color getBackgroundColor(); - - public void setDoc( StyledDocument doc ) { - - SimpleStyle s; - - if( doc == null ) - throw new NullPointerException( "Document must not be null." ); - - for( String key : styleMap.keySet() ) { - - s = styleMap.get( key ); - if( s == null ) - throw new NullPointerException( "Style for '"+key+"' not registered." ); - - s.addStyleToDoc( doc, key ); - } - } - - private void setStyle( String key, SimpleStyle s ) { - - if( key == null ) - throw new NullPointerException( "Key must not be null." ); - - if( key.isEmpty() ) - throw new RuntimeException( "Key must not be empty." ); - - if( s == null ) - throw new NullPointerException( "Style object must not be null." ); - - styleMap.put( key, s ); - } - - public void setApplyStyle( SimpleStyle s ) { - setStyle( KEY_APPLY, s ); - } - - public void setCallStyle( SimpleStyle s ) { - setStyle( KEY_CALL, s ); - } - - public void setKeywordStyle( SimpleStyle s ) { - setStyle( KEY_KEYWORD, s ); - } - - public void setVarnameStyle( SimpleStyle s ) { - setStyle( KEY_VARNAME, s ); - } - - public void setCommentStyle( SimpleStyle s ) { - setStyle( KEY_COMMENT, s ); - } - - public void setStatStyle( SimpleStyle s ) { - setStyle( KEY_STAT, s ); - } - - public void setDataStyle( SimpleStyle s ) { - setStyle( KEY_DATA, s ); - } - - public void setTypeStyle( SimpleStyle s ) { - setStyle( KEY_TYPE, s ); - } - - public void setForeignStyle( SimpleStyle s ) { - setStyle( KEY_FOREIGN, s ); - } -} diff --git a/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/SyntaxListener.java b/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/SyntaxListener.java deleted file mode 100644 index a71dac0..0000000 --- a/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/SyntaxListener.java +++ /dev/null @@ -1,385 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.cfide.editor; - - -import javax.swing.JTextPane; -import javax.swing.text.Style; -import javax.swing.text.StyledDocument; - -import org.antlr.v4.runtime.ANTLRInputStream; -import org.antlr.v4.runtime.CommonTokenStream; -import org.antlr.v4.runtime.ParserRuleContext; -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.TokenStream; -import org.antlr.v4.runtime.misc.NotNull; -import org.antlr.v4.runtime.tree.ParseTree; -import org.antlr.v4.runtime.tree.ParseTreeWalker; -import org.antlr.v4.runtime.tree.TerminalNode; - -import de.huberlin.wbi.cuneiform.core.parser.CuneiformBaseListener; -import de.huberlin.wbi.cuneiform.core.parser.CuneiformLexer; -import de.huberlin.wbi.cuneiform.core.parser.CuneiformParser; - -public class SyntaxListener extends CuneiformBaseListener { - - private JTextPane textPane; - - public SyntaxListener( JTextPane textPane, StyleConf conf ) { - - if( textPane == null ) - throw new NullPointerException( "Text pane must not be null." ); - - if( conf == null ) - throw new NullPointerException( "Style configuration object never set." ); - - this.textPane = textPane; - conf.setDoc( getDoc() ); - - } - - public StyledDocument getDoc() { - return textPane.getStyledDocument(); - } - - public static void process( JTextPane textPane, StyleConf conf ) { - - ANTLRInputStream instream; - CuneiformLexer lexer; - TokenStream tokenStream; - CuneiformParser parser; - ParseTree tree; - SyntaxListener syntaxListener; - ParseTreeWalker walker; - - walker = new ParseTreeWalker(); - - - // parse content - instream = new ANTLRInputStream( textPane.getText() ); - - lexer = new CuneiformLexer( instream ); - lexer.removeErrorListeners(); - - tokenStream = new CommonTokenStream( lexer ); - - parser = new CuneiformParser( tokenStream ); - parser.removeErrorListeners(); - - syntaxListener = new SyntaxListener( textPane, conf ); - - tree = parser.script(); - walker.walk( syntaxListener, tree ); - } - - @Override - public void enterNilExpr( @NotNull CuneiformParser.NilExprContext ctx ) { - mark( ctx, StyleConf.KEY_KEYWORD ); - mark( ctx, StyleConf.KEY_DATA ); - } - - @Override - public void enterStat( @NotNull CuneiformParser.StatContext ctx ) { - mark( ctx, StyleConf.KEY_STAT, true ); - } - - @Override - public void enterScript( @NotNull CuneiformParser.ScriptContext ctx ) { - - StyledDocument doc; - - doc = getDoc(); - - doc.setCharacterAttributes( - 0, - doc.getLength(), - doc.getStyle( StyleConf.KEY_COMMENT ), - true ); - } - - @Override - public void enterTarget( @NotNull CuneiformParser.TargetContext ctx ) { - mark( ctx, StyleConf.KEY_APPLY ); - } - - @Override - public void enterNativeDefTask( @NotNull CuneiformParser.NativeDefTaskContext ctx ) { - mark( ctx.DEFTASK(), StyleConf.KEY_KEYWORD ); - mark( ctx.ID(), StyleConf.KEY_CALL ); - mark( ctx.ID(), StyleConf.KEY_VARNAME ); - } - - @Override - public void enterForeignDefTask( @NotNull CuneiformParser.ForeignDefTaskContext ctx ) { - mark( ctx.DEFTASK(), StyleConf.KEY_KEYWORD ); - mark( ctx.ID(), StyleConf.KEY_CALL ); - mark( ctx.ID(), StyleConf.KEY_VARNAME ); - } - - @Override - public void enterDefTaskErr1( @NotNull CuneiformParser.DefTaskErr1Context ctx ) { - mark( ctx.DEFTASK(), StyleConf.KEY_KEYWORD ); - } - - @Override - public void enterDefTaskErr2( @NotNull CuneiformParser.DefTaskErr2Context ctx ) { - mark( ctx.DEFTASK(), StyleConf.KEY_KEYWORD ); - mark( ctx.ID(), StyleConf.KEY_CALL ); - mark( ctx.ID(), StyleConf.KEY_VARNAME ); - } - - @Override - public void enterDefTaskErr3( @NotNull CuneiformParser.DefTaskErr3Context ctx ) { - mark( ctx.DEFTASK(), StyleConf.KEY_KEYWORD ); - mark( ctx.ID(), StyleConf.KEY_CALL ); - mark( ctx.ID(), StyleConf.KEY_VARNAME ); - } - - @Override - public void enterFnPrototypeErr1( @NotNull CuneiformParser.FnPrototypeErr1Context ctx ) { - mark( ctx.DEFTASK(), StyleConf.KEY_KEYWORD ); - mark( ctx.ID(), StyleConf.KEY_CALL ); - mark( ctx.ID(), StyleConf.KEY_VARNAME ); - } - - @Override - public void enterFnPrototypeErr2( @NotNull CuneiformParser.FnPrototypeErr2Context ctx ) { - mark( ctx.DEFTASK(), StyleConf.KEY_KEYWORD ); - mark( ctx.ID(), StyleConf.KEY_CALL ); - mark( ctx.ID(), StyleConf.KEY_VARNAME ); - } - - @Override - public void enterForeignBody( @NotNull CuneiformParser.ForeignBodyContext ctx ) { - mark( ctx.INLANG(), StyleConf.KEY_KEYWORD ); - mark( ctx.BODY(), StyleConf.KEY_FOREIGN ); - } - - @Override - public void enterForeignFnBodyErr2( @NotNull CuneiformParser.ForeignFnBodyErr2Context ctx ) { - mark( ctx.INLANG(), StyleConf.KEY_KEYWORD ); - } - - @Override - public void enterNameInferredType( @NotNull CuneiformParser.NameInferredTypeContext ctx ) { - mark( ctx.ID(), StyleConf.KEY_VARNAME ); - } - - @Override - public void enterNameDataType( @NotNull CuneiformParser.NameDataTypeContext ctx ) { - mark( ctx, StyleConf.KEY_TYPE ); - mark( ctx.ID( 0 ), StyleConf.KEY_VARNAME ); - } - - @Override public void enterNameDeepFnType( @NotNull CuneiformParser.NameDeepFnTypeContext ctx ) { - mark( ctx, StyleConf.KEY_TYPE ); - mark( ctx.ID(), StyleConf.KEY_VARNAME ); - } - - @Override - public void enterNamePlainFnType( @NotNull CuneiformParser.NamePlainFnTypeContext ctx ) { - mark( ctx, StyleConf.KEY_TYPE ); - mark( ctx.ID(), StyleConf.KEY_VARNAME ); - } - - @Override - public void enterIntExpr( @NotNull CuneiformParser.IntExprContext ctx ) { - mark( ctx, StyleConf.KEY_DATA ); - } - - @Override - public void enterStringExpr( @NotNull CuneiformParser.StringExprContext ctx ) { - mark( ctx, StyleConf.KEY_DATA ); - } - - @Override - public void enterApplyExpr( @NotNull CuneiformParser.ApplyExprContext ctx ) { - mark( ctx.APPLY(), StyleConf.KEY_KEYWORD ); - mark( ctx.APPLY(), StyleConf.KEY_CALL ); - } - - @Override - public void enterCallExpr( @NotNull CuneiformParser.CallExprContext ctx ) { - mark( ctx.ID(), StyleConf.KEY_CALL ); - mark( ctx.ID(), StyleConf.KEY_VARNAME ); - } - - @Override public void enterCurryExpr(@NotNull CuneiformParser.CurryExprContext ctx) { - mark( ctx.CURRY(), StyleConf.KEY_KEYWORD ); - mark( ctx.CURRY(), StyleConf.KEY_CALL ); - } - - @Override - public void enterNativeLambdaExpr( @NotNull CuneiformParser.NativeLambdaExprContext ctx ) { - mark( ctx.LAMBDA(), StyleConf.KEY_KEYWORD ); - } - - @Override - public void enterForeignLambdaExpr( @NotNull CuneiformParser.ForeignLambdaExprContext ctx ) { - mark( ctx.LAMBDA(), StyleConf.KEY_KEYWORD ); - } - - @Override - public void enterParamBind( @NotNull CuneiformParser.ParamBindContext ctx ) { - mark( ctx.ID(), StyleConf.KEY_VARNAME ); - } - - @Override - public void enterDanglingExpr( @NotNull CuneiformParser.DanglingExprContext ctx ) { - mark( ctx.TOSTACK(), StyleConf.KEY_COMMENT ); - } - - @Override - public void enterFromStackExpr( @NotNull CuneiformParser.FromStackExprContext ctx ) { - mark( ctx.FROMSTACK(), StyleConf.KEY_COMMENT ); - } - - private void mark( TerminalNode tn, String styleName ) { - - Token sym; - - if( tn == null ) - return; - - sym = tn.getSymbol(); - if( sym == null ) - return; - - mark( sym, styleName ); - } - - private void mark( Token t, String styleName ) { - - Style style; - int start, len; - StyledDocument doc; - - if( t == null ) - return; - - if( styleName == null ) - throw new NullPointerException( "Style name must not be null." ); - - if( styleName.isEmpty() ) - throw new RuntimeException( "Style name must not be empty." ); - - doc = getDoc(); - - style = doc.getStyle( styleName ); - if( style == null ) - throw new NullPointerException( "A style with name '"+styleName+"' has never been defined." ); - - start = t.getStartIndex(); - if( start < 0 ) - return; - - len = t.getStopIndex()-start+1; - if( len <= 0 ) - return; - - doc.setCharacterAttributes( - start, - len, - style, - false ); - } - - private void mark( ParserRuleContext ctx, String styleName ) { - mark( ctx, styleName, false ); - } - - private void mark( ParserRuleContext ctx, String styleName, boolean supersede ) { - - Style style; - int start, len; - StyledDocument doc; - - if( ctx == null ) - throw new NullPointerException( "Context must not be null." ); - - if( styleName == null ) - throw new NullPointerException( "Style name must not be null." ); - - if( styleName.isEmpty() ) - throw new RuntimeException( "Style name must not be empty." ); - - if( ctx.stop == null ) - return; - - if( ctx.start == null ) - return; - - doc = getDoc(); - - style = doc.getStyle( styleName ); - if( style == null ) - throw new NullPointerException( "A style with name '"+styleName+"' has never been defined." ); - - start = getStart( ctx ); - if( start < 0 ) - return; - - len = getLen( ctx ); - if( len <= 0 ) - return; - - doc.setCharacterAttributes( - start, - len, - style, - supersede ); - } - - private static int getStart( ParserRuleContext ctx ) { - - if( ctx == null ) - throw new NullPointerException( "Context must not be null." ); - - if( ctx.start == null ) - throw new NullPointerException( "Start token must not be null." ); - - return ctx.start.getStartIndex(); - } - - private static int getLen( ParserRuleContext ctx ) { - - if( ctx == null ) - throw new NullPointerException( "Context must not be null." ); - - if( ctx.stop == null ) - throw new NullPointerException( "Stop token must not be null." ); - - return ctx.stop.getStopIndex()-getStart( ctx )+1; - } - -} diff --git a/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/SyntaxPanel.java b/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/SyntaxPanel.java deleted file mode 100644 index 221e90b..0000000 --- a/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/editor/SyntaxPanel.java +++ /dev/null @@ -1,121 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.cfide.editor; - -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Cursor; -import java.awt.Font; -import java.awt.event.KeyListener; - -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTextPane; -import javax.swing.event.CaretListener; -import javax.swing.text.Document; - -public class SyntaxPanel extends JPanel { - - private static final long serialVersionUID = -385807381349136708L; - - private JTextPane editPane; - protected StyleConf sc; - - public SyntaxPanel() { - - JPanel editPanel, innerPanel; - JScrollPane scrollPane; - - - setLayout( new BorderLayout() ); - sc = new DarkStyleConf(); - - // edit pane - editPane = new JTextPane(); - editPane.setBackground( sc.getBackgroundColor() ); - editPane.setFont( new Font( "Courier", Font.PLAIN, 14 ) ); - editPane.setForeground( Color.WHITE ); - editPane.setCaretColor( Color.WHITE ); - editPane.setCursor( new Cursor( Cursor.TEXT_CURSOR ) ); - editPane.setEditable( false ); - - innerPanel = new JPanel(); - innerPanel.setLayout( new BorderLayout() ); - innerPanel.add( editPane ); - - scrollPane = new JScrollPane( innerPanel ); - scrollPane.getVerticalScrollBar().setUnitIncrement( 32 ); - scrollPane.getHorizontalScrollBar().setUnitIncrement( 32 ); - - editPanel = new JPanel(); - editPanel.setLayout( new BorderLayout() ); - editPanel.add( scrollPane, BorderLayout.CENTER ); - add( editPanel, BorderLayout.CENTER ); - - - } - - public int getCaretPosition() { - return editPane.getCaretPosition(); - } - - public Document getDocument() { - return editPane.getDocument(); - } - - public JTextPane getEditPane() { - return editPane; - } - - public String getText() { - return editPane.getText(); - } - - public void setText( String text ) { - editPane.setText( text ); - SyntaxListener.process( editPane, sc ); - } - - public void setEditable( boolean editable ) { - editPane.setEditable( editable ); - } - - @Override - public synchronized void addKeyListener( KeyListener listener ) { - editPane.addKeyListener( listener ); - } - - public void addCaretListener( CaretListener listener ) { - editPane.addCaretListener( listener ); - } -} diff --git a/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/main/Main.java b/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/main/Main.java deleted file mode 100644 index ff65983..0000000 --- a/cuneiform-addons/cuneiform-cfide/src/main/java/de/huberlin/wbi/cuneiform/cfide/main/Main.java +++ /dev/null @@ -1,108 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.cfide.main; - -import java.io.File; - -import javax.swing.JFrame; -import javax.swing.JMenuBar; -import javax.swing.SwingUtilities; -import javax.swing.WindowConstants; - -import de.huberlin.wbi.cuneiform.cfide.editor.MainPanel; - -public class Main implements Runnable { - - private String[] loadList; - - public static void main( String[] args ) { - - Main m; - - m = new Main( args ); - - SwingUtilities.invokeLater( m ); - } - - public Main( String[] args ) { - - if( args == null ) - throw new IllegalArgumentException( "Argument vector must not be null." ); - - loadList = args; - } - - - @Override - public void run() { - - JFrame frame; - JMenuBar menuBar; - MainPanel editRunPanel; - - - // prepare frame - frame = new JFrame( "Cuneiform Editor" ); - frame.setSize( 1000, 750 ); - frame.setLocation( 0, 50 ); - frame.setDefaultCloseOperation( WindowConstants.DO_NOTHING_ON_CLOSE ); - - // add main panel - editRunPanel = new MainPanel( frame ); - frame.addWindowListener( editRunPanel ); - frame.add( editRunPanel ); - - // add menu bar - menuBar = editRunPanel.getMenuBar(); - frame.setJMenuBar( menuBar ); - - // load designated files - for( String filename : loadList ) - editRunPanel.open( new File( filename ) ); - - - - - - - - - - - - - - - frame.setVisible( true ); - } -} diff --git a/cuneiform-addons/cuneiform-dax/.gitignore b/cuneiform-addons/cuneiform-dax/.gitignore deleted file mode 100644 index 6afedc5..0000000 --- a/cuneiform-addons/cuneiform-dax/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/target -/bin -/.classpath -/.settings -/.project diff --git a/cuneiform-addons/cuneiform-dax/pom.xml b/cuneiform-addons/cuneiform-dax/pom.xml deleted file mode 100644 index a889cd7..0000000 --- a/cuneiform-addons/cuneiform-dax/pom.xml +++ /dev/null @@ -1,67 +0,0 @@ - - 4.0.0 - - de.hu-berlin.wbi.cuneiform - cuneiform-addons - 2.0.4-SNAPSHOT - - cuneiform-dax - - - - de.hu-berlin.wbi.cuneiform - cuneiform-core - ${project.version} - - - - - - - org.apache.maven.plugins - maven-source-plugin - 2.4 - - - attach-sources - - jar - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.10.3 - - - attach-javadocs - - jar - - - - - - org.antlr - antlr4-maven-plugin - 4.5 - - ${basedir}/src/main/antlr - true - true - - - - - antlr4 - - - - - - - - \ No newline at end of file diff --git a/cuneiform-addons/cuneiform-dax/src/main/antlr/de/huberlin/cuneiform/libdax/parser/Dax.g4 b/cuneiform-addons/cuneiform-dax/src/main/antlr/de/huberlin/cuneiform/libdax/parser/Dax.g4 deleted file mode 100644 index 9450b9b..0000000 --- a/cuneiform-addons/cuneiform-dax/src/main/antlr/de/huberlin/cuneiform/libdax/parser/Dax.g4 +++ /dev/null @@ -1,138 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -grammar Dax; - -adag : LTAG ADAG adagProp* RTAG adagEl* LTAG SLASH ADAG RTAG ; - -adagProp : XMLNS EQ STRING # AdagPropXmlns - | XSI EQ STRING # AdagPropXsi - | SCHEMALOCATION EQ STRING # AdagPropSchemaLocation - | VERSION EQ STRING # AdagPropVersion - | COUNT EQ STRING # AdagPropCount - | INDEX EQ STRING # AdagPropIndex - | NAME EQ STRING # AdagPropName - ; - -adagEl : filename - | job - | child - ; - -filename : LTAG( FILE | FILENAME )filenameProp* SLASH RTAG ; - -filenameProp : ( FILE | NAME )EQ STRING # FilenamePropFile - | LINK EQ INPUT # FilenamePropLinkInput - | LINK EQ OUTPUT # FilenamePropLinkOutput - | LINK EQ INOUT # FilenamePropLinkInout - ; - -job : LTAG JOB jobProp* RTAG jobEl* LTAG SLASH JOB RTAG ; - -jobProp : ID EQ STRING # JobPropId - | NAME EQ STRING # JobPropName - | VERSION EQ STRING # JobPropVersion - | LEVEL EQ STRING # JobPropLevel - | DVNAME EQ STRING # JobPropDvName - | DVVERSION EQ STRING # JobPropDvVersion - | NAMESPACE EQ STRING # JobPropNamespace - ; - -jobEl : LARGUMENT argumentEl* RARGUMENT # JobElArgument - | LTAG USES jobUsesProp* SLASH RTAG # JobElUses - ; - -argumentEl : ARG # ArgumentElPlain - | filename # ArgumentElFilename - ; - -jobUsesProp : ( FILE | NAME )EQ STRING # JobUsesPropFile - | LINK EQ INPUT # JobUsesPropLinkInput - | LINK EQ OUTPUT # JobUsesPropLinkOutput - | REGISTER EQ( TRUE | FALSE ) # JobUsesPropRegister - | TRANSFER EQ( TRUE | FALSE ) # JobUsesPropTransfer - | TYPE EQ EXECUTABLE # JobUsesPropExecutable - | OPTIONAL EQ TRUE # JobUsesPropOptionalTrue - | OPTIONAL EQ FALSE # JobUsesPropOptionalFalse - ; - -child : LTAG CHILD REF EQ STRING RTAG parent+ LTAG SLASH CHILD RTAG ; - -parent : LTAG PARENT REF EQ STRING SLASH RTAG ; - -ADAG : 'adag' ; -ARGUMENT : 'argument' ; -CHILD : 'child' ; -COUNT : 'count' ; -DVNAME : 'dv-name' ; -DVVERSION : 'dv-version' ; -EQ : '=' ; -EXECUTABLE : '"executable"' ; -FALSE : '"false"' ; -FILE : 'file' ; -FILENAME : 'filename' ; -ID : 'id' ; -INDEX : 'index' ; -INOUT : '"inout"' ; -INPUT : '"input"' ; -JOB : 'job' ; -LARGUMENT : '' ; -LEVEL : 'level' ; -LINK : 'link' ; -LTAG : '<' ; -NAME : 'name' ; -NAMESPACE : 'namespace' ; -OPTIONAL : 'optional' ; -OUTPUT : '"output"' ; -PARENT : 'parent' ; -RARGUMENT : '' ; -REF : 'ref' ; -REGISTER : 'register' ; -RTAG : '>' ; -SCHEMALOCATION : 'xsi:schemaLocation' ; -SLASH : '/' ; -TRANSFER : 'transfer' ; -TRUE : '"true"' ; -TYPE : 'type' ; -USES : 'uses' ; -VERSION : 'version' ; -XMLNS : 'xmlns' ; -XSI : 'xmlns:xsi' ; - -STRING : '"' .*? '"' ; -ARG : [a-zA-Z0-9\-\.]+ ; - -METAINFO : '' -> skip ; -COMMENT : '' -> skip ; -WS : [ \t\r\n] -> skip ; - - diff --git a/cuneiform-addons/cuneiform-dax/src/main/java/de/huberlin/cuneiform/dax/repl/DaxRepl.java b/cuneiform-addons/cuneiform-dax/src/main/java/de/huberlin/cuneiform/dax/repl/DaxRepl.java deleted file mode 100644 index 183a68f..0000000 --- a/cuneiform-addons/cuneiform-dax/src/main/java/de/huberlin/cuneiform/dax/repl/DaxRepl.java +++ /dev/null @@ -1,116 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.cuneiform.dax.repl; - -import java.util.UUID; - -import org.antlr.v4.runtime.ANTLRInputStream; -import org.antlr.v4.runtime.CommonTokenStream; -import org.antlr.v4.runtime.tree.ParseTree; -import org.antlr.v4.runtime.tree.ParseTreeWalker; -import org.apache.commons.logging.Log; - -import de.huberlin.cuneiform.dax.semanticmodel.DaxSemanticModelListener; -import de.huberlin.cuneiform.libdax.parser.DaxLexer; -import de.huberlin.cuneiform.libdax.parser.DaxParser; -import de.huberlin.wbi.cuneiform.core.repl.BaseRepl; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CompoundExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.TopLevelContext; -import de.huberlin.wbi.cuneiform.core.ticketsrc.TicketSrcActor; - -public class DaxRepl extends BaseRepl { - - public DaxRepl( TicketSrcActor ticketSrc, Log statLog ) { - super( ticketSrc, statLog ); - } - - @Override - public synchronized int interpret( String input ) { - - DaxSemanticModelListener adag; - TopLevelContext tlc; - - adag = process( input ); - tlc = adag.toTopLevelContext(); - - return interpret( tlc ); - - } - - @Override - public void queryFailedPost( UUID queryId, Long ticketId, Exception e, - String script, String stdOut, String stdErr ) {} - - @Override - public void queryFinishedPost( UUID queryId, CompoundExpr result ) {} - - @Override - public void queryStartedPost( UUID runId ) {} - - public static DaxSemanticModelListener process( String input ) { - - ANTLRInputStream instream; - DaxLexer lexer; - CommonTokenStream tokenStream; - DaxParser parser; - ParseTree tree; - ParseTreeWalker walker; - DaxSemanticModelListener adag; - - walker = new ParseTreeWalker(); - - // parse original content - instream = new ANTLRInputStream( input ); - - lexer = new DaxLexer( instream ); - lexer.removeErrorListeners(); - - tokenStream = new CommonTokenStream( lexer ); - - parser = new DaxParser( tokenStream ); - parser.removeErrorListeners(); - - adag = new DaxSemanticModelListener(); - lexer.addErrorListener( adag ); - parser.addErrorListener( adag ); - - - tree = parser.adag(); - - walker.walk( adag, tree ); - - return adag; - } - - -} diff --git a/cuneiform-addons/cuneiform-dax/src/main/java/de/huberlin/cuneiform/dax/semanticmodel/DaxFilename.java b/cuneiform-addons/cuneiform-dax/src/main/java/de/huberlin/cuneiform/dax/semanticmodel/DaxFilename.java deleted file mode 100644 index fbb7ba1..0000000 --- a/cuneiform-addons/cuneiform-dax/src/main/java/de/huberlin/cuneiform/dax/semanticmodel/DaxFilename.java +++ /dev/null @@ -1,120 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.cuneiform.dax.semanticmodel; - -import de.huberlin.wbi.cuneiform.core.semanticmodel.NameExpr; - -public class DaxFilename { - - public static final int LINK_INPUT = 1; - public static final int LINK_OUTPUT = 2; - public static final int LINK_INOUT = 3; - private static final String PREFIX_LINK = "link"; - - private String file; - private Integer link; - - @Override - public boolean equals( Object obj ) { - - DaxFilename other; - - if( !( obj instanceof DaxFilename ) ) - return false; - - other = ( DaxFilename )obj; - if( file == null ) - throw new NullPointerException( - "Trying to compare filenames when file member is not set." ); - - return file.equals( other.file ); - } - - public String getFile() { - return file; - } - - @Override - public int hashCode() { - return file.hashCode(); - } - - public boolean isLinkInput() { - - if( link == null ) - throw new NullPointerException( "Link direction not set." ); - - return link == LINK_INPUT; - } - - public boolean isLinkOutput() { - - if( link == null ) - throw new NullPointerException( "Link direction not set." ); - - return link == LINK_OUTPUT; - } - - public void setFile( String file ) { - - if( file == null ) - throw new NullPointerException( "File string must not be null." ); - - if( file.isEmpty() ) - throw new RuntimeException( "File string must not be empty." ); - - this.file = file; - } - - public void setLinkInput() { - link = LINK_INPUT; - } - - public void setLinkOutput() { - link = LINK_OUTPUT; - } - - public void setLinkInout() { - link = LINK_INOUT; - } - - public NameExpr getNameExpr() { - return new NameExpr( PREFIX_LINK+file.hashCode() ); - } - - @Override - public String toString() { - return file; - } - -} diff --git a/cuneiform-addons/cuneiform-dax/src/main/java/de/huberlin/cuneiform/dax/semanticmodel/DaxJob.java b/cuneiform-addons/cuneiform-dax/src/main/java/de/huberlin/cuneiform/dax/semanticmodel/DaxJob.java deleted file mode 100644 index 9d29508..0000000 --- a/cuneiform-addons/cuneiform-dax/src/main/java/de/huberlin/cuneiform/dax/semanticmodel/DaxJob.java +++ /dev/null @@ -1,383 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.cuneiform.dax.semanticmodel; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import de.huberlin.wbi.cuneiform.core.semanticmodel.ApplyExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CfSemanticModelVisitor; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CompoundExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.DataType; -import de.huberlin.wbi.cuneiform.core.semanticmodel.ForeignLambdaExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NameExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NotDerivableException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Prototype; -import de.huberlin.wbi.cuneiform.core.semanticmodel.ReduceVar; -import de.huberlin.wbi.cuneiform.core.semanticmodel.StringExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Type; - -public class DaxJob { - - private static final String PREFIX_OUT = "out"; - private static final String PREFIX_IN = "in"; - - private String name; - private final List parentSet; - private final List childSet; - private final List argList; - private final List jobUsesList; - - public DaxJob() { - parentSet = new ArrayList<>(); - childSet = new ArrayList<>(); - argList = new ArrayList<>(); - jobUsesList = new ArrayList<>(); - } - - public void addChild( DaxJob child ) { - - if( child == null ) - throw new NullPointerException( "Child DAX job must not be null." ); - - childSet.add( child ); - } - - public void addFilenameArg( DaxFilename filename ) { - - if( filename == null ) - throw new NullPointerException( "Filename must not be null." ); - - argList.add( filename ); - } - - public void addJobUses( DaxJobUses jobUses ) { - - if( jobUses == null ) - throw new NullPointerException( "Job-Uses element object must not be null." ); - - jobUsesList.add( jobUses ); - } - - public void addParent( DaxJob parent ) { - - if( parent == null ) - throw new NullPointerException( "Parent DAX job must not be null." ); - - parentSet.add( parent ); - } - - public void addPlainArg( String arg ) { - - if( arg == null ) - throw new NullPointerException( "Argument string must not be null." ); - - if( arg.isEmpty() ) - throw new RuntimeException( "Argument string must not be empty." ); - - argList.add( arg ); - } - - public String getName() { - return name; - } - - public boolean hasName() { - return name != null; - } - - public boolean isLeaf() { - return childSet.isEmpty(); - } - - public boolean isRoot() { - return parentSet.isEmpty(); - } - - public void setName( String name ) { - - if( name == null ) { - this.name = null; - return; - } - - if( name.isEmpty() ) - throw new RuntimeException( "Name string must not be empty." ); - - this.name = name; - } - - public Set getInputJobUsesSet() { - - HashSet set; - - set = new HashSet<>(); - for( DaxJobUses jobUses : jobUsesList ) - if( jobUses.isLinkInput() ) - set.add( jobUses ); - - return set; - } - - public SetgetOutputJobUsesSet() { - - HashSet set; - - set = new HashSet<>(); - for( DaxJobUses jobUses : jobUsesList ) { - - if( isBidirectional( jobUses ) ) - continue; - - if( jobUses.isLinkOutput() ) - set.add( jobUses ); - } - - return set; - } - - public Prototype getPrototype() { - - Prototype prototype; - Type type; - int n, m; - - prototype = new Prototype(); - prototype.addParam( new NameExpr( CfSemanticModelVisitor.LABEL_TASK ) ); - - n = 1; - m = 1; - type = new DataType( DataType.LABEL_FILE ); - - for( DaxJobUses jobUses : jobUsesList ) { - - if( jobUses.isExecutable() ) - continue; - - if( jobUses.isLinkOutput() ) { - - if( isBidirectional( jobUses ) ) - continue; - - if( jobUses.isOptional() ) - prototype.addOutput( new ReduceVar( PREFIX_OUT+( n++ ), type ) ); - else - prototype.addOutput( new NameExpr( PREFIX_OUT+( n++ ), type ) ); - } - else - prototype.addParam( new NameExpr( PREFIX_IN+( m++ ), type ) ); - - } - - return prototype; - } - - public boolean isBidirectional( DaxJobUses filename ) { - - int i; - - i = 0; - for( DaxJobUses jobUses : jobUsesList ) { - - if( !jobUses.equals( filename ) ) - continue; - - i++; - } - - return i > 1; - } - - public String getReference( DaxFilename filename ) { - - int i; - - i = 1; - for( DaxJobUses jobUses : jobUsesList ) { - - if( !jobUses.isLinkInput() ) - continue; - - if( jobUses.isExecutable() ) - continue; - - if( jobUses.equals( filename ) ) - return PREFIX_IN+i; - - i++; - } - - i = 1; - for( DaxJobUses jobUses : jobUsesList ) { - - if( !jobUses.isLinkOutput() ) - continue; - - if( jobUses.equals( filename ) ) - return PREFIX_OUT+i; - - i++; - } - - throw new RuntimeException( "DAX filename '"+filename.getFile()+"' not registered in any direction." ); - } - - public ForeignLambdaExpr getLambda() { - - ForeignLambdaExpr lambda; - StringBuffer buf; - - buf = new StringBuffer(); - - for( DaxJobUses jobUses : jobUsesList ) { - - if( jobUses.isLinkInput() ) - continue; - - if( isBidirectional( jobUses ) ) - continue; - - buf.append( getReference( jobUses ) ).append( "=\"" ); - buf.append( jobUses.getFile() ).append( "\"\n" ); - } - - buf.append( name ); - for( Object arg : argList ) { - - buf.append( ' ' ); - - if( arg instanceof String ) { - buf.append( arg ); - continue; - } - - if( arg instanceof DaxFilename ) { - - buf.append( '$' ); - buf.append( getReference( ( DaxFilename )arg ) ); - continue; - } - - throw new RuntimeException( "Argument type not recognized." ); - } - - for( DaxJobUses jobUses : jobUsesList ) - if( jobUses.isLinkOutput() ) - if( jobUses.isOptional() ) - buf.append( "\nif [[ ! -f "+jobUses.getFile()+" ]]\nthen\n"+getReference( jobUses )+"=\nfi" ); - - lambda = new ForeignLambdaExpr( - getPrototype(), - ForeignLambdaExpr.LANGID_PEGASUS, - buf.toString() ); - - return lambda; - } - - public int getChannel( DaxFilename filename ) { - - int channel; - - if( filename == null ) - throw new NullPointerException( "DAX filename must not be null." ); - - channel = 1; - for( DaxJobUses jobUses : jobUsesList ) { - - if( !jobUses.isLinkOutput() ) - continue; - - if( jobUses.equals( filename ) ) - return channel; - - channel++; - } - - throw new RuntimeException( "DAX filename not registered." ); - } - - public ApplyExpr getApplyExpr( DaxFilename filename, List fileList ) { - - ApplyExpr applyExpr; - int channel, i; - Prototype prototype; - - // find out channel - channel = getChannel( filename ); - - // create new apply expression - applyExpr = new ApplyExpr( channel, false ); - - // set task expression - applyExpr.setTaskExpr( new CompoundExpr( getLambda() ) ); - - // bind parameters - i = 1; - for( DaxJobUses jobUses : jobUsesList ) { - - if( jobUses.isLinkOutput() ) - continue; - - if( jobUses.isExecutable() ) - continue; - - if( fileList.contains( jobUses ) ) - applyExpr.putAssign( - new NameExpr( PREFIX_IN+( i++ ) ), - new CompoundExpr( jobUses.getNameExpr() ) ); - else { - - try { - - prototype = applyExpr.getPrototype(); - prototype.removeParam( PREFIX_IN+i ); - prototype.addParam( new NameExpr( PREFIX_IN+i ) ); - - applyExpr.putAssign( - new NameExpr( PREFIX_IN+( i++ ) ), - new CompoundExpr( new StringExpr( jobUses.getFile() ) ) ); - } - catch( NotDerivableException e ) { - throw new RuntimeException( e ); - } - - } - } - - return applyExpr; - } - - -} diff --git a/cuneiform-addons/cuneiform-dax/src/main/java/de/huberlin/cuneiform/dax/semanticmodel/DaxJobUses.java b/cuneiform-addons/cuneiform-dax/src/main/java/de/huberlin/cuneiform/dax/semanticmodel/DaxJobUses.java deleted file mode 100644 index c336591..0000000 --- a/cuneiform-addons/cuneiform-dax/src/main/java/de/huberlin/cuneiform/dax/semanticmodel/DaxJobUses.java +++ /dev/null @@ -1,62 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.cuneiform.dax.semanticmodel; - - -public class DaxJobUses extends DaxFilename { - - private boolean executable; - private boolean optional; - - public DaxJobUses() { - executable = false; - optional = false; - } - - public boolean isExecutable() { - return executable; - } - - public boolean isOptional() { - return optional; - } - - public void setExecutable( boolean e ) { - executable = e; - } - - public void setOptional( boolean o ) { - optional = o; - } - -} diff --git a/cuneiform-addons/cuneiform-dax/src/main/java/de/huberlin/cuneiform/dax/semanticmodel/DaxSemanticModelListener.java b/cuneiform-addons/cuneiform-dax/src/main/java/de/huberlin/cuneiform/dax/semanticmodel/DaxSemanticModelListener.java deleted file mode 100644 index 2801847..0000000 --- a/cuneiform-addons/cuneiform-dax/src/main/java/de/huberlin/cuneiform/dax/semanticmodel/DaxSemanticModelListener.java +++ /dev/null @@ -1,321 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.cuneiform.dax.semanticmodel; - -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.BitSet; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.antlr.v4.runtime.ANTLRErrorListener; -import org.antlr.v4.runtime.Parser; -import org.antlr.v4.runtime.RecognitionException; -import org.antlr.v4.runtime.Recognizer; -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.atn.ATNConfigSet; -import org.antlr.v4.runtime.dfa.DFA; -import org.antlr.v4.runtime.misc.NotNull; -import org.antlr.v4.runtime.tree.TerminalNode; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import de.huberlin.cuneiform.libdax.parser.DaxBaseListener; -import de.huberlin.cuneiform.libdax.parser.DaxParser; -import de.huberlin.wbi.cuneiform.core.preprocess.ParseException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.ApplyExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CompoundExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.StringExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.TopLevelContext; - -public class DaxSemanticModelListener extends DaxBaseListener implements ANTLRErrorListener { - - private final Map idJobMap; - private final Map fileJobMap; - private final List fileList; - private final List outputList; - private DaxFilename filename; - private DaxJobUses jobUses; - private DaxJob job; - private final Log log; - - public DaxSemanticModelListener() { - idJobMap = new HashMap<>(); - fileJobMap = new HashMap<>(); - fileList = new ArrayList<>(); - outputList = new ArrayList<>(); - log = LogFactory.getLog( DaxSemanticModelListener.class ); - } - - @Override - public void enterFilename( @NotNull DaxParser.FilenameContext ctx ) { - filename = new DaxFilename(); - } - - @Override - public void exitFilename( @NotNull DaxParser.FilenameContext ctx ) { - - if( job == null ) { - - fileList.add( filename ); - if( filename.isLinkOutput() ) - outputList.add( filename ); - } - else - job.addFilenameArg( filename ); - - filename = null; - } - - @Override - public void enterFilenamePropFile( @NotNull DaxParser.FilenamePropFileContext ctx ) { - filename.setFile( getString( ctx.STRING() ) ); - } - - @Override - public void enterFilenamePropLinkInput( @NotNull DaxParser.FilenamePropLinkInputContext ctx ) { - filename.setLinkInput(); - } - - @Override - public void enterFilenamePropLinkOutput( @NotNull DaxParser.FilenamePropLinkOutputContext ctx ) { - filename.setLinkOutput(); - } - - @Override - public void enterFilenamePropLinkInout( @NotNull DaxParser.FilenamePropLinkInoutContext ctx ) { - filename.setLinkInout(); - } - - @Override - public void enterJob( @NotNull DaxParser.JobContext ctx ) { - job = new DaxJob(); - } - - @Override - public void exitJob( @NotNull DaxParser.JobContext ctx ) { - job = null; - } - - @Override - public void exitJobPropId( @NotNull DaxParser.JobPropIdContext ctx ) { - - String id; - - id = getString( ctx.STRING() ); - - idJobMap.put( id, job ); - } - - @Override - public void enterJobPropName( @NotNull DaxParser.JobPropNameContext ctx ) { - job.setName( getString( ctx.STRING() ) ); - } - - @Override - public void enterArgumentElPlain( @NotNull DaxParser.ArgumentElPlainContext ctx ) { - job.addPlainArg( ctx.ARG().getText() ); - } - - @Override - public void enterJobElUses( @NotNull DaxParser.JobElUsesContext ctx ) { - jobUses = new DaxJobUses(); - job.addJobUses( jobUses ); - } - - @Override - public void exitJobElUses( @NotNull DaxParser.JobElUsesContext ctx ) { - - if( jobUses.isLinkOutput() ) - fileJobMap.put( jobUses.getFile(), job ); - - jobUses = null; - } - - @Override - public void enterJobUsesPropFile( @NotNull DaxParser.JobUsesPropFileContext ctx ) { - jobUses.setFile( getString( ctx.STRING() ) ); - } - - @Override - public void enterJobUsesPropLinkInput( @NotNull DaxParser.JobUsesPropLinkInputContext ctx ) { - jobUses.setLinkInput(); - } - - @Override - public void enterJobUsesPropLinkOutput( @NotNull DaxParser.JobUsesPropLinkOutputContext ctx ) { - jobUses.setLinkOutput(); - } - - @Override - public void enterJobUsesPropExecutable( @NotNull DaxParser.JobUsesPropExecutableContext ctx ) { - jobUses.setExecutable( true ); - } - - @Override - public void enterJobUsesPropOptionalTrue( @NotNull DaxParser.JobUsesPropOptionalTrueContext ctx ) { - jobUses.setOptional( true ); - } - - - @Override - public void enterChild( @NotNull DaxParser.ChildContext ctx ) { - - String id; - - id = getString( ctx.STRING() ); - - job = idJobMap.get( id ); - if( job == null ) - throw new NullPointerException( "Could not retrieve referenced child job." ); - } - - @Override - public void exitChild( @NotNull DaxParser.ChildContext ctx ) { - job = null; - } - - @Override - public void enterParent( @NotNull DaxParser.ParentContext ctx ) { - - DaxJob parent; - String id; - - id = getString( ctx.STRING() ); - - parent = idJobMap.get( id ); - if( job == null ) - throw new NullPointerException( "Could not retrieve referenced parent job." ); - - parent.addChild( job ); - job.addParent( parent ); - } - - public TopLevelContext toTopLevelContext() { - - TopLevelContext tlc; - CompoundExpr ce; - ApplyExpr applyExpr; - - tlc = new TopLevelContext(); - ce = new CompoundExpr(); - tlc.addTarget( ce ); - - - // gather input contract - for( DaxFilename input : fileList ) - tlc.putAssign( input.getNameExpr(), new CompoundExpr( new StringExpr( input.getFile() ) ) ); - - // gather jobs - for( DaxJob j : idJobMap.values() ) { - - for( DaxFilename f : j.getOutputJobUsesSet() ) { - - applyExpr = j.getApplyExpr( f, fileList ); - tlc.putAssign( f.getNameExpr(), new CompoundExpr( applyExpr ) ); - } - } - - // gather output contract - for( DaxFilename output : outputList ) - ce.addSingleExpr( output.getNameExpr() ); - - return tlc; - } - - public static int getInt( TerminalNode node ) { - return Integer.valueOf( getString( node ) ); - } - - public static String getString( TerminalNode node ) { - - String s; - - s = node.getText(); - s = s.substring( 1, s.length()-1 ); - - return s; - } - - public static URL getUrl( TerminalNode node ) { - - try { - return new URL( getString( node ) ); - } - catch( MalformedURLException e ) { - throw new RuntimeException( e ); - } - } - - @Override - public void reportAmbiguity( Parser arg0, DFA arg1, int arg2, int arg3, - boolean arg4, BitSet arg5, ATNConfigSet arg6 ) { - - if( log.isDebugEnabled() ) - log.debug( "Ambiguity detected." ); - - } - - @Override - public void reportAttemptingFullContext( Parser arg0, DFA arg1, int arg2, - int arg3, BitSet arg4, ATNConfigSet arg5 ) { - - if( log.isDebugEnabled() ) - log.debug( "Attempting full context." ); - - } - - @Override - public void reportContextSensitivity( Parser arg0, DFA arg1, int arg2, - int arg3, int arg4, ATNConfigSet arg5) { - - if( log.isDebugEnabled() ) - log.debug( "Context sensitivity detected." ); - } - - @Override - public void syntaxError( Recognizer arg0, Object offendingSymbol, int line, - int charPositionInLine, String msg, RecognitionException arg5 ) { - - String near; - - near = null; - if( offendingSymbol != null ) - near = ( ( Token )offendingSymbol ).getText(); - - throw new ParseException( line, charPositionInLine, near, msg ); - } - -} diff --git a/cuneiform-addons/cuneiform-htcondorcre/.gitignore b/cuneiform-addons/cuneiform-htcondorcre/.gitignore deleted file mode 100644 index 6afedc5..0000000 --- a/cuneiform-addons/cuneiform-htcondorcre/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/target -/bin -/.classpath -/.settings -/.project diff --git a/cuneiform-addons/cuneiform-htcondorcre/InstallHTCondor.md b/cuneiform-addons/cuneiform-htcondorcre/InstallHTCondor.md deleted file mode 100644 index 85912a9..0000000 --- a/cuneiform-addons/cuneiform-htcondorcre/InstallHTCondor.md +++ /dev/null @@ -1,21 +0,0 @@ -# Setup HTCondor Master Node -This project uses the HTCondor distributed server software. If you have no access to a HTCondor pool, you need to setup your own server, starting with a master node. -Download the HTCondor binaries or source code from [the official website](http://research.cs.wisc.edu/htcondor/downloads/). -This project has been developed with version 8.2.4-281588 (Nov 12, 2014) for Unix. - -## Preparation -The [install guide](http://research.cs.wisc.edu/htcondor/manual/v8.2/3_2Installation_Start.html) suggests a few decisions before the installation. Here are the some decisions made for this project: -1. What machines should be allowed to submit jobs? - Use the default settings for testing. The default setting will allow no machine to connect and submit jobs. If you need this to be changed, referr to the install guide to see how. -2. Will HTCondor run as root or not? - Yes. -3. Will you have a Unix user named condor, and will its home directory be shared? - Yes. - - - - -## Configuration -1. Edit the global config file condor_config to include the command "ALLOW_WRITE = */*" -2. Add the command "UID_DOMAIN = $(FULL_HOSTNAME)" to ensure that the jobs are not run as user "nobody", wich would result in permission problems - -## Start HTCondor - -Run the condor_master command with root access and check with "ps -ef | egrep condor_" if it worked (check part 3.2.4 "Starting HTCondor Under Unix After Installation" in the installation guide to see what result to expect). Your server should be ready to work with cuneiform now. diff --git a/cuneiform-addons/cuneiform-htcondorcre/README.md b/cuneiform-addons/cuneiform-htcondorcre/README.md deleted file mode 100644 index 5a2dde5..0000000 --- a/cuneiform-addons/cuneiform-htcondorcre/README.md +++ /dev/null @@ -1,11 +0,0 @@ -htcondorcre -=========== - -The HTCondorCre extends the [Cuneiform](https://github.com/joergen7/cuneiform) functional language to run on HTCondor Servers (http://research.cs.wisc.edu/htcondor/). Cuneiform is a workflow specification language which makes it easy to integrate heterogeneous tools and libraries and exploit data parallelism. This extension creates another execution enviroment for the language, beside [Hi-WAY](https://github.com/marcbux/Hi-WAY), wich is used to run Cuneiform on Hadoop YARN. - - -#Attention - -The code is under active developement and not executable yet. It still lacks the ability to check the status of the job after it has been submitted to HTCondor and will not recieve the output files. - - diff --git a/cuneiform-addons/cuneiform-htcondorcre/htcondor_settings/condor_config b/cuneiform-addons/cuneiform-htcondorcre/htcondor_settings/condor_config deleted file mode 100644 index 90b78b9..0000000 --- a/cuneiform-addons/cuneiform-htcondorcre/htcondor_settings/condor_config +++ /dev/null @@ -1,100 +0,0 @@ -###################################################################### -## -## condor_config -## -## This is the global configuration file for condor. This is where -## you define where the local config file is. Any settings -## made here may potentially be overridden in the local configuration -## file. KEEP THAT IN MIND! To double-check that a variable is -## getting set from the configuration file that you expect, use -## condor_config_val -v -## -## condor_config.annotated is a more detailed sample config file -## -## Unless otherwise specified, settings that are commented out show -## the defaults that are used if you don't define a value. Settings -## that are defined here MUST BE DEFINED since they have no default -## value. -## -###################################################################### - -## Where have you installed the bin, sbin and lib condor directories? -RELEASE_DIR = /usr - -## Where is the local condor directory for each host? This is where the local config file(s), logs and -## spool/execute directories are located. this is the default for Linux and Unix systems. -LOCAL_DIR = /var - -## Where is the machine-specific local config file for each host? -LOCAL_CONFIG_FILE = /etc/condor/condor_config.local -## If your configuration is on a shared file system, then this might be a better default -#LOCAL_CONFIG_FILE = $(RELEASE_DIR)/etc/$(HOSTNAME).local -## If the local config file is not present, is it an error? (WARNING: This is a potential security issue.) -REQUIRE_LOCAL_CONFIG_FILE = false - -## The normal way to do configuration with RPMs is to read all of the -## files in a given directory that don't match a regex as configuration files. -## Config files are read in lexicographic order. -LOCAL_CONFIG_DIR = /etc/condor/config.d -#LOCAL_CONFIG_DIR_EXCLUDE_REGEXP = ^((\..*)|(.*~)|(#.*)|(.*\.rpmsave)|(.*\.rpmnew))$ - -## Use a host-based security policy. By default CONDOR_HOST and the local machine will be allowed -use SECURITY : HOST_BASED -## To expand your condor pool beyond a single host, set ALLOW_WRITE to match all of the hosts -ALLOW_ADMINISTRATOR = $(CONDOR_HOST) -ALLOW_OWNER = $(FULL_HOSTNAME), $(ALLOW_ADMINISTRATOR) -ALLOW_READ = * -ALLOW_WRITE = * -ALLOW_NEGOTIATOR = $(COLLECTOR_HOST) -ALLOW_NEGOTIATOR_SCHEDD = $(COLLECTOR_HOST), $(FLOCK_NEGOTIATOR_HOSTS) -ALLOW_WRITE_COLLECTOR = $(ALLOW_WRITE), $(FLOCK_FROM) -ALLOW_WRITE_STARTD = $(ALLOW_WRITE), $(FLOCK_FROM) -ALLOW_READ_COLLECTOR = $(ALLOW_READ), $(FLOCK_FROM) -ALLOW_READ_STARTD = $(ALLOW_READ), $(FLOCK_FROM) -ALLOW_CLIENT = * -## FLOCK_FROM defines the machines that grant access to your pool via flocking. (i.e. these machines can join your pool). -#FLOCK_FROM = -## FLOCK_TO defines the central managers that your schedd will advertise itself to (i.e. these pools will give matches to your schedd). -#FLOCK_TO = condor.cs.wisc.edu, cm.example.edu - -##-------------------------------------------------------------------- -## Values set by the debian patch script: -##-------------------------------------------------------------------- - -## For Unix machines, the path and file name of the file containing -## the pool password for password authentication. -#SEC_PASSWORD_FILE = $(LOCAL_DIR)/lib/condor/pool_password - -## Pathnames -RUN = $(LOCAL_DIR)/run/condor -LOG = $(LOCAL_DIR)/log/condor -LOCK = $(LOCAL_DIR)/lock/condor -SPOOL = $(LOCAL_DIR)/lib/condor/spool -EXECUTE = $(LOCAL_DIR)/lib/condor/execute -BIN = $(RELEASE_DIR)/bin -LIB = $(RELEASE_DIR)/lib/condor -INCLUDE = $(RELEASE_DIR)/include/condor -SBIN = $(RELEASE_DIR)/sbin -LIBEXEC = $(RELEASE_DIR)/lib/condor/libexec -SHARE = $(RELEASE_DIR)/share/condor - -PROCD_ADDRESS = $(RUN)/procd_pipe - -## What machine is your central manager? - -CONDOR_HOST = $(FULL_HOSTNAME) - -## Network domain parameters: -## Internet domain of machines sharing a common UID space. If your -## machines don't share a common UID space, set it to -## UID_DOMAIN = $(FULL_HOSTNAME) -## to specify that each machine has its own UID space. -## An administrator could set UID_DOMAIN to *. -## This will match all domains, but it is a gaping security hole. It is not recommended. - -UID_DOMAIN = $(FULL_HOSTNAME) - -## This macro determines what daemons the condor_master will start and keep its watchful eyes on. -## The list is a comma or space separated list of subsystem names - -DAEMON_LIST = COLLECTOR, MASTER, NEGOTIATOR, SCHEDD, STARTD \ No newline at end of file diff --git a/cuneiform-addons/cuneiform-htcondorcre/pom.xml b/cuneiform-addons/cuneiform-htcondorcre/pom.xml deleted file mode 100644 index a4d800d..0000000 --- a/cuneiform-addons/cuneiform-htcondorcre/pom.xml +++ /dev/null @@ -1,71 +0,0 @@ - - 4.0.0 - - de.hu-berlin.wbi.cuneiform - cuneiform-addons - 2.0.4-SNAPSHOT - - cuneiform-htcondorcre - - - - Björn Groß - grossbjo@informatik.hu-berlin.de - Humboldt-Universität zu Berlin - https://www.hu-berlin.de/ - - - Jörgen Brandt - brandjoe@informatik.hu-berlin.de - Humboldt-Universität zu Berlin - https://www.hu-berlin.de/ - - - Ulf Leser - leser@informatik.hu-berlin.de - Humboldt-Universität zu Berlin - https://www.hu-berlin.de/ - - - - - - de.hu-berlin.wbi.cuneiform - cuneiform-core - ${project.version} - - - - - - - org.apache.maven.plugins - maven-source-plugin - 2.4 - - - attach-sources - - jar - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.10.3 - - - attach-javadocs - - jar - - - - - - - - \ No newline at end of file diff --git a/cuneiform-addons/cuneiform-htcondorcre/src/main/java/de/huberlin/wbi/cuneiform/htcondorcre/CondorCreActor.java b/cuneiform-addons/cuneiform-htcondorcre/src/main/java/de/huberlin/wbi/cuneiform/htcondorcre/CondorCreActor.java deleted file mode 100644 index 60070f1..0000000 --- a/cuneiform-addons/cuneiform-htcondorcre/src/main/java/de/huberlin/wbi/cuneiform/htcondorcre/CondorCreActor.java +++ /dev/null @@ -1,591 +0,0 @@ -/******************************************************************************* - * The HTCondorCRE provides a execution base for the functional - * workflow language Cuneiform, using the HTCondor software - * (formerly known as 'Condor'). - * - * List of Contributors: - * - * Björn Groß (HU Berlin) - * Jörgen Brandt (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.htcondorcre; - -import de.huberlin.wbi.cuneiform.core.actormodel.Actor; -import de.huberlin.wbi.cuneiform.core.cre.BaseCreActor; -import de.huberlin.wbi.cuneiform.core.cre.TicketReadyMsg; -import de.huberlin.wbi.cuneiform.core.invoc.Invocation; -import de.huberlin.wbi.cuneiform.core.semanticmodel.JsonReportEntry; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NameExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Ticket; -import de.huberlin.wbi.cuneiform.core.ticketsrc.TicketFailedMsg; -import de.huberlin.wbi.cuneiform.core.ticketsrc.TicketFinishedMsg; -import de.huberlin.wbi.cuneiform.core.ticketsrc.TicketSrcActor; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.IOException; -import java.nio.charset.Charset; -import java.nio.file.*; -import java.nio.file.attribute.PosixFilePermissions; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Set; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -public class CondorCreActor extends BaseCreActor { - public static final String VERSION = "2015-03-05-4"; - - private CondorWatcher watcher; - - private static final String PATH_CENTRALREPO = "repo"; - private static final int WAIT_INTERVAL = 100; - private static final int MAX_TRIALS = 4; - - private static String verbose = null; - private static String unused = null; - - private final Path buildDir; - private final Path centralRepo; - private ExecutorService executor; - - private long maxTransferBytes = Unit.G.bytes; - - //htcondor max file transfer size, T isn't even here because transfering Terabytes of data makes no sense. - public static enum Unit{ - G(1073741824), - M(1048576), - K(1024); - - private final long bytes; - - Unit(long bytes){ - this.bytes = bytes; - } - - protected long convert(double numUnits){ - return Math.round(numUnits * this.bytes); - } - - protected static long convertToBytes(String in){ - try{ - return Long.valueOf(in); - } - catch(Exception e) { - Unit u = valueOf(in.substring(in.length() - 1).toUpperCase()); - double numUnits = Double.valueOf(in.substring(0, in.length() - 1)); - return u.convert(numUnits); - } - } - } - - public CondorCreActor(Path buildDir, String maxTransferBytes) throws Exception{ - this(buildDir); - this.maxTransferBytes = Unit.convertToBytes(maxTransferBytes); - } - - public CondorCreActor(Path buildDir) throws IOException { - // creates an actor for default jobs - if (log.isDebugEnabled()) { - log.debug("Condor CRE actor created. Version " + VERSION); - } - - if (buildDir == null) { - throw new NullPointerException("Build directory must not be null."); - } - if (!Files.exists(buildDir)) { - throw new RuntimeException("Build directory does not exist."); - } - if (!Files.isDirectory(buildDir)) { - throw new RuntimeException("Directory type expected."); - } - this.buildDir = buildDir; - centralRepo = buildDir.resolve(PATH_CENTRALREPO); - if (!Files.exists(centralRepo)) { - Files.createDirectories(centralRepo); - } - - - executor = Executors.newCachedThreadPool(); - // create a new condor watcher to watch for job status changes - watcher = new CondorWatcher(this); - - executor.submit(watcher); - executor.shutdown(); - } - - /** - * Decides whether the condor job should be submitted using the verbose - * flag. The default option is false. - * - * Verbose output - display the created job ClassAd - * - * @param value - * Adds the verbose flag if true, removes the flag if false - */ - public void setVerbose(boolean value) { - if (value) { - verbose = "-verbose"; - } else { - verbose = null; - } - } - - /** - * Sets the unused flag settings for the condor job. As a default, causes no - * warnings to be issued about user-defined macros not being used within the - * submit description file. The meaning reverses (toggles) when the - * configuration variable WARN_ON_UNUSED_SUBMIT_FILE_MACROS is set to the - * non default value of False. Printing the warnings can help identify - * spelling errors of submit description file commands. The warnings are - * sent to stderr. - * - * @param value - * True to activate the flag, false to delete the flag. - */ - public void setUnused(boolean value) { - if (value) { - unused = "-unused"; - } else { - unused = null; - } - } - - /** - * Used for status messages received from the watcher - * - * @param msg - */ - protected void processMsg(StatusMessage msg) { - - Actor sender; - TicketSrcActor ticketSrc; - Ticket ticket; - - if (log.isDebugEnabled()) { - log.debug("CondorCRE received status message with status code " - + msg.getStatusCode()); - } - - sender = msg.getSender(); - if (sender != watcher) { - throw new RuntimeException( - "Status message source different from designated watcher."); - } - - ticket = msg.getTicket(); - ticketSrc = (TicketSrcActor) msg.getOriginalSender(); - Set entry = this.gatherReport(msg); - - if (msg.getStatusCode() == StatusMessage.CODEJobTerminated) { - // create link in central data repository - Invocation invoc = Invocation.createInvocation(ticket); - Path location = buildDir.resolve(String.valueOf(invoc.getTicketId())); - - try{ - invoc.evalReport(entry); - if (log.isDebugEnabled()) { - // for testing purpose only, show the first staged file - for( NameExpr nameExpr : ticket.getOutputList()){ - log.debug("Ticket "+ticket.getTicketId()+" has at least one output file: "+nameExpr.getId()); - //only display the first file - log.debug("Total number of output files: "+ticket.getOutputList().size()); - break; - } - } - - for( String f : invoc.getStageOutList() ) { - - Path srcPath = location.resolve( f ); - Path destPath = centralRepo.resolve( f ); - - if( Files.exists( destPath ) ) - continue; - - if( log.isTraceEnabled() ) - log.trace( "Creating link from "+srcPath+" to "+destPath+"." ); - - Files.createSymbolicLink( destPath, srcPath ); - } - }catch (Exception e){ - if (log.isTraceEnabled()) { - log.trace("Something went wrong."); - } - if (log.isDebugEnabled()) { - // Show full stacktrace - log.debug(e.getMessage()); - } - ticketSrc.sendMsg(new TicketFailedMsg(this, ticket, e, null, null, null)); - } - - //notify of finished job - ticketSrc.sendMsg(new TicketFinishedMsg(this, ticket, entry)); - - return; - } - - if (msg.getStatusCode() == StatusMessage.CODEJobAborted) { - ticketSrc.sendMsg(new TicketFailedMsg(this, ticket, null, null, - null, null)); - - return; - } - - } - - @Override - protected void processMsg(TicketReadyMsg msg) { - - Actor sender; - TicketSrcActor ticketSrc; - Ticket ticket; - - sender = msg.getSender(); - if (!(sender instanceof TicketSrcActor)) { - throw new RuntimeException("Ticket source actor expected."); - } - - ticketSrc = (TicketSrcActor) sender; - - ticket = msg.getTicket(); - - if (!ticket.isNormal()) - throw new RuntimeException("Ticket " + ticket.getTicketId() - + ": Trying to evaluate ticket that is not ready."); - - if (ticket.isEvaluated()) - throw new RuntimeException( - "Ticket " - + ticket.getTicketId() - + ": Trying to evaluate ticket that has already been evaluated."); - - try { - submitJob(ticketSrc, ticket); - } catch (InterruptedException e) { - - if (log.isTraceEnabled()) - log.trace("CondorCRE has been interrupted."); - } catch (Exception e) { - Exception ex = e; - if (log.isTraceEnabled()) { - log.trace("Something went wrong."); - } - if (log.isDebugEnabled()) { - // Show full stacktrace - log.debug(ex.getMessage()); - } - - ticketSrc.sendMsg(new TicketFailedMsg(this, ticket, ex, null, null, - null)); - - } - - } - - @Override - protected void shutdown() { - executor.shutdownNow(); - } - - private Set gatherReport(StatusMessage msg) { - Set report; - JsonReportEntry entry; - Charset cs; - String line; - Invocation invoc = Invocation.createInvocation(msg.getTicket()); - Path location = buildDir.resolve(String.valueOf(invoc.getTicketId())); - Path reportFile = location.resolve(Invocation.REPORT_FILENAME); - - report = new HashSet<>(); - cs = Charset.forName( "UTF-8" ); - try (BufferedReader reader = Files.newBufferedReader(reportFile, cs)) { - - while ((line = reader.readLine()) != null) { - - line = line.trim(); - - if (line.isEmpty()) - continue; - - entry = new JsonReportEntry(line); - - // If the report comes from the hard cache then the run id - // is different from the run id of this invocation. This is - // corrected here. - entry.setRunId(invoc.getRunId()); - - report.add(entry); - } - invoc.evalReport(report); - - } catch (Exception e) { - if (log.isDebugEnabled()) { - log.debug("Exception while gathering json report data: " + e.getMessage() + "."); - } - } - - return report; - - } - - /** - * Submits a job to condor - */ - private void submitJob(TicketSrcActor ticketSrc, Ticket ticket) - throws Exception { - - if (ticketSrc == null) { - throw new NullPointerException("Ticket source must not be null."); - } - if (ticket == null) { - throw new NullPointerException("Ticket must not be null."); - } - - // Setup - Invocation invoc = Invocation.createInvocation(ticket); - Path location = buildDir.resolve(String.valueOf(invoc.getTicketId())); - Files.createDirectories( location ); - if (log.isDebugEnabled()) { - log.debug("Build directory for ticket: " + location.toString()); - } - Path submitFile = location.resolve("cfsubmitfile"); - String script = invoc.toScript(); - Charset cs = Charset.forName("UTF-8"); - Path scriptFile = invoc.getExecutablePath( location ); - Path reportFile = location.resolve(Invocation.REPORT_FILENAME); - - /** - * Log created by the condor job, used to monitor the job. Each job - * should have it's own log file for monitoring */ - java.util.Date date = new java.util.Date(); - Path cjLogFile = location.resolve((date.getTime()) + "cjlog.txt"); - - if (log.isDebugEnabled()) { - log.debug("Starting up condor_submit for ticket " - + invoc.getTicketId() + "."); - } - - // add input files - Set inputs = new HashSet<>(); - long total_size = 0; - for (String filename : invoc.getStageInList()) { - if( filename.charAt( 0 ) == '/' ){ - throw new UnsupportedOperationException( "Absolute path encountered '"+filename+"'." ); - } - Path srcPath = centralRepo.resolve( filename ); - Path destPath = location.resolve( filename ); - Path callLocation = Paths.get( System.getProperty( "user.dir" ) ); - - if( !Files.exists( srcPath ) ) { - - srcPath = callLocation.resolve( filename ); - if( log.isTraceEnabled() ) - log.trace( "Resolving relative path '"+srcPath+"'." ); - } - else - - if( log.isTraceEnabled() ) - log.trace( "Resolving path to central repository '"+srcPath+"'." ); - - if( log.isTraceEnabled() ) - log.trace( "Trying to create symbolic link from '"+srcPath+"' to '"+destPath+"'." ); - - if( !Files.exists( destPath.getParent() ) ) - Files.createDirectories( destPath.getParent() ); - - Files.createSymbolicLink( destPath, srcPath ); - //add the path to the set to insert it in the submitfile later on - inputs.add(destPath.toString()); - - Path target = srcPath; - int infLoopGuard = 10; // I think symbolic links can get self-referential - while(Files.isSymbolicLink(target) && infLoopGuard > 0){ - infLoopGuard--; - target = Files.readSymbolicLink(target); -; } - total_size += Files.size(target); - } - - try { - Files.createFile(scriptFile, - PosixFilePermissions.asFileAttribute( - PosixFilePermissions.fromString("rwxr-xrwx" ) ) ); - if (log.isDebugEnabled()) { - log.debug("Scriptfile for ticket " + invoc.getTicketId() + " has successfully been created at "+scriptFile.toString()); - } - scriptFile.toFile().setWritable(true, false); - } catch (FileAlreadyExistsException faee) { - // if file already exists do nothing - if (log.isDebugEnabled()) { - log.debug("Scriptfile for ticket " + invoc.getTicketId() + " already exists."); - } - } - - // write executable script - try (BufferedWriter writer = Files.newBufferedWriter(scriptFile, cs, - StandardOpenOption.CREATE)) { - writer.write(script); - } - - // write executable log entry - try (BufferedWriter writer = Files.newBufferedWriter(reportFile, cs, - StandardOpenOption.CREATE)) { - writer.write(ticket.getExecutableLogEntry().toString()); - writer.write('\n'); - } - - try { - Files.createFile(submitFile, PosixFilePermissions - .asFileAttribute(PosixFilePermissions - .fromString("rwxr-x---"))); - } catch (FileAlreadyExistsException faee) { - if (log.isDebugEnabled()) { - log.debug("submitFile " + submitFile.toString() - + " already exists."); - } - } - - Path condorError = location.resolve("condor_stderr.txt"); - Path condorOutput = location.resolve("condor_stdout.txt"); - try { - condorError = Files.createFile(condorError, PosixFilePermissions - .asFileAttribute(PosixFilePermissions - .fromString("rwxr-xrw-"))); - condorError.toFile().setWritable(true, false); - condorOutput = Files.createFile(condorOutput, PosixFilePermissions - .asFileAttribute(PosixFilePermissions - .fromString("rwxr-xrw-"))); - condorOutput.toFile().setWritable(true, false); - } catch (FileAlreadyExistsException faee) { - if (log.isDebugEnabled()) { - log.debug("condorError or condorOutput for "+ ticket.getTicketId() +" already exists."); - } - } - - String universe="vanilla"; - String should_transfer_files="YES"; - String when_to_transfer_output = "when_to_transfer_output = ON_EXIT \n"; - if (total_size >= maxTransferBytes){ - log.info("Total size of files to be transferred exceeds the max transfer limit of " + maxTransferBytes + ". Running in the local universe..."); - universe="local"; - should_transfer_files="NO"; - when_to_transfer_output = "\n"; - } - - try (BufferedWriter writer = Files.newBufferedWriter(submitFile, cs, - StandardOpenOption.CREATE)) { - // name of the executable script - writer.write("executable = " + scriptFile.toString()); - writer.write('\n'); - writer.write("universe = " + universe); - writer.write('\n'); - writer.write("run_as_owner = True"); - writer.write('\n'); - writer.write("log = " + cjLogFile.toString()); - writer.write('\n'); - writer.write("output = " + condorOutput.toString()); - writer.write('\n'); - writer.write("error = " + condorError.toString()); - writer.write('\n'); - //TODO: Transfer files or not? - writer.write("should_transfer_files = " + should_transfer_files + " \n"); - writer.write(when_to_transfer_output); - // inputfiles - if (!inputs.isEmpty() && total_size < maxTransferBytes) { - writer.write("transfer_input_files = "); - boolean successor = false; - for (String file : inputs) { - if(successor){ - writer.write("," ); - }else{ - successor = true; - } - writer.write(file); - } - // TODO: is the ',' causing problems? - writer.write('\n'); - } - // at last add the job to the queue - writer.write('\n'); - writer.write("initialdir = "+location.toString()); - writer.write('\n'); - writer.write("queue"); - } - // run script - // TODO: Add command line arguments here - ArrayList command = new ArrayList(); - command.add("condor_submit"); - command.add(submitFile.toString()); - if (verbose != null) { - command.add(verbose); - } - ProcessBuilder processBuilder = new ProcessBuilder( - command.toArray(new String[command.size()])); - /* - * Sets this process builder's working directory. - * Subprocesses subsequently started by this object's start() method will - * use this as their working directory. The argument may be null -- this - * means to use the working directory of the current Java process, usually the - * directory named by the system property user.dir, as the working directory - * of the child process. */ - processBuilder.directory(location.toFile()); - - Path stdOutFile = location.resolve( Invocation.STDOUT_FILENAME ); - Path stdErrFile = location.resolve( Invocation.STDERR_FILENAME ); - - processBuilder.redirectOutput( stdOutFile.toFile() ); - processBuilder.redirectError( stdErrFile.toFile() ); - - int trial = 1; - boolean suc = false; - Exception ex = null; - - do { - try { - processBuilder.start(); - suc = true; - } catch (IOException e) { - ex = e; - if (log.isWarnEnabled() && trial > 1) - log.warn("Retrying " + (++trial) + "th time." - + " Waiting " + WAIT_INTERVAL + "ms: " - + e.getMessage()); - Thread.sleep(WAIT_INTERVAL); - } - } while (suc == false && trial <= MAX_TRIALS); - - if (suc == false) { - // Couldn't find condor_submit or another error occured - end - // execution - ticketSrc.sendMsg(new TicketFailedMsg(this, ticket, ex, script, - null, null)); - return; - } - - // worked, add job to the watchlist - StatusMessage sm = new StatusMessage(this, ticket.getRunId(), - cjLogFile, ticket, ticketSrc); - watcher.processMsg(sm); - - } - -} diff --git a/cuneiform-addons/cuneiform-htcondorcre/src/main/java/de/huberlin/wbi/cuneiform/htcondorcre/CondorWatcher.java b/cuneiform-addons/cuneiform-htcondorcre/src/main/java/de/huberlin/wbi/cuneiform/htcondorcre/CondorWatcher.java deleted file mode 100644 index 5b82ef6..0000000 --- a/cuneiform-addons/cuneiform-htcondorcre/src/main/java/de/huberlin/wbi/cuneiform/htcondorcre/CondorWatcher.java +++ /dev/null @@ -1,136 +0,0 @@ -package de.huberlin.wbi.cuneiform.htcondorcre; - -import de.huberlin.wbi.cuneiform.core.actormodel.Actor; -import de.huberlin.wbi.cuneiform.core.actormodel.Message; - -import java.io.BufferedReader; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.ArrayList; - - -public class CondorWatcher extends Actor { - public static final String VERSION = "2015-02-17-1"; - - private CondorCreActor caller = null; - private ArrayList messages = new ArrayList(); - - private static final int WAIT_INTERVAL = 100; - private static final int MAX_TRIALS = 4; - - //polled in intervall condor_wait für alle angegebenen jobs und sendet nachricht - //an cre, sobald ein job finished oder failed ist - public CondorWatcher(CondorCreActor cre){ - if( log.isDebugEnabled() ){ - log.debug( "Condor Watcher actor created, version "+VERSION ); - } - caller = cre; - } - - - - @Override - protected synchronized void processMsg( Message msg ){ - if( msg instanceof StatusMessage ) { - StatusMessage sm = (StatusMessage) msg; - messages.add(sm); - - debug( "Condor Watcher received a new status message with job path "+sm.getJobpath().toString() ); - - return; - } - - throw new RuntimeException( "Message type not recognized." ); - } - - //executed before processQueue (contains processMsg) call - @Override - protected void preRec(){ - int result; - if(!messages.isEmpty()){ - //will hold all messages that are removable after the loop - ArrayList removable = new ArrayList(); - //check all messages in waitline - for(StatusMessage sm : messages){ - result = checkJobStatus(sm); - if(result == 5 || result == 2 || result == 9){ - debug("Condor Watcher found a finished or aborted job: "+sm.getJobpath()); - StatusMessage answer = new StatusMessage(this, sm.getQueryId(), sm.getJobpath(), sm.getTicket(), sm.getOriginalSender()); - answer.setStatusCode(result); - caller.processMsg(answer); - removable.add(sm); - } - } - //remove finished jobs - for(StatusMessage sm : removable){ - messages.remove(sm); - } - removable.clear(); - } - } - - @Override - protected void shutdown() { - System.exit(0); - } - - private int checkJobStatus(StatusMessage sm){ - String jobfile = sm.getJobpath().toString(); - - int trial = 1; - boolean suc = false; - Exception ex = null; - - do { - try { - FileInputStream in = new FileInputStream(jobfile); - BufferedReader br = new BufferedReader(new InputStreamReader(in)); - String tmp; - int tempId = -1; - int lastIdLine = -2; - /* The following will search for the last state id of the job. - * This assumes that only one job uses the log file, so log files - * for multiple jobs will behave unexpected. - * The last id is the current state id. - */ - while ((tmp = br.readLine()) != null) { - try{ - tempId = Integer.parseInt(tmp.substring(0, 3)); - }catch(NumberFormatException nfe){ - continue; - } - //debug(tmp.substring(0, 3) + " and integer "+tempId); - lastIdLine = tempId; - } - in.close(); - - int shellExitStatus = lastIdLine; - suc = true; - - //debug( "CondorWatcher checked job '"+jobfile+"' and got return status "+shellExitStatus+"." ); - return shellExitStatus; - } - catch( IOException e ) { - ex = e; - if( log.isWarnEnabled() && trial > 1) { - log.warn( "Retrying "+( ++trial )+"th time. Waiting "+WAIT_INTERVAL+"ms: "+ex.getMessage() ); - } - try { - Thread.sleep( WAIT_INTERVAL ); - }catch(Exception exept){ - log.warn( "Wait time canceled due to exception "+exept.getMessage() ); - } - } - } while( suc == false && trial <= MAX_TRIALS ); - - return -1; - } - - private void debug(String message){ - if( log.isDebugEnabled() ){ - log.debug( message ); - } - } - -} diff --git a/cuneiform-addons/cuneiform-htcondorcre/src/main/java/de/huberlin/wbi/cuneiform/htcondorcre/StatusMessage.java b/cuneiform-addons/cuneiform-htcondorcre/src/main/java/de/huberlin/wbi/cuneiform/htcondorcre/StatusMessage.java deleted file mode 100644 index a8285ce..0000000 --- a/cuneiform-addons/cuneiform-htcondorcre/src/main/java/de/huberlin/wbi/cuneiform/htcondorcre/StatusMessage.java +++ /dev/null @@ -1,96 +0,0 @@ -package de.huberlin.wbi.cuneiform.htcondorcre; - -import java.nio.file.Path; -import java.util.UUID; - -import de.huberlin.wbi.cuneiform.core.actormodel.Actor; -import de.huberlin.wbi.cuneiform.core.actormodel.Message; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Ticket; - -public class StatusMessage extends Message { - public static final int CODESubmit = 0; - public static final int CODEExecute = 1; - public static final int CODEExecutableError = 2; - public static final int CODECheckpointed = 3; - public static final int CODEJobEvicted = 4; - public static final int CODEJobTerminated = 5; - public static final int CODEImageSize = 6; - public static final int CODEShadowException = 7; - public static final int CODEGeneric = 8; - public static final int CODEJobAborted = 9; - public static final int CODEJobSuspended = 10; - public static final int CODEJobUnsuspended = 11; - public static final int CODEJobHeld = 12; - public static final int CODEJobReleased = 13; - public static final int CODENodeExecute = 14; - public static final int CODENodeTerminated = 15; - public static final int CODEPostScriptTerminated = 16; - public static final int CODEGlobusSubmit = 17; - public static final int CODEGlobusSubmitFailed = 18; - public static final int CODEGlobusResourceUp = 19; - public static final int CODEGlobusResourceDown = 20; - public static final int CODERemoteError = 21; - - private final Path jobpath; - private final Actor originalSender; - private final UUID queryId; - private final Ticket ticket; - private int status = 0; - - public StatusMessage(Actor sender, UUID queryId, Path jobpath, Ticket ticket, Actor originalSender) { - super(sender); - - if( jobpath == null ){ - throw new NullPointerException( "Jobpath must not be null." ); - } - - if( queryId == null ){ - throw new NullPointerException( "Run ID must not be null." ); - } - - if( ticket == null ){ - throw new NullPointerException( "Ticket must not be null." ); - } - - if( originalSender == null ){ - throw new NullPointerException( "Original sender must not be null." ); - } - - this.jobpath = jobpath; - this.queryId = queryId; - this.ticket = ticket; - this.originalSender = originalSender; - } - - public Path getJobpath(){ - return this.jobpath; - } - - public Actor getOriginalSender(){ - return this.originalSender; - } - - public int getStatusCode(){ - return this.status; - } - - public void setStatusCode(int status){ - if(status >= 0 && status <= 21){ - this.status = status; - } - } - - public UUID getQueryId() { - return this.queryId; - } - - public Ticket getTicket() { - return this.ticket; - } - - @Override - public String toString() { - return "{ statusMessage, \""+queryId+"\", "+jobpath+"\" }"; - } - -} diff --git a/cuneiform-addons/cuneiform-logview/.gitignore b/cuneiform-addons/cuneiform-logview/.gitignore deleted file mode 100644 index 6afedc5..0000000 --- a/cuneiform-addons/cuneiform-logview/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/target -/bin -/.classpath -/.settings -/.project diff --git a/cuneiform-addons/cuneiform-logview/pom.xml b/cuneiform-addons/cuneiform-logview/pom.xml deleted file mode 100644 index e4464e4..0000000 --- a/cuneiform-addons/cuneiform-logview/pom.xml +++ /dev/null @@ -1,63 +0,0 @@ - - 4.0.0 - - cuneiform-logview - - de.hu-berlin.wbi.cuneiform - cuneiform-addons - 2.0.4-SNAPSHOT - - - - UTF-8 - - - - - - de.hu-berlin.wbi.cuneiform - cuneiform-core - ${project.version} - - - - jfree - jfreechart - 1.0.13 - - - - - - - - org.apache.maven.plugins - maven-source-plugin - 2.4 - - - attach-sources - - jar - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.10.3 - - - attach-javadocs - - jar - - - - - - - - diff --git a/cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/logview/common/Visualizable.java b/cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/logview/common/Visualizable.java deleted file mode 100644 index fc984bf..0000000 --- a/cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/logview/common/Visualizable.java +++ /dev/null @@ -1,15 +0,0 @@ -package de.huberlin.wbi.cuneiform.logview.common; - -import javax.swing.JPanel; - -import de.huberlin.wbi.cuneiform.core.semanticmodel.JsonReportEntry; - -public abstract class Visualizable extends JPanel { - - private static final long serialVersionUID = -1940465202761413892L; - - public abstract void register( JsonReportEntry entry ) throws Exception; - public abstract void clear(); - public abstract void updateView(); - -} diff --git a/cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/logview/graphview/CfEdge.java b/cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/logview/graphview/CfEdge.java deleted file mode 100644 index 991ac5e..0000000 --- a/cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/logview/graphview/CfEdge.java +++ /dev/null @@ -1,53 +0,0 @@ -package de.huberlin.wbi.cuneiform.logview.graphview; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -public class CfEdge { - - private final String title; - private Long producer; - private final Set consumerIdSet; - - public CfEdge( String title ) { - this( title, null ); - } - - public CfEdge( String title, Long producer ) { - - if( title == null ) - throw new NullPointerException( "Vertex title must not be null." ); - - if( title.isEmpty() ) - throw new RuntimeException( "Vertex title must not be empty." ); - - this.title = title; - this.producer = producer; - consumerIdSet = new HashSet<>(); - } - - public void addConsumerId( long invocId ) { - consumerIdSet.add( invocId ); - } - - public boolean isConsumerIdSetEmpty() { - return consumerIdSet.isEmpty(); - } - - public Set getConsumerIdSet() { - return Collections.unmodifiableSet( consumerIdSet ); - } - - public String getTitle() { - return title; - } - - public boolean hasProducer() { - return producer != null; - } - - public Long getProducerId() { - return producer; - } -} diff --git a/cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/logview/graphview/GraphView.java b/cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/logview/graphview/GraphView.java deleted file mode 100644 index 0fdfb94..0000000 --- a/cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/logview/graphview/GraphView.java +++ /dev/null @@ -1,163 +0,0 @@ -package de.huberlin.wbi.cuneiform.logview.graphview; - -import java.awt.BorderLayout; -import java.awt.Font; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import javax.swing.JScrollPane; -import javax.swing.JTextArea; - -import de.huberlin.wbi.cuneiform.core.semanticmodel.JsonReportEntry; -import de.huberlin.wbi.cuneiform.logview.common.Visualizable; - -public class GraphView extends Visualizable { - - private static final long serialVersionUID = 9059116172334909768L; - private static final String COLOR_FILE = "darkgoldenrod"; - private static final String COLOR_INVOC = "blue"; - private static final double WIDTH_VERTEX = .01; - private static final double NODESEP = .03; - - private final Map edgeMap; - private final Map> vertexMap; - private final JTextArea dotArea; - - public GraphView() { - - edgeMap = new HashMap<>(); - vertexMap = new HashMap<>(); - - setLayout( new BorderLayout() ); - - dotArea = new JTextArea(); - dotArea.setEditable( false ); - dotArea.setFont( new Font( Font.MONOSPACED, Font.PLAIN, 11 ) ); - add( new JScrollPane( dotArea ), BorderLayout.CENTER ); - } - - @Override - public void register( JsonReportEntry entry ) throws Exception { - - long invocId; - String filename; - CfEdge edge; - String taskName; - Set vertexSet; - - if( !entry.hasInvocId() ) - return; - - invocId = entry.getInvocId(); - - taskName = entry.getTaskName(); - if( taskName == null ) - taskName = "[lambda]"; - - vertexSet = vertexMap.get( taskName ); - if( vertexSet == null ) { - vertexSet = new HashSet<>(); - vertexMap.put( taskName, vertexSet ); - } - - vertexSet.add( invocId ); - - if( entry.isKeyFileSizeStageIn() ) { - - filename = entry.getFile(); - - edge = edgeMap.get( filename ); - if( edge == null ) { - edge = new CfEdge( filename ); - edgeMap.put( filename, edge ); - } - - edge.addConsumerId( invocId ); - } - else if( entry.isKeyFileSizeStageOut() ) { - - filename = entry.getFile(); - edgeMap.put( filename, new CfEdge( filename, invocId ) ); - } - } - - @Override - public void clear() { - vertexMap.clear(); - edgeMap.clear(); - } - - @Override - public void updateView() { - - CfEdge edge; - StringBuffer buf; - int sg; - long producerId; - int hc; - - buf = new StringBuffer(); - buf.append( "digraph G {\n nodesep=" ).append( NODESEP ).append( ";\n" ); - - - // add vertices to subgraphs - sg = 0; - for( String taskName : vertexMap.keySet() ) { - - buf.append( " subgraph cluster" ).append( sg++ ).append( " {\n" ); - buf.append( " label=\"" ).append( taskName ).append( "\";\n" ); - - for( Long invocId : vertexMap.get( taskName ) ) - buf.append( " node_invoc" ).append( invocId ) - .append( " [shape=box,color=" ).append( COLOR_INVOC ) - .append( ",width=" ).append( WIDTH_VERTEX ).append( ",label=\"\"];\n" ); - - buf.append( " }\n" ); - } - - for( String filename : edgeMap.keySet() ) { - - edge = edgeMap.get( filename ); - hc = Math.abs( filename.hashCode() ); - - - if( !edge.hasProducer() ) { - - // edge is an input file - buf.append( " node_infile" ).append( hc ) - .append( " [shape=box,color=" ).append( COLOR_FILE ) - .append( ",width=" ).append( WIDTH_VERTEX ).append( ",label=\"\"];\n" ); - - for( long consumerId : edge.getConsumerIdSet() ) - - buf.append( " node_infile" ).append( hc ).append( ":s -> " ) - .append( "node_invoc" ).append( consumerId ).append( ":n;\n" ); - } - else { - - // edge has a producer - producerId = edge.getProducerId(); - - if( edge.isConsumerIdSetEmpty() ) - buf.append( " node_outfile" ).append( hc ).append( " [shape=box,color=" ).append( COLOR_FILE ) - .append( ",width=" ).append( WIDTH_VERTEX ).append( ",label=\"\"];\n" ) - .append( " node_invoc" ).append( producerId ) - .append( ":s -> node_outfile" ).append( hc ).append( ":n;\n" ); - - else - for( long consumerId : edge.getConsumerIdSet() ) - - buf.append( " node_invoc" ).append( producerId ).append( ":s -> " ) - .append( "node_invoc" ).append( consumerId ).append( ":n;\n" ); - - } - } - - buf.append( "}\n" ); - - dotArea.setText( buf.toString() ); - } - -} diff --git a/cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/logview/main/Main.java b/cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/logview/main/Main.java deleted file mode 100644 index d5eea5f..0000000 --- a/cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/logview/main/Main.java +++ /dev/null @@ -1,118 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.logview.main; - - -import java.awt.BorderLayout; -import java.io.BufferedReader; -import java.nio.charset.Charset; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; - -import javax.swing.JFrame; -import javax.swing.JSplitPane; -import javax.swing.JTabbedPane; -import javax.swing.WindowConstants; - -import de.huberlin.wbi.cuneiform.core.semanticmodel.JsonReportEntry; -import de.huberlin.wbi.cuneiform.logview.graphview.GraphView; -import de.huberlin.wbi.cuneiform.logview.parallelismview.ParallelismView; -import de.huberlin.wbi.cuneiform.taskview.TaskBrowser; -import de.huberlin.wbi.cuneiform.taskview.TaskView; - -public class Main { - - public static void main( String[] args ) throws Exception { - - - JFrame frame; - JSplitPane splitPane; - TaskBrowser taskBrowser; - TaskView taskView; - Path logPath; - String line; - JTabbedPane tabbedPane; - ParallelismView parallelismView; - JsonReportEntry entry; - GraphView graphView; - Path buildPath; - - buildPath = Paths.get( System.getProperty( "user.home" ) ).resolve( ".cuneiform" ); - if( args.length > 0 ) - buildPath = Paths.get( args[ 0 ] ); - - frame = new JFrame( "Cuneiform Log View" ); - - frame.setSize( 1024, 768 ); - frame.setDefaultCloseOperation( WindowConstants.DISPOSE_ON_CLOSE ); - frame.setLayout( new BorderLayout() ); - - - taskView = new TaskView( buildPath ); - taskBrowser = new TaskBrowser( taskView ); - splitPane = new JSplitPane( JSplitPane.HORIZONTAL_SPLIT, taskBrowser, taskView ); - splitPane.setDividerLocation( 200 ); - - parallelismView = new ParallelismView(); - - graphView = new GraphView(); - - tabbedPane = new JTabbedPane(); - tabbedPane.addTab( "Task browser", splitPane ); - tabbedPane.addTab( "Parallelism", parallelismView ); - tabbedPane.addTab( "Invocation graph", graphView ); - - frame.add( tabbedPane, BorderLayout.CENTER ); - - logPath = Paths.get( "/tmp/cuneiform-stat.log" ); - try( BufferedReader reader = Files.newBufferedReader( logPath, Charset.forName( "UTF-8" ) ) ) { - - while( ( line = reader.readLine() ) != null ) { - entry = new JsonReportEntry( line ); - taskBrowser.register( entry ); - parallelismView.register( entry ); - graphView.register( entry ); - } - - } - - taskBrowser.updateView(); - parallelismView.updateView(); - graphView.updateView(); - - - frame.setVisible( true ); - - } -} diff --git a/cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/logview/parallelismview/ParallelismView.java b/cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/logview/parallelismview/ParallelismView.java deleted file mode 100644 index 61b46e8..0000000 --- a/cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/logview/parallelismview/ParallelismView.java +++ /dev/null @@ -1,189 +0,0 @@ -package de.huberlin.wbi.cuneiform.logview.parallelismview; - -import java.awt.BorderLayout; -import java.util.HashMap; -import java.util.Map; - -import org.jfree.chart.ChartFactory; -import org.jfree.chart.ChartPanel; -import org.jfree.chart.JFreeChart; -import org.jfree.chart.plot.PlotOrientation; -import org.jfree.data.xy.DefaultTableXYDataset; -import org.jfree.data.xy.XYSeries; -import org.json.JSONException; - -import de.huberlin.wbi.cuneiform.core.semanticmodel.JsonReportEntry; -import de.huberlin.wbi.cuneiform.logview.common.Visualizable; - -public class ParallelismView extends Visualizable { - - private static final long serialVersionUID = -5167316615121741821L; - private static final int NSAMPLE = 1024; - - private long firstBegin; - private long lastBegin; - private long lastDur; - private final Map beginMap; - private final Map durMap; - private final Map taskNameMap; - - public ParallelismView() { - - beginMap = new HashMap<>(); - durMap = new HashMap<>(); - taskNameMap = new HashMap<>(); - clear(); - - setLayout( new BorderLayout() ); - } - - @Override - public void clear() { - - firstBegin = Long.MAX_VALUE; - lastDur = Long.MIN_VALUE; - - beginMap.clear(); - durMap.clear(); - taskNameMap.clear(); - } - - @Override - public void register( JsonReportEntry entry ) throws JSONException { - - long begin, dur; - long invocId; - String taskName; - - if( entry == null ) - throw new NullPointerException( "JSON report entry must not be null." ); - - if( !entry.isKeyInvocTime() ) - return; - - invocId = entry.getInvocId(); - taskName = entry.getTaskName(); - - dur = entry.getValueJsonObj().getLong( JsonReportEntry.LABEL_REALTIME ); - begin = entry.getTimestamp(); - if( begin < firstBegin ) - firstBegin = begin; - else - if( begin+dur > lastBegin+lastDur ) { - lastBegin = begin; - lastDur = dur; - } - - beginMap.put( invocId, begin ); - durMap.put( invocId, dur ); - taskNameMap.put( invocId, taskName ); - } - - @Override - public void updateView() { - - JFreeChart chart; - DefaultTableXYDataset dataset; - Map seriesMap; - String taskName; - int[] cvec; - int i; - long begin, stop, t; - long[] tvec; - long delta; - XYSeries series; - long dur; - String uname; - int udiv; - - seriesMap = new HashMap<>(); - tvec = new long[ NSAMPLE ]; - dur = lastBegin+lastDur-firstBegin; - delta = dur/( NSAMPLE-1 )+1; - - t = firstBegin; - for( i = 0; i < NSAMPLE; i++ ) { - - tvec[ i ] = t; - - for( Long invocId : beginMap.keySet() ) { - - begin = beginMap.get( invocId ); - if( begin > t ) - continue; - - stop = begin+durMap.get( invocId ); - if( stop < t ) - continue; - - taskName = taskNameMap.get( invocId ); - if( taskName == null ) - taskName = "[lambda]"; - - cvec = seriesMap.get( taskName ); - if( cvec == null ) { - cvec = new int[ NSAMPLE ]; - seriesMap.put( taskName, cvec ); - } - - cvec[ i ]++; - - } - - t += delta; - } - - udiv = 3600000*24; - uname = "d"; - - if( dur < 2*3600000*24 ) { - - udiv = 3600000; - uname = "h"; - } - - if( dur < 2*3600000 ) { - - udiv = 60000; - uname = "min"; - } - - if( dur < 2*60000 ) { - - udiv = 1000; - uname = "s"; - } - - if( dur < 2000 ) { - - udiv = 1; - uname = "ms"; - } - - dataset = new DefaultTableXYDataset(); - for( String n : seriesMap.keySet() ) { - - cvec = seriesMap.get( n ); - series = new XYSeries( n, true, false ); - for( i = 0; i < NSAMPLE; i++ ) - series.add( ( ( double )( tvec[ i ]-firstBegin ) )/udiv, cvec[ i ] ); - - dataset.addSeries( series ); - } - - chart = ChartFactory.createStackedXYAreaChart( - null, // title - "Time ["+uname+"]", // xAxisLabel - "N invocations", // yAxisLabel - dataset, // dataset - PlotOrientation.VERTICAL, // orientation - true, // legend - false, // tooltips - true // urls - ); - - add( new ChartPanel( chart ), BorderLayout.CENTER ); - - } - -} \ No newline at end of file diff --git a/cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/taskview/FileBrowser.java b/cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/taskview/FileBrowser.java deleted file mode 100644 index 8084566..0000000 --- a/cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/taskview/FileBrowser.java +++ /dev/null @@ -1,156 +0,0 @@ -package de.huberlin.wbi.cuneiform.taskview; - -import java.awt.BorderLayout; -import java.awt.Font; -import java.io.BufferedReader; -import java.io.IOException; -import java.nio.charset.Charset; -import java.nio.file.Files; -import java.nio.file.Path; - -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JSplitPane; -import javax.swing.JTextArea; -import javax.swing.JTree; -import javax.swing.ScrollPaneConstants; -import javax.swing.event.TreeSelectionEvent; -import javax.swing.event.TreeSelectionListener; -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.DefaultTreeModel; -import javax.swing.tree.TreePath; -import javax.swing.tree.TreeSelectionModel; - -public class FileBrowser extends JPanel implements TreeSelectionListener { - - private static final long serialVersionUID = 3161764896005980182L; - - private final JTree tree; - private final DefaultMutableTreeNode top; - private final DefaultTreeModel treeModel; - private final JTextArea contentArea; - private final Path buildPath; - - public FileBrowser( Path buildPath ) { - - JSplitPane splitPane; - JScrollPane scrollPane; - - if( buildPath == null ) - throw new IllegalArgumentException( "Build path must not be null." ); - - this.buildPath = buildPath; - top = new DefaultMutableTreeNode( "[Container]" ); - treeModel = new DefaultTreeModel( top ); - tree = new JTree( treeModel ); - tree.getSelectionModel().setSelectionMode( TreeSelectionModel.SINGLE_TREE_SELECTION ); - tree.addTreeSelectionListener( this ); - - - setLayout( new BorderLayout() ); - - contentArea = new JTextArea(); - contentArea.setEditable( false ); - contentArea.setFont( new Font( Font.MONOSPACED, Font.PLAIN, 11 ) ); - - scrollPane = new JScrollPane( tree ); - scrollPane.setHorizontalScrollBarPolicy( ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER ); - - splitPane = new JSplitPane( - JSplitPane.HORIZONTAL_SPLIT, - scrollPane, - new JScrollPane ( contentArea ) ); - splitPane.setDividerLocation( 300 ); - - add( splitPane, BorderLayout.CENTER ); - } - - public void blank() { - - int i; - - for( i = top.getChildCount()-1; i >= 0; i-- ) - treeModel.removeNodeFromParent( ( DefaultMutableTreeNode )top.getChildAt( i ) ); - - - - contentArea.setText( null ); - } - - public void setInvocId( long invocId ) { - - Path currentPath; - - try { - - blank(); - currentPath = buildPath.resolve( String.valueOf( invocId ) ); - ls( currentPath, top ); - tree.expandPath( new TreePath( top.getPath() ) ); - } - catch( IOException e ) { - e.printStackTrace(); - } - } - - private void ls( Path currentPath, DefaultMutableTreeNode currentNode ) throws IOException { - - DefaultMutableTreeNode node; - - for( Path path : Files.newDirectoryStream( currentPath ) ) { - - node = new FileMutableTreeNode( path ); - treeModel.insertNodeInto( - node, - currentNode, - treeModel.getChildCount( currentNode ) ); - - if( Files.isDirectory( path ) ) - ls( path, node ); - } - - } - - @Override - public void valueChanged( TreeSelectionEvent e ) { - - JTree t; - DefaultMutableTreeNode node; - int i; - StringBuffer buf; - String line; - - t = ( JTree )e.getSource(); - node = ( DefaultMutableTreeNode )t.getLastSelectedPathComponent(); - - if( node.isLeaf() ) - - if( node != top ) { - - - try( BufferedReader reader = - Files.newBufferedReader( ( ( FileMutableTreeNode )node ).getFilePath(), Charset.forName( "UTF-8" ) ) ) { - - buf = new StringBuffer(); - for( i = 0; i < 1024; i++ ) { - - line = reader.readLine(); - if( line == null ) - break; - - buf.append( line ).append( '\n' ); - } - contentArea.setText( buf.toString() ); - - return; - } - catch( IOException x ) { - contentArea.setText( "[binary]" ); - return; - } - } - - contentArea.setText( null ); - - } -} diff --git a/cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/taskview/FileMutableTreeNode.java b/cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/taskview/FileMutableTreeNode.java deleted file mode 100644 index 6a16daf..0000000 --- a/cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/taskview/FileMutableTreeNode.java +++ /dev/null @@ -1,21 +0,0 @@ -package de.huberlin.wbi.cuneiform.taskview; - -import java.nio.file.Path; - -import javax.swing.tree.DefaultMutableTreeNode; - -public class FileMutableTreeNode extends DefaultMutableTreeNode { - - private static final long serialVersionUID = -3967012888405802072L; - - private Path filePath; - - public FileMutableTreeNode( Path filePath ) { - super( filePath.getFileName() ); - this.filePath = filePath; - } - - public Path getFilePath() { - return filePath; - } -} diff --git a/cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/taskview/InvocationItem.java b/cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/taskview/InvocationItem.java deleted file mode 100644 index 5c932a7..0000000 --- a/cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/taskview/InvocationItem.java +++ /dev/null @@ -1,44 +0,0 @@ -package de.huberlin.wbi.cuneiform.taskview; - -import javax.swing.tree.DefaultMutableTreeNode; - -public class InvocationItem extends DefaultMutableTreeNode { - - private static final long serialVersionUID = -381630579332316845L; - - private final long invocId; - private final String taskName; - private String stdErr; - private String stdOut; - - public InvocationItem( long invocId, String taskName ) { - super( String.valueOf( invocId ) ); - - this.invocId = invocId; - this.taskName = taskName; - } - - public long getInvocId() { - return invocId; - } - - public String getStdOut() { - return stdOut; - } - - public String getStdErr() { - return stdErr; - } - - public String getTaskName() { - return taskName; - } - - public void setStdOut( String stdOut ) { - this.stdOut = stdOut; - } - - public void setStdErr( String stdErr ) { - this.stdErr = stdErr; - } -} diff --git a/cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/taskview/TaskBrowser.java b/cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/taskview/TaskBrowser.java deleted file mode 100644 index 55cc133..0000000 --- a/cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/taskview/TaskBrowser.java +++ /dev/null @@ -1,123 +0,0 @@ -package de.huberlin.wbi.cuneiform.taskview; - -import java.awt.BorderLayout; -import java.util.HashMap; -import java.util.Map; - -import javax.swing.JScrollPane; -import javax.swing.JTree; -import javax.swing.ScrollPaneConstants; -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.DefaultTreeModel; -import javax.swing.tree.TreePath; -import javax.swing.tree.TreeSelectionModel; - -import de.huberlin.wbi.cuneiform.core.semanticmodel.JsonReportEntry; -import de.huberlin.wbi.cuneiform.logview.common.Visualizable; - -public class TaskBrowser extends Visualizable { - - private static final long serialVersionUID = 2782394011894606586L; - - private final DefaultMutableTreeNode top; - private DefaultMutableTreeNode unnamed; - private final Map invocMap; - private final Map taskMap; - private final JTree tree; - private final DefaultTreeModel treeModel; - - public TaskBrowser( TaskView taskView ) { - - JScrollPane scrollPane; - - if( taskView == null ) - throw new NullPointerException( "Task view must not be null." ); - - invocMap = new HashMap<>(); - taskMap = new HashMap<>(); - - setLayout( new BorderLayout() ); - - top = new DefaultMutableTreeNode( "Cuneiform tasks" ); - - treeModel = new DefaultTreeModel( top ); - tree = new JTree( treeModel ); - tree.getSelectionModel().setSelectionMode( TreeSelectionModel.SINGLE_TREE_SELECTION ); - - scrollPane = new JScrollPane( tree ); - scrollPane.setHorizontalScrollBarPolicy( ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER ); - - add( scrollPane, BorderLayout.CENTER ); - - tree.addTreeSelectionListener( taskView ); - - } - - @Override - public void register( JsonReportEntry entry ) { - - long invocId; - InvocationItem invocItem; - String taskName; - DefaultMutableTreeNode taskItem; - - if( !entry.hasInvocId() ) - return; - - tree.expandPath( new TreePath( top.getPath() ) ); - - - invocId = entry.getInvocId(); - - invocItem = invocMap.get( invocId ); - if( invocItem == null ) { - - - taskName = null; - if( entry.hasTaskname() ) { - - taskName = entry.getTaskName(); - taskItem = taskMap.get( taskName ); - if( taskItem == null ) { - taskItem = new DefaultMutableTreeNode( taskName ); - taskMap.put( taskName, taskItem ); - treeModel.insertNodeInto( taskItem, top, top.getChildCount() ); - top.add( taskItem ); - } - } - else { - - if( unnamed == null ) { - unnamed = new DefaultMutableTreeNode( "[lambda]" ); - treeModel.insertNodeInto( unnamed, top, 0 ); - } - taskItem = unnamed; - } - invocItem = new InvocationItem( invocId, taskName ); - invocMap.put( invocId, invocItem ); - - treeModel.insertNodeInto( invocItem, taskItem, taskItem.getChildCount() ); - } - - if( entry.isKeyInvocStdErr() ) - invocItem.setStdErr( entry.getValueRawString() ); - - if( entry.isKeyInvocStdOut() ) - invocItem.setStdOut( entry.getValueRawString() ); - - } - - @Override - public void clear() { - - int i; - - for( i = treeModel.getChildCount( top )-1; i >= 0; i-- ) - treeModel.removeNodeFromParent( ( DefaultMutableTreeNode )top.getChildAt( i ) ); - } - - @Override - public void updateView() { - // nothing to do - } -} diff --git a/cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/taskview/TaskView.java b/cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/taskview/TaskView.java deleted file mode 100644 index 05cff4f..0000000 --- a/cuneiform-addons/cuneiform-logview/src/main/java/de/huberlin/wbi/cuneiform/taskview/TaskView.java +++ /dev/null @@ -1,109 +0,0 @@ -package de.huberlin.wbi.cuneiform.taskview; - -import java.awt.BorderLayout; -import java.awt.Font; -import java.nio.file.Path; - -import javax.swing.BoxLayout; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTabbedPane; -import javax.swing.JTextArea; -import javax.swing.JTextField; -import javax.swing.JTree; -import javax.swing.event.TreeSelectionEvent; -import javax.swing.event.TreeSelectionListener; -import javax.swing.tree.DefaultMutableTreeNode; - -public class TaskView extends JPanel implements TreeSelectionListener { - - private static final long serialVersionUID = -5409910527314838886L; - - private final JTextField invocIdField; - private final JTextField taskNameField; - private final JTextArea stdOutArea; - private final JTextArea stdErrArea; - private final FileBrowser fileBrowser; - - public TaskView( Path buildPath ) { - - JPanel infoBox; - JPanel col; - JTabbedPane tabbedPane; - Font font; - - setLayout( new BorderLayout() ); - - infoBox = new JPanel(); - infoBox.setLayout( new BorderLayout() ); - add( infoBox, BorderLayout.NORTH ); - - col = new JPanel(); - col.setLayout( new BoxLayout( col, BoxLayout.Y_AXIS ) ); - infoBox.add( col, BorderLayout.WEST ); - - col.add( new JLabel( "Invoc. ID:" ) ); - col.add( new JLabel( "Task name:" ) ); - - - col = new JPanel(); - col.setLayout( new BoxLayout( col, BoxLayout.Y_AXIS ) ); - infoBox.add( col, BorderLayout.CENTER ); - - invocIdField = new JTextField(); - invocIdField.setEditable( false ); - taskNameField = new JTextField(); - taskNameField.setEditable( false ); - - col.add( invocIdField ); - col.add( taskNameField ); - - font = new Font( Font.MONOSPACED, Font.PLAIN, 11 ); - - stdOutArea = new JTextArea(); - stdOutArea.setEditable( false ); - stdOutArea.setFont( font ); - stdErrArea = new JTextArea(); - stdErrArea.setEditable( false ); - stdErrArea.setFont( font ); - - fileBrowser = new FileBrowser( buildPath ); - - tabbedPane = new JTabbedPane(); - tabbedPane.addTab( "Stdout", new JScrollPane( stdOutArea ) ); - tabbedPane.addTab( "Stderr", new JScrollPane( stdErrArea ) ); - tabbedPane.addTab( "Container", fileBrowser ); - add( tabbedPane, BorderLayout.CENTER ); - } - - @Override - public void valueChanged( TreeSelectionEvent e ) { - - JTree tree; - DefaultMutableTreeNode node; - InvocationItem invocItem; - - tree = ( JTree )e.getSource(); - node = ( DefaultMutableTreeNode )tree.getLastSelectedPathComponent(); - - if( node instanceof InvocationItem ) { - - invocItem = ( InvocationItem )node; - invocIdField.setText( String.valueOf( invocItem.getInvocId() ) ); - taskNameField.setText( invocItem.getTaskName() ); - stdOutArea.setText( invocItem.getStdOut() ); - stdErrArea.setText( invocItem.getStdErr() ); - fileBrowser.setInvocId( invocItem.getInvocId() ); - } - else { - invocIdField.setText( null ); - taskNameField.setText( null ); - stdOutArea.setText( null ); - stdErrArea.setText( null ); - fileBrowser.blank(); - } - - } - -} diff --git a/cuneiform-addons/cuneiform-starlinger/.gitignore b/cuneiform-addons/cuneiform-starlinger/.gitignore deleted file mode 100644 index 6afedc5..0000000 --- a/cuneiform-addons/cuneiform-starlinger/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/target -/bin -/.classpath -/.settings -/.project diff --git a/cuneiform-addons/cuneiform-starlinger/pom.xml b/cuneiform-addons/cuneiform-starlinger/pom.xml deleted file mode 100644 index 26f0167..0000000 --- a/cuneiform-addons/cuneiform-starlinger/pom.xml +++ /dev/null @@ -1,49 +0,0 @@ - - 4.0.0 - - de.hu-berlin.wbi.cuneiform - cuneiform-addons - 2.0.4-SNAPSHOT - - cuneiform-starlinger - - - - de.hu-berlin.wbi.cuneiform - cuneiform-core - ${project.version} - - - - - - - org.apache.maven.plugins - maven-source-plugin - 2.4 - - - attach-sources - - jar - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.10.3 - - - attach-javadocs - - jar - - - - - - - \ No newline at end of file diff --git a/cuneiform-addons/cuneiform-starlinger/src/main/java/de/huberlin/wbi/cuneiform/starlinger/JsonMap.java b/cuneiform-addons/cuneiform-starlinger/src/main/java/de/huberlin/wbi/cuneiform/starlinger/JsonMap.java deleted file mode 100644 index 72aeb82..0000000 --- a/cuneiform-addons/cuneiform-starlinger/src/main/java/de/huberlin/wbi/cuneiform/starlinger/JsonMap.java +++ /dev/null @@ -1,85 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.starlinger; - -import java.util.HashMap; -import java.util.Map; - -public class JsonMap { - - private Map attributeMap; - - public JsonMap() { - attributeMap = new HashMap<>(); - } - - public String getAttribute( String key ) { - return attributeMap.get( key ); - } - - public void putAttribute( String key, String value ) { - - if( key == null ) - throw new NullPointerException( "Key must not be null." ); - - attributeMap.put( key, value ); - } - - @Override - public String toString() { - - StringBuffer buf; - boolean comma; - - buf = new StringBuffer(); - - buf.append( "{\n" ); - - comma = false; - for( String key : attributeMap.keySet() ) { - - if( comma ) - buf.append( ",\n" ); - comma = true; - - buf.append( '\'' ).append( key ).append( "'=>" ) - .append( attributeMap.get( key ) ); - } - - buf.append( "\n}" ); - - return buf.toString(); - } - - -} diff --git a/cuneiform-addons/cuneiform-starlinger/src/main/java/de/huberlin/wbi/cuneiform/starlinger/StarlingerEdgeSet.java b/cuneiform-addons/cuneiform-starlinger/src/main/java/de/huberlin/wbi/cuneiform/starlinger/StarlingerEdgeSet.java deleted file mode 100644 index 0f815fb..0000000 --- a/cuneiform-addons/cuneiform-starlinger/src/main/java/de/huberlin/wbi/cuneiform/starlinger/StarlingerEdgeSet.java +++ /dev/null @@ -1,97 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.starlinger; - -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -public class StarlingerEdgeSet { - - private Map> edgeMap; - - public StarlingerEdgeSet() { - - edgeMap = new HashMap<>(); - } - - public void addEdge( String src, String sink ) { - - List sinkList; - - sinkList = edgeMap.get( src ); - - if( sinkList == null ) { - - sinkList = new LinkedList<>(); - edgeMap.put( src, sinkList ); - } - - sinkList.add( sink ); - } - - @Override - public String toString() { - - JsonMap jsonMap; - StringBuffer buf; - boolean comma; - - jsonMap = new JsonMap(); - - for( String key : edgeMap.keySet() ) { - - - buf = new StringBuffer(); - - buf.append( '[' ); - - comma = false; - for( String value : edgeMap.get( key ) ) { - - if( comma ) - buf.append( ',' ); - comma = true; - - buf.append( '\'' ).append( value ).append( '\'' ); - } - - buf.append( ']' ); - - jsonMap.putAttribute( key, buf.toString() ); - } - - return jsonMap.toString(); - } -} diff --git a/cuneiform-addons/cuneiform-starlinger/src/main/java/de/huberlin/wbi/cuneiform/starlinger/StarlingerNode.java b/cuneiform-addons/cuneiform-starlinger/src/main/java/de/huberlin/wbi/cuneiform/starlinger/StarlingerNode.java deleted file mode 100644 index 33c8957..0000000 --- a/cuneiform-addons/cuneiform-starlinger/src/main/java/de/huberlin/wbi/cuneiform/starlinger/StarlingerNode.java +++ /dev/null @@ -1,141 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.starlinger; - -public class StarlingerNode extends JsonMap { - - public static final String ATT_TYPE = "type"; - public static final String ATT_ID = "id"; - public static final String ATT_NAME = "name"; - public static final String ATT_FOREIGN_SRC = "foreign-src"; - public static final String ATT_STRING_CONTENT = "string-content"; - - public static final String LABEL_NIL = "nil"; - public static final String LABEL_APPEND = "append"; - public static final String LABEL_NATIVE_LAMBDA = "\\\\{}"; - public static final String LABEL_CURRY = "curry"; - public static final String LABEL_FOREIGN_LAMBDA = "\\\\*{}*"; - public static final String LABEL_COND = "cond"; - public static final String LABEL_APPLY = "apply"; - - public static final String TYPE_APPEND = "Append"; - public static final String TYPE_NIL = "Nil"; - public static final String TYPE_STRING = "StringExpr"; - public static final String TYPE_APPLY = "ApplyExpr"; - public static final String TYPE_CURRY = "CurryExpr"; - public static final String TYPE_FOREIGN_LAMBDA = "ForeignLambdaExpr"; - public static final String TYPE_NATIVE_LAMBDA = "NativeLambdaExpr"; - public static final String TYPE_COND = "CondExpr"; - public static final String TYPE_NAME = "NameExpr"; - - public static StarlingerNode createAppendNode( String id ) { - return new StarlingerNode( id, LABEL_APPEND, TYPE_APPEND ); - } - - public static StarlingerNode createNilNode( String id ) { - return new StarlingerNode( id, LABEL_NIL, TYPE_NIL ); - } - - public static StarlingerNode createStringNode( String id, String label ) { - - StarlingerNode node; - - node = new StarlingerNode( id, label, TYPE_STRING ); - node.setStringContent( label ); - - return node; - } - - public static StarlingerNode createCurryNode( String id ) { - return new StarlingerNode( id, LABEL_CURRY, TYPE_CURRY ); - } - - public static StarlingerNode createForeignLambdaNode( String id ) { - return new StarlingerNode( id, LABEL_FOREIGN_LAMBDA, TYPE_FOREIGN_LAMBDA ); - } - - public static StarlingerNode createNativeLambdaNode( String id ) { - return new StarlingerNode( id, LABEL_NATIVE_LAMBDA, TYPE_NATIVE_LAMBDA ); - } - - public static StarlingerNode createCondNode( String id ) { - return new StarlingerNode( id, LABEL_COND, TYPE_COND ); - } - - public static StarlingerNode createApplyNode( String id ) { - return new StarlingerNode( id, LABEL_APPLY, TYPE_APPLY ); - } - - public static StarlingerNode createApplyNode( String id, String label ) { - return new StarlingerNode( id, label, TYPE_APPLY ); - } - - public static StarlingerNode createNameNode( String id, String label ) { - return new StarlingerNode( id, label, TYPE_NAME ); - } - - - - - public StarlingerNode( String id, String label, String type ) { - setId( id ); - setLabel( label ); - setType( type ); - } - - public String getId() { - - String s; - - s = getAttribute( ATT_ID ); - - return s.substring( 1, s.length()-1 ); - } - - public void setType( String type ) { - putAttribute( ATT_TYPE, "'"+type+"'" ); - } - - public void setLabel( String label ) { - putAttribute( ATT_NAME, "'"+label+"'" ); - } - - public void setId( String id ) { - putAttribute( ATT_ID, "'"+id+"'" ); - } - - public void setStringContent( String content ) { - putAttribute( ATT_STRING_CONTENT, "'"+content+"'" ); - } - -} diff --git a/cuneiform-addons/cuneiform-starlinger/src/main/java/de/huberlin/wbi/cuneiform/starlinger/StarlingerNodeSet.java b/cuneiform-addons/cuneiform-starlinger/src/main/java/de/huberlin/wbi/cuneiform/starlinger/StarlingerNodeSet.java deleted file mode 100644 index 1d9a9b9..0000000 --- a/cuneiform-addons/cuneiform-starlinger/src/main/java/de/huberlin/wbi/cuneiform/starlinger/StarlingerNodeSet.java +++ /dev/null @@ -1,40 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.starlinger; - -public class StarlingerNodeSet extends JsonMap { - - public void addNode( StarlingerNode node ) { - putAttribute( node.getId(), node.toString() ); - } -} diff --git a/cuneiform-addons/cuneiform-starlinger/src/main/java/de/huberlin/wbi/cuneiform/starlinger/StarlingerNodeVisitor.java b/cuneiform-addons/cuneiform-starlinger/src/main/java/de/huberlin/wbi/cuneiform/starlinger/StarlingerNodeVisitor.java deleted file mode 100644 index 2834c71..0000000 --- a/cuneiform-addons/cuneiform-starlinger/src/main/java/de/huberlin/wbi/cuneiform/starlinger/StarlingerNodeVisitor.java +++ /dev/null @@ -1,372 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.starlinger; - -import java.util.HashMap; -import java.util.Map; - -import de.huberlin.wbi.cuneiform.core.semanticmodel.ApplyExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Block; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CompoundExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CondExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CorrelParam; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CurryExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.DataType; -import de.huberlin.wbi.cuneiform.core.semanticmodel.DrawParam; -import de.huberlin.wbi.cuneiform.core.semanticmodel.ForeignLambdaExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.HasFailedException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.LambdaType; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NameExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NativeLambdaExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CfNode; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NodeVisitor; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NotBoundException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Prototype; -import de.huberlin.wbi.cuneiform.core.semanticmodel.QualifiedTicket; -import de.huberlin.wbi.cuneiform.core.semanticmodel.ReduceVar; -import de.huberlin.wbi.cuneiform.core.semanticmodel.SingleExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.StringExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.TopLevelContext; - -public class StarlingerNodeVisitor extends StarlingerWorkflow implements NodeVisitor { - - private Map exprMap; - private int nextNodeId; - - public StarlingerNodeVisitor() { - exprMap = new HashMap<>(); - nextNodeId = 0; - } - - @Override - public String accept(StringExpr stringExpr) { - - String nodeId; - StarlingerNode starlingerNode; - - if( exprMap.containsKey( stringExpr ) ) - return exprMap.get( stringExpr ); - - nodeId = popNodeId(); - - starlingerNode = StarlingerNode.createStringNode( nodeId, stringExpr.getContent() ); - - addNode( starlingerNode ); - - exprMap.put( stringExpr, nodeId ); - - return nodeId; - } - - @Override - public String accept( QualifiedTicket qualifiedTicket ) { - throw new RuntimeException( "invalid qualified ticket." ); - } - - @Override - public String accept(NativeLambdaExpr nativeLambdaExpr) { - - String nodeId; - StarlingerNode starlingerNode; - - if( exprMap.containsKey( nativeLambdaExpr ) ) - return exprMap.get( nativeLambdaExpr ); - - nodeId = popNodeId(); - - starlingerNode = StarlingerNode.createNativeLambdaNode( nodeId ); - addNode( starlingerNode ); - - exprMap.put( nativeLambdaExpr, nodeId ); - - return nodeId; - } - - @Override - public String accept(NameExpr nameExpr) { - - String nodeId; - StarlingerNode starlingerNode; - - if( exprMap.containsKey( nameExpr ) ) - return exprMap.get( nameExpr ); - - nodeId = popNodeId(); - - starlingerNode = StarlingerNode.createNameNode( nodeId, nameExpr.getId() ); - - addNode( starlingerNode ); - - exprMap.put( nameExpr, nodeId ); - - return nodeId; - } - - @Override - public String accept( LambdaType lambdaType ) { - throw new RuntimeException( "Not an expression." ); - } - - @Override - public String accept(DrawParam drawParam) { - throw new RuntimeException( "Not an expression." ); - } - - @Override - public String accept(DataType dataType) { - throw new RuntimeException( "Not an expression." ); - } - - @Override - public String accept(CondExpr condExpr) throws HasFailedException, NotBoundException { - - String nodeId; - String childId; - StarlingerNode starlingerNode; - - if( exprMap.containsKey( condExpr ) ) - return exprMap.get( condExpr ); - - nodeId = popNodeId(); - - starlingerNode = StarlingerNode.createCondNode( nodeId ); - - addNode( starlingerNode ); - - childId = condExpr.getIfExpr().visit( this ); - addEdge( childId, nodeId ); - - childId = condExpr.getThenExpr().visit( this ); - addEdge( childId, nodeId ); - - childId = condExpr.getElseExpr().visit( this ); - addEdge( childId, nodeId ); - - exprMap.put( condExpr, nodeId ); - - return nodeId; - } - - @Override - public String accept(Block block) { - throw new RuntimeException( "Not an expression." ); - } - - @Override - public String accept(ApplyExpr applyExpr) throws HasFailedException, NotBoundException { - String taskNodeId, refNodeId, taskName; - SingleExpr se; - StarlingerNode starlingerNode; - - if( exprMap.containsKey( applyExpr ) ) - return exprMap.get( applyExpr ); - - taskNodeId = popNodeId(); - - if( applyExpr.getTaskExpr().getNumSingleExpr() == 0 ) - throw new RuntimeException( "Task expression must not be nil." ); - - se = applyExpr.getTaskExpr().getSingleExpr( 0 ); - - if( applyExpr.getTaskExpr().getNumSingleExpr() != 1 || se instanceof CurryExpr ) { - - refNodeId = applyExpr.getTaskExpr().visit( this ); - starlingerNode = StarlingerNode.createApplyNode( taskNodeId ); - - addNode( starlingerNode ); - addEdge( refNodeId, taskNodeId ); - } - else { - - if( se instanceof NativeLambdaExpr ) - taskName = StarlingerNode.LABEL_NATIVE_LAMBDA; - else if( se instanceof ForeignLambdaExpr ) - taskName = StarlingerNode.LABEL_FOREIGN_LAMBDA; - else if( se instanceof NameExpr ) - taskName = ( ( NameExpr)se ).getId(); - else - throw new RuntimeException( "Task type not recognized." ); - - starlingerNode = StarlingerNode.createApplyNode( taskNodeId, taskName ); - - addNode( starlingerNode ); - } - - - for( NameExpr nameExpr : applyExpr.getNameSet() ) - try { - - refNodeId = applyExpr.getExpr( nameExpr ).visit( this ); - - addEdge( refNodeId, taskNodeId ); - } - catch( NotBoundException e ) { - // cannot happen, because we only ask for what is there - throw new RuntimeException( e.getMessage() ); - } - - exprMap.put( applyExpr, taskNodeId ); - - return taskNodeId; - } - - @Override - public String accept(CompoundExpr compoundExpr) throws HasFailedException, NotBoundException { - - String nodeId; - int n; - StarlingerNode starlingerNode; - - if( exprMap.containsKey( compoundExpr ) ) - return exprMap.get( compoundExpr ); - - n = compoundExpr.getNumSingleExpr(); - - if( n == 0 ) { - - nodeId = popNodeId(); - - starlingerNode = StarlingerNode.createNilNode( nodeId ); - - addNode( starlingerNode ); - exprMap.put( compoundExpr, nodeId ); - - return nodeId; - } - - if( n > 1 ) { - - nodeId = popNodeId(); - - - starlingerNode = StarlingerNode.createAppendNode( nodeId ); - addNode( starlingerNode ); - - - for( SingleExpr se : compoundExpr.getSingleExprList() ) - addEdge( se.visit( this ), nodeId ); - - exprMap.put( compoundExpr, nodeId ); - - return nodeId; - } - - - return compoundExpr.getSingleExpr( 0 ).visit( this ); - } - - @Override - public String accept(CorrelParam correlParam) { - throw new RuntimeException( "Not an expression." ); - } - - @Override - public String accept(ForeignLambdaExpr foreignLambdaExpr) { - - String nodeId; - StarlingerNode starlingerNode; - - if( exprMap.containsKey( foreignLambdaExpr ) ) - return exprMap.get( foreignLambdaExpr ); - - nodeId = popNodeId(); - - starlingerNode = StarlingerNode.createForeignLambdaNode( nodeId ); - - addNode( starlingerNode ); - - exprMap.put( foreignLambdaExpr, nodeId ); - - return nodeId; - } - - @Override - public String accept(CurryExpr curryExpr) throws HasFailedException, NotBoundException { - String taskNodeId, refNodeId; - StarlingerNode starlingerNode; - - if( exprMap.containsKey( curryExpr ) ) - return exprMap.get( curryExpr ); - - taskNodeId = popNodeId(); - - - refNodeId = curryExpr.getTaskExpr().visit( this ); - starlingerNode = StarlingerNode.createCurryNode( taskNodeId ); - - addNode( starlingerNode ); - addEdge( refNodeId, taskNodeId ); - - - for( NameExpr nameExpr : curryExpr.getNameSet() ) - try { - - refNodeId = curryExpr.getExpr( nameExpr ).visit( this ); - - addEdge( refNodeId, taskNodeId ); - } - catch( NotBoundException e ) { - // cannot happen, because we only ask for what is there - throw new RuntimeException( e.getMessage() ); - } - - exprMap.put( curryExpr, taskNodeId ); - - return taskNodeId; - - } - - @Override - public String accept(Prototype prototype) { - throw new RuntimeException( "Not an expression." ); - } - - @Override - public String accept(ReduceVar reduceVar) { - throw new RuntimeException( "Not an expression." ); - } - - @Override - public String accept( TopLevelContext tlc ) throws HasFailedException, NotBoundException { - - for( CompoundExpr ce : tlc.getTargetList() ) - ce.visit( this ); - - return null; - } - - private String popNodeId() { - return "node"+( nextNodeId++ ); - } - -} diff --git a/cuneiform-addons/cuneiform-starlinger/src/main/java/de/huberlin/wbi/cuneiform/starlinger/StarlingerWorkflow.java b/cuneiform-addons/cuneiform-starlinger/src/main/java/de/huberlin/wbi/cuneiform/starlinger/StarlingerWorkflow.java deleted file mode 100644 index 20ca4ed..0000000 --- a/cuneiform-addons/cuneiform-starlinger/src/main/java/de/huberlin/wbi/cuneiform/starlinger/StarlingerWorkflow.java +++ /dev/null @@ -1,90 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.starlinger; - -public class StarlingerWorkflow extends JsonMap { - - private static final String LABEL_FILENAME = "filename"; - private static final String LABEL_RESOURCE_URI = "resource_uri"; - private static final String LABEL_TITLE = "title"; - private static final String LABEL_FILEPATH = "filepath"; - private static final String LABEL_DESCRIPTION = "description"; - private static final String LABEL_NODES = "nodes"; - private static final String LABEL_EDGES = "edges"; - - private StarlingerNodeSet nodeSet; - private StarlingerEdgeSet edgeSet; - - public StarlingerWorkflow() { - nodeSet = new StarlingerNodeSet(); - edgeSet = new StarlingerEdgeSet(); - } - - public void addEdge( String src, String sink ) { - edgeSet.addEdge( src, sink ); - } - - public void addNode( StarlingerNode node ) { - nodeSet.addNode( node ); - } - - public void setFilename( String filename ) { - putAttribute( LABEL_FILENAME, "'"+filename+"'" ); - } - - public void setResourceUri( String resourceUri ) { - putAttribute( LABEL_RESOURCE_URI, "'"+resourceUri+"'" ); - } - - public void setTitle( String title ) { - putAttribute( LABEL_TITLE, "'"+title+"'" ); - } - - public void setFilepath( String filepath ) { - putAttribute( LABEL_FILEPATH, "'"+filepath+"'" ); - } - - public void setDescription( String description ) { - putAttribute( LABEL_DESCRIPTION, "'"+description+"'" ); - } - - @Override - public String toString() { - - putAttribute( LABEL_EDGES, edgeSet.toString() ); - putAttribute( LABEL_NODES, nodeSet.toString() ); - - return super.toString(); - } - -} diff --git a/cuneiform-addons/pom.xml b/cuneiform-addons/pom.xml deleted file mode 100644 index 1d05a7b..0000000 --- a/cuneiform-addons/pom.xml +++ /dev/null @@ -1,17 +0,0 @@ - - 4.0.0 - - de.hu-berlin.wbi.cuneiform - cuneiform - 2.0.4-SNAPSHOT - - cuneiform-addons - pom - - cuneiform-starlinger - cuneiform-dax - cuneiform-cfide - cuneiform-logview - cuneiform-htcondorcre - - \ No newline at end of file diff --git a/cuneiform-cmdline/.gitignore b/cuneiform-cmdline/.gitignore deleted file mode 100644 index 6afedc5..0000000 --- a/cuneiform-cmdline/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/target -/bin -/.classpath -/.settings -/.project diff --git a/cuneiform-cmdline/pom.xml b/cuneiform-cmdline/pom.xml deleted file mode 100644 index 147a69c..0000000 --- a/cuneiform-cmdline/pom.xml +++ /dev/null @@ -1,70 +0,0 @@ - - 4.0.0 - - de.hu-berlin.wbi.cuneiform - cuneiform - 2.0.4-SNAPSHOT - - cuneiform-cmdline - cuneiform-cmdline - - - - - - de.hu-berlin.wbi.cuneiform - cuneiform-core - ${project.version} - - - - de.hu-berlin.wbi.cuneiform - cuneiform-dax - ${project.version} - - - - de.hu-berlin.wbi.cuneiform - cuneiform-htcondorcre - ${project.version} - - - - commons-cli - commons-cli - 1.2 - - - - - - - org.apache.maven.plugins - maven-source-plugin - 2.4 - - - attach-sources - - jar - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.10.3 - - - attach-javadocs - - jar - - - - - - - \ No newline at end of file diff --git a/cuneiform-cmdline/src/main/java/de/huberlin/wbi/cuneiform/cmdline/main/JsonSummary.java b/cuneiform-cmdline/src/main/java/de/huberlin/wbi/cuneiform/cmdline/main/JsonSummary.java deleted file mode 100644 index 98c904c..0000000 --- a/cuneiform-cmdline/src/main/java/de/huberlin/wbi/cuneiform/cmdline/main/JsonSummary.java +++ /dev/null @@ -1,90 +0,0 @@ -package de.huberlin.wbi.cuneiform.cmdline.main; - -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -import de.huberlin.wbi.cuneiform.core.cre.LocalCreActor; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CompoundExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NotDerivableException; - -public class JsonSummary { - - private final UUID runId; - private final Path buildDir; - private final List output; - - public JsonSummary( UUID runId, Path buildDir, CompoundExpr output ) - throws NotDerivableException { - - if( runId == null ) - throw new NullPointerException( "Run Id must not be null." ); - - if( buildDir == null ) - throw new NullPointerException( "Build directory must not be null." ); - - if( output == null ) - this.output = new ArrayList<>(); - else - this.output = output.normalize(); - - this.runId = runId; - this.buildDir = buildDir; - } - - @Override - public String toString() { - - StringBuffer buf; - String s; - int i, n; - boolean res, comma; - Path candidate; - - buf = new StringBuffer(); - - buf.append( "{\n" ); - - buf.append( " \"runId\":\"" ).append( runId ).append( "\",\n" ); - - buf.append( " \"output\":[" ); - res = false; - if( !output.isEmpty() ) { - - n = output.size(); - comma = false; - - for( i = 0; i < n; i++ ) { - - if( comma ) - buf.append( ", " ); - comma = true; - - s = output.get( i ); - candidate = buildDir.resolve( LocalCreActor.PATH_CENTRALREPO ).resolve( s ); - - if( Files.exists( candidate ) ) { - s = candidate.toAbsolutePath().toString(); - res = true; - } - - buf.append( '"' ).append( s ).append( '"' ); - } - } - buf.append( "],\n" ); - - buf.append( " \"type\":\"" ); - if( res ) - buf.append( "File" ); - else - buf.append( "String" ); - buf.append( "\"\n" ); - - - buf.append( "}\n" ); - - return buf.toString(); - } -} diff --git a/cuneiform-cmdline/src/main/java/de/huberlin/wbi/cuneiform/cmdline/main/Main.java b/cuneiform-cmdline/src/main/java/de/huberlin/wbi/cuneiform/cmdline/main/Main.java deleted file mode 100644 index c907523..0000000 --- a/cuneiform-cmdline/src/main/java/de/huberlin/wbi/cuneiform/cmdline/main/Main.java +++ /dev/null @@ -1,356 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.cmdline.main; - -import de.huberlin.cuneiform.dax.repl.DaxRepl; -import de.huberlin.wbi.cuneiform.core.actormodel.Actor; -import de.huberlin.wbi.cuneiform.core.cre.BaseCreActor; -import de.huberlin.wbi.cuneiform.core.cre.LocalCreActor; -import de.huberlin.wbi.cuneiform.core.cre.LocalThread; -import de.huberlin.wbi.cuneiform.core.invoc.Invocation; -import de.huberlin.wbi.cuneiform.core.repl.BaseRepl; -import de.huberlin.wbi.cuneiform.core.repl.CmdlineRepl; -import de.huberlin.wbi.cuneiform.core.repl.InteractiveRepl; -import de.huberlin.wbi.cuneiform.core.semanticmodel.ForeignLambdaExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NotDerivableException; -import de.huberlin.wbi.cuneiform.core.ticketsrc.TicketSrcActor; -import de.huberlin.wbi.cuneiform.htcondorcre.CondorCreActor; -import org.apache.commons.cli.*; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.io.*; -import java.nio.charset.Charset; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -public class Main { - - private static final String FORMAT_CF = "cf"; - private static final String FORMAT_DAX = "dax"; - private static final String PLATFORM_LOCAL = "local"; - private static final String PLATFORM_HTCONDOR = "htcondor"; - - - public static final int MAX_TRANSFER = 1073741824; // no more than 1G of total transfer - - private static String platform; - private static String format; - private static Path[] inputFileVector; - - - public static void main( String[] args ) throws IOException, ParseException, InterruptedException, NotDerivableException { - - CommandLine cmd; - Options opt; - BaseRepl repl; - BaseCreActor cre; - Path sandbox; - ExecutorService executor; - TicketSrcActor ticketSrc; - JsonSummary summary; - Path summaryPath; - Log statLog; - int nthread; - Path workDir; - - statLog = LogFactory.getLog( "statLogger" ); - - executor = Executors.newCachedThreadPool(); - try { - - opt = getOptions(); - cmd = parse( args, opt ); - config( cmd ); - - if( cmd.hasOption( 'h' ) ) { - - System.out.println( - "CUNEIFORM - A Functional Workflow Language\nversion " - +BaseRepl.LABEL_VERSION+" build "+BaseRepl.LABEL_BUILD ); - new HelpFormatter().printHelp( - "java -jar cuneiform.jar [OPTION]*", opt ); - - return; - } - - if( cmd.hasOption( 'r' ) ) - Invocation.putLibPath( ForeignLambdaExpr.LANGID_R, cmd.getOptionValue( 'r' ) ); - - if( cmd.hasOption( 'y' ) ) - Invocation.putLibPath( ForeignLambdaExpr.LANGID_PYTHON, cmd.getOptionValue( 'y' ) ); - - if( cmd.hasOption( 'l' ) ) - sandbox = Paths.get( cmd.getOptionValue( "l" ) ); - else - sandbox = Paths.get( System.getProperty( "user.home" ) ).resolve( ".cuneiform" ); - - sandbox = sandbox.toAbsolutePath(); - - if( cmd.hasOption( 'c' ) ) - LocalThread.deleteIfExists( sandbox ); - - if( cmd.hasOption( 't' ) ) - nthread = Integer.valueOf( cmd.getOptionValue( 't' ) ); - else - nthread = Runtime.getRuntime().availableProcessors(); - - if( cmd.hasOption( 'w' ) ) - workDir = Paths.get( cmd.getOptionValue( 'w' ) ); - else - workDir = Paths.get( System.getProperty( "user.dir" ) ); - - workDir = workDir.toAbsolutePath(); - - - - - switch( platform ) { - - case PLATFORM_LOCAL : - - if( !Files.exists( sandbox ) ) - Files.createDirectories( sandbox ); - - - cre = new LocalCreActor( sandbox, workDir, nthread ); - break; - - case PLATFORM_HTCONDOR : - - if( !Files.exists( sandbox ) ) - Files.createDirectories( sandbox ); - - if (cmd.hasOption('m')) { // MAX_TRANSFER SIZE - String maxTransferSize = cmd.getOptionValue('m'); - try { - cre = new CondorCreActor(sandbox, maxTransferSize); - } catch (Exception e) { - System.out.println( - "INVALID '-m' option value: " + maxTransferSize + - "\n\nCUNEIFORM - A Functional Workflow Language\nversion " - + BaseRepl.LABEL_VERSION + " build " + BaseRepl.LABEL_BUILD); - new HelpFormatter().printHelp( - "java -jar cuneiform.jar [OPTION]*", opt); - - return; - } - } - else{ - cre = new CondorCreActor(sandbox); - } - - break; - - default : throw new RuntimeException( "Platform not recognized." ); - } - - executor.submit( cre ); - ticketSrc = new TicketSrcActor( cre ); - executor.submit( ticketSrc ); - executor.shutdown(); - - switch( format ) { - - case FORMAT_CF : - - if( cmd.hasOption( "i" ) ) - repl = new InteractiveRepl( ticketSrc, statLog ); - else - repl = new CmdlineRepl( ticketSrc, statLog ); - break; - - case FORMAT_DAX : - repl = new DaxRepl( ticketSrc, statLog ); - break; - - default : - throw new RuntimeException( "Format not recognized." ); - } - - if( cmd.hasOption( "i" ) ) { - - // run in interactive mode - BaseRepl.run( repl ); - - return; - } - - // run in quiet mode - - if( inputFileVector.length > 0 ) - - for( Path f : inputFileVector ) - repl.interpret( readFile( f ) ); - - else - repl.interpret( readStdIn() ); - - - Thread.sleep( 3*Actor.DELAY ); - while( repl.isBusy() ) - Thread.sleep( Actor.DELAY ); - - if( cmd.hasOption( "s" ) ) { - - summary = new JsonSummary( ticketSrc.getRunId(), sandbox, repl.getAns() ); - summaryPath = Paths.get( cmd.getOptionValue( "s" ) ); - summaryPath = summaryPath.toAbsolutePath(); - try( BufferedWriter writer = Files.newBufferedWriter( summaryPath, Charset.forName( "UTF-8" ) ) ) { - - writer.write( summary.toString() ); - } - - } - - - } - finally { - executor.shutdownNow(); - } - - } - - public static void config( CommandLine cmd ) { - - String[] fileVector; - Path f; - String s; - int i, n; - - fileVector = cmd.getArgs(); - n = fileVector.length; - inputFileVector = new Path[ n ]; - - for( i = 0; i < n; i++ ) { - - s = fileVector[ i ]; - f = Paths.get( s ); - - inputFileVector[ i ] = f; - } - - if( cmd.hasOption( 'p' ) ) - platform = cmd.getOptionValue( 'p' ); - else - platform = PLATFORM_LOCAL; - - if( cmd.hasOption( 'f' ) ) - format = cmd.getOptionValue( 'f' ); - else - format = FORMAT_CF; - } - - public static CommandLine parse( String[] args, Options opt ) throws ParseException { - - GnuParser parser; - CommandLine cmd; - - parser = new GnuParser(); - cmd = parser.parse( opt, args ); - return cmd; - } - - public static Options getOptions() { - - Options opt; - - opt = new Options(); - - opt.addOption( "c", "clean", false, "Clear local cache before start." ); - - opt.addOption( "f", "format", true, - "The format of the input file. Must be either '"+FORMAT_CF+"' for Cuneiform or '"+FORMAT_DAX+"' for Pegasus DAX. Default is '"+FORMAT_CF+"'." ); - - opt.addOption( "h", "help", false, "Output help." ); - - opt.addOption( "i", "interactive", false, "Start an interactive REPL." ); - - opt.addOption( "l", "localcache", true, "Path to the local cache. Defaults to '~/.cuneiform'." ); - - opt.addOption( "p", "platform", true, - "The platform to run. Currently available platforms are '"+PLATFORM_LOCAL+"' and '"+PLATFORM_HTCONDOR+"'. Default is '"+PLATFORM_LOCAL+"'." ); - - opt.addOption("m", "maxtransfer", true, - "Optional. Takes effect only if the platform is '"+PLATFORM_HTCONDOR+"'. Default is 1G. Controls max input file transfer. If total input files exceed this limit, condor job is run in the local universe. Takes a number in bytes by default or specified units [G|M|K], i.e. 250000000 or 2G or 1000M or 234K"); - - opt.addOption( "r", "rlib", true, "Optional. The directory in which custom R libraries are installed. If set, the directory is added to R's libPath list." ); - - opt.addOption( "s", "summary", true, - "The name of a JSON summary file. No file is created if this parameter is not specified." ); - - opt.addOption( "t", "threads", true, "The number of threads to use. Defaults to the number of CPU cores available on this machine. Takes effect only if the platform is '"+PLATFORM_LOCAL+"'." ); - - opt.addOption( "w", "workdir", true, "Optional. The working directory from which to look for local data. The default is the current working directory from which Cuneiform was called." ); - - opt.addOption( "y", "pylib", true, "Optional. The directory in which custom Python libraries are installed. If set, the directory is added to Python's system path list." ); - - - return opt; - - } - - public static String readFile( Path f ) throws FileNotFoundException, IOException { - - String line; - StringBuffer buf; - - buf = new StringBuffer(); - try( BufferedReader reader = Files.newBufferedReader( f, Charset.forName( "UTF-8" ) ) ) { - - while( ( line = reader.readLine() ) != null ) - buf.append( line ).append( '\n' ); - } - - return buf.toString(); - - } - - public static String readStdIn() throws IOException { - - StringBuffer buf; - String line; - - buf = new StringBuffer(); - try( BufferedReader reader = new BufferedReader( new InputStreamReader( System.in ) ) ) { - - while( ( line = reader.readLine() ) != null ) - buf.append( line ).append( '\n' ); - } - - return buf.toString(); - } -} diff --git a/cuneiform-core/.gitignore b/cuneiform-core/.gitignore deleted file mode 100644 index 6afedc5..0000000 --- a/cuneiform-core/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/target -/bin -/.classpath -/.settings -/.project diff --git a/cuneiform-core/pom.xml b/cuneiform-core/pom.xml deleted file mode 100644 index f6e95e4..0000000 --- a/cuneiform-core/pom.xml +++ /dev/null @@ -1,99 +0,0 @@ - - 4.0.0 - - de.hu-berlin.wbi.cuneiform - cuneiform - 2.0.4-SNAPSHOT - - cuneiform-core - - - - junit - junit - 4.12 - test - - - - org.antlr - antlr4 - 4.5 - - - - org.json - json - 20090211 - - - - commons-logging - commons-logging - 1.1.3 - - - - log4j - log4j - 1.2.17 - - - - org.mockito - mockito-all - 1.10.19 - - - - - - - - - org.apache.maven.plugins - maven-source-plugin - 2.4 - - - attach-sources - - jar - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.10.3 - - - attach-javadocs - - jar - - - - - - org.antlr - antlr4-maven-plugin - 4.5 - - ${basedir}/src/main/antlr - true - true - - - - - antlr4 - - - - - - - \ No newline at end of file diff --git a/cuneiform-core/src/main/antlr/de/huberlin/wbi/cuneiform/core/parser/Cuneiform.g4 b/cuneiform-core/src/main/antlr/de/huberlin/wbi/cuneiform/core/parser/Cuneiform.g4 deleted file mode 100644 index 3518c5a..0000000 --- a/cuneiform-core/src/main/antlr/de/huberlin/wbi/cuneiform/core/parser/Cuneiform.g4 +++ /dev/null @@ -1,208 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -grammar Cuneiform ; - - -// NON-TERMINAL SYMBOLS - -script : stat* EOF ; - -// the body -stat : target // top-level - | importFile - | instat - | expr - { notifyErrorListeners( "Dangling expression. Expecting ';' or '-+'." ); } - ; - -instat : assign // allowed also in blocks - | defTask - | danglingExpr - ; - -// imports -importFile : ( IMPORT | INCLUDE )STRING SEMICOLON ; - -// assignments, tasks and lambda expressions -assign : name+ EQUAL expr SEMICOLON ; - -defTask : DEFTASK ID prototype LBRACE instat+ RBRACE # NativeDefTask - | DEFTASK ID prototype foreignBody # ForeignDefTask - | DEFTASK - { notifyErrorListeners( "Incomplete Task definition. Task name expected." ); } # DefTaskErr1 - | DEFTASK ID prototype LBRACE - { notifyErrorListeners( "Missing '}'." ); } # DefTaskErr2 - | DEFTASK ID prototype LBRACE RBRACE - { notifyErrorListeners( "Empty native task block." ); } # DefTaskErr3 - | DEFTASK ID LPAREN - { notifyErrorListeners( "Incomplete task prototype. Expecting at least one output variable declaration." ); } # FnPrototypeErr1 - | DEFTASK ID LPAREN output+ COLON param* - { notifyErrorListeners( "Incomplete task prototype. Expecting input parameter declaration or ')'." ); } # FnPrototypeErr2 - | DEFTASK ID LPAREN output+ COLON param* RPAREN RPAREN+ - { notifyErrorListeners( "Too many ')'." ); } # FnPrototypeErr3 - ; - -// type system -prototype : LPAREN output+ COLON param* RPAREN ; - -name : ID # NameInferredType - | ID LPAREN ID RPAREN # NameDataType - | ID LPAREN COLON RPAREN # NamePlainFnType - | ID prototype # NameDeepFnType - | ID LPAREN COLON? - { notifyErrorListeners( "Missing ')'." ); } # NameErr1 - | ID LPAREN ID RPAREN RPAREN+ - { notifyErrorListeners( "Too many ')'." ); } # NameErr2 - ; - -param : name - | reduceVar - | correlParam - | draw - ; - -draw : LBRACE COMB INT COLON( name )RBRACE # DrawComb - | LBRACE COMBR INT COLON( name )RBRACE # DrawCombr - | LBRACE VAR INT COLON( name )RBRACE # DrawVar - | LBRACE PERM INT COLON( name )RBRACE # DrawPerm - ; - -output : name - | reduceVar - ; - -reduceVar : LTAG name RTAG ; - -correlParam : LSQUAREBR name name+ RSQUAREBR - | LSQUAREBR name RSQUAREBR - { notifyErrorListeners( "Correlated parameter list must have at least two entries." ); } - | LSQUAREBR RSQUAREBR - { notifyErrorListeners( "Empty correlated parameter list." ); } - ; - -// expressions -expr : NIL # NilExpr - | singleExpr+ # CompoundExpr - ; - -danglingExpr : expr TOSTACK ; - -singleExpr : ID # IdExpr - | INT # IntExpr - | STRING # StringExpr - | FROMSTACK # FromStackExpr - | IF expr THEN expr ELSE expr END # CondExpr - | channel? APPLY LPAREN paramBind( COMMA paramBind )* TILDE? RPAREN # ApplyExpr - | channel? ID LPAREN( paramBind( COMMA paramBind )* )? TILDE? RPAREN # CallExpr - | CURRY LPAREN paramBind( COMMA paramBind )* RPAREN # CurryExpr - | LAMBDA prototype block # NativeLambdaExpr - | LAMBDA prototype foreignBody # ForeignLambdaExpr - | APPLY - { notifyErrorListeners( "Incomplete task application. Missing '('." ); } # SingleExprErr1 - | APPLY LPAREN - { notifyErrorListeners( "Incomplete task application. Missing Parameter bindings, e.g. 'param: value'." ); } # SingleExprErr2 - | APPLY LPAREN paramBind( COMMA paramBind )* - { notifyErrorListeners( "Incomplete task application. Missing ')'." ); } # SingleExprErr3 - | APPLY LPAREN ID COLON - { notifyErrorListeners( "Incomplete Parameter binding. Missing value." ); } # ParamBindErr1 - | LAMBDA prototype INLANG OPENBODY - { notifyErrorListeners( "In foreign task definition: Missing '}*'." ); } # ForeignFnBodyErr2 - ; - -channel : LSQUAREBR INT RSQUAREBR ; - -block : LBRACE instat+ RBRACE - | LBRACE RBRACE - { notifyErrorListeners( "Empty block. Expecting target, assignment, or task definition." ); } - ; - -paramBind : ID COLON expr ; - -target : expr SEMICOLON ; - -foreignBody : INLANG BODY ; - -// TERMINAL SYMBOLS - -APPLY : 'apply' ; -COLON : ':' ; -COMMA : ',' ; -COMB : 'comb' ; -COMBR : 'combr' ; -CURRY : 'curry' ; -DEFTASK : 'deftask' ; -ELSE : 'else' ; -END : 'end' ; -EQUAL : '=' ; -FROMSTACK : '<' '-'+ '+' ; -IF : 'if' ; -INLANG : 'in' WSSYMB+ LANGSYMB ; -fragment LANGSYMB: 'bash' | 'r' | 'R' | 'lisp' | 'octave' | 'matlab' | 'perl' - | 'pegasus' | 'python' | 'java' | 'scala' | 'beanshell' ; -IMPORT : 'import' ; -INCLUDE : 'include' ; -LAMBDA : '\\' ; -LBRACE : '{' ; -LPAREN : '(' ; -LSQUAREBR : '[' ; -LTAG : '<' ; -NIL : 'nil' ; -PERM : 'perm' ; -RBRACE : '}' ; -RPAREN : ')' ; -RSQUAREBR : ']' ; -RTAG : '>' ; -SEMICOLON : ';' ; -TILDE : '~' ; -THEN : 'then' ; -TOSTACK : '-'+ '+' ; -VAR : 'var' ; - -INT : [0-9] - | '-'? [1-9][0-9]* - ; -BODY : LMMECB .*? RMMECB ; -OPENBODY : LMMECB .*? ; -fragment LMMECB : '*{' ; -fragment RMMECB : '}*' ; -STRING : '\'' ( '\\\'' | '\\\\' | . )*? '\'' - | '"' ( '\\"' | '\\\\' | . )*? '"' - ; -COMMENT : ( ( '#' | '//' | '%' ) ~'\n'* - | '/*' .*? '*/' - | '' - | '|' ) -> skip - ; -ID : [a-zA-Z0-9\.\-_\+\*/]+ ; -WS : WSSYMB -> channel( HIDDEN ) ; -fragment WSSYMB : [ \n\r\t] ; diff --git a/cuneiform-core/src/main/antlr/de/huberlin/wbi/cuneiform/core/parser/ParseCtlLexer.g4 b/cuneiform-core/src/main/antlr/de/huberlin/wbi/cuneiform/core/parser/ParseCtlLexer.g4 deleted file mode 100644 index d0d0e30..0000000 --- a/cuneiform-core/src/main/antlr/de/huberlin/wbi/cuneiform/core/parser/ParseCtlLexer.g4 +++ /dev/null @@ -1,46 +0,0 @@ -lexer grammar ParseCtlLexer; - -// LEXER RULES - -RC : '#' -> mode( COMMENT ) ; -OC : '%' -> mode( COMMENT ) ; -CC : '//' -> mode( COMMENT ) ; -LCCOMMENT : '/*' -> mode( CCOMMENT ) ; -LPAREN : '(' -> mode( APPLY ) ; -LXCOMMENT : '' -> mode( DEFAULT_MODE ) ; -ANYXC : . -> skip ; - - -mode APPLY ; - -RPAREN : ')' -> mode( DEFAULT_MODE ) ; -ANYA : . -> skip ; - -mode FOREIGN ; - -RMMECB : '}*' -> mode( DEFAULT_MODE ) ; -ANYF : . -> skip ; \ No newline at end of file diff --git a/cuneiform-core/src/main/doc/cuneiform-logo.svg b/cuneiform-core/src/main/doc/cuneiform-logo.svg deleted file mode 100644 index d1e3aca..0000000 --- a/cuneiform-core/src/main/doc/cuneiform-logo.svg +++ /dev/null @@ -1,541 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - diff --git a/cuneiform-core/src/main/doc/g18225.png b/cuneiform-core/src/main/doc/g18225.png deleted file mode 100644 index 3b8a0bc9f87a9e4662ff3a2db6082cb9321205a8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 143604 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 z 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 eQXePLlgYna)d%o1&!fectN#IIOC!) inbox; - - public Actor() { - inbox = new ArrayList<>(); - log = LogFactory.getLog( Actor.class ); - } - - public synchronized void sendMsg( Message msg ) { - - if( msg == null ) - throw new NullPointerException( "Message must not be null." ); - - if( log.isDebugEnabled() ) - log.debug( "Sending message. "+msg.getSender().getClass().getSimpleName()+" -> "+getClass().getSimpleName()+" "+msg ); - - - inbox.add( msg ); - - } - - private synchronized void processQueue() { - - if( inbox == null ) - throw new NullPointerException( "Inbox must not be null." ); - - for( Message msg : inbox ) { - - if( msg == null ) - throw new NullPointerException( "Message must not be null." ); - - if( log.isDebugEnabled() ) - log.debug( "Receiving message. "+msg.getSender().getClass().getSimpleName()+" -> "+getClass().getSimpleName()+" "+msg ); - - processMsg( msg ); - } - inbox.clear(); - - } - - protected abstract void processMsg( Message msg ); - - @Override - public void run() { - - try { - - if( log.isDebugEnabled() ) - log.debug( "Starting actor: "+getClass().getSimpleName() ); - - while( true ) { - - - Thread.sleep( DELAY ); - - if( log.isDebugEnabled() ) - log.debug( getClass()+" is alive." ); - - preRec(); - processQueue(); - postRec(); - - } - } - catch( InterruptedException e ) { - - if( log.isDebugEnabled() ) - log.debug( getClass()+" caught InterruptedException. Shutting down." ); - - } - catch( Throwable e ) { - - if( log.isDebugEnabled() ) - log.debug( getClass()+" caught unexpected throwable: "+e.getMessage() ); - - e.printStackTrace(); - } - finally { - - if( log.isDebugEnabled() ) - log.debug( "Downing "+getClass()+"." ); - - shutdown(); - } - } - - protected abstract void shutdown(); - protected void preRec() { - // override if necessary - } - protected void postRec() { - // override if necessary - } - -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/actormodel/Message.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/actormodel/Message.java deleted file mode 100644 index c967e3e..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/actormodel/Message.java +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.actormodel; - -public abstract class Message { - - private final Actor sender; - - public Message( Actor sender ) { - - if( sender == null ) - throw new NullPointerException( "Sender must not be null." ); - - this.sender = sender; - } - - public Actor getSender() { - return sender; - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/cre/BaseCreActor.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/cre/BaseCreActor.java deleted file mode 100644 index 6f177a1..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/cre/BaseCreActor.java +++ /dev/null @@ -1,55 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.cre; - -import de.huberlin.wbi.cuneiform.core.actormodel.Actor; -import de.huberlin.wbi.cuneiform.core.actormodel.Message; - -public abstract class BaseCreActor extends Actor { - - protected abstract void processMsg( TicketReadyMsg msg ); - - @Override - protected synchronized void processMsg( Message msg ) { - - if( msg instanceof TicketReadyMsg ) { - - processMsg( ( TicketReadyMsg )msg ); - return; - } - - throw new RuntimeException( "Message type not recognized." ); - - } - -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/cre/LocalCreActor.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/cre/LocalCreActor.java deleted file mode 100644 index b0b37ec..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/cre/LocalCreActor.java +++ /dev/null @@ -1,130 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.cre; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import de.huberlin.wbi.cuneiform.core.actormodel.Actor; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Ticket; -import de.huberlin.wbi.cuneiform.core.ticketsrc.TicketSrcActor; - -public class LocalCreActor extends BaseCreActor { - - public static final String PATH_CENTRALREPO = "repo"; - - - private final ExecutorService executor; - private final Path buildDir; - private final Path centralRepo; - private final Path workDir; - - public LocalCreActor( Path buildDir, Path workDir, int nthread ) throws IOException { - - if( buildDir == null ) - throw new NullPointerException( "Build directory must not be null." ); - - if( !Files.exists( buildDir ) ) - throw new RuntimeException( "Build directory does not exist." ); - - if( !Files.isDirectory( buildDir ) ) - throw new RuntimeException( "Directory expected." ); - - if( nthread < 1 ) - throw new RuntimeException( "Number of threads must at least be 1. It was "+nthread+"." ); - - if( workDir == null ) - throw new IllegalArgumentException( "Working directory must not be null." ); - - if( !Files.exists( workDir ) ) - throw new RuntimeException( "Working directory does not exist." ); - - if( !Files.isDirectory( workDir ) ) - throw new RuntimeException( "Working directory expected to be a directory." ); - - - this.buildDir = buildDir; - this.workDir = workDir; - - executor = Executors.newFixedThreadPool( nthread ); - - centralRepo = buildDir.resolve( PATH_CENTRALREPO ); - if( !Files.exists( centralRepo ) ) - Files.createDirectories( centralRepo ); - - if( log.isDebugEnabled() ) - log.debug( "Local CRE actor created with "+nthread+" threads." ); - } - - public LocalCreActor( Path buildDir, Path workDir ) throws IOException { - this( buildDir, workDir, Runtime.getRuntime().availableProcessors() ); - } - - @Override - protected void processMsg( TicketReadyMsg msg ) { - - LocalThread localThread; - Actor sender; - TicketSrcActor ticketSrc; - Ticket ticket; - - sender = msg.getSender(); - if( !( sender instanceof TicketSrcActor ) ) - throw new RuntimeException( "Ticket source actor expected." ); - - ticketSrc = ( TicketSrcActor )sender; - - ticket = msg.getTicket(); - - if( !ticket.isNormal() ) - throw new RuntimeException( "Ticket "+ticket.getTicketId()+": Trying to evaluate ticket that is not ready." ); - - if( ticket.isEvaluated() ) - throw new RuntimeException( - "Ticket "+ticket.getTicketId()+": Trying to evaluate ticket that has already been evaluated." ); - - localThread = new LocalThread( ticketSrc, this, ticket, buildDir, centralRepo, workDir ); - - executor.submit( localThread ); - - } - - @Override - protected void shutdown() { - executor.shutdownNow(); - } - -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/cre/LocalThread.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/cre/LocalThread.java deleted file mode 100644 index 0967cfa..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/cre/LocalThread.java +++ /dev/null @@ -1,434 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.cre; - -import de.huberlin.wbi.cuneiform.core.actormodel.Message; -import de.huberlin.wbi.cuneiform.core.invoc.Invocation; -import de.huberlin.wbi.cuneiform.core.semanticmodel.JsonReportEntry; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Ticket; -import de.huberlin.wbi.cuneiform.core.ticketsrc.TicketFailedMsg; -import de.huberlin.wbi.cuneiform.core.ticketsrc.TicketFinishedMsg; -import de.huberlin.wbi.cuneiform.core.ticketsrc.TicketSrcActor; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.json.JSONObject; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.IOException; -import java.nio.charset.Charset; -import java.nio.file.*; -import java.nio.file.attribute.PosixFilePermissions; -import java.util.HashSet; -import java.util.Set; - -public class LocalThread implements Runnable { - - private static final int WAIT_INTERVAL = 100; - private static final int MAX_TRIALS = 4; - - private final Invocation invoc; - private final Log log; - private final Path buildDir; - private final TicketSrcActor ticketSrc; - private final BaseCreActor cre; - private final Path centralRepo; - private final Path workDir; - - public LocalThread(TicketSrcActor ticketSrc, BaseCreActor cre, - Ticket ticket, Path buildDir, Path centralRepo, Path workDir ) { - - if( buildDir == null ) - throw new NullPointerException( "Build directory must not be null." ); - - if( !Files.exists( buildDir ) ) - throw new RuntimeException( "Build directory does not exist." ); - - if( !Files.isDirectory( buildDir ) ) - throw new RuntimeException( "Build path expected to be a directory." ); - - if( cre == null ) - throw new NullPointerException( "CRE actor must not be null." ); - - if( ticketSrc == null ) - throw new NullPointerException( "Ticket source must not be null." ); - - if( centralRepo == null ) - throw new NullPointerException( "Central repository must not be null." ); - - if( !Files.exists( centralRepo ) ) - throw new RuntimeException( "Central repository does not exist." ); - - if( !Files.isDirectory( centralRepo ) ) - throw new RuntimeException( "Central repository path expected to be a directory." ); - - if( workDir == null ) - throw new IllegalArgumentException( "Working directory must not be null." ); - - if( !Files.exists( workDir ) ) - throw new RuntimeException( "Working directory does not exist." ); - - if( !Files.isDirectory( workDir ) ) - throw new RuntimeException( "Working directory expected to be a directory." ); - - this.ticketSrc = ticketSrc; - this.cre = cre; - this.buildDir = buildDir; - this.centralRepo = centralRepo; - this.workDir = workDir; - - invoc = Invocation.createInvocation( ticket ); - log = LogFactory.getLog( LocalThread.class ); - } - - @Override - public void run() { - - Path scriptFile, location, successMarker, reportFile, stdErrFile, stdOutFile; - // Path lockMarker; - Process process; - int exitValue; - Set report; - JsonReportEntry entry; - String line; - StringBuffer buf; - Path srcPath, destPath; - ProcessBuilder processBuilder; - Ticket ticket; - String script, stdOut, stdErr; - long tic, toc; - JSONObject obj; - Message msg; - Charset cs; - int trial; - boolean suc; - Exception ex; - Path parent; - - - if( log.isDebugEnabled() ) - log.debug( "Starting up local thread for ticket "+invoc.getTicketId()+"." ); - - - if( invoc == null ) - throw new NullPointerException( "Invocation must not be null." ); - - - ticket = invoc.getTicket(); - process = null; - stdOut = null; - stdErr = null; - // lockMarker = null; - script = null; - successMarker = null; - cs = Charset.forName( "UTF-8" ); - - try { - - - - // callLocation = Paths.get( System.getProperty( "user.dir" ) ); - location = buildDir.resolve( String.valueOf( invoc.getTicketId() ) ); - // lockMarker = location.resolve( Invocation.LOCK_FILENAME ); - successMarker = location.resolve( Invocation.SUCCESS_FILENAME ); - reportFile = location.resolve( Invocation.REPORT_FILENAME ); - script = invoc.toScript(); - - // if( Files.exists( lockMarker ) ) - // throw new IOException( "Lock held on ticket "+invoc.getTicketId() ); - - if( !Files.exists( successMarker ) ) { - - deleteIfExists( location ); - Files.createDirectories( location ); - - // Files.createFile( lockMarker ); - - scriptFile = invoc.getExecutablePath( location ); - - Files.createFile( scriptFile, - PosixFilePermissions.asFileAttribute( - PosixFilePermissions.fromString( "rwxr-x---" ) ) ); - - // write executable script - try( BufferedWriter writer = Files.newBufferedWriter( scriptFile, cs, StandardOpenOption.CREATE ) ) { - writer.write( script ); - } - - // write executable log entry - try( BufferedWriter writer = Files.newBufferedWriter( reportFile, cs, StandardOpenOption.CREATE ) ) { - writer.write( ticket.getExecutableLogEntry().toString() ); - writer.write( '\n' ); - } - - for( String filename : invoc.getStageInList() ) { - - - - if( filename.charAt( 0 ) == '/' ) - throw new UnsupportedOperationException( "Absolute path encountered '"+filename+"'." ); - - srcPath = centralRepo.resolve( filename ); - destPath = location.resolve( filename ); - if( destPath == null ) - throw new NullPointerException( "Link destination path must not be null." ); - - if( !Files.exists( srcPath ) ) { - - srcPath = workDir.resolve( filename ); - if( log.isTraceEnabled() ) - log.trace( "Resolving relative path '"+srcPath+"'." ); - } - else - - if( log.isTraceEnabled() ) - log.trace( "Resolving path to central repository '"+srcPath+"'." ); - - if( log.isTraceEnabled() ) - log.trace( "Trying to create symbolic link from '"+srcPath+"' to '"+destPath+"'." ); - - parent = destPath.getParent(); - if( parent == null ) - throw new NullPointerException( "Parent path of destination path must not be null." ); - - if( !Files.exists( parent ) ) - Files.createDirectories( parent ); - - Files.createSymbolicLink( destPath, srcPath ); - - } - - // run script - processBuilder = new ProcessBuilder( invoc.getCmd() ); - processBuilder.directory( location.toFile() ); - - stdOutFile = location.resolve( Invocation.STDOUT_FILENAME ); - stdErrFile = location.resolve( Invocation.STDERR_FILENAME ); - - processBuilder.redirectOutput( stdOutFile.toFile() ); - processBuilder.redirectError( stdErrFile.toFile() ); - - trial = 1; - suc = false; - ex = null; - tic = System.currentTimeMillis(); - do { - try { - process = processBuilder.start(); - - suc = true; - } - catch( IOException e ) { - - ex = e; - if( log.isWarnEnabled() && trial > 1) // one retry is normal, 2 is a WARN - log.warn( "Retrying "+ ( ++trial ) +"th time. Waiting "+WAIT_INTERVAL+"ms: "+e.getMessage() ); - Thread.sleep( WAIT_INTERVAL ); - } - } while( suc == false && trial <= MAX_TRIALS ); - - if( process == null ) { - - if( log.isInfoEnabled() ) - log.info( "Sending ticket failed message because the received process object was null." ); - - ticketSrc.sendMsg( new TicketFailedMsg( cre, ticket, ex, script, null, null ) ); - // Files.delete( lockMarker ); - return; - } - - - exitValue = process.waitFor(); - toc = System.currentTimeMillis(); - - try( BufferedWriter writer = Files.newBufferedWriter( reportFile, cs, StandardOpenOption.APPEND ) ) { - - obj = new JSONObject(); - obj.put( JsonReportEntry.LABEL_REALTIME, toc-tic ); - entry = invoc.createJsonReportEntry( tic, JsonReportEntry.KEY_INVOC_TIME, obj ); - - writer.write( entry.toString() ); - writer.write( '\n' ); - - try( BufferedReader reader = Files.newBufferedReader( stdOutFile, cs ) ) { - - buf = new StringBuffer(); - while( ( line = reader.readLine() ) != null ) - buf.append( line ).append( '\n' ); - - - stdOut = buf.toString(); - - if( !stdOut.isEmpty() ) { - entry = invoc.createJsonReportEntry( JsonReportEntry.KEY_INVOC_STDOUT, stdOut ); - writer.write( entry.toString() ); - writer.write( '\n' ); - } - } - - try( BufferedReader reader = Files.newBufferedReader( stdErrFile, cs ) ) { - - buf = new StringBuffer(); - while( ( line = reader.readLine() ) != null ) - buf.append( line ).append( '\n' ); - - stdErr = buf.toString(); - if( !stdErr.isEmpty() ) { - - entry = invoc.createJsonReportEntry( JsonReportEntry.KEY_INVOC_STDERR, stdErr ); - writer.write( entry.toString() ); - writer.write( '\n' ); - } - } - - if( exitValue == 0 ) - - Files.createFile( successMarker ); - - else { - - if( log.isInfoEnabled() ) - log.info( "Sending ticket failed message because exit value was non-zero." ); - - ticketSrc.sendMsg( new TicketFailedMsg( cre, ticket, null, script, stdOut, stdErr ) ); - // Files.delete( lockMarker ); - return; - - } - } - - - } - - // gather report - report = new HashSet<>(); - try( BufferedReader reader = Files.newBufferedReader( reportFile, cs ) ) { - - while( ( line = reader.readLine() ) != null ) { - - line = line.trim(); - - if( line.isEmpty() ) - continue; - - entry = new JsonReportEntry( line ); - - // If the report comes from the hard cache then the run id - // is different from the run id of this invocation. This is - // corrected here. - entry.setRunId( invoc.getRunId() ); - - report.add( entry ); - } - - } - - invoc.evalReport( report ); - - // create link in central data repository - for( String f : invoc.getStageOutList() ) { - - srcPath = location.resolve( f ); - destPath = centralRepo.resolve( f ); - - if( Files.exists( destPath ) ) - continue; - - if( log.isTraceEnabled() ) - log.trace( "Creating link from "+srcPath+" to "+destPath+"." ); - - Files.createSymbolicLink( destPath, srcPath ); - } - - - ticketSrc.sendMsg( new TicketFinishedMsg( cre, invoc.getTicket(), report ) ); - - if( log.isTraceEnabled() ) - log.trace( "Local thread ran through without exception." ); - - // Files.deleteIfExists( lockMarker ); - - } - catch( InterruptedException e ) { - - if( log.isTraceEnabled() ) - log.trace( "Local thread has been interrupted." ); - } - catch( Exception e ) { - - if( log.isTraceEnabled() ) - log.trace( "Something went wrong. Deleting success marker if present." ); - - if( successMarker != null ) - try { - Files.deleteIfExists( successMarker ); - } - catch( IOException e1 ) { - e1.printStackTrace(); - } - - if( log.isInfoEnabled() ) - log.info( "Sending ticket failed message because an exception was caught: "+e.getMessage() ); - - msg = new TicketFailedMsg( cre, ticket, e, script, stdOut, stdErr ); - - ticketSrc.sendMsg( msg ); - - } - finally { - - - if( process != null ) { - - if( log.isDebugEnabled() ) - log.debug( "Stopping local thread for ticket "+invoc.getTicketId()+"." ); - - process.destroy(); - } - } - } - - public static void deleteIfExists( Path f ) throws IOException { - - if( !Files.exists( f, LinkOption.NOFOLLOW_LINKS ) ) - return; - - if( Files.isDirectory( f ) ) - try( DirectoryStream stream = Files.newDirectoryStream( f ) ) { - for( Path p : stream ) - deleteIfExists( p ); - } - - Files.delete( f ); - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/cre/TicketReadyMsg.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/cre/TicketReadyMsg.java deleted file mode 100644 index 393a77f..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/cre/TicketReadyMsg.java +++ /dev/null @@ -1,74 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.cre; - -import java.util.UUID; - -import de.huberlin.wbi.cuneiform.core.actormodel.Actor; -import de.huberlin.wbi.cuneiform.core.actormodel.Message; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Ticket; - -public class TicketReadyMsg extends Message { - - private final UUID queryId; - private final Ticket ticket; - - public TicketReadyMsg( Actor sender, UUID queryId, Ticket ticket ) { - - super( sender ); - - if( ticket == null ) - throw new NullPointerException( "Ticket set must not be null." ); - - if( queryId == null ) - throw new NullPointerException( "Run ID must not be null." ); - - this.queryId = queryId; - this.ticket = ticket; - } - - public UUID getQueryId() { - return queryId; - } - - public Ticket getTicket() { - return ticket; - } - - @Override - public String toString() { - return "{ ticketReady, \""+queryId+"\", "+ticket.getTicketId()+", \""+ticket.toString().replace( '\n', ' ' )+"\" }"; - } - - -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/BashInvocation.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/BashInvocation.java deleted file mode 100644 index 352cc87..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/BashInvocation.java +++ /dev/null @@ -1,451 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.invoc; - -import de.huberlin.wbi.cuneiform.core.semanticmodel.CompoundExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.JsonReportEntry; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NotDerivableException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Ticket; - -public class BashInvocation extends Invocation { - - private static String bashAllFrom( String varname ) { - - if( varname == null ) - throw new NullPointerException( "Varname must not be null." ); - - if( varname.isEmpty() ) - throw new RuntimeException( "Varname must not be empty." ); - - return bashArrayGet( varname, "@" ); - } - - private static String bashArrayGet( String varName, String index ) { - - String v, i; - - if( varName == null ) - throw new NullPointerException( "Varname must not be null." ); - - v = varName.trim(); - - if( v.isEmpty() ) - throw new RuntimeException( "Varname must not be empty." ); - - if( v.startsWith( "$" ) ) - throw new RuntimeException( "Varname '"+varName+"' already dereferenced." ); - - if( v.contains( "\n" ) ) - throw new RuntimeException( - "Varname cannot be a multi-line expression." ); - - if( index == null ) - throw new NullPointerException( "Index must not be null." ); - - i = index.trim(); - - if( i.isEmpty() ) - throw new RuntimeException( "Index must not be empty." ); - - if( i.contains( "\n" ) ) - throw new RuntimeException( - "Index cannot be a multi-line expression." ); - - - - return "${"+v+"["+index+"]}"; - } - - private static String bashArraySize( String varName ) { - return "${#"+varName+"[@]}"; - } - - private static String bashIfNotEquals( String a, String b, String thenBlock ) { - - if( a == null ) - throw new NullPointerException( "Operand a must not be null." ); - - if( a.isEmpty() ) - throw new RuntimeException( "Operand a must not be empty." ); - - if( b == null ) - throw new NullPointerException( "Operand b must not be null." ); - - if( b.isEmpty() ) - throw new RuntimeException( "Operand b must not be empty." ); - - if( thenBlock == null ) - throw new NullPointerException( "Then block must not be null." ); - - if( thenBlock.isEmpty() ) - throw new RuntimeException( "Then block must not be empty." ); - - - String ret; - ret = "if [ \""+a+"\" -ne \""+b+"\" ]\nthen\n"+thenBlock+"\n"; - - ret += "fi\n"; - - return ret; - } - - private static final String BASH_SHEBANG = "#!/usr/bin/env bash\nset -eu -o pipefail\n"; - - - public BashInvocation( Ticket ticket, String libPath ) { - super( ticket, libPath ); - } - - @Override - protected String callFunction( String name, String... argValue ) { - - StringBuffer buf; - - if( name == null ) - throw new NullPointerException( "Function name must not be null." ); - - if( name.isEmpty() ) - throw new RuntimeException( "Function name must not be empty." ); - - if( argValue == null ) - throw new NullPointerException( "Parameter bindings must not be null." ); - - buf = new StringBuffer(); - - buf.append( '`' ).append( name ); - - for( String value : argValue ) - - if( value.trim().startsWith( "\"" ) && value.trim().endsWith( "\"" ) ) - buf.append( ' ' ).append( value ); - else - buf.append( " \"" ).append( value ).append( '"' ); - - - buf.append( '`' ); - - return buf.toString(); - } - - @Override - protected String callProcedure( String name, String... argValue ) { - - StringBuffer buf; - - if( name == null ) - throw new NullPointerException( "Function name must not be null." ); - - if( name.isEmpty() ) - throw new RuntimeException( "Function name must not be empty." ); - - if( argValue == null ) - throw new NullPointerException( "Parameter bindings must not be null." ); - - buf = new StringBuffer(); - - buf.append( name ); - - for( String value : argValue ) - - if( value.trim().startsWith( "\"" ) && value.trim().endsWith( "\"" ) ) - buf.append( ' ' ).append( value ); - else - buf.append( " \"" ).append( value ).append( '"' ); - - - buf.append( '\n' ); - - return buf.toString(); - } - - @Override - protected String clip(String varName) { - return varName+"=${"+varName+":1}\n"; - } - - @Override - protected String comment( String comment ) { - return "# "+comment.replace( "\n", "\n# " )+"\n"; - } - - @Override - protected String copyArray( String from, String to ) { - return newList( to )+varDef( to, bashAllFrom( from ) ); - } - - private String defFunction( String funName, String outputName, String[] inputNameList, String body ) { - - int i; - - if( funName == null ) - throw new NullPointerException( "Function name must not be null." ); - - if( funName.isEmpty() ) - throw new RuntimeException( "Function name must not be empty." ); - - if( body == null ) - throw new NullPointerException( "Function body must not be null." ); - - if( body.isEmpty() ) - throw new RuntimeException( "Function body must not be empty." ); - - StringBuffer buf; - - buf = new StringBuffer(); - - buf.append( funName ).append( "() {\n" ); - - i = 0; - for( String inputName : inputNameList ) - buf.append( - varDef( inputName, dereference( String.valueOf( ++i ) ) ) ); - - buf.append( body ); - - if( outputName != null ) - buf.append( "echo " ).append( dereference( outputName ) ); - - buf.append( "\n}\n" ); - - return buf.toString(); - } - - @Override - protected String defFunctionLog() throws NotDerivableException { - - StringBuffer buf; - - buf = new StringBuffer(); - - buf.append( "echo -e \"{" ).append( JsonReportEntry.ATT_TIMESTAMP ) - .append( ':' ).append( System.currentTimeMillis() ).append( ',' ) - .append( JsonReportEntry.ATT_RUNID ).append( ":\\\"" ) - .append( getRunId() ).append( "\\\"," ) - .append( JsonReportEntry.ATT_TASKID ).append( ':' ) - .append( getTaskId() ).append( ',' ); - - if( hasTaskName() ) - buf.append( JsonReportEntry.ATT_TASKNAME ).append( ":\\\"" ) - .append( getTaskName() ).append( "\\\"," ); - - buf.append( JsonReportEntry.ATT_LANG ).append( ":\\\"" ) - .append( getLangLabel() ).append( "\\\"," ) - .append( JsonReportEntry.ATT_INVOCID ).append( ':' ) - .append( getTicketId() ).append( ',' ) - .append( JsonReportEntry.ATT_KEY ).append( ":\\\"$1\\\"," ) - .append( JsonReportEntry.ATT_VALUE ).append( ":$2}\" >> " ) - .append( REPORT_FILENAME ); - - return defFunction( FUN_LOG, null, new String[] { "key", "payload" }, buf.toString() ); - } - - @Override - protected String defFunctionLogFile() throws NotDerivableException { - - StringBuffer buf; - - buf = new StringBuffer(); - - buf.append( "echo -e \"{" ).append( JsonReportEntry.ATT_TIMESTAMP ) - .append( ':' ).append( System.currentTimeMillis() ).append( ',' ) - .append( JsonReportEntry.ATT_RUNID ).append( ":\\\"" ) - .append( getRunId() ).append( "\\\"," ) - .append( JsonReportEntry.ATT_TASKID ).append( ':' ) - .append( getTaskId() ).append( ',' ); - - if( hasTaskName() ) - buf.append( JsonReportEntry.ATT_TASKNAME ).append( ":\\\"" ) - .append( getTaskName() ).append( "\\\"," ); - - buf.append( JsonReportEntry.ATT_LANG ).append( ":\\\"" ) - .append( getLangLabel() ).append( "\\\"," ) - .append( JsonReportEntry.ATT_INVOCID ).append( ':' ) - .append( getTicketId() ).append( ',' ) - .append( JsonReportEntry.ATT_FILE ).append( ":\\\"$1\\\"," ) - .append( JsonReportEntry.ATT_KEY ).append( ":\\\"$2\\\"," ) - .append( JsonReportEntry.ATT_VALUE ).append( ":$3}\" >> " ) - .append( REPORT_FILENAME ); - - return defFunction( FUN_LOGFILE, null, new String[] { "file", "key", "payload" }, buf.toString() ); - } - - @Override - protected String defFunctionNormalize() throws NotDerivableException { - return defFunction( - FUN_NORMALIZE, - null, - new String[] { "channel", "f" }, - "echo "+getTicketId()+"_"+"${channel}_${f##*/}\n" ); - } - - @Override - protected String dereference(String varName) { - return "$"+varName; - } - - @Override - protected String fileSize(String filename) { - // return "`du -b -L "+filename+" | awk '{print $1}'`"; - // return "`stat -c %s "+filename+"`"; - return "`du -k -L "+filename+" | awk '{print $1}'`"; - } - - @Override - protected String forEach(String listName, String elementName, String body) { - - StringBuffer buf; - - buf = new StringBuffer(); - - buf.append( "for " ).append( elementName ).append( " in "+bashAllFrom( listName )+"\ndo\n" ); - buf.append( body ); - buf.append( "\ndone\n" ); - - return buf.toString(); - } - - @Override - protected String getImport() { - return ""; - } - - @Override - protected String getShebang() { - return BASH_SHEBANG; - } - - @Override - protected String ifListIsNotEmpty( String listName, String body ) { - return bashIfNotEquals( bashArraySize( listName ), "0", body ); - } - - @Override - protected String ifNotFileExists( String filename, String body ) { - - String ret; - - if( filename == null ) - throw new NullPointerException( "Filename must not be null." ); - - if( filename.isEmpty() ) - throw new RuntimeException( "Filename must not be empty." ); - - if( body == null ) - throw new NullPointerException( "Then block must not be null." ); - - if( body.isEmpty() ) - throw new RuntimeException( "Then block must not be empty." ); - - - ret = "if [ ! -e "+filename+" ]\nthen\n"+body+"\n"; - - ret += "fi\n"; - - return ret; - } - - @Override - protected String join( String... elementList ) { - - StringBuffer buf; - - buf = new StringBuffer(); - for( String element : elementList ) - buf.append( element ); - return buf.toString(); - } - - @Override - protected String listAppend( String listName, String element ) { - return listName+"=("+bashAllFrom( listName )+" "+element+")\n"; - } - - @Override - protected String listToBraceCommaSeparatedString( String src, String dest, String open, String close ) { - return dest+"=`printf \",%s\" ${"+src+"[@]}`\n"+dest+"="+open+"${"+dest+":1}"+close+"\n"; - } - - @Override - protected String newList( String listName ) { - return listName+"=\"\"\n"; - } - - @Override - protected String quote( String content ) { - - String ret; - - ret = "\""+content.replace( "\"", "\\\"" )+"\""; - - return ret; - } - - @Override - protected String raise( String msg ) { - return "echo "+msg+" >&2\nexit -1"; - } - - @Override - protected String symlink( String src, String dest ) { - // return "mv -f "+src+" "+dest+"\n"; - return "ln -s "+src+" "+dest+"\n"; - } - - @Override - protected String varDef( String varname, CompoundExpr list ) throws NotDerivableException { - - StringBuffer buf; - - buf = new StringBuffer(); - - buf.append( varname ).append( "=( " ); - for( String s : list.normalize() ) - buf.append( '"' ).append( s ).append( "\" " ); - buf.append( ")\n" ); - - return buf.toString(); - - } - - @Override - protected String varDef( String varname, String value ) { - return varname+"="+value+"\n"; - } - - @Override - protected String getLibPath() { - throw new UnsupportedOperationException( "NYI" ); - } - - -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/BeanshellInvocation.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/BeanshellInvocation.java deleted file mode 100644 index 683c42a..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/BeanshellInvocation.java +++ /dev/null @@ -1,273 +0,0 @@ -package de.huberlin.wbi.cuneiform.core.invoc; - -import de.huberlin.wbi.cuneiform.core.semanticmodel.CompoundExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.JsonReportEntry; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NotDerivableException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Ticket; - -public class BeanshellInvocation extends Invocation { - - public BeanshellInvocation( Ticket ticket, String libPath ) { - super( ticket, libPath ); - } - - @Override - protected String callFunction( String name, String... argValue ) { - - StringBuffer buf; - boolean comma; - - buf = new StringBuffer(); - - buf.append( name ).append( '(' ); - - comma = false; - for( String arg : argValue ) { - - if( comma ) - buf.append( ',' ); - comma = true; - - buf.append( arg ); - } - - buf.append( ")" ); - - return buf.toString(); - } - - @Override - protected String callProcedure( String name, String... argValue ) { - return callFunction( name, argValue )+";\n"; - } - - @Override - protected String clip( String varName ) { - return varName+"="+varName+".substring(1);\n"; - } - - @Override - protected String comment( String comment ) { - return "// "+comment+"\n"; - } - - @Override - protected String copyArray( String from, String to ) { - return to+"=new ArrayList();\nto.addAll("+from+");\n"; - } - - @Override - protected String defFunctionLog() throws NotDerivableException { - - StringBuffer buf; - - buf = new StringBuffer(); - - buf.append( "void "+FUN_LOG+"( String key, String value ) {\n" ); - - buf.append( " FileWriter writer = new FileWriter(\""+REPORT_FILENAME+"\",true);\n" ); - buf.append( " writer.write(\"{" ); - - buf.append( JsonReportEntry.ATT_TIMESTAMP ) - .append( ':' ).append( System.currentTimeMillis() ).append( ',' ) - .append( JsonReportEntry.ATT_RUNID ).append( ":\\\"" ) - .append( getRunId() ).append( "\\\"," ) - .append( JsonReportEntry.ATT_TASKID ).append( ':' ) - .append( getTaskId() ).append( ',' ); - - if( hasTaskName() ) - buf.append( JsonReportEntry.ATT_TASKNAME ).append( ":\\\"" ) - .append( getTaskName() ).append( "\\\"," ); - - buf.append( JsonReportEntry.ATT_LANG ).append( ":\\\"" ) - .append( getLangLabel() ).append( "\\\"," ) - .append( JsonReportEntry.ATT_INVOCID ).append( ':' ) - .append( getTicketId() ).append( ',' ) - .append( JsonReportEntry.ATT_KEY ).append( ":\\\"\"+key+\"\\\"," ) - .append( JsonReportEntry.ATT_VALUE ).append( ":\"+value+\"}\\n\"" ); - - buf.append( ");\n writer.close();\n" ); - - buf.append( "}\n" ); - - return buf.toString(); - } - - @Override - protected String defFunctionLogFile() throws NotDerivableException { - - StringBuffer buf; - - buf = new StringBuffer(); - - buf.append( "void "+FUN_LOGFILE+"( String file, String key, String value ) {\n" ); - - buf.append( " FileWriter writer = new FileWriter(\""+REPORT_FILENAME+"\",true);\n" ); - buf.append( " writer.write(\"{" ); - - buf.append( JsonReportEntry.ATT_TIMESTAMP ) - .append( ':' ).append( System.currentTimeMillis() ).append( ',' ) - .append( JsonReportEntry.ATT_RUNID ).append( ":\\\"" ) - .append( getRunId() ).append( "\\\"," ) - .append( JsonReportEntry.ATT_TASKID ).append( ':' ) - .append( getTaskId() ).append( ',' ); - - if( hasTaskName() ) - buf.append( JsonReportEntry.ATT_TASKNAME ).append( ":\\\"" ) - .append( getTaskName() ).append( "\\\"," ); - - buf.append( JsonReportEntry.ATT_LANG ).append( ":\\\"" ) - .append( getLangLabel() ).append( "\\\"," ) - .append( JsonReportEntry.ATT_INVOCID ).append( ':' ) - .append( getTicketId() ).append( ',' ) - .append( JsonReportEntry.ATT_FILE ).append( ":\\\"\"+file+\"\\\"," ) - .append( JsonReportEntry.ATT_KEY ).append( ":\\\"\"+key+\"\\\"," ) - .append( JsonReportEntry.ATT_VALUE ).append( ":\"+value+\"}\\n\"" ); - - buf.append( ");\n writer.close();\n" ); - - buf.append( "}\n" ); - - return buf.toString(); - } - - @Override - protected String defFunctionNormalize() throws NotDerivableException { - - StringBuffer buf; - - buf = new StringBuffer(); - - buf.append( "String "+FUN_NORMALIZE+"(int channel, String filename) {" ); - buf.append( " Path p = Paths.get(filename, new String[] {});\n"); - buf.append( " return \""+getTicketId()+"_\"+channel+\"_\"+p.getName(p.getNameCount()-1);\n" ); - buf.append( "}\n" ); - - return buf.toString(); - } - - @Override - protected String dereference( String varName ) { - return varName; - } - - @Override - protected String fileSize( String filename ) { - return "Files.size(Paths.get("+filename+")).toString()"; - } - - @Override - protected String forEach( String listName, String elementName, String body ) { - return "for(String "+elementName+":"+listName+") {\n"+body+"\n}\n"; - } - - @Override - protected String getShebang() { - return "#!/usr/bin/env bsh"; - } - - @Override - protected String getLibPath() { - throw new UnsupportedOperationException( "NYI" ); - } - - @Override - protected String getImport() { - return "import java.nio.file.Paths;\nimport java.io.FileWriter;\n" - +"import java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.attribute.FileAttribute;\n"; - } - - @Override - protected String ifListIsNotEmpty(String listName, String body) { - return( "if(!"+listName+".isEmpty()) {\n"+body+"\n}\n" ); - } - - @Override - protected String ifNotFileExists(String fileName, String body) { - return( "if(!Files.exists(Paths.get("+fileName+"))) {\n"+body+"\n}\n" ); - } - - @Override - protected String declareString( String outputName ) { - return "String "+outputName+";\n"; - } - - @Override - protected String declareList( String paramName ) { - return "List "+paramName+";\n"; - } - - @Override - protected String join( String... elementList ) { - - StringBuffer buf; - boolean comma; - - buf = new StringBuffer(); - - comma = false; - for( String element : elementList ) { - - if( comma ) - buf.append( "+" ); - comma = true; - - buf.append( element ); - } - - return buf.toString(); - } - - @Override - protected String listAppend(String listName, String element) { - return listName+"="+listName+":+"+element+"\n"; - } - - @Override - protected String listToBraceCommaSeparatedString(String listName, String stringName, String open, String close) { - return stringName+"=\""+open+"\"+"+listName+".mkString(\",\")+\""+close+"\"\n"; - } - - @Override - protected String newList( String listName ) { - return "var "+listName+"=List()\n"; - } - - @Override - protected String quote( String content ) { - return "\""+content.replace( "\"", "\\\"" )+"\""; - } - - @Override - protected String raise( String msg ) { - return "throw new RuntimeException("+msg+")\n"; - } - - @Override - protected String symlink( String src, String dest ) { - return "Files.createSymbolicLink(Paths.get("+dest+", new String[] {}),Paths.get("+src+", new String[] {}), new FileAttribute[] {});\n"; - } - - @Override - protected String varDef( String varname, String value ) { - return varname+"="+value+";\n"; - } - - @Override - protected String varDef( String varname, CompoundExpr ce ) throws NotDerivableException { - - StringBuffer buf; - int i, n; - - buf = new StringBuffer(); - - buf.append( varname+"=new ArrayList();\n" ); - - n = ce.getNumAtom(); - for( i = 0; i < n; i++ ) - buf.append( varname+".add(\""+ce.getStringExprValue( i )+"\");\n" ); - - return buf.toString(); - } - -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/Invocation.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/Invocation.java deleted file mode 100644 index 281fc29..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/Invocation.java +++ /dev/null @@ -1,886 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.invoc; - -import java.nio.file.Path; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import de.huberlin.wbi.cuneiform.core.semanticmodel.CompoundExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.DataType; -import de.huberlin.wbi.cuneiform.core.semanticmodel.ForeignLambdaExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.JsonReportEntry; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NameExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NotBoundException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NotDerivableException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Param; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Prototype; -import de.huberlin.wbi.cuneiform.core.semanticmodel.ReduceVar; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CfSemanticModelVisitor; -import de.huberlin.wbi.cuneiform.core.semanticmodel.StringExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Ticket; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Type; - -public abstract class Invocation { - - private static final Map libPathMap = new HashMap<>(); - - protected static final String FUN_LOG = "cflogmsg"; - protected static final String FUN_LOGFILE = "cflogfilemsg"; - protected static final String FUN_NORMALIZE = "cfnormalize"; - public static final String REPORT_FILENAME = "__report__.txt"; - public static final String SCRIPT_NAME = "cfscript"; - public static final String SUCCESS_FILENAME = "__success__"; - public static final String STDOUT_FILENAME = "__stdout__.txt"; - public static final String STDERR_FILENAME = "__stderr__.txt"; - public static final String LOCK_FILENAME = "__lock__"; - - - protected final String libPath; - private final Ticket ticket; - - public Invocation( Ticket ticket, String libPath ) { - - if( ticket == null ) - throw new NullPointerException( "Ticket must not be null." ); - - this.ticket = ticket; - this.libPath = libPath; - } - - public void evalReport( Set report ) throws JSONException { - - if( report == null ) - throw new NullPointerException( "Report entry set must not be null." ); - - for( JsonReportEntry entry : report ) - evalReport( entry ); - } - - public void evalReport( JsonReportEntry entry ) throws JSONException { - - JSONObject obj; - JSONArray array; - CompoundExpr ce; - int i, n; - - if( entry == null ) - throw new NullPointerException( "Report entry must not be null." ); - - - if( !entry.getKey().equals( JsonReportEntry.KEY_INVOC_OUTPUT ) ) - return; - - - obj = entry.getValueJsonObj(); - - - for( NameExpr nameExpr : ticket.getOutputList() ) { - - array = obj.getJSONArray( nameExpr.getId() ); - ce = new CompoundExpr(); - n = array.length(); - - for( i = 0; i < n; i++ ) - ce.addSingleExpr( new StringExpr( array.getString( i ) ) ); - - ticket.setValue( nameExpr, ce ); - } - - } - - @SuppressWarnings( "static-method" ) - public String[] getCmd() { - return new String[] { "./"+SCRIPT_NAME }; - } - - @SuppressWarnings( "static-method" ) - public Path getExecutablePath( Path location ) { - return location.resolve( SCRIPT_NAME ); - } - - public JsonReportEntry getExecutableLogEntry() { - return ticket.getExecutableLogEntry(); - } - - public JsonReportEntry getScriptLogEntry() throws NotBoundException, NotDerivableException { - return new JsonReportEntry( ticket, JsonReportEntry.KEY_INVOC_SCRIPT, toScript() ); - } - - public String getFunDef() throws NotDerivableException { - return defFunctionLog() - +defFunctionNormalize() - +defFunctionLogFile(); - } - - public String getLangLabel() { - return ticket.getLangLabel(); - } - - public Set getStageInList() throws NotDerivableException { - - CompoundExpr ce; - Set set; - - try { - - set = new HashSet<>(); - - for( NameExpr nameExpr : ticket.getNameSet() ) - - if( isParamStage( nameExpr.getId() ) ) { - - ce = ticket.getExpr( nameExpr ); - for( String s : ce.normalize() ) - set.add( s ); - } - - return set; - } - catch( NotBoundException e ) { - throw new RuntimeException( e.getMessage() ); - } - } - - /** Get the union of all files that have been created by this invocation. - * - * All the files created in the execution of the invocation are subsumed - * independent of the channel in which they appear. - * - * This method assumes that the method Invocation.evalReport() has been - * called with the report created during execution of this invocation. - * Otherwise, a NotBoundException will be rethrown as a RuntimeException. - * - * @return A set of strings containing relative file names. - * @throws NotDerivableException if normalization fails - */ - public Set getStageOutList() throws NotDerivableException { - - CompoundExpr ce; - Set set; - - try { - - set = new HashSet<>(); - - for( NameExpr nameExpr : ticket.getOutputList() ) - - if( isOutputStage( nameExpr.getId() ) ) { - - ce = ticket.getOutputValue( nameExpr ); - for( String s : ce.normalize() ) - set.add( s ); - } - - return set; - } - catch( NotBoundException e ) { - throw new RuntimeException( e.getMessage() ); - } - } - - public UUID getRunId() { - return ticket.getRunId(); - } - - public long getTaskId() { - return ticket.getLambdaId(); - } - - public String getTaskName() { - return ticket.getTaskName(); - } - - public Ticket getTicket() { - return ticket; - } - - public long getTicketId() { - return ticket.getTicketId(); - } - - public boolean hasTaskName() { - return ticket.hasTaskName(); - } - - public boolean hasLibPath() { - return libPath != null; - } - - public String toScript() throws NotBoundException, NotDerivableException { - - StringBuffer buf; - - buf = new StringBuffer(); - - // insert shebang - buf.append( getShebang() ).append( '\n' ); - - // import libraries - buf.append( comment( "import libraries" ) ); - buf.append( getImport() ).append( '\n' ); - - // modify library path - buf.append( comment( "modify library path" ) ); - if( hasLibPath() ) - buf.append( getLibPath() ); - - // define necessary functions - buf.append( comment( "define necessary functions" ) ); - buf.append( getFunDef() ).append( '\n' ); - - // bind single output variables to default values - buf.append( comment( "bind single output variables to default values" ) ); - for( String outputName : getSingleOutputNameSet() ) { - buf.append( declareString( outputName ) ); - buf.append( - varDef( - outputName, - quote( outputName ) ) ); - } - buf.append( '\n' ); - - // bind input parameters - buf.append( comment( "bind input parameters" ) ); - for( String paramName : getSingleParamNameSet() ) { - - if( paramName.equals( CfSemanticModelVisitor.LABEL_TASK ) ) - continue; - - buf.append( declareString( paramName ) ); - buf.append( varDef( paramName, quote( getResolveableBoundToSingleParam( paramName ) ) ) ); - } - for( String paramName : getReduceParamNameSet() ) { - - buf.append( declareList( paramName ) ); - buf.append( varDef( paramName, getReduceParam( paramName ) ) ); - } - buf.append( '\n' ); - - // report stage in file sizes and report error when something is missing - buf.append( comment( "report stage in file sizes and report error when something is missing" ) ); - buf.append( getStageInCollect() ).append( '\n' ); - - // insert body prefix - buf.append( comment( "insert body prefix" ) ); - buf.append( getBodyPrefix() ).append( '\n' ); - - - // insert function body - buf.append( comment( "insert function body" ) ); - buf.append( postProcess( ticket.getBody() ) ).append( '\n' ); - - // rename output files - buf.append( comment( "rename output files" ) ); - buf.append( getOutputRename() ).append( '\n' ); - - // collect output variables - buf.append( comment( "collect output variables" ) ); - buf.append( getOutputCollect() ).append( '\n' ); - - // collect stage out information - buf.append( comment( "collect stage out information" ) ); - buf.append( getStageOutCollect() ).append( '\n' ); - - return buf.toString(); - } - - @SuppressWarnings({ "static-method", "unused" }) - protected String declareList( String paramName ) { - return ""; - } - - @SuppressWarnings({ "static-method", "unused" }) - protected String declareString( String outputName ) { - return ""; - } - - @SuppressWarnings( "static-method" ) - protected String getImport() { - return ""; - } - - @SuppressWarnings("static-method") - protected String getBodyPrefix() { - return ""; - } - - protected abstract String callFunction( String name, String... argValue ); - protected abstract String callProcedure( String name, String... argValue ); - - /** Removes the first character of a string. - * - * @param varName The name of the variable that holds the input string. - * @return A statement in the foreign language. - */ - protected abstract String clip( String varName ); - - protected abstract String comment( String comment ); - protected abstract String copyArray( String from, String to ); - protected abstract String defFunctionLog() throws NotDerivableException; - protected abstract String defFunctionLogFile() throws NotDerivableException; - protected abstract String defFunctionNormalize() throws NotDerivableException; - protected abstract String dereference( String varName ); - protected abstract String fileSize( String filename ); - protected abstract String forEach( String listName, String elementName, String body ); - protected abstract String getShebang(); - protected abstract String getLibPath(); - protected abstract String ifListIsNotEmpty( String listName, String body ); - - protected abstract String ifNotFileExists( String fileName, String body ); - protected abstract String join( String ... elementList ); - protected abstract String listAppend( String listName, String element ); - protected abstract String listToBraceCommaSeparatedString( String listName, String stringName, String open, String close ); - protected abstract String newList( String listName ); - protected abstract String quote( String content ); - protected abstract String raise( String msg ); - protected abstract String symlink( String src, String dest ); - protected abstract String varDef( String varname, String value ); - protected abstract String varDef( String varname, CompoundExpr ce ) throws NotDerivableException; - - private boolean isOutputStage( String outputName ) { - - Prototype prototype; - Type type; - DataType dataType; - - prototype = ticket.getPrototype(); - - for( NameExpr nameExpr : prototype.getOutputList() ) - - if( nameExpr.getId().equals( outputName ) ) { - - if( !nameExpr.hasType() ) - return false; - - type = nameExpr.getType(); - if( !( type instanceof DataType ) ) - return false; - - dataType = ( DataType )type; - - return dataType.getId().equals( CfSemanticModelVisitor.LABEL_FILE ); - } - - throw new RuntimeException( "Output not found." ); - } - - private boolean isParamStage( String paramName ) { - - Prototype prototype; - Type type; - DataType dataType; - - prototype = ticket.getPrototype(); - - for( NameExpr nameExpr : prototype.getParamNameSet() ) - - if( nameExpr.getId().equals( paramName ) ) { - - if( !nameExpr.hasType() ) - return false; - - type = nameExpr.getType(); - if( !( type instanceof DataType ) ) - return false; - - dataType = ( DataType )type; - - return dataType.getId().equals( CfSemanticModelVisitor.LABEL_FILE ); - } - - throw new RuntimeException( "Output not found." ); - } - - private int getOutputChannel( String outputName ) { - - Prototype prototype; - int i, n; - NameExpr output; - - prototype = ticket.getPrototype(); - n = prototype.getNumOutput(); - - - for( i = 0; i < n; i++ ) { - - output = prototype.getOutput( i ); - - if( output.getId().equals( outputName ) ) - return i+1; - } - - throw new RuntimeException( "Output not found." ); - } - - protected String getOutputCollect() { - - StringBuffer buf; - - buf = new StringBuffer(); - - buf.append( declareString( "CFSTR" ) ); - - buf.append( varDef( "CFSTR", quote( "" ) ) ); - for( String outputName : getSingleOutputNameSet() ) - - buf.append( - varDef( - "CFSTR", - join( - dereference( "CFSTR" ), - quote( "," ), - quote( outputName+":[\"" ), - dereference( outputName ), - quote( "\"]" ) ) ) ); - - - buf.append( declareString( "CFSTR1" ) ); - buf.append( declareString( "CFI" ) ); - for( String outputName : getReduceOutputNameSet() ) { - - buf - .append( varDef( "CFSTR1", quote( "" ) ) ) - .append( - forEach( - outputName, - "CFI", - varDef( - "CFSTR1", - join( - dereference( "CFSTR1" ), - quote( ",\"" ), - dereference( "CFI" ), - quote( "\"" ) ) ) ) ) - .append( clip( "CFSTR1" ) ) - .append( - varDef( - "CFSTR", - join( - dereference( "CFSTR" ), - quote( "," ), - quote( outputName+":[" ), - dereference( "CFSTR1" ), - quote( "]" ) ) ) ); - } - - buf - .append( clip( "CFSTR" ) ) - - .append( - varDef( - "CFSTR", - join( - quote( "{" ), - dereference( "CFSTR" ), - quote( "}" ) ) ) ) - - .append( - callProcedure( - FUN_LOG, - quote( JsonReportEntry.KEY_INVOC_OUTPUT ), - dereference( "CFSTR" ) ) ).append( '\n' ); - - - return buf.toString(); - - } - - protected String getOutputRename() { - - StringBuffer buf; - - buf = new StringBuffer(); - - buf.append( declareString( "CFFILENAME" ) ); - - for( String outputName : getSingleOutputNameSet() ) - - if( isOutputStage( outputName ) ) { - - buf.append( - varDef( - "CFFILENAME", - callFunction( - FUN_NORMALIZE, - String.valueOf( getOutputChannel( outputName ) ), - dereference( outputName ) ) ) ); - - buf.append( - symlink( - dereference( outputName ), - dereference( "CFFILENAME" ) ) ); - - buf.append( - varDef( - outputName, - dereference( "CFFILENAME" ) ) ); - } - - for( String outputName : getReduceOutputNameSet() ) - - if( isOutputStage( outputName ) ) { - - buf.append( newList( "CFLIST" ) ); - - buf.append( - forEach( - outputName, - "CFFILENAME", - - varDef( - "CFNEWFILENAME", - callFunction( - FUN_NORMALIZE, - String.valueOf( - getOutputChannel( outputName ) ), - dereference( "CFFILENAME" ) ) ) - - +listAppend( "CFLIST", dereference( "CFNEWFILENAME" ) ) - - +symlink( - dereference( "CFFILENAME" ), - dereference( "CFNEWFILENAME" ) ) ) ); - - // buf.append( varDef( outputName, dereference( "__LIST" ) ) ); - buf.append( copyArray( "CFLIST", outputName ) ); - } - - return buf.toString(); - } - - private Set getReduceOutputNameSet() { - - List outputList; - Set reduceList; - - outputList = ticket.getOutputList(); - reduceList = new HashSet<>(); - - for( NameExpr nameExpr : outputList ) - - if( nameExpr instanceof ReduceVar ) - reduceList.add( nameExpr.getId() ); - - return reduceList; - } - - protected Set getReduceParamNameSet() { - - Set paramSet; - Set reduceList; - - paramSet = ticket.getParamSet(); - reduceList = new HashSet<>(); - - for( Param param : paramSet ) - - if( param instanceof ReduceVar ) - reduceList.add( ( ( ReduceVar )param ).getId() ); - - - return reduceList; - } - - protected CompoundExpr getReduceParam( String paramName ) throws NotBoundException { - return ticket.getExpr( paramName ); - } - - protected String getResolveableBoundToSingleParam( String paramName ) - throws NotBoundException, NotDerivableException { - return ticket.getExpr( paramName ).normalize().get( 0 ); - } - - protected Set getSingleOutputNameSet() { - - List outputList; - Set nonReduceList; - - outputList = ticket.getOutputList(); - nonReduceList = new HashSet<>(); - - for( NameExpr nameExpr : outputList ) - - if( !( nameExpr instanceof ReduceVar ) ) - nonReduceList.add( nameExpr.getId() ); - - return nonReduceList; - } - - protected Set getSingleParamNameSet() { - - Set paramSet; - Set nonReduceList; - - paramSet = ticket.getParamSet(); - nonReduceList = new HashSet<>(); - - for( Param param : paramSet ) - - if( !( param instanceof ReduceVar ) ) - for( NameExpr nameExpr : param.getNameExprSet() ) - nonReduceList.add( nameExpr.getId() ); - - return nonReduceList; - - } - - protected String getStageInCollect() { - - StringBuffer buf; - - buf = new StringBuffer(); - - buf.append( declareString( "SIZE" ) ); - - - for( String inputName : getSingleParamNameSet() ) - if( isParamStage( inputName ) ) - buf - .append( ifNotFileExists( - dereference( inputName ), - raise( join( quote( "Stage in: A file " ), dereference( inputName ), - quote( " should be present but has not been found." ) ) ) ) ) - - .append( varDef( "SIZE", fileSize( dereference( inputName ) ) ) ) - - .append( - callProcedure( - FUN_LOGFILE, - dereference( inputName ), - quote( JsonReportEntry.KEY_FILE_SIZE_STAGEIN ), - dereference( "SIZE" ) ) ).append( '\n' ); - - - for( String inputName : getReduceParamNameSet() ) - if( isParamStage( inputName ) ) - - buf.append( - forEach( - inputName, - "CFI", - ifNotFileExists( - dereference( "CFI" ), - raise( - join( - quote( "Stage in: A file " ), - dereference( "CFI" ), - quote( " should be present but has not been found." ) ) ) ) - - - +varDef( "SIZE", fileSize( dereference( "CFI" ) ) ) - - +callFunction( - FUN_LOGFILE, - dereference( "CFI" ), - quote( JsonReportEntry.KEY_FILE_SIZE_STAGEIN ), - dereference( "SIZE" ) ) ) ); - - return buf.toString(); - } - - protected String getStageOutCollect() { - - StringBuffer buf; - - buf = new StringBuffer(); - - - for( String outputName : getSingleOutputNameSet() ) - if( isOutputStage( outputName ) ) - buf - .append( ifNotFileExists( - dereference( outputName ), - raise( join( quote( "Stage out: A file " ), dereference( outputName ), - quote( " should have been created but has not been found." ) ) ) ) ) - - .append( varDef( "SIZE", fileSize( dereference( outputName ) ) ) ) - - .append( - callProcedure( - FUN_LOGFILE, - dereference( outputName ), - quote( JsonReportEntry.KEY_FILE_SIZE_STAGEOUT ), - dereference( "SIZE" ) ) ).append( '\n' ); - - - for( String outputName : getReduceOutputNameSet() ) - if( isOutputStage( outputName ) ) - - buf.append( - forEach( - outputName, - "CFI", - ifNotFileExists( - dereference( "CFI" ), - raise( - join( - quote( "Stage out: A file " ), - dereference( "CFI" ), - quote( " should be present but has not been found." ) ) ) ) - - - +varDef( "SIZE", fileSize( dereference( "CFI" ) ) ) - - +callFunction( - FUN_LOGFILE, - dereference( "CFI" ), - quote( JsonReportEntry.KEY_FILE_SIZE_STAGEOUT ), - dereference( "SIZE" ) ) ) ); - - return buf.toString(); - } - - @SuppressWarnings("static-method") - protected String postProcess( String body ) { return body; } - - public static Invocation createInvocation( Ticket ticket ) { - - String label, libPath; - - label = ticket.getLangLabel(); - libPath = libPathMap.get( label ); - - switch( label ) { - - case ForeignLambdaExpr.LANGID_BASH : return new BashInvocation( ticket, libPath ); - case ForeignLambdaExpr.LANGID_R : return new RInvocation( ticket, libPath ); - case ForeignLambdaExpr.LANGID_PERL : return new PerlInvocation( ticket, libPath ); - case ForeignLambdaExpr.LANGID_MATLAB : return new MatlabInvocation( ticket, libPath ); - case ForeignLambdaExpr.LANGID_OCTAVE : return new OctaveInvocation( ticket, libPath ); - case ForeignLambdaExpr.LANGID_PYTHON : return new PythonInvocation( ticket, libPath ); - case ForeignLambdaExpr.LANGID_LISP : return new LispInvocation( ticket, libPath ); - case ForeignLambdaExpr.LANGID_PEGASUS : return new PegasusInvocation( ticket, libPath ); - case ForeignLambdaExpr.LANGID_JAVA : - case ForeignLambdaExpr.LANGID_BEANSHELL : return new BeanshellInvocation( ticket, libPath ); - case ForeignLambdaExpr.LANGID_SCALA : return new ScalaInvocation( ticket, libPath ); - default : throw new RuntimeException( "Language label '"+label+"' not recognized." ); - } - } - - public static void putLibPath( String langId, String libPath ) { - - if( langId == null ) - throw new NullPointerException( "Language id must not be null." ); - - libPathMap.put( langId, libPath ); - } - - - public JsonReportEntry createJsonReportEntry( String file, String key, String value ) { - return new JsonReportEntry( - getRunId(), - getTaskId(), - getTaskName(), - getLangLabel(), - getTicketId(), - file, - key, - value ); - } - - public JsonReportEntry createJsonReportEntry( long timestamp, String file, String key, String value ) { - return new JsonReportEntry( - timestamp, - getRunId(), - getTaskId(), - getTaskName(), - getLangLabel(), - getTicketId(), - file, - key, - value ); - } - - public JsonReportEntry createJsonReportEntry( long timestamp, String file, String key, JSONObject value ) { - return new JsonReportEntry( - timestamp, - getRunId(), - getTaskId(), - getTaskName(), - getLangLabel(), - getTicketId(), - file, - key, - value ); - } - - public JsonReportEntry createJsonReportEntry( String key, String value ) { - return new JsonReportEntry( - getRunId(), - getTaskId(), - getTaskName(), - getLangLabel(), - getTicketId(), - null, - key, - value ); - } - - public JsonReportEntry createJsonReportEntry( long timestamp, String key, String value ) { - return new JsonReportEntry( - timestamp, - getRunId(), - getTaskId(), - getTaskName(), - getLangLabel(), - getTicketId(), - null, - key, - value ); - } - - public JsonReportEntry createJsonReportEntry( long timestamp, String key, JSONObject value ) { - return new JsonReportEntry( - timestamp, - getRunId(), - getTaskId(), - getTaskName(), - getLangLabel(), - getTicketId(), - null, - key, - value ); - } - - - -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/LispInvocation.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/LispInvocation.java deleted file mode 100644 index e13d5aa..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/LispInvocation.java +++ /dev/null @@ -1,159 +0,0 @@ -package de.huberlin.wbi.cuneiform.core.invoc; - -import de.huberlin.wbi.cuneiform.core.semanticmodel.CompoundExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NotDerivableException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Ticket; - -public class LispInvocation extends Invocation { - - public LispInvocation( Ticket ticket, String libPath ) { - super( ticket, libPath ); - } - - @Override - protected String callFunction(String name, String... argValue) { - // TODO Auto-generated method stub - return null; - } - - @Override - protected String callProcedure(String name, String... argValue) { - // TODO Auto-generated method stub - return null; - } - - @Override - protected String clip(String varName) { - // TODO Auto-generated method stub - return null; - } - - @Override - protected String comment(String comment) { - // TODO Auto-generated method stub - return null; - } - - @Override - protected String copyArray(String from, String to) { - // TODO Auto-generated method stub - return null; - } - - @Override - protected String defFunctionLog() throws NotDerivableException { - // TODO Auto-generated method stub - return null; - } - - @Override - protected String defFunctionLogFile() throws NotDerivableException { - // TODO Auto-generated method stub - return null; - } - - @Override - protected String defFunctionNormalize() throws NotDerivableException { - // TODO Auto-generated method stub - return null; - } - - @Override - protected String dereference(String varName) { - // TODO Auto-generated method stub - return null; - } - - @Override - protected String fileSize(String filename) { - // TODO Auto-generated method stub - return null; - } - - @Override - protected String forEach(String listName, String elementName, String body) { - // TODO Auto-generated method stub - return null; - } - - @Override - protected String getShebang() { - // TODO Auto-generated method stub - return null; - } - - @Override - protected String ifListIsNotEmpty(String listName, String body) { - // TODO Auto-generated method stub - return null; - } - - @Override - protected String ifNotFileExists(String fileName, String body) { - // TODO Auto-generated method stub - return null; - } - - @Override - protected String join(String... elementList) { - // TODO Auto-generated method stub - return null; - } - - @Override - protected String listAppend(String listName, String element) { - // TODO Auto-generated method stub - return null; - } - - @Override - protected String listToBraceCommaSeparatedString(String listName, - String stringName, String open, String close) { - // TODO Auto-generated method stub - return null; - } - - @Override - protected String newList(String listName) { - // TODO Auto-generated method stub - return null; - } - - @Override - protected String quote(String content) { - // TODO Auto-generated method stub - return null; - } - - @Override - protected String raise(String msg) { - // TODO Auto-generated method stub - return null; - } - - @Override - protected String symlink(String src, String dest) { - // TODO Auto-generated method stub - return null; - } - - @Override - protected String varDef(String varname, String value) { - // TODO Auto-generated method stub - return null; - } - - @Override - protected String varDef(String varname, CompoundExpr ce) - throws NotDerivableException { - // TODO Auto-generated method stub - return null; - } - - @Override - protected String getLibPath() { - // TODO Auto-generated method stub - return null; - } - -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/MatlabInvocation.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/MatlabInvocation.java deleted file mode 100644 index 8075ecf..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/MatlabInvocation.java +++ /dev/null @@ -1,143 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.invoc; - -import java.nio.file.Path; - -import de.huberlin.wbi.cuneiform.core.semanticmodel.CfSemanticModelVisitor; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NotBoundException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NotDerivableException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Ticket; - -public class MatlabInvocation extends OctaveInvocation { - - public MatlabInvocation( Ticket ticket, String libPath ) { - super( ticket, libPath ); - } - - @Override - protected String getShebang() { - return ""; - } - - @Override - public Path getExecutablePath( Path location ) { - return location.resolve( SCRIPT_NAME+".m" ); - } - - @Override - public String[] getCmd() { - - return new String[] { - "matlab", - "-nodisplay", - "-nosplash", - "-r", - SCRIPT_NAME }; - } - - @SuppressWarnings("static-method") - public String getScriptHead() { - return "function "+SCRIPT_NAME+"\ntry\n"; - } - - @SuppressWarnings("static-method") - public String getScriptFoot() { - return "catch ex\nex\nex.stack\nexit( -1 )\nend\nexit\nend\n"; - } - - @Override - public String toScript() throws NotBoundException, NotDerivableException { - - StringBuffer buf; - - buf = new StringBuffer(); - - // get script header - buf.append( comment( "script header" ) ); - buf.append( getScriptHead() ); - - // bind single output variables to default values - buf.append( comment( "bind single output variables to default values" ) ); - for( String outputName : getSingleOutputNameSet() ) - buf.append( - varDef( - outputName, - quote( outputName ) ) ); - buf.append( '\n' ); - - // bind input parameters - buf.append( comment( "bind input parameters" ) ); - for( String paramName : getSingleParamNameSet() ) { - - if( paramName.equals( CfSemanticModelVisitor.LABEL_TASK ) ) - continue; - - buf.append( varDef( paramName, quote( getResolveableBoundToSingleParam( paramName ) ) ) ); - } - for( String paramName : getReduceParamNameSet() ) - buf.append( varDef( paramName, getReduceParam( paramName ) ) ); - buf.append( '\n' ); - - // report stage in file sizes and report error when something is missing - buf.append( comment( "report stage in file sizes and report error when something is missing" ) ); - buf.append( getStageInCollect() ).append( '\n' ); - - // insert function body - buf.append( comment( "insert function body" ) ); - buf.append( getTicket().getBody() ).append( '\n' ); - - // rename output files - buf.append( comment( "rename output files" ) ); - buf.append( getOutputRename() ).append( '\n' ); - - // collect output variables - buf.append( comment( "collect output variables" ) ); - buf.append( getOutputCollect() ).append( '\n' ); - - // collect stage out information - buf.append( comment( "collect stage out information" ) ); - buf.append( getStageOutCollect() ).append( '\n' ); - - // script footer - buf.append( comment( "script footer" ) ); - buf.append( getScriptFoot() ); - - // define necessary functions - buf.append( comment( "define necessary functions" ) ); - buf.append( getFunDef() ).append( '\n' ); - - return buf.toString(); - } - -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/OctaveInvocation.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/OctaveInvocation.java deleted file mode 100644 index 36bffc6..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/OctaveInvocation.java +++ /dev/null @@ -1,346 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.invoc; - -import java.util.List; - -import de.huberlin.wbi.cuneiform.core.semanticmodel.CompoundExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.JsonReportEntry; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NotDerivableException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Ticket; - -public class OctaveInvocation extends Invocation { - - public OctaveInvocation( Ticket ticket, String libPath ) { - super( ticket, libPath ); - } - - @Override - protected String callFunction( String name, String... argValue ) { - - StringBuffer buf; - boolean comma; - - buf = new StringBuffer(); - - buf.append( name ).append( "( " ); - - comma = false; - for( String value : argValue ) { - - if( comma ) - buf.append( ", " ); - - comma = true; - - buf.append( value ); - } - - buf.append( " )" ); - - return buf.toString(); - } - - @Override - protected String callProcedure( String name, String... argValue ) { - return callFunction( name, argValue )+";\n"; - } - - @Override - protected String clip( String varName ) { - return varName+" = "+varName+"( 2:length( "+varName+" ) );\n"; - } - - @Override - protected String comment( String comment ) { - return "% "+comment+"\n"; - } - - @Override - protected String copyArray( String from, String to ) { - return to+" = "+from+";\n"; - } - - @Override - protected String defFunctionLog() throws NotDerivableException { - - StringBuffer buf; - - buf = new StringBuffer(); - - buf.append( "if( ~ischar( key ) ); error( 'Parameter ''key'' must be of type char.' ); end\n" ) - .append( "if( ~ischar( value ) ); error( 'Parameter ''value'' must be of type char.' ); end\n" ) - .append( "[fid msg] = fopen( '"+REPORT_FILENAME+"', 'a' );\n" ) - .append( "if( fid < 0 ); error( msg ); end\n" ) - .append( "fprintf( fid, '{" ) - .append( JsonReportEntry.ATT_TIMESTAMP+":"+System.currentTimeMillis()+"," ) - .append( JsonReportEntry.ATT_RUNID+":\""+getRunId()+"\"," ) - .append( JsonReportEntry.ATT_TASKID+":"+getTaskId()+"," ); - - if( this.hasTaskName() ) - buf.append( JsonReportEntry.ATT_TASKNAME+":\""+getTaskName()+"\"," ); - - buf.append( JsonReportEntry.ATT_LANG+":\""+getLangLabel()+"\"," ) - .append( JsonReportEntry.ATT_INVOCID+":"+getTicketId()+"," ) - .append( JsonReportEntry.ATT_KEY+":\"%s\"," ) - .append( JsonReportEntry.ATT_VALUE+":%s}\\n', key, value )\n" ) - .append( "if( fclose( fid ) < 0 ); error( 'Could not close report file' ); end" ); - - return defFunction( FUN_LOG, null, new String[] { "key", "value" }, buf.toString() ); - } - - @Override - protected String defFunctionLogFile() throws NotDerivableException { - - StringBuffer buf; - - buf = new StringBuffer(); - - buf.append( "if( ~ischar( key ) ); error( 'Parameter ''key'' must be of type char.' ); end\n" ) - .append( "if( ~ischar( value ) ); error( 'Parameter ''value'' must be of type char.' ); end\n" ) - .append( "[fid msg] = fopen( '"+REPORT_FILENAME+"', 'a' );\n" ) - .append( "if( fid < 0 ); error( msg ); end\n" ) - .append( "fprintf( fid, '{" ) - .append( JsonReportEntry.ATT_TIMESTAMP+":"+System.currentTimeMillis()+"," ) - .append( JsonReportEntry.ATT_RUNID+":\""+getRunId()+"\"," ) - .append( JsonReportEntry.ATT_TASKID+":"+getTaskId()+"," ); - - if( this.hasTaskName() ) - buf.append( JsonReportEntry.ATT_TASKNAME+":\""+getTaskName()+"\"," ); - - buf.append( JsonReportEntry.ATT_LANG+":\""+getLangLabel()+"\"," ) - .append( JsonReportEntry.ATT_INVOCID+":"+getTicketId()+"," ) - .append( JsonReportEntry.ATT_FILE+":\"%s\"," ) - .append( JsonReportEntry.ATT_KEY+":\"%s\"," ) - .append( JsonReportEntry.ATT_VALUE+":%s}\\n', file, key, value )\n" ) - .append( "if( fclose( fid ) < 0 ); error( 'Could not close report file' ); end" ); - - return defFunction( FUN_LOGFILE, null, new String[] { "file", "key", "value" }, buf.toString() ); - } - - @Override - protected String defFunctionNormalize() throws NotDerivableException { - - return defFunction( - FUN_NORMALIZE, - null, - new String[] { "channel", "f" }, - "sprintf( '"+getTicketId() - +"_%d_%s', channel, f )\n" ); - } - - @Override - protected String dereference( String varName ) { - return varName; - } - - @Override - protected String fileSize( String filename ) { - return "stat( "+filename+" ).size"; - } - - @Override - protected String forEach( String listName, String elementName, String body ) { - - StringBuffer buf; - - buf = new StringBuffer(); - - buf.append( "for i = 1:length( " ).append( listName ).append( ")\n" ); - buf.append( varDef( elementName, listName+"{ i };\n" ) ); - buf.append( body ); - buf.append( "\nend\n" ); - - return buf.toString(); - } - - @Override - protected String getShebang() { - return "#!/usr/bin/octave -q\n"; - } - - @Override - protected String ifListIsNotEmpty( String listName, String body ) { - return "if ~isempty( "+listName+" )\n"+body+"\nend\n"; - } - - @Override - protected String ifNotFileExists( String fileName, String body ) { - return "if exist( "+fileName+", 'file' ) == 2\n"+body+"\nend\n"; - } - - @Override - protected String join( String... elementList ) { - - StringBuffer buf; - boolean comma; - - buf = new StringBuffer(); - - buf.append( "[" ); - - comma = false; - for( String element : elementList ) { - - if( comma ) - buf.append( " " ); - comma = true; - - buf.append( element ); - } - buf.append( "]" ); - - return buf.toString(); - } - - @Override - protected String listAppend( String listName, String element ) { - return listName+" = ["+listName+" {"+element+"}];"; - } - - @Override - protected String listToBraceCommaSeparatedString(String listName, - String stringName, String open, String close) { - - StringBuffer buf; - - buf = new StringBuffer(); - - buf.append( stringName ).append( " = '" ).append( open ); - buf.append( "';\n__COMMA = false;\n" ); - buf.append( - octaveForLoop( "i", "length( "+listName+" )", - "if( __COMMA ); ret = [ret ',']; end\n__COMMA = true;\n" - +"ret = [ret "+listName+"{ i }];\n" ) ); - buf.append( "ret = [ret '" ).append( close ).append( "'];" ); - - return buf.toString(); - } - - @Override - protected String newList( String listName ) { - return listName+" = {};\n"; - } - - @Override - protected String quote( String content ) { - return "'"+content+"'"; - } - - @Override - protected String raise( String msg ) { - return callProcedure( "error", msg ); - } - - @Override - protected String symlink(String src, String dest) { - return "system( sprintf( 'ln -s %s %s', "+src+", "+dest+" ) )"; - } - - @Override - protected String varDef( String varname, String value ) { - return varname+" = "+value+";\n"; - } - - @Override - protected String varDef( String varname, CompoundExpr ce ) - throws NotDerivableException { - - StringBuffer buf; - int i; - boolean comma; - List list; - - list = ce.normalize(); - - buf = new StringBuffer(); - - buf.append( varname ) - .append( " = {" ); - - comma = false; - for( i = 0; i < list.size(); i++ ) { - - if( comma ) - buf.append( ';' ); - - comma = true; - - buf.append( " '" ).append( list.get( i ) ).append( "'" ); - } - - buf.append( "};\n" ); - - return buf.toString(); - } - - private static String defFunction( String funName, String outputName, String[] inputNameList, String body ) { - - boolean comma; - StringBuffer buf; - - buf = new StringBuffer(); - - buf.append( "function " ); - - if( outputName != null ) - buf.append( outputName ).append( " = " ); - - buf.append( funName ).append( "( " ); - - comma = false; - for( String inputName : inputNameList ) { - - if( comma ) - buf.append( ", " ); - - comma = true; - - buf.append( inputName ); - } - - buf.append( " )\n" ).append( body ).append( "\nend\n" ); - - return buf.toString(); - } - - private static String octaveForLoop( String runVar, String times, String body ) { - return "for "+runVar+" = 1:"+times+"\n"+body+"\nend\n"; - } - - @Override - protected String getLibPath() { - // TODO Auto-generated method stub - return null; - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/PegasusInvocation.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/PegasusInvocation.java deleted file mode 100644 index 5c6c1b0..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/PegasusInvocation.java +++ /dev/null @@ -1,22 +0,0 @@ -package de.huberlin.wbi.cuneiform.core.invoc; - -import de.huberlin.wbi.cuneiform.core.semanticmodel.NotDerivableException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Ticket; - -public class PegasusInvocation extends BashInvocation { - - public PegasusInvocation( Ticket ticket, String libPath ) { - super( ticket, libPath ); - } - - @Override - public String getFunDef() throws NotDerivableException { - return defFunctionLog() - +defFunctionLogFile(); - } - - @Override - public String getOutputRename() { - return ""; - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/PerlInvocation.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/PerlInvocation.java deleted file mode 100644 index 87afc37..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/PerlInvocation.java +++ /dev/null @@ -1,347 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.invoc; - -import java.util.List; - -import de.huberlin.wbi.cuneiform.core.semanticmodel.CompoundExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.JsonReportEntry; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NotDerivableException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Ticket; - -public class PerlInvocation extends Invocation { - - public PerlInvocation( Ticket ticket, String libPath ) { - super( ticket, libPath ); - } - - @Override - protected String callFunction( String name, String... argValue ) { - - StringBuffer buf; - boolean comma; - - buf = new StringBuffer(); - - buf.append( "&" + name ).append( "( " ); - comma = false; - for( String arg : argValue ) { - - if( comma ) - buf.append( ", " ); - comma = true; - - buf.append( arg ); - } - - buf.append( " )" ); - - return buf.toString(); - } - - @Override - protected String callProcedure( String name, String... argValue ) { - - StringBuffer buf; - boolean comma; - - buf = new StringBuffer(); - - buf.append( "&" + name ).append( "( " ); - comma = false; - for( String arg : argValue ) { - - if( comma ) - buf.append( ", " ); - comma = true; - - buf.append( arg ); - } - - buf.append( " );\n" ); - - return buf.toString(); - } - - @Override - protected String clip( String varName ) { - - return "$"+varName+" = substr(\"$"+varName+"\",1);"; - } - - @Override - protected String comment( String comment ) { - return "# "+comment+"\n"; - } - - @Override - protected String copyArray( String from, String to ) { - return "@"+to+" = @"+from+";"; - } - - @Override - protected String defFunctionLog() throws NotDerivableException { - - StringBuffer buf; - - buf = new StringBuffer(); - - buf.append( "sub " ).append( FUN_LOG ).append( " {\n" ) - .append( " my ( $key, $value ) = @_;\n" ) - - .append( " my $logfile = \"" ).append( REPORT_FILENAME ).append( "\";\n" ) - .append( " open my $fh, \">>\", $logfile or die \"Can't open $logfile for appending log: $!\\n\";\n" ) - .append( " flock($fh, 2) or die \"Can't obtain write lock on $logfile:$!\\n\";\n" ) - - - // .append( " print $fh \"$key : $value\\\n\";\n" ) - - .append( " print $fh \"{" ) - .append( JsonReportEntry.ATT_TIMESTAMP ) - .append( ':' ).append( System.currentTimeMillis() ).append( ',' ) - .append( JsonReportEntry.ATT_RUNID ).append( ":\\\"" ) - .append( getRunId() ).append( "\\\"," ) - .append( JsonReportEntry.ATT_TASKID ).append( ':' ) - .append( getTaskId() ).append( ',' ); - - if( hasTaskName() ) - buf.append( JsonReportEntry.ATT_TASKNAME ).append( ":\\\"" ) - .append( getTaskName() ).append( "\\\"," ); - - buf.append( JsonReportEntry.ATT_LANG ).append( ":\\\"" ) - .append( getLangLabel() ).append( "\\\"," ) - .append( JsonReportEntry.ATT_INVOCID ).append( ':' ) - .append( getTicketId() ).append( ',' ) - .append( JsonReportEntry.ATT_KEY ).append( ":\\\"$key\\\"," ) - .append( JsonReportEntry.ATT_VALUE ).append( ":$value}\";\n" ) - - - .append( " close $fh or die \"Can't close $logfile after appending: $!\\n\";\n" ) - .append( "}\n" ); - - return buf.toString(); - } - - @Override - protected String defFunctionLogFile() throws NotDerivableException { - StringBuffer buf; - - buf = new StringBuffer(); - - buf.append( "sub " ).append( FUN_LOGFILE ).append( " {\n" ) - .append( " my ( $file, $key, $value ) = @_;\n" ) - - .append( " my $logfile = \"" ).append( REPORT_FILENAME ).append( "\";\n" ) - .append( " open my $fh, \">>\", $logfile or die \"Can't open $logfile for appending log: $!\\\n\";\n" ) - .append( " flock($fh, 2) or die \"Can't obtain write lock on $logfile:$!\\n\";\n" ) - - // .append( " print $fh \"$file : $key : $value\\\n\";\n" ) - - .append( " print $fh \"{" ) - .append( JsonReportEntry.ATT_TIMESTAMP ) - .append( ':' ).append( System.currentTimeMillis() ).append( ',' ) - .append( JsonReportEntry.ATT_RUNID ).append( ":\\\"" ) - .append( getRunId() ).append( "\\\"," ) - .append( JsonReportEntry.ATT_TASKID ).append( ':' ) - .append( getTaskId() ).append( ',' ); - - if( hasTaskName() ) - buf.append( JsonReportEntry.ATT_TASKNAME ).append( ":\\\"" ) - .append( getTaskName() ).append( "\\\"," ); - - buf.append( JsonReportEntry.ATT_LANG ).append( ":\\\"" ) - .append( getLangLabel() ).append( "\\\"," ) - .append( JsonReportEntry.ATT_INVOCID ).append( ':' ) - .append( getTicketId() ).append( ',' ) - .append( JsonReportEntry.ATT_FILE ).append( ":\\\"$file\\\"," ) - .append( JsonReportEntry.ATT_KEY ).append( ":\\\"$key\\\"," ) - .append( JsonReportEntry.ATT_VALUE ).append( ":$value}\";\n" ) - - .append( " close $fh or die \"Can't close $logfile after appending: $!\\n\";\n" ) - .append( "}\n" ); - - return buf.toString(); - } - - @Override - protected String defFunctionNormalize() throws NotDerivableException { - StringBuffer buf = new StringBuffer(); - - long id = getTicketId(); - buf.append( "sub " ).append( FUN_NORMALIZE ).append( " {\n" ) - .append( " my ( $channel, $f ) = @_;\n" ) - .append( " $f =~ m!([^/])+$!;\n" ) - .append(" my $fn = $1;\n") - .append(" die \"Can't determine filename from $f\\n\" unless $fn;\n") - .append(" return \"" ).append( id ).append( "_${channel}_$fn\";\n") - .append(" }\n" ); - - return buf.toString(); - } - - @Override - protected String dereference(String varName) { - return "$"+varName; - } - - @Override - protected String fileSize( String filename ) { - return "-s "+filename; - } - - @Override - protected String forEach(String listName, String elementName, String body) { - - StringBuffer buf; - - buf = new StringBuffer(); - - - buf.append( "for my $" ).append( elementName ).append( "(@" ) - .append( listName ).append( ") {\n" ) - .append( body ) - .append( "\n}\n" ); - - return buf.toString(); - } - - @Override - protected String getShebang() { - return "#!/usr/bin/env perl"; - } - - @Override - protected String ifListIsNotEmpty(String listName, String body) { - return "if (scalar "+listName+") {\n"+body+"\n}\n"; - - } - - @Override - protected String ifNotFileExists(String fileName, String body) { - return "unless (-e "+fileName+") {\n"+body+"\n}\n"; - } - - @Override - protected String join( String... elementList ) { - - StringBuffer buf; - - buf = new StringBuffer(); - buf.append("join('',("); - for (int i = 0; i < elementList.length; i++) { - buf.append( elementList[i] ); - if (i < elementList.length - 1) buf.append(","); - } - buf.append("))"); - return buf.toString(); - } - - @Override - protected String listAppend(String listName, String element) { - return "push @"+listName+", "+element+";\n"; - } - - @Override - protected String listToBraceCommaSeparatedString(String listName, - String stringName, String open, String close) { - return "$"+stringName + " = " + open + ".join(',', @"+listName+")."+ close +";\n"; - } - - @Override - protected String newList(String listName) { - return "@"+listName+" = ();\n"; - } - - @Override - protected String quote( String content ) { - - String ret; - - ret = "\""+content.replace( "\"", "\\\"" )+"\""; - - return ret; - } - - @Override - protected String raise( String msg ) { - return "die "+msg+";\n"; - } - - @Override - protected String symlink(String src, String dest) { - return "`ln -s "+src+" "+dest+"`;\n"; - } - - @Override - protected String varDef(String varname, String value) { - StringBuffer buf; - buf = new StringBuffer(); - - buf.append( "$"+ varname ).append( " = " ).append( value ).append(";\n"); - return buf.toString(); - } - - @Override - protected String varDef( String varname, CompoundExpr ce ) throws NotDerivableException { - StringBuffer buf; - int i; - boolean comma; - List list; - - list = ce.normalize(); - - buf = new StringBuffer(); - - comma = false; - buf.append( "@"+ varname ).append( " = ( " ); - for( i = 0; i < list.size(); i++ ) { - - if( comma ) - buf.append( ", " ); - comma = true; - - buf.append( "\"" ).append( list.get( i ) ).append( "\"" ); - } - - buf.append( " );\n" ); - - return buf.toString(); - } - - @Override - protected String getLibPath() { - // TODO Auto-generated method stub - return null; - } - -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/PythonInvocation.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/PythonInvocation.java deleted file mode 100644 index 5538902..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/PythonInvocation.java +++ /dev/null @@ -1,265 +0,0 @@ -package de.huberlin.wbi.cuneiform.core.invoc; - -import de.huberlin.wbi.cuneiform.core.semanticmodel.CompoundExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.JsonReportEntry; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NotDerivableException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Ticket; - -public class PythonInvocation extends Invocation { - - private static String defFunction( String funname, String[] inputNameList, String body ) { - - StringBuffer buf; - boolean comma; - - buf = new StringBuffer(); - - buf.append( "def " ).append( funname ).append( "( " ); - - comma = false; - for( String inputName : inputNameList ) { - - if( comma ) - buf.append( ", " ); - comma = true; - - buf.append( inputName ); - } - - buf.append( " ):\n " ); - - buf.append( body.replace( "\n", "\n " ) ); - buf.append( "\n" ); - - return buf.toString(); - } - - public PythonInvocation( Ticket ticket, String libPath ) { - super( ticket, libPath ); - } - - @Override - protected String callFunction( String name, String... argValue ) { - - StringBuffer buf; - boolean comma; - - buf = new StringBuffer(); - - buf.append( name ).append( '(' ); - - comma = false; - for( String arg : argValue ) { - - if( comma ) - buf.append( ',' ); - - comma = true; - - buf.append( arg ); - } - - buf.append( ")" ); - - return buf.toString(); - } - - @Override - protected String callProcedure( String name, String... argValue ) { - return callFunction( name, argValue )+"\n"; - } - - @Override - protected String clip( String varName ) { - return varName+" = "+varName+"[1:]\n"; - } - - @Override - protected String comment( String comment ) { - return "# "+comment.replace( "\n", "\n# " )+"\n"; - } - - @Override - protected String copyArray( String from, String to ) { - return to+" = copy.copy( "+from+" )\n"; - } - - @Override - protected String defFunctionLog() throws NotDerivableException { - return defFunction( FUN_LOG, new String[] { "key", "value" }, - "f = file(\""+REPORT_FILENAME+"\",\"a\")\nf.write("+"\"{" - +JsonReportEntry.ATT_TIMESTAMP+":"+System.currentTimeMillis()+"," - +JsonReportEntry.ATT_RUNID+":\\\""+getRunId()+"\\\"," - +JsonReportEntry.ATT_TASKID+":"+getTaskId()+"," - +JsonReportEntry.ATT_TASKNAME+":\\\""+getTaskName()+"\\\"," - +JsonReportEntry.ATT_LANG+":\\\""+getLangLabel()+"\\\"," - +JsonReportEntry.ATT_INVOCID+":"+getTicketId()+"," - +JsonReportEntry.ATT_KEY+":\\\"%s\\\"," - +JsonReportEntry.ATT_VALUE+":%s}\\n\"%(key,value))\nf.close()\n" ); - } - - @Override - protected String defFunctionLogFile() throws NotDerivableException { - return defFunction( FUN_LOGFILE, new String[] { "fx", "key", "value" }, - "f = file(\""+REPORT_FILENAME+"\",\"a\")\nf.write("+"\"{" - +JsonReportEntry.ATT_TIMESTAMP+":"+System.currentTimeMillis()+"," - +JsonReportEntry.ATT_RUNID+":\\\""+getRunId()+"\\\"," - +JsonReportEntry.ATT_TASKID+":"+getTaskId()+"," - +JsonReportEntry.ATT_TASKNAME+":\\\""+getTaskName()+"\\\"," - +JsonReportEntry.ATT_LANG+":\\\""+getLangLabel()+"\\\"," - +JsonReportEntry.ATT_INVOCID+":"+getTicketId()+"," - +JsonReportEntry.ATT_FILE+":\\\"%s\\\"," - +JsonReportEntry.ATT_KEY+":\\\"%s\\\"," - +JsonReportEntry.ATT_VALUE+":%s}\\n\"%(fx,key,value))\nf.close()\n" ); - } - - @Override - protected String defFunctionNormalize() throws NotDerivableException { - return defFunction( - FUN_NORMALIZE, - new String[] { "channel", "f" }, - "return \""+getTicketId()+"_%d_%s\"%(channel,os.path.basename(f))" ); - } - - @Override - protected String dereference( String varName ) { - return varName; - } - - @Override - protected String fileSize( String filename ) { - return "os.stat("+filename+").st_size"; - } - - @Override - protected String forEach( String listName, String elementName, String body ) { - return - "for "+elementName+" in "+listName+":\n " - +body.replace( "\n", "\n " )+"\n"; - } - - @Override - protected String getBodyPrefix() { - return "if True:\n"; - } - - @Override - protected String getImport() { - return "import copy, os, sys\n"; - } - - @Override - protected String getShebang() { - return "#!/usr/bin/env python\n"; - } - - @Override - protected String ifListIsNotEmpty( String listName, String body ) { - return "if not("+listName+"):\n "+body.replace( "\n", "\n " )+"\n"; - } - - @Override - protected String ifNotFileExists( String fileName, String body ) { - return - "if not(os.path.exists("+fileName+")):\n " - +body.replace( "\n", "\n " )+"\n"; - } - - @Override - protected String join( String... elementList ) { - - boolean comma; - StringBuffer buf; - - buf = new StringBuffer(); - - comma = false; - for( String element : elementList ) { - - if( comma ) - buf.append( '+' ); - - comma = true; - - buf.append( element ); - } - - return buf.toString(); - } - - @Override - protected String listAppend( String listName, String element ) { - return listName+".append("+element+")\n"; - } - - @Override - protected String listToBraceCommaSeparatedString( String listName, - String stringName, String open, String close ) { - return - stringName+"='"+open+"'+','.join( i for i in "+listName - +" )+'"+close+"'\n"; - } - - @Override - protected String newList( String listName ) { - return listName+"=[]\n"; - } - - @Override - protected String quote( String content ) { - return "\""+content.replace( "\\", "\\\\" ).replace( "\"", "\\\"")+"\""; - } - - @Override - protected String raise( String msg ) { - return "raise Exception("+quote( msg )+")"; - } - - @Override - protected String symlink( String src, String dest ) { - return "os.symlink("+src+","+dest+")\n"; - } - - @Override - protected String varDef( String varname, CompoundExpr ce ) - throws NotDerivableException { - - StringBuffer buf; - boolean comma; - - buf = new StringBuffer(); - - buf.append( varname ).append( "=[" ); - - comma = false; - for( String s : ce.normalize() ) { - - if( comma ) - buf.append( ',' ); - - comma = true; - - buf.append( quote( s ) ); - } - - buf.append( "]\n" ); - - return buf.toString(); - } - - @Override - protected String varDef( String varname, String value ) { - return varname+"="+value+"\n"; - } - - @Override - protected String getLibPath() { - return callProcedure( "sys.path.append", quote( libPath ) ); - } - - @Override - protected String postProcess( String body ) { - return body.replace( "\n", "\n " ); - } - -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/RInvocation.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/RInvocation.java deleted file mode 100644 index 92fb0aa..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/RInvocation.java +++ /dev/null @@ -1,333 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.invoc; - -import java.util.List; - -import de.huberlin.wbi.cuneiform.core.semanticmodel.CompoundExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.JsonReportEntry; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NotDerivableException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Ticket; - -public class RInvocation extends Invocation { - - protected RInvocation( Ticket ticket, String libPath ) { - super( ticket, libPath ); - } - - @Override - protected String defFunctionLog() throws NotDerivableException { - - StringBuffer buf; - - buf = new StringBuffer(); - - buf.append( defFunction( FUN_LOG, null, new String[] { "key", "value" }, - "if( mode( key ) != \"character\" )\n" - +"stop( \"Expected key to be of type 'character'.\" )\n" - +"if( mode( value ) != \"character\" )\n" - +"stop( \"Expected key to be of type 'value'.\" )\n" - +"write( paste( \"{" - +JsonReportEntry.ATT_TIMESTAMP+":"+System.currentTimeMillis()+"," - +JsonReportEntry.ATT_RUNID+":\\\""+getRunId()+"\\\"," - +JsonReportEntry.ATT_TASKID+":"+getTaskId()+"," - +JsonReportEntry.ATT_TASKNAME+":"+getTaskName()+"," - +JsonReportEntry.ATT_LANG+":"+getLangLabel()+"," - +JsonReportEntry.ATT_INVOCID+":"+getTicketId()+"," - +JsonReportEntry.ATT_KEY+":\\\"\", key, \"\\\"," - +JsonReportEntry.ATT_VALUE+":\", value, \"}\\n\", sep=\"\" ), " - +"file=\""+REPORT_FILENAME+"\", append=TRUE )" ) ); - - return buf.toString(); - } - - @Override - protected String getShebang() { - return "#!/usr/bin/env Rscript\n"; - } - - @Override - protected String varDef( String varname, CompoundExpr ce ) - throws NotDerivableException { - - StringBuffer buf; - int i; - boolean comma; - List list; - - list = ce.normalize(); - - buf = new StringBuffer(); - - comma = false; - buf.append( varname ).append( " <- c( " ); - for( i = 0; i < list.size(); i++ ) { - - if( comma ) - buf.append( ',' ); - comma = true; - - buf.append( "\"" ).append( list.get( i ) ).append( "\"" ); - } - - buf.append( ")\n" ); - - return buf.toString(); - } - - @Override - protected String varDef( String varname, String value ) { - return varname+" <- "+value+"\n"; - } - - /** - * @param outputName - */ - @SuppressWarnings( "static-method" ) - private String defFunction( String funName, String outputName, String[] inputNameList, String body ) { - - StringBuffer buf; - boolean comma; - - buf = new StringBuffer(); - - buf.append( funName ).append( " <- function(" ); - - comma = false; - for( String arg : inputNameList ) { - - if( comma ) - buf.append( ',' ); - - comma = true; - - buf.append( ' ' ).append( arg ); - } - - buf.append( " ) {\n" ).append( body ).append( "\n}\n" ); - - return buf.toString(); - } - - @Override - protected String callFunction( String name, String... argValue ) { - - StringBuffer buf; - boolean comma; - - buf = new StringBuffer(); - - buf.append( name ).append( "( " ); - comma = false; - for( String arg : argValue ) { - - if( comma ) - buf.append( ", " ); - comma = true; - - buf.append( arg ); - } - - buf.append( " )" ); - - return buf.toString(); - } - - @Override - protected String callProcedure( String name, String... argValue ) { - - StringBuffer buf; - boolean comma; - - buf = new StringBuffer(); - - buf.append( name ).append( "( " ); - comma = false; - for( String arg : argValue ) { - - if( comma ) - buf.append( ", " ); - comma = true; - - buf.append( arg ); - } - - buf.append( " )\n" ); - - return buf.toString(); - } - - @Override - protected String newList( String listName ) { - return varDef( listName, "NULL" ); - } - - @Override - protected String listAppend( String listName, String element ) { - return listName+" <- append( "+listName+", "+element+" )\n"; - } - - @Override - protected String dereference( String varName ) { - return varName; - } - - @Override - protected String forEach( String listName, String elementName, String body ) { - return "for( "+elementName+" in "+listName+" ) {\n"+body+"\n}\n"; - } - - @Override - protected String ifNotFileExists( String fileName, String body ) { - return - "if( !" - +callFunction( "file.exists", dereference( fileName ) ) - +" ) {\n" - +body - +"\n}\n"; - } - - @Override - protected String raise( String msg ) { - return callProcedure( "stop", msg ); - } - - @Override - protected String join( String... elementList ) { - - StringBuffer buf; - boolean comma; - - buf = new StringBuffer(); - - buf.append( "paste( " ); - - comma = false; - for( String element : elementList ) { - - if( comma ) - buf.append( ", " ); - comma = true; - - buf.append( element ); - } - - buf.append( ", sep=\"\" )" ); - - return buf.toString(); - } - - @Override - protected String quote( String content ) { - return "\""+content.replace( "\"", "\\\"" )+"\""; - } - - @Override - protected String fileSize( String filename ) { - return "sprintf( \"%.0f\", file.info( "+filename+" )$size/1024 )"; - } - - @Override - protected String ifListIsNotEmpty( String listName, String body ) { - return "if( length( "+listName+" ) != 0 ) {\n"+body+"\n}\n"; - } - - @Override - protected String listToBraceCommaSeparatedString( String listName, - String stringName, String open, String close ) { - return stringName+" = paste( "+listName+", sep=\"\", collapse=\",\" )\n"; - } - - @Override - protected String defFunctionNormalize() throws NotDerivableException { - return defFunction( - FUN_NORMALIZE, - null, - new String[] { "channel", "f" }, - "sprintf( \""+getTicketId() - +"_%d_%s\", channel, basename( f ) )\n" ); - } - - @Override - protected String symlink( String src, String dest ) { - return callProcedure( "file.symlink", src, dest )+"\n"; - } - - @Override - protected String comment( String comment ) { - return "# "+comment.replace( "\n", "\n# " )+"\n"; - } - - @Override - protected String copyArray( String from, String to ) { - return to+"="+from+"\n"; - } - - @Override - protected String clip( String varName ) { - return varName+" <- substring( "+varName+", 2 )\n"; - } - - @Override - protected String defFunctionLogFile() throws NotDerivableException { - - StringBuffer buf; - - buf = new StringBuffer(); - - buf.append( defFunction( FUN_LOGFILE, null, new String[] { "file", "key", "value" }, - "if( mode( key ) != \"character\" )\n" - +"stop( \"Expected key to be of type 'character'.\" )\n" - +"if( mode( value ) != \"character\" )\n" - +"stop( \"Expected value to be of type 'character'.\" )\n" - +"write( paste( \"{" - +JsonReportEntry.ATT_TIMESTAMP+":"+System.currentTimeMillis()+"," - +JsonReportEntry.ATT_RUNID+":\\\""+getRunId()+"\\\"," - +JsonReportEntry.ATT_TASKID+":"+getTaskId()+"," - +JsonReportEntry.ATT_TASKNAME+":"+getTaskName()+"," - +JsonReportEntry.ATT_LANG+":"+getLangLabel()+"," - +JsonReportEntry.ATT_INVOCID+":"+getTicketId()+"," - +JsonReportEntry.ATT_FILE+":\\\"\", file, \"\\\"," - +JsonReportEntry.ATT_KEY+":\\\"\", key, \"\\\"," - +JsonReportEntry.ATT_VALUE+":\", value, \"}\\n\", sep=\"\" ), " - +"file=\""+REPORT_FILENAME+"\", append=TRUE )" ) ); - - return buf.toString(); - } - - @Override - protected String getLibPath() { - return callProcedure( ".libPaths", quote( libPath ) ); - } - -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/ScalaInvocation.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/ScalaInvocation.java deleted file mode 100644 index a6198a6..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/invoc/ScalaInvocation.java +++ /dev/null @@ -1,281 +0,0 @@ -package de.huberlin.wbi.cuneiform.core.invoc; - -import de.huberlin.wbi.cuneiform.core.semanticmodel.CompoundExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.JsonReportEntry; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NotDerivableException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Ticket; - -public class ScalaInvocation extends Invocation { - - public ScalaInvocation( Ticket ticket, String libPath ) { - super( ticket, libPath ); - } - - @Override - protected String callFunction( String name, String... argValue ) { - - StringBuffer buf; - boolean comma; - - buf = new StringBuffer(); - - buf.append( name ).append( '(' ); - - comma = false; - for( String arg : argValue ) { - - if( comma ) - buf.append( ',' ); - comma = true; - - buf.append( arg ); - } - - buf.append( ")" ); - - return buf.toString(); - } - - @Override - protected String callProcedure( String name, String... argValue ) { - return callFunction( name, argValue )+"\n"; - } - - @Override - protected String clip( String varName ) { - return varName+"="+varName+" substring(1)\n"; - } - - @Override - protected String comment( String comment ) { - return "// "+comment+"\n"; - } - - @Override - protected String copyArray( String from, String to ) { - return "val "+to+"="+from+"\n"; - } - - @Override - protected String defFunctionLog() throws NotDerivableException { - - StringBuffer buf; - - buf = new StringBuffer(); - - buf.append( "def "+FUN_LOG+"( key:String, value:String ) : Unit = {\n" ); - - buf.append( " val writer = new FileWriter(\""+REPORT_FILENAME+"\",true);\n" ); - buf.append( " writer write(\"{" ); - - buf.append( JsonReportEntry.ATT_TIMESTAMP ) - .append( ':' ).append( System.currentTimeMillis() ).append( ',' ) - .append( JsonReportEntry.ATT_RUNID ).append( ":\\\"" ) - .append( getRunId() ).append( "\\\"," ) - .append( JsonReportEntry.ATT_TASKID ).append( ':' ) - .append( getTaskId() ).append( ',' ); - - if( hasTaskName() ) - buf.append( JsonReportEntry.ATT_TASKNAME ).append( ":\\\"" ) - .append( getTaskName() ).append( "\\\"," ); - - buf.append( JsonReportEntry.ATT_LANG ).append( ":\\\"" ) - .append( getLangLabel() ).append( "\\\"," ) - .append( JsonReportEntry.ATT_INVOCID ).append( ':' ) - .append( getTicketId() ).append( ',' ) - .append( JsonReportEntry.ATT_KEY ).append( ":\\\"\"+key+\"\\\"," ) - .append( JsonReportEntry.ATT_VALUE ).append( ":\"+value+\"}\\n\"" ); - - buf.append( ")\n writer close\n" ); - - buf.append( "}\n" ); - - return buf.toString(); - } - - @Override - protected String defFunctionLogFile() throws NotDerivableException { - - StringBuffer buf; - - buf = new StringBuffer(); - - buf.append( "def "+FUN_LOGFILE+"( file:String, key:String, value:String ) : Unit = {\n" ); - - buf.append( " val writer = new FileWriter(\""+REPORT_FILENAME+"\",true);\n" ); - buf.append( " writer write(\"{" ); - - buf.append( JsonReportEntry.ATT_TIMESTAMP ) - .append( ':' ).append( System.currentTimeMillis() ).append( ',' ) - .append( JsonReportEntry.ATT_RUNID ).append( ":\\\"" ) - .append( getRunId() ).append( "\\\"," ) - .append( JsonReportEntry.ATT_TASKID ).append( ':' ) - .append( getTaskId() ).append( ',' ); - - if( hasTaskName() ) - buf.append( JsonReportEntry.ATT_TASKNAME ).append( ":\\\"" ) - .append( getTaskName() ).append( "\\\"," ); - - buf.append( JsonReportEntry.ATT_LANG ).append( ":\\\"" ) - .append( getLangLabel() ).append( "\\\"," ) - .append( JsonReportEntry.ATT_INVOCID ).append( ':' ) - .append( getTicketId() ).append( ',' ) - .append( JsonReportEntry.ATT_FILE ).append( ":\\\"\"+file+\"\\\"," ) - .append( JsonReportEntry.ATT_KEY ).append( ":\\\"\"+key+\"\\\"," ) - .append( JsonReportEntry.ATT_VALUE ).append( ":\"+value+\"}\\n\"" ); - - buf.append( ")\n writer close\n" ); - - buf.append( "}\n" ); - - return buf.toString(); - } - - @Override - protected String defFunctionNormalize() throws NotDerivableException { - - StringBuffer buf; - - buf = new StringBuffer(); - - buf.append( "def "+FUN_NORMALIZE+"(channel:Int,filename:String) : String = {" ); - buf.append( "val p = Paths.get(filename)\n"); - buf.append( "return \""+getTicketId()+"_\"+channel+\"_\"+p.getName(p.getNameCount-1)\n" ); - buf.append( "}\n" ); - - return buf.toString(); - } - - @Override - protected String dereference( String varName ) { - return varName; - } - - @Override - protected String fileSize( String filename ) { - return "Files.size(Paths.get("+filename+")).toString"; - } - - @Override - protected String forEach( String listName, String elementName, String body ) { - return "for(String "+elementName+":"+listName+") {\n"+body+"\n}\n"; - } - - @Override - protected String getShebang() { - return "#!/bin/sh\nexec scala \"$0\" \"$@\"\n!#"; - } - - @Override - protected String getLibPath() { - throw new UnsupportedOperationException( "NYI" ); - } - - @Override - protected String getImport() { - return "import java.nio.file.Paths\nimport java.io.FileWriter\nimport java.nio.file.Files"; - } - - @Override - protected String ifListIsNotEmpty(String listName, String body) { - return( "if(!"+listName+".isEmpty) {\n"+body+"\n}\n" ); - } - - @Override - protected String ifNotFileExists(String fileName, String body) { - return( "if(!Files.exists(Paths.get("+fileName+"))) {\n"+body+"\n}\n" ); - } - - @Override - protected String declareString( String outputName ) { - return "var "+outputName+"=\"\"\n"; - } - - @Override - protected String declareList( String paramName ) { - return "var "+paramName+"=List()\n"; - } - - @Override - protected String join( String... elementList ) { - - StringBuffer buf; - boolean comma; - - buf = new StringBuffer(); - - comma = false; - for( String element : elementList ) { - - if( comma ) - buf.append( "+" ); - comma = true; - - buf.append( element ); - } - - return buf.toString(); - } - - @Override - protected String listAppend(String listName, String element) { - return listName+"="+listName+":+"+element+"\n"; - } - - @Override - protected String listToBraceCommaSeparatedString(String listName, String stringName, String open, String close) { - return stringName+"=\""+open+"\"+"+listName+".mkString(\",\")+\""+close+"\"\n"; - } - - @Override - protected String newList( String listName ) { - return "var "+listName+"=List()\n"; - } - - @Override - protected String quote( String content ) { - return "\""+content.replace( "\"", "\\\"" )+"\""; - } - - @Override - protected String raise( String msg ) { - return "throw new RuntimeException("+msg+")\n"; - } - - @Override - protected String symlink( String src, String dest ) { - return "Files.createSymbolicLink(Paths.get("+dest+"),Paths.get("+src+"))\n"; - } - - @Override - protected String varDef( String varname, String value ) { - return varname+"="+value+"\n"; - } - - @Override - protected String varDef( String varname, CompoundExpr ce ) throws NotDerivableException { - - StringBuffer buf; - boolean comma; - int i, n; - - buf = new StringBuffer(); - - buf.append( "val "+varname+"=List(" ); - - comma = false; - n = ce.getNumAtom(); - for( i = 0; i < n; i++ ) { - - if( comma ) - buf.append( ',' ); - comma = true; - - buf.append( ce.getStringExprValue( i ) ); - } - buf.append( ")\n" ); - - return buf.toString(); - } - -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/preprocess/ChannelListener.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/preprocess/ChannelListener.java deleted file mode 100644 index fa77652..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/preprocess/ChannelListener.java +++ /dev/null @@ -1,266 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.preprocess; - -import java.util.BitSet; -import java.util.LinkedList; -import java.util.List; - -import org.antlr.v4.runtime.ANTLRErrorListener; -import org.antlr.v4.runtime.ANTLRInputStream; -import org.antlr.v4.runtime.CommonTokenStream; -import org.antlr.v4.runtime.Parser; -import org.antlr.v4.runtime.RecognitionException; -import org.antlr.v4.runtime.Recognizer; -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.TokenStream; -import org.antlr.v4.runtime.TokenStreamRewriter; -import org.antlr.v4.runtime.atn.ATNConfigSet; -import org.antlr.v4.runtime.dfa.DFA; -import org.antlr.v4.runtime.misc.NotNull; -import org.antlr.v4.runtime.tree.ParseTree; -import org.antlr.v4.runtime.tree.ParseTreeWalker; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import de.huberlin.wbi.cuneiform.core.parser.CuneiformBaseListener; -import de.huberlin.wbi.cuneiform.core.parser.CuneiformLexer; -import de.huberlin.wbi.cuneiform.core.parser.CuneiformParser; -import de.huberlin.wbi.cuneiform.core.parser.CuneiformParser.ApplyExprContext; -import de.huberlin.wbi.cuneiform.core.parser.CuneiformParser.CallExprContext; -import de.huberlin.wbi.cuneiform.core.parser.CuneiformParser.CompoundExprContext; -import de.huberlin.wbi.cuneiform.core.parser.CuneiformParser.ExprContext; -import de.huberlin.wbi.cuneiform.core.parser.CuneiformParser.NameContext; -import de.huberlin.wbi.cuneiform.core.parser.CuneiformParser.NilExprContext; -import de.huberlin.wbi.cuneiform.core.parser.CuneiformParser.SingleExprContext; - -public class ChannelListener extends CuneiformBaseListener implements ANTLRErrorListener { - - private final TokenStreamRewriter rewriter; - private final Log log; - - public ChannelListener( CommonTokenStream tokenStream ) { - - if( tokenStream == null ) - throw new NullPointerException( "Token stream must not be empty." ); - - rewriter = new TokenStreamRewriter( tokenStream ); - log = LogFactory.getLog( ChannelListener.class ); - } - - @Override - public void enterAssign( @NotNull CuneiformParser.AssignContext ctx ) { - - List unqual; - int i, n; - StringBuffer buf; - TokenStream stream; - NameContext name; - String nameString; - - if( rewriter == null ) - throw new NullPointerException( "Token stream has never been set." ); - - stream = rewriter.getTokenStream(); - unqual = getUnqualifiedApplicationList( ctx.expr() ); - - - n = ctx.name().size(); - - for( i = n-1; i > 0; i-- ) { - - buf = new StringBuffer(); - name = ctx.name( i ); - - buf.append( '\n' ); - buf.append( stream.getText( name.getStart(), name.getStop() ) ); - buf.append( " =" ); - - if( unqual.isEmpty() ) - buf.append( " nil" ); - else - for( SingleExprContext se : unqual ) - - buf.append( " [" ).append( i+1 ).append( "]" ) - .append( stream.getText( se.getStart(), se.getStop() ) ); - - - - buf.append( ';' ); - - rewriter.insertAfter( ctx.getStop(), buf.toString() ); - } - - name = ctx.name( 0 ); - nameString = stream.getText( name.getStart(), name.getStop() ); - - rewriter.replace( name.getStart(), ctx.EQUAL().getSymbol(), nameString+" =" ); - } - - @Override - public void enterCondExpr( @NotNull CuneiformParser.CondExprContext ctx ) { - - if( rewriter == null ) - throw new NullPointerException( "Token stream has never been set." ); - } - - @Override - public void enterScript( @NotNull CuneiformParser.ScriptContext ctx ) { - - if( rewriter == null ) - throw new NullPointerException( "Token stream not set." ); - } - - public String getRewrittenText() { - - if( rewriter == null ) - throw new NullPointerException( "Token stream not set." ); - - return rewriter.getText(); - } - - public static String process( String input ) { - - ANTLRInputStream instream; - CuneiformLexer lexer; - CommonTokenStream tokenStream; - CuneiformParser parser; - ParseTree tree; - ParseTreeWalker walker; - ChannelListener channelListener; - - walker = new ParseTreeWalker(); - - - // parse original content - instream = new ANTLRInputStream( input ); - - lexer = new CuneiformLexer( instream ); - lexer.removeErrorListeners(); - - tokenStream = new CommonTokenStream( lexer ); - - parser = new CuneiformParser( tokenStream ); - parser.removeErrorListeners(); - - channelListener = new ChannelListener( tokenStream ); - lexer.addErrorListener( channelListener ); - parser.addErrorListener( channelListener ); - - tree = parser.script(); - - walker.walk( channelListener, tree ); - - return channelListener.getRewrittenText(); - } - - public static List getUnqualifiedApplicationList( ExprContext expr ) { - - List unqualifiedList; - CompoundExprContext cec; - - if( expr == null ) - throw new NullPointerException( "Expression must not be null." ); - - unqualifiedList = new LinkedList<>(); - - if( expr instanceof NilExprContext ) - return unqualifiedList; - - if( expr instanceof CompoundExprContext ) { - - cec = ( CompoundExprContext )expr; - - for( SingleExprContext singleExpr : cec.singleExpr() ) - if( isUnqualifiedApplication( singleExpr ) ) - unqualifiedList.add( singleExpr ); - - return unqualifiedList; - } - - throw new RuntimeException( "Expression type not recognized." ); - } - - public static boolean isUnqualifiedApplication( SingleExprContext singleExpr ) { - - if( singleExpr instanceof ApplyExprContext ) - - if( ( ( ApplyExprContext )singleExpr ).channel() == null ) - return true; - - - if( singleExpr instanceof CallExprContext ) - - if( ( ( CallExprContext )singleExpr ).channel() == null ) - return true; - - return false; - } - - @Override - public void syntaxError( Recognizer recognizer, - Object offendingSymbol, int line, int charPositionInLine, - String msg, RecognitionException e ) { - throw new ParseException( line, charPositionInLine, ( ( Token )offendingSymbol ).getText(), msg ); - } - - @Override - public void reportAmbiguity( Parser arg0, DFA arg1, int arg2, int arg3, - boolean arg4, BitSet arg5, ATNConfigSet arg6 ) { - - if( log.isDebugEnabled() ) - log.debug( "Ambiguity detected." ); - - } - - @Override - public void reportAttemptingFullContext( Parser arg0, DFA arg1, int arg2, - int arg3, BitSet arg4, ATNConfigSet arg5 ) { - - if( log.isTraceEnabled() ) - log.trace( "Attempting full context." ); - - } - - @Override - public void reportContextSensitivity( Parser arg0, DFA arg1, int arg2, - int arg3, int arg4, ATNConfigSet arg5) { - - if( log.isTraceEnabled() ) - log.trace( "Context sensitivity detected." ); - } - - - - -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/preprocess/ParseException.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/preprocess/ParseException.java deleted file mode 100644 index 94c6e4b..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/preprocess/ParseException.java +++ /dev/null @@ -1,130 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.preprocess; - -public class ParseException extends RuntimeException { - - private static final long serialVersionUID = -3262992285049846787L; - - private Integer line; - private Integer charPositionInLine; - private String near; - - public ParseException( Integer line, Integer charPositionInLine, String near, String msg ) { - super( msg ); - setLine( line ); - setCharPositionInLine( charPositionInLine ); - setNear( near ); - } - - public int getLine() { - return line; - } - - public int getCharPositionInLine() { - return charPositionInLine; - } - - public String getNear() { - return near; - } - - public boolean hasLine() { - return line != null; - } - - public boolean hasCharPositionInLine() { - return charPositionInLine != null; - } - - public boolean hasNear() { - return near != null; - } - - public void setLine( Integer line ) { - - if( line == null ) { - this.line = null; - return; - } - - if( line < 1 ) - throw new RuntimeException( "Line must be a positive number. Received "+line+" instead." ); - this.line = line; - } - - public void setNear( String near ) { - - if( near == null ) { - this.near = null; - return; - } - - if( near.isEmpty() ) - throw new RuntimeException( "Near string must not be empty." ); - - this.near = near; - } - - public void setCharPositionInLine( Integer charPositionInLine ) { - - if( charPositionInLine == null ) { - this.charPositionInLine = null; - return; - } - - if( charPositionInLine < 0 ) - throw new RuntimeException( "Character position in line must be a positive number. Received "+charPositionInLine+" instead." ); - - this.charPositionInLine = charPositionInLine; - } - - @Override - public String toString() { - - StringBuffer buf; - - buf = new StringBuffer(); - - if( hasLine() ) - buf.append( "line " ).append( line ).append( ":" ) - .append( charPositionInLine ).append( ' ' ); - - if( hasNear() ) - buf.append( "near " ).append( near ).append( ": " ); - - buf.append( getMessage() ); - - return buf.toString(); - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/preprocess/PreListener.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/preprocess/PreListener.java deleted file mode 100644 index b979503..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/preprocess/PreListener.java +++ /dev/null @@ -1,329 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.preprocess; - -import java.util.BitSet; -import java.util.LinkedList; -import java.util.List; - -import org.antlr.v4.runtime.ANTLRErrorListener; -import org.antlr.v4.runtime.ANTLRInputStream; -import org.antlr.v4.runtime.CommonTokenStream; -import org.antlr.v4.runtime.Parser; -import org.antlr.v4.runtime.RecognitionException; -import org.antlr.v4.runtime.Recognizer; -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.TokenStreamRewriter; -import org.antlr.v4.runtime.atn.ATNConfigSet; -import org.antlr.v4.runtime.dfa.DFA; -import org.antlr.v4.runtime.misc.NotNull; -import org.antlr.v4.runtime.tree.ParseTree; -import org.antlr.v4.runtime.tree.ParseTreeWalker; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import de.huberlin.wbi.cuneiform.core.parser.CuneiformBaseListener; -import de.huberlin.wbi.cuneiform.core.parser.CuneiformLexer; -import de.huberlin.wbi.cuneiform.core.parser.CuneiformParser; -import de.huberlin.wbi.cuneiform.core.parser.CuneiformParser.CondExprContext; -import de.huberlin.wbi.cuneiform.core.parser.CuneiformParser.CorrelParamContext; -import de.huberlin.wbi.cuneiform.core.parser.CuneiformParser.PrototypeContext; -import de.huberlin.wbi.cuneiform.core.parser.CuneiformParser.NameContext; -import de.huberlin.wbi.cuneiform.core.parser.CuneiformParser.NameDataTypeContext; -import de.huberlin.wbi.cuneiform.core.parser.CuneiformParser.NameDeepFnTypeContext; -import de.huberlin.wbi.cuneiform.core.parser.CuneiformParser.NameInferredTypeContext; -import de.huberlin.wbi.cuneiform.core.parser.CuneiformParser.NamePlainFnTypeContext; -import de.huberlin.wbi.cuneiform.core.parser.CuneiformParser.ParamContext; -import de.huberlin.wbi.cuneiform.core.parser.CuneiformParser.ReduceVarContext; - -/** Simplifies token stream by removing syntactic sugar. - * - * - Replaces deftask statements with assignments to lambda expressions - * - Replaces task calls with apply expressions - * - Resolves pipe notation to regular nested function calls - * - Removes comments - * - Explicitly references channels in applications - * - Adds explicit task parameter to all task prototypes - * - Quotes numbers - * - * @author jorgen - * - */ -public class PreListener extends CuneiformBaseListener implements ANTLRErrorListener { - - private final TokenStreamRewriter rewriter; - private final LinkedList exprStack; - private final Log log; - - public PreListener( CommonTokenStream tokenStream ) { - - if( tokenStream == null ) - throw new NullPointerException( "Token stream must not be empty." ); - - rewriter = new TokenStreamRewriter( tokenStream ); - exprStack = new LinkedList<>(); - log = LogFactory.getLog( PreListener.class ); - } - - public static String process( String input ) { - - ANTLRInputStream instream; - CuneiformLexer lexer; - CommonTokenStream tokenStream; - CuneiformParser parser; - ParseTree tree; - ParseTreeWalker walker; - PreListener preListener; - - - walker = new ParseTreeWalker(); - - // parse original content - instream = new ANTLRInputStream( input ); - - lexer = new CuneiformLexer( instream ); - lexer.removeErrorListeners(); - - tokenStream = new CommonTokenStream( lexer ); - - parser = new CuneiformParser( tokenStream ); - parser.removeErrorListeners(); - - preListener = new PreListener( tokenStream ); - lexer.addErrorListener( preListener ); - parser.addErrorListener( preListener ); - - - tree = parser.script(); - - walker.walk( preListener, tree ); - - return preListener.getRewrittenText(); - } - - @Override - public void enterForeignDefTask( @NotNull CuneiformParser.ForeignDefTaskContext ctx ) { - - Token deftask; - Token id; - Token bodyStop; - - deftask = ctx.DEFTASK().getSymbol(); - bodyStop = ctx.foreignBody().getStop(); - id = ctx.ID().getSymbol(); - - rewriter.insertAfter( bodyStop, ";" ); - rewriter.insertAfter( id, " = \\" ); - rewriter.replace( deftask, id, id.getText() ); - - } - - @Override - public void enterNativeDefTask( @NotNull CuneiformParser.NativeDefTaskContext ctx ) { - - Token deftask; - Token id; - Token bodyStop; - - deftask = ctx.DEFTASK().getSymbol(); - bodyStop = ctx.RBRACE().getSymbol(); - id = ctx.ID().getSymbol(); - - rewriter.insertAfter( bodyStop, ";" ); - rewriter.insertAfter( id, " = \\" ); - rewriter.replace( deftask, id, id.getText() ); - - } - - @Override - public void exitDanglingExpr( @NotNull CuneiformParser.DanglingExprContext ctx ) { - exprStack.push( rewriter.getText( ctx.expr().getSourceInterval() ) ); - rewriter.delete( ctx.getStart(), ctx.getStop() ); - } - - @Override - public void enterPrototype( @NotNull CuneiformParser.PrototypeContext ctx ) { - - - if( !( ctx.getParent() instanceof CondExprContext ) ) - if( !containsParam( ctx, "task" ) ) - rewriter.insertAfter( ctx.COLON().getSymbol(), " task " ); - } - - @Override - public void enterScript( @NotNull CuneiformParser.ScriptContext ctx ) { - - if( rewriter == null ) - throw new NullPointerException( "Token stream not set." ); - } - - @Override - public void exitFromStackExpr( @NotNull CuneiformParser.FromStackExprContext ctx ) { - - Token symbol; - - - symbol = ctx.FROMSTACK().getSymbol(); - - if( exprStack.isEmpty() ) - throw new ParseException( symbol.getLine(), symbol.getCharPositionInLine(), symbol.getText(), - "Pipe destination encountered where there is no source." ); - - - rewriter.replace( symbol, exprStack.pop() ); - } - - public String getRewrittenText() { - return rewriter.getText(); - } - - public static boolean containsParam( PrototypeContext prototype, String paramName ) { - - List nameList; - - nameList = getNameList( prototype ); - return nameList.contains( paramName ); - } - - public static List getNameList( PrototypeContext prototype ) { - - List nameList; - - nameList = new LinkedList<>(); - for( ParamContext param : prototype.param() ) - nameList.addAll( getNameList( param ) ); - - return nameList; - } - - public static List getNameList( ParamContext param ) { - - List list; - - list = new LinkedList<>(); - - if( param.name() != null ) { - list.add( getName( param.name() ) ); - return list; - } - - if( param.reduceVar() != null ) { - list.add( getName( param.reduceVar() ) ); - return list; - } - - if( param.correlParam() != null ) { - list.addAll( getNameList( param.correlParam() ) ); - return list; - } - - throw new RuntimeException( "Parameter type not recognized." ); - - } - - public static String getName( NameContext name ) { - - if( name == null ) - throw new NullPointerException( "Name must not be null." ); - - if( name instanceof NameInferredTypeContext ) - return ( ( NameInferredTypeContext )name ).ID().getText(); - - if( name instanceof NameDataTypeContext ) - return ( ( NameDataTypeContext )name ).ID( 0 ).getText(); - - if( name instanceof NamePlainFnTypeContext ) - return ( ( NamePlainFnTypeContext )name ).ID().getText(); - - if( name instanceof NameDeepFnTypeContext ) - return ( ( NameDeepFnTypeContext )name ).ID().getText(); - - throw new RuntimeException( "Name type "+name.getClass().getName()+" not recognized. In '"+name.getText()+"'" ); - } - - public static String getName( ReduceVarContext reduceVar ) { - return getName( reduceVar.name() ); - } - - public static List getNameList( CorrelParamContext correlVar ) { - - List list; - - list = new LinkedList<>(); - - for( NameContext nc : correlVar.name() ) - list.add( getName( nc ) ); - - return list; - } - - @Override - public void syntaxError( Recognizer recognizer, - Object offendingSymbol, int line, int charPositionInLine, - String msg, RecognitionException e ) { - - String near; - - near = null; - if( offendingSymbol != null ) - near = ( ( Token )offendingSymbol ).getText(); - - throw new ParseException( line, charPositionInLine, near, msg ); - } - - @Override - public void reportAmbiguity( Parser arg0, DFA arg1, int arg2, int arg3, - boolean arg4, BitSet arg5, ATNConfigSet arg6 ) { - - if( log.isDebugEnabled() ) - log.debug( "Ambiguity detected." ); - - } - - @Override - public void reportAttemptingFullContext( Parser arg0, DFA arg1, int arg2, - int arg3, BitSet arg4, ATNConfigSet arg5 ) { - - if( log.isTraceEnabled() ) - log.trace( "Attempting full context." ); - - } - - @Override - public void reportContextSensitivity( Parser arg0, DFA arg1, int arg2, - int arg3, int arg4, ATNConfigSet arg5) { - - if( log.isTraceEnabled() ) - log.trace( "Context sensitivity detected." ); - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/preprocess/PrePhaseException.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/preprocess/PrePhaseException.java deleted file mode 100644 index f537e9a..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/preprocess/PrePhaseException.java +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.preprocess; - -public class PrePhaseException extends ParseException { - - private static final long serialVersionUID = 5468102633060593479L; - - public PrePhaseException( Integer row, Integer col, String near, String msg ) { - super( row, col, near, msg ); - } - -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/repl/BaseRepl.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/repl/BaseRepl.java deleted file mode 100644 index 1caaf25..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/repl/BaseRepl.java +++ /dev/null @@ -1,441 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.repl; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; - -import org.antlr.v4.runtime.ANTLRInputStream; -import org.antlr.v4.runtime.CommonTokenStream; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import de.huberlin.wbi.cuneiform.core.parser.CuneiformLexer; -import de.huberlin.wbi.cuneiform.core.parser.CuneiformParser; -import de.huberlin.wbi.cuneiform.core.preprocess.ChannelListener; -import de.huberlin.wbi.cuneiform.core.preprocess.ParseException; -import de.huberlin.wbi.cuneiform.core.preprocess.PreListener; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CompoundExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.JsonReportEntry; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NameExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CfSemanticModelVisitor; -import de.huberlin.wbi.cuneiform.core.semanticmodel.SingleExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Ticket; -import de.huberlin.wbi.cuneiform.core.semanticmodel.TopLevelContext; -import de.huberlin.wbi.cuneiform.core.ticketsrc.ReplTicketSrc; - -public abstract class BaseRepl { - - public static final int CTL_NIL = 0; - public static final int CTL_QUIT = 1; - public static final int CTL_STATE = 2; - public static final int CTL_QUERYSET = 4; - public static final int CTL_TICKETSET = 8; - - public static final String LABEL_VERSION = "2.0.4-SNAPSHOT"; - public static final String LABEL_BUILD = "2016-02-08"; - - private final CfSemanticModelVisitor state; - private final Map runningMap; - private final ReplTicketSrc ticketSrc; - private final Log log; - private CompoundExpr ans; - private final Log statLog; - - - - public BaseRepl( ReplTicketSrc ticketSrc, Log statLog ) { - - if( ticketSrc == null ) - throw new NullPointerException( "Ticket source actor must not be null." ); - - this.ticketSrc = ticketSrc; - - runningMap = new HashMap<>(); - state = new CfSemanticModelVisitor(); - log = LogFactory.getLog( BaseRepl.class ); - this.statLog = statLog; - } - - public CompoundExpr getAns() { - return ans; - } - - public Set getRunningSet() { - return runningMap.keySet(); - } - - public Set getTicketSet() { - - Set set; - - set = new HashSet<>(); - - for( UUID queryId : runningMap.keySet() ) - set.addAll( ticketSrc.getTicketSet( queryId ) ); - - return set; - } - - public TopLevelContext getState() { - return state.getTopLevelContext(); - } - - public boolean hasAns() { - return ans != null; - } - - public int interpret( String input ) { - - String afterPre, afterChannel; - CuneiformLexer lexer; - CuneiformParser parser; - TopLevelContext tlc; - - if( input == null ) - throw new NullPointerException( "Input string must not be null." ); - - // pre-step - afterPre = PreListener.process( input ); - - // channel-step - afterChannel = ChannelListener.process( afterPre ); - - // create lexer - lexer = new CuneiformLexer( new ANTLRInputStream( afterChannel ) ); - lexer.removeErrorListeners(); - lexer.addErrorListener( state ); - - // create parser - parser = new CuneiformParser( new CommonTokenStream( lexer ) ); - parser.removeErrorListeners(); - parser.addErrorListener( state ); - - // visit parsed script - tlc = ( TopLevelContext )state.visit( parser.script() ); - - return interpret( tlc ); - } - - public int interpret( TopLevelContext tlc ) { - - int ctl; - DynamicNodeVisitor reducer; - UUID queryId; - - // remove control targets - ctl = fetchCtl( tlc ); - - if( !tlc.isTargetListEmpty() ) { - - reducer = new DynamicNodeVisitor( ticketSrc, this, tlc ); - queryId = reducer.getQueryId(); - runningMap.put( queryId, reducer ); - - try { - - queryStarted( queryId ); - - // trigger reduction - reducer.step(); - - } - catch( ParseException e ) { - queryFailed( queryId, null, e, null, null, null ); - } - } - - return ctl; - } - - public boolean isBusy() { - return !runningMap.isEmpty(); - } - - public boolean isRunning( UUID queryId ) { - - if( queryId == null ) - throw new NullPointerException( "Query id must not be null." ); - - return runningMap.containsKey( queryId ); - } - - public void queryFailed( UUID queryId, Long ticketId, Exception e, String script, String stdOut, String stdErr ) { - - String s; - - if( queryId == null ) - throw new NullPointerException( "Query id must not be null." ); - - runningMap.remove( queryId ); - - s = ""; - - if( e != null ) { - - s += " "+e.getClass().getName(); - - if( e.getMessage() != null ) - s += ": \""+e.getMessage()+"\""; - } - - /* if( stdOut != null ) - s += " Output channel: \""+stdOut.replace( '\n', ' ' )+"\""; - - if( stdErr != null ) - s += " Error channel: \""+stdErr.replace( '\n', ' ' )+"\""; */ - - if( log.isErrorEnabled() ) - if( ticketId == null ) - log.error( "Query "+queryId+" failed."+s ); - else - log.error( "Query "+queryId+" failed while executing ticket "+ticketId+"."+s ); - - queryFailedPost( queryId, ticketId, e, script, stdOut, stdErr ); - } - - public abstract void queryFailedPost( UUID queryId, Long ticketId, Exception e, String script, String stdOut, String stdErr ); - - public void queryFinished( UUID queryId, CompoundExpr result ) { - - if( queryId == null ) - throw new NullPointerException( "Query id must not be null." ); - - if( result == null ) - throw new NullPointerException( "Result compound expression must not be null." ); - - runningMap.remove( queryId ); - ans = result; - - if( log.isInfoEnabled() ) - log.info( "Query "+queryId+" finished: "+result ); - - queryFinishedPost( queryId, result ); - } - - public abstract void queryFinishedPost( UUID queryId, CompoundExpr result ); - - public void queryStarted( UUID runId ) { - - if( log.isInfoEnabled() ) - log.info( "Query "+runId+" started." ); - - queryStartedPost( runId ); - } - - public abstract void queryStartedPost( UUID runId ); - - public synchronized void ticketFinished( UUID queryId, long ticketId, Set reportEntrySet ) { - - DynamicNodeVisitor dnv; - - if( queryId == null ) - throw new NullPointerException( "Query ID must not be null." ); - - if( reportEntrySet == null ) - throw new NullPointerException( "Report entry set must not be null." ); - - dnv = runningMap.get( queryId ); - if( dnv == null ) - throw new NullPointerException( "Dynamic node visitor must not be null." ); - - if( log.isDebugEnabled() ) - log.debug( "Stepping expression in query "+queryId+"." ); - - dnv.step(); - - if( log.isDebugEnabled() ) - log.debug( "Ticket finished: "+ticketId+" part of query "+queryId ); - - flushStatLog( reportEntrySet ); - - } - - protected void flushStatLog( Set reportEntrySet ) { - - if( statLog == null ) - return; - - if( statLog.isDebugEnabled() ) - for( JsonReportEntry entry : reportEntrySet ) - statLog.debug( entry ); - } - - public static void run( BaseRepl repl ) throws IOException { - - StringBuffer buf; - String line; - QueryParseCtlLexer lexer; - int ctl; - - System.out.println( BaseRepl.getLogo() ); - - buf = new StringBuffer(); - System.out.print( "> " ); - - try( BufferedReader reader = new BufferedReader( new InputStreamReader( System.in, Charset.forName( "UTF-8" ) ) ) ) { - - while( ( line = reader.readLine() ) != null ) { - - buf.append( line ).append( '\n' ); - - lexer = new QueryParseCtlLexer( new ANTLRInputStream( buf.toString() ) ); - - - if( lexer.isReady() ) { - - try { - - ctl = repl.interpret( buf.toString() ); - - if( ( ctl & BaseRepl.CTL_STATE ) != 0 ) - System.out.print( repl.getState() ); - - if( ( ctl & BaseRepl.CTL_QUERYSET ) != 0 ) - System.out.print( repl.getRunningSet() ); - - if( ( ctl & BaseRepl.CTL_TICKETSET ) != 0 ) - System.out.print( repl.getTicketSet() ); - - if( ( ctl & BaseRepl.CTL_QUIT ) != 0 ) - break; - } - catch( ParseException e ) { - System.out.println( e ); - } - - buf = new StringBuffer(); - System.out.print( "> " ); - } - - } - - } - System.out.println( "Bye." ); - } - - public static String getLogo() { - - return " _\n" - +" _gg@@@L\n" - +" _g@@@@@@k\n" - +" g@@@@BBBA\n" - +" gB@@@P\n" - +" _@@@@B\n" - +" __@@@@@gg@@BBBB@@gggp\n" - +" __gg@@@@@@@@@@@@@@@@@@@@BF\n" - +" _gg@@@@@@@@@@@BBBBBBBBBBBB@BL\n" - +" _g@@@@@B@@BMB@@@F\n" - +" _@B@@@@@#P^ @@@@F\n" - +" _gB@@@B#F q@@@@L\n" - +" _@@@@@#\" q@@@BL\n" - +" g@@@BF q@@@BL\n" - +" _@@@@F q@@@BL\n" - +" 4@@@@L q@@@BL\n" - +" ^@@@@gg_____ggp q@@@BL\n" - +" MB@@@@@@@@@@@g q@@@BL\n" - +" ^WB@@@@@@@@BB q@@@BL\n" - +" \"MM##MP\"\" q@BB@L\n" - +" \"\"\"`\n" - +"\nCUNEIFORM - A Functional Workflow Language\nVersion " - +LABEL_VERSION+" build "+LABEL_BUILD+"\n\nJorgen Brandt Marc Bux Ulf Leser\n"; - } - - public static int fetchCtl( TopLevelContext tlc ) { - - int ctl; - List removeCandidateList; - CompoundExpr cp; - - if( tlc == null ) - throw new NullPointerException( "Top level context must not be null." ); - - ctl = 0; - removeCandidateList = new ArrayList<>(); - - - for( CompoundExpr ce : tlc.getTargetList() ) { - - cp = new CompoundExpr( ce ); - - for( SingleExpr se : cp.getSingleExprList() ) - if( se instanceof NameExpr ) { - - - if( ( ( NameExpr )se ).getId().equals( "state" ) ) { - ctl += CTL_STATE; - ce.remove( se ); - removeCandidateList.add( ce ); - continue; - } - - if( ( ( NameExpr )se ).getId().equals( "quit" ) ) { - ctl += CTL_QUIT; - ce.remove( se ); - removeCandidateList.add( ce ); - continue; - } - - if( ( ( NameExpr )se ).getId().equals( "queries" ) ) { - ctl += CTL_QUERYSET; - ce.remove( se ); - removeCandidateList.add( ce ); - continue; - } - - if( ( ( NameExpr )se ).getId().equals( "tickets" ) ) { - ctl += CTL_TICKETSET; - ce.remove( se ); - removeCandidateList.add( ce ); - continue; - } - } - } - - - for( CompoundExpr ce : removeCandidateList ) - if( ce.getNumSingleExpr() == 0 ) - tlc.removeTarget( ce ); - - return ctl; - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/repl/CmdlineRepl.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/repl/CmdlineRepl.java deleted file mode 100644 index ec49352..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/repl/CmdlineRepl.java +++ /dev/null @@ -1,21 +0,0 @@ -package de.huberlin.wbi.cuneiform.core.repl; - -import java.util.UUID; - -import org.apache.commons.logging.Log; - -import de.huberlin.wbi.cuneiform.core.ticketsrc.ReplTicketSrc; - -public class CmdlineRepl extends InteractiveRepl { - - public CmdlineRepl( ReplTicketSrc ticketSrc, Log statLog ) { - super( ticketSrc, statLog ); - } - - @Override - public synchronized void queryFailedPost( UUID queryId, Long ticketId, Exception e, String script, String stdOut, String stdErr ) { - super.queryFailedPost( queryId, ticketId, e, script, stdOut, stdErr ); - System.exit( -1 ); - } - -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/repl/DynamicNodeVisitor.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/repl/DynamicNodeVisitor.java deleted file mode 100644 index c6e83c5..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/repl/DynamicNodeVisitor.java +++ /dev/null @@ -1,810 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.repl; - -import java.util.LinkedList; -import java.util.UUID; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import de.huberlin.wbi.cuneiform.core.semanticmodel.ApplyExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.BaseBlock; -import de.huberlin.wbi.cuneiform.core.semanticmodel.BaseNodeVisitor; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Block; -import de.huberlin.wbi.cuneiform.core.semanticmodel.EnumHelper; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CompoundExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CondExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CurryExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.ForeignLambdaExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.HasFailedException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.JsonReportEntry; -import de.huberlin.wbi.cuneiform.core.semanticmodel.LambdaExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NameExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NativeLambdaExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NotBoundException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NotDerivableException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Prototype; -import de.huberlin.wbi.cuneiform.core.semanticmodel.QualifiedTicket; -import de.huberlin.wbi.cuneiform.core.semanticmodel.SemanticModelException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.SingleExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Ticket; -import de.huberlin.wbi.cuneiform.core.semanticmodel.TopLevelContext; -import de.huberlin.wbi.cuneiform.core.ticketsrc.NodeVisitorTicketSrc; - -public class DynamicNodeVisitor extends BaseNodeVisitor { - - private final NodeVisitorTicketSrc ticketSrc; - private final BaseRepl repl; - private final UUID queryId; - private BaseBlock currentBlock; - private final LinkedList blockStack; - private final Log log; - private final Log statLog; - - public DynamicNodeVisitor( NodeVisitorTicketSrc ticketSrc, BaseRepl repl, TopLevelContext tlc ) { - - if( ticketSrc == null ) - throw new NullPointerException( "Ticket source must not be null." ); - - if( repl == null ) - throw new NullPointerException( "REPL must not be null." ); - - this.repl = repl; - this.ticketSrc = ticketSrc; - - queryId = UUID.randomUUID(); - blockStack = new LinkedList<>(); - log = LogFactory.getLog( DynamicNodeVisitor.class ); - statLog = LogFactory.getLog( "statLogger" ); - - setTopLevelContext( tlc ); - } - - @Override - public CompoundExpr accept( NameExpr nameExpr ) throws HasFailedException, NotBoundException { - return currentBlock.getExpr( nameExpr ).visit( this ); - } - - @Override - public CompoundExpr accept( CondExpr condExpr ) throws HasFailedException, NotBoundException { - - CompoundExpr ifExpr, ifExpr1; - CondExpr cnd1; - - ifExpr = condExpr.getIfExpr(); - if( ifExpr == null ) - throw new NullPointerException( "Condition must not be null." ); - - // try to reduce task expression - ifExpr1 = ifExpr.visit( this ); - if( ifExpr1 == null ) - throw new NullPointerException( "Evaluation of condition must not result in null." ); - - try { - - if( ifExpr1.isNormal() ) { - - // the result could be determined - - if( ifExpr1.getNumAtom() == 0 ) - return condExpr.getElseExpr().visit( this ); - - return condExpr.getThenExpr().visit( this ); - - } - - // the result is still open - cnd1 = new CondExpr( ifExpr1, condExpr.getThenExpr(), condExpr.getElseExpr() ); - - return new CompoundExpr( cnd1 ); - } - catch( NotDerivableException e ) { - throw new RuntimeException( e ); - } - - } - - @Override - public CompoundExpr accept( ApplyExpr applyExpr ) throws HasFailedException, NotBoundException { - - ApplyExpr applyExpr1; - CompoundExpr taskExpr1, paramExpr, paramExpr1; - boolean rest; - int channel; - SingleExpr se; - - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor accept ApplyExpr: "+applyExpr.toString().replace( '\n', ' ' ) ); - - // prepare reduced apply expression - channel = applyExpr.getChannel(); - rest = applyExpr.hasRest(); - applyExpr1 = new ApplyExpr( channel, rest ); - - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor accept ApplyExpr: Trying to reduce task expression." ); - - // try to reduce task expression - taskExpr1 = applyExpr.getTaskExpr().visit( this ); - - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor accept ApplyExpr: Replacing task expression with "+taskExpr1+"." ); - applyExpr1.setTaskExpr( taskExpr1 ); - - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor accept ApplyExpr: Trying to reduce parameter list." ); - - // try to reduce the parameter list - try { - for( NameExpr nameExpr : applyExpr.getNameSet() ) { - - paramExpr = applyExpr.getExpr( nameExpr ); - paramExpr1 = paramExpr.visit( this ); - - applyExpr1.putAssign( nameExpr, paramExpr1 ); - } - } - catch( NotBoundException e ) { - throw new RuntimeException( e ); - } - - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor accept ApplyExpr: Trying to push rest bindings." ); - - // try to push the rest - /* try { - - applyExpr1.attemptPushRest(); - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor accept ApplyExpr: Push of rest bindings successful or none present." ); - - } - catch( NotDerivableException e ) { - - // if it does not work in this round, it may still work in the next - - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor accept ApplyExpr: Push of rest bindings not successful. It may still work later." ); - } */ - - if( taskExpr1.getNumSingleExpr() == 1 ) { - - // task expression is single expression - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor accept ApplyExpr: Task expression is single expression." ); - - try { - - if( taskExpr1.getNumAtom() == 1 ) { - - // task expression is single value - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor accept ApplyExpr: Task expression is single value." ); - - se = taskExpr1.getSingleExpr( 0 ); - - if( !( se instanceof LambdaExpr ) ) { - - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor accept ApplyExpr: Singular task expression is not a lambda expression. Returning what we have so far: "+applyExpr1.toString().replace( '\n', ' ' ) ); - - return new CompoundExpr( applyExpr1 ); - } - - // combine parameters - return combineParam( applyExpr1 ); - - } - - // task expression is single expression but multiple value - return reducePotentiallyCorrelated( applyExpr1 ); - } - catch( NotDerivableException e ) { - - // cardinality cannot be derived yet - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor accept ApplyExpr: Cardinality cannot be derived yet. Returning what we have so far: "+applyExpr.toString().replace( '\n', ' ' ) ); - - return new CompoundExpr( applyExpr1 ); - } - } - - // task expression is multiple - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor accept ApplyExpr: Task expression is multiple." ); - - return reducePotentiallyCorrelated( applyExpr1 ); - - } - - - - - @Override - public CompoundExpr accept( CompoundExpr ce ) throws HasFailedException, NotBoundException { - - CompoundExpr result, intermediate; - - if( ce == null ) - throw new NullPointerException( "Compound expression must not be null." ); - - result = new CompoundExpr(); - - for( SingleExpr singleExpr : ce.getSingleExprList() ) { - - intermediate = singleExpr.visit( this ); - if( intermediate == null ) - throw new NullPointerException( "Evaluation of single expression must not result in null." ); - - result.addCompoundExpr( intermediate ); - - } - - return result; - } - - @Override - public CompoundExpr accept( CurryExpr curryExpr ) throws HasFailedException, NotBoundException { - - Prototype originalPrototype; - SingleExpr se; - LambdaExpr lambdaExpr; - NativeLambdaExpr nativeLambdaExpr; - Block originalBodyBlock; - Block curriedBodyBlock; - Prototype curriedPrototype; - NativeLambdaExpr curriedLambdaExpr; - - if( !curryExpr.hasTaskExpr() ) - throw new SemanticModelException( - curryExpr.toString(), - "Task parameter not bound." ); - - if( curryExpr.getTaskExpr().getNumSingleExpr() == 0 ) - throw new SemanticModelException( - curryExpr.toString(), - "Task expression must not be nil." ); - - if( curryExpr.getTaskExpr().getNumSingleExpr() > 1 ) - return new CompoundExpr( curryExpr ); - - se = curryExpr.getTaskExpr().visit( this ).getSingleExpr( 0 ); - - if( se instanceof NameExpr ) - return new CompoundExpr( curryExpr ); - - if( !( se instanceof LambdaExpr ) ) - throw new SemanticModelException( curryExpr.toString(), - se+" is not a lambda expression." ); - - - lambdaExpr = ( LambdaExpr )se; - - originalPrototype = lambdaExpr.getPrototype(); - - // the prototype of the curried lambda expression is derived from - // the original prototype - curriedPrototype = new Prototype( originalPrototype ); - - // from the prototype we remove all inputs that are bound by - // currying - for( NameExpr nameExpr : curryExpr.getNameSet() ) - curriedPrototype.removeParam( nameExpr ); - - // TODO: Foreign lambda expressions can of course also be curried - // TODO: Make sure that the remaining parameters and all output - // variables in the prototype are uncorrelated reduce - if( !( lambdaExpr instanceof NativeLambdaExpr ) ) - throw new UnsupportedOperationException( "NYI. Only native lambda expression can be curried." ); - - nativeLambdaExpr = ( NativeLambdaExpr )lambdaExpr; - - originalBodyBlock = nativeLambdaExpr.getBodyBlock(); - - // the body block of the curried lambda expression is derived from the - // body block of the original lambda expression - curriedBodyBlock = new Block(); - for( NameExpr ne : originalBodyBlock.getFullNameSet() ) - curriedBodyBlock.putAssign( ne, new CompoundExpr( originalBodyBlock.getExpr( ne ) ) ); - - // with the curried expression's binding block merged in - try { - for( NameExpr nameExpr : curryExpr.getNameSet() ) - curriedBodyBlock.putAssign( - nameExpr, curryExpr.getExpr( nameExpr ) ); - } - catch( NotBoundException e ) { - throw new RuntimeException( e.getMessage() ); - } - - // from the curried prototype and body expression we form the - // resulting curried lambda expression - curriedLambdaExpr = new NativeLambdaExpr( curriedPrototype, curriedBodyBlock ); - - return new CompoundExpr( curriedLambdaExpr ); - - // reuse this commented block when in dynamic reducer - /* if( lambdaExpr instanceof ForeignLambdaExpr ) { - - applyExpr = new ApplyExpr( 1, false ); - - applyExpr.setTaskExpr( new CompoundExpr( lambdaExpr ) ); - - try { - - for( NameExpr nameExpr : originalPrototype.getParamNameExprSet() ) - - if( curryExpr.containsName( nameExpr ) ) - applyExpr.putAssign( nameExpr, curryExpr.getExpr( nameExpr ) ); - else - applyExpr.putAssign( nameExpr, new CompoundExpr( nameExpr ) ); - } - catch( NotBoundException e ) { - throw new RuntimeException( e.getMessage() ); - } - - curriedBodyBlock = new Block(); - - n = originalPrototype.getNumOutput(); - - // replicate apply expression for each output name expression - for( i = 0; i < n; i++ ) { - - ne = originalPrototype.getOutput( i ); - - ae = applyExpr.clone(); - ae.setChannel( i+1 ); - - curriedBodyBlock.putAssign( ne, new CompoundExpr( ae ) ); - } - - curriedLambdaExpr = new NativeLambdaExpr( curriedPrototype, curriedBodyBlock ); - - return new CompoundExpr( curriedLambdaExpr ); - } */ - - } - - public UUID getQueryId() { - return queryId; - } - - public void setTopLevelContext( TopLevelContext tlc ) { - - if( tlc == null ) - throw new NullPointerException( "Top level context must not be null." ); - - currentBlock = tlc; - - } - - public void step() { - - CompoundExpr ce; - long tic, toc; - StringBuffer buf; - - try { - tic = System.currentTimeMillis(); - - ce = currentBlock.visit( this ); - toc = System.currentTimeMillis(); - - if( statLog.isDebugEnabled() ) - statLog.debug( new JsonReportEntry( ticketSrc.getRunId(), null, null, null, null, null, JsonReportEntry.KEY_REDUCTION_TIME, String.valueOf( toc-tic ) ) ); - - if( log.isDebugEnabled() ) - log.debug( "Checking if queue is clear ..." ); - - if( ticketSrc.isQueueClear( queryId ) ) { - - if( log.isDebugEnabled() ) - log.debug( "Queue is clear. Finishing query "+queryId+"." ); - - repl.queryFinished( queryId, ce ); - - return; - } - - if( log.isDebugEnabled() ) { - - buf = new StringBuffer(); - - buf.append( "Queue is not empty. " ).append( queryId ).append( " waits for [ " ); - for( Ticket t : ticketSrc.getTicketSet( queryId ) ) - buf.append( t.getTicketId() ).append( ' ' ); - buf.append( ']' ); - - log.debug( buf.toString() ); - } - - - } - catch( Exception e ) { - repl.queryFailed( queryId, null, e, null, null, null ); - } - } - - public CompoundExpr getCurrentExpr() { - - CompoundExpr result; - TopLevelContext tlc; - - if( !( currentBlock instanceof TopLevelContext ) ) - throw new RuntimeException( "Current block is not a top level context." ); - - tlc = ( TopLevelContext )currentBlock; - - result = new CompoundExpr(); - - for( CompoundExpr ce : tlc.getTargetList() ) - result.addCompoundExpr( ce ); - - return result; - - } - - private CompoundExpr combineParam( ApplyExpr applyExpr ) throws HasFailedException { - - EnumHelper helper; - int i, n; - CompoundExpr ce, ce0; - Block bindingBlock; - LambdaExpr lambda; - ApplyExpr singularApplyExpr; - QualifiedTicket qt; - - try { - - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor combineParam ApplyExpr: "+applyExpr.toString().replace( '\n', ' ') ); - - helper = new EnumHelper( applyExpr ); - n = helper.getCardinality(); - - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor combineParam ApplyExpr: Creating CombiHelper with cardinality "+n ); - - ce = new CompoundExpr(); - - for( i = 0; i < n; i++ ) { - - bindingBlock = helper.getSingularBindingBlock( i ); // throws NotDerivableException - lambda = helper.getSingularLambdaExpr( i ); // throws NotDerivableException - - singularApplyExpr = new ApplyExpr( applyExpr.getChannel(), applyExpr.hasRest() ); - singularApplyExpr.setParamBindMap( bindingBlock.getParamBindMap() ); - singularApplyExpr.setTaskExpr( new CompoundExpr( lambda ) ); - - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor combineParam ApplyExpr: Enumerating singular application "+singularApplyExpr.toString().replace( '\n', ' ' ) ); - - if( lambda instanceof ForeignLambdaExpr ) { - - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor combineParam ApplyExpr: Task expression is foreign." ); - - if( singularApplyExpr.isParamNormal() ) { - - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor combineParam ApplyExpr: Application parameters are in normal form." ); - - qt = ticketSrc.requestTicket( repl, queryId, singularApplyExpr ); - if( qt == null ) - throw new NullPointerException( "Qualified ticket must not be null." ); - - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor combineParam ApplyExpr: Ticket requested. Appending qualified ticket: "+qt.toString().replace( '\n', ' ' ) ); - - ce.addSingleExpr( qt ); - continue; - } - - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor combineParam ApplyExpr: Application parameters are not in normal form. Appending what we have so far: "+singularApplyExpr.toString().replace( '\n', ' ' ) ); - - ce.addSingleExpr( singularApplyExpr ); - continue; - } - - - if( lambda instanceof NativeLambdaExpr ) { - - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor combineParam ApplyExpr: Task expression is native." ); - - ce0 = reduceSingleNative( singularApplyExpr ); - - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor combineParam ApplyExpr: Appending result of single native reduction step: "+ce0.toString().replace( '\n', ' ' ) ); - - ce.addCompoundExpr( ce0 ); - continue; - } - - throw new RuntimeException( "Lambda expression type not recognized." ); - } - - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor combineParam ApplyExpr: Combination complete; returning: "+ce.toString().replace( '\n', ' ' ) ); - - return ce; - } - catch( NotDerivableException e ) { - - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor combineParam ApplyExpr: Some information could not be derived. Returning original: "+applyExpr.toString().replace( '\n', ' ' ) ); - - return new CompoundExpr( applyExpr ); - } - } - - private void popBlock() { - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor popping out of block." ); - - currentBlock = blockStack.pop(); - } - - private void pushIntoBlock( Block block ) { - - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor pushing into block." ); - - - blockStack.push( currentBlock ); - currentBlock = block; - } - - private CompoundExpr reducePotentiallyCorrelated( ApplyExpr applyExpr ) throws HasFailedException, NotBoundException { - - CompoundExpr taskExpr, ce, ce0; - SingleExpr se; - LambdaExpr lambda; - Prototype prototype; - ApplyExpr applyExpr1; - int i, n; - - - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor reducePotentiallyCorrelated ApplyExpr: "+applyExpr.toString().replace( '\n', ' ' ) ); - - - taskExpr = applyExpr.getTaskExpr(); - se = taskExpr.getSingleExpr( 0 ); - - if( !( se instanceof LambdaExpr ) ) { - - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor reducePotentiallyCorrelated ApplyExpr: Task expression is not a lambda expression. Returning original: "+applyExpr.toString().replace( '\n', ' ' ) ); - - return new CompoundExpr( applyExpr ); - } - - lambda = ( LambdaExpr )se; - prototype = lambda.getPrototype(); - - if( prototype.isTaskCorrelated() ) { - - // task parameter is correlated - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor reducePotentiallyCorrelated ApplyExpr: Prototype is task-correlated." ); - - // combine and create tickets - - return combineParam( applyExpr ); - } - - // enumerate task expression and create an application from each - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor reducePotentiallyCorrelated ApplyExpr: Prototype is not task-correlated.Enumerate task expressions and create application for each." ); - - try { - n = taskExpr.getNumAtom(); - } - catch( NotDerivableException e ) { - - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor reducePotentiallyCorrelated ApplyExpr: Could not derive cardinality of task expression. Returning original: "+applyExpr.toString().replace( '\n', ' ' ) ); - - return new CompoundExpr( applyExpr ); - } - - ce = new CompoundExpr(); - - for( i = 0; i < n; i++ ) { - - applyExpr1 = new ApplyExpr( applyExpr ); - - // TODO: This won't work if the task expression was the result of an output-reduce task - ce0 = new CompoundExpr( taskExpr.getSingleExpr( i ) ); - - try { - if( ce0.getNumAtom() != 1 ) - throw new RuntimeException( "Enumeration resulted in non-singular expression: "+ce0 ); - } catch (NotDerivableException e) { - throw new RuntimeException( e ); - } - - applyExpr1.setTaskExpr( ce0 ); - - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor reducePotentiallyCorrelated ApplyExpr: Appending "+applyExpr.toString().replace( '\n', ' ' ) ); - - ce.addSingleExpr( applyExpr1 ); - } - - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor reducePotentiallyCorrelated ApplyExpr: Trying to reduce "+ce.toString().replace( '\n', ' ' ) ); - - ce0 = ce.visit( this ); - - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor reducePotentiallyCorrelated ApplyExpr: Returning "+ce0.toString().replace( '\n', ' ' ) ); - - return ce0; - - } - - private CompoundExpr reduceSingleNative( ApplyExpr applyExpr ) throws HasFailedException { - - CompoundExpr taskResult; - SingleExpr se; - NativeLambdaExpr lambda; - NameExpr targetNameExpr; - int channel; - CompoundExpr targetCompoundExpr, ce; - ApplyExpr applyExpr1; - CompoundExpr lamList; - boolean push; - Block body, originalBody; - Prototype sign; - Block binding; - - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor reduceSingleNative ApplyExpr: "+applyExpr.toString().replace( '\n', ' ' ) ); - - - taskResult = applyExpr.getTaskExpr(); - try { - if( taskResult.getNumAtom() != 1 ) - throw new RuntimeException( "Expected application with singular task expression" ); - } - catch( NotDerivableException e2 ) { - throw new RuntimeException( "Cannot derive cardinality of task expression." ); - } - - channel = applyExpr.getChannel(); - push = applyExpr.hasRest(); - - // fetch that lambda expression - se = taskResult.getSingleExpr( 0 ); - - if( se == null ) - throw new NullPointerException( "Single expression must not be null." ); - - // continue only if that single lambda expression is native - if( !( se instanceof NativeLambdaExpr ) ) - throw new RuntimeException( "Single native lambda expression expected." ); - - - lambda = ( NativeLambdaExpr )se; - applyExpr.setParent( lambda.getBodyBlock() ); - - - try { - pushIntoBlock( applyExpr.getParamBlock() ); - } catch( NotDerivableException e ) { - throw new RuntimeException( e ); - } - - targetNameExpr = lambda.getPrototype().getOutput( channel-1 ); - - try { - - if( log.isDebugEnabled() ) - log.debug( "Visiting "+currentBlock.getExpr( targetNameExpr ) ); - - targetCompoundExpr = currentBlock.getExpr( targetNameExpr ).visit( this ); - if( targetCompoundExpr == null ) - throw new NullPointerException( "Evaluation of target expression must not result in null." ); - } - catch( NotBoundException e1 ) { - throw new SemanticModelException( applyExpr.toString(), e1.getMessage() ); - } - popBlock(); - - if( log.isTraceEnabled() ) - log.trace( "DynamicNodeVisitor reduceSingleNative ApplyExpr: Returning "+targetCompoundExpr.toString().replace( '\n', ' ' ) ); - - if( targetCompoundExpr.isNormal() ) - return targetCompoundExpr; - - - - sign = lambda.getPrototype(); - - - originalBody = lambda.getBodyBlock(); - - try { - body = new Block(); - for( NameExpr ne : originalBody.getFullNameSet() ) - body.putAssign( ne, new CompoundExpr( originalBody.getExpr( ne ) ) ); - } catch (NotBoundException e) { - throw new RuntimeException( e ); - } - - body.putAssign( targetNameExpr, targetCompoundExpr ); - - lamList = new CompoundExpr( new NativeLambdaExpr( sign, body ) ); - - binding = new Block(); - for( NameExpr ne : applyExpr.getParamBindMap().keySet() ) { - - ce = applyExpr.getParamBindMap().get( ne ); - - binding.putAssign( ne, new CompoundExpr( ce ) ); - } - - - applyExpr1 = new ApplyExpr( channel, push ); - applyExpr1.setTaskExpr( lamList ); - applyExpr1.setParamBindMap( binding.getParamBindMap() ); - - - return new CompoundExpr( applyExpr1 ); - - - } - - @Override - public CompoundExpr accept( TopLevelContext tlc ) throws HasFailedException, NotBoundException { - - CompoundExpr result; - - - result = new CompoundExpr(); - - for( CompoundExpr ce : tlc.getTargetList() ) - result.addCompoundExpr( ce.visit( this ) ); - - tlc.clearTargetList(); - tlc.addTarget( result ); - - return result; - } - - -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/repl/InteractiveRepl.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/repl/InteractiveRepl.java deleted file mode 100644 index eb99ac7..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/repl/InteractiveRepl.java +++ /dev/null @@ -1,114 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.repl; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.StringReader; -import java.util.UUID; - -import org.apache.commons.logging.Log; - -import de.huberlin.wbi.cuneiform.core.semanticmodel.CompoundExpr; -import de.huberlin.wbi.cuneiform.core.ticketsrc.ReplTicketSrc; - -public class InteractiveRepl extends BaseRepl { - - private static final int MAX_OUTPUT_LEN = 1000; - - public InteractiveRepl( ReplTicketSrc ticketSrc, Log statLog ) { - super( ticketSrc, statLog ); - } - - @Override - public synchronized void queryFinishedPost( UUID queryId, CompoundExpr result ) { - // nothing to do - } - - @Override - public synchronized void queryStartedPost( UUID runId ) { - // nothing to do - } - - @Override - public synchronized void queryFailedPost( UUID queryId, Long ticketId, Exception e, String script, String stdOut, String stdErr ) { - - String line; - int i; - - if( script != null ) - try( BufferedReader reader = new BufferedReader( new StringReader( script ) ) ) { - - System.out.println( "[script]" ); - - i = 0; - - while( ( line = reader.readLine() ) != null ) - System.out.println( String.format( "%3d %s", ++i, line ) ); - - } - catch( IOException e1 ) { - throw new RuntimeException( e1 ); - } - - if( stdOut != null ) { - System.out.println( "[out]" ); - - i = stdOut.length(); - if( i > MAX_OUTPUT_LEN ) - line = "...\n"+stdOut.substring( i-MAX_OUTPUT_LEN ); - else - line = stdOut; - - System.out.println( line ); - } - - if( stdErr != null ) { - System.out.println( "[err]" ); - - i = stdErr.length(); - if( i > MAX_OUTPUT_LEN ) - line = "...\n"+stdErr.substring( i-MAX_OUTPUT_LEN ); - else - line = stdErr; - - System.out.println( line ); - } - - if( e != null ) { - System.out.println( "[trace]" ); - e.printStackTrace(); - } - - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/repl/QueryParseCtlLexer.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/repl/QueryParseCtlLexer.java deleted file mode 100644 index 9c435b2..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/repl/QueryParseCtlLexer.java +++ /dev/null @@ -1,81 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.repl; - -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.Recognizer; -import org.antlr.v4.runtime.Token; - -import de.huberlin.wbi.cuneiform.core.parser.ParseCtlLexer; - -public class QueryParseCtlLexer extends ParseCtlLexer { - - public QueryParseCtlLexer( CharStream input ) { - super( input ); - } - - public boolean isReady() { - - int depth; - Token t; - boolean ready; - - reset(); - - depth = 0; - ready = true; - while( ( t = nextToken() ).getType() != Recognizer.EOF ) { - - switch( t.getType() ) { - - case ParseCtlLexer.LXCOMMENT : - case ParseCtlLexer.LCCOMMENT : - case ParseCtlLexer.LBRACE : depth++; break; - - case ParseCtlLexer.RXCOMMENT : - case ParseCtlLexer.RCCOMMENT : - case ParseCtlLexer.RBRACE : depth--; if( depth == 0 ) ready = true; break; - - case ParseCtlLexer.RMMECB : if( depth == 0 ) ready = true; break; - case ParseCtlLexer.ANY : if( depth == 0 ) ready = false; break; - case ParseCtlLexer.SEMICOLON : if( depth == 0 ) ready = true; break; - default : break; // ignore - } - } - - if( depth != 0 ) - return false; - - return ready; - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/ApplyExpr.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/ApplyExpr.java deleted file mode 100644 index 62c5d98..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/ApplyExpr.java +++ /dev/null @@ -1,324 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - - - -public class ApplyExpr extends BaseBlock implements SingleExpr { - - private int channel; - private boolean rest; - private CompoundExpr taskExpr; - - public ApplyExpr( int channel, boolean inheritsExtra ) { - this( channel, inheritsExtra, null ); - } - - public ApplyExpr( int channel, boolean inheritsExtra, BaseBlock parent ) { - - super( parent ); - - setChannel( channel ); - setRest( inheritsExtra ); - } - - public ApplyExpr( ApplyExpr template ) { - - if( template.taskExpr == null ) - throw new IllegalArgumentException( "Template apply expression has no task expression: "+template+"." ); - - channel = template.channel; - rest = template.rest; - taskExpr = new CompoundExpr( template.taskExpr ); - - try { - for( NameExpr ne : template.getFullNameSet() ) - putAssign( ne, new CompoundExpr( template.getExpr( ne ) ) ); - } - catch( NotBoundException e ) { - throw new RuntimeException( e ); - } - } - - public String getBlockString() { - return super.toString(); - } - - public int getChannel() { - return channel; - } - - public Prototype getPrototype() throws NotDerivableException { - - for( SingleExpr se : taskExpr.getSingleExprList() ) - if( se instanceof LambdaExpr ) - return ( ( LambdaExpr )se ).getPrototype(); - - throw new NotDerivableException( "Cannot derive prototype for "+taskExpr+"." ); - } - - public Block getParamBlock() throws NotDerivableException { - - Prototype prototype; - Block paramBlock; - - prototype = getPrototype(); - - paramBlock = new Block( getParent() ); - - try { - for( NameExpr nameExpr : getNameSet() ) { - - if( prototype.containsParam( nameExpr ) ) - paramBlock.putAssign( nameExpr, getExpr( nameExpr ) ); - } - } - catch( NotBoundException e ) { - // cannot happen because we only ask for legal symbols - throw new RuntimeException( e.getMessage() ); - } - - return paramBlock; - } - - public CompoundExpr getTaskExpr() { - - if( taskExpr == null ) - throw new NullPointerException( "Task expression never set." ); - - return taskExpr; - } - - @Override - public StringExpr getStringExprValue( int i ) throws NotDerivableException { - throw new NotDerivableException( "Cannot derive value in application." ); - } - - @Override - public int hashCode() { - - String s; - - s = toString(); - s = s.substring( s.indexOf( ']' ) ); - - return s.hashCode(); - } - - public boolean hasRest() { - return rest; - } - - public boolean hasTaskExpr() { - return taskExpr != null; - } - - public boolean isParamNormal() { - - CompoundExpr ce; - - try { - for( NameExpr nameExpr : getNameSet() ) { - - ce = getExpr( nameExpr ); - if( !ce.isNormal() ) - return false; - } - - return true; - } - catch( NotBoundException e ) { - throw new RuntimeException( e.getMessage() ); - } - - } - - public void attemptPushRest() throws NotDerivableException { - - Block restBlock; - Prototype prototype; - NativeLambdaExpr nativeLambda; - Block bodyBlock; - - try { - prototype = getPrototype(); - - restBlock = new Block(); - - for( NameExpr name : getNameSet() ) - if( !prototype.containsParam( name ) ) - restBlock.putAssign( name, getExpr( name ) ); - - if( !taskExpr.isNormal() ) - throw new NotDerivableException( "Task expression not in not normal." ); - - for( SingleExpr se : taskExpr.getSingleExprList() ) { - - if( se instanceof NativeLambdaExpr ) { - - - nativeLambda = ( NativeLambdaExpr )se; - - bodyBlock = nativeLambda.getBodyBlock(); - for( NameExpr name : bodyBlock.getNameSet() ) - bodyBlock.getExpr( name ).pushRest( restBlock ); - - continue; - } - - if( se instanceof ForeignLambdaExpr ) - continue; - - throw new RuntimeException( - "Lambda expression expected." ); - - } - - } - catch( NotBoundException e ) { - throw new RuntimeException( e.getMessage() ); - } - - } - - @Override - public void pushRest( BaseBlock restBlock ) { - - if( !rest ) - return; - - super.pushRest( restBlock ); - - rest = false; - } - - public void setChannel( int channel ) { - - if( channel < 1 ) - throw new SemanticModelException( - String.valueOf( channel ), - "Invalid channel "+channel+". Channel must be a positive integer." ); - - this.channel = channel; - } - - public void setRest( boolean inheritsExtra ) { - this.rest = inheritsExtra; - } - - public void setTaskExpr( CompoundExpr taskExpr ) { - - if( taskExpr == null ) - throw new NullPointerException( "Task expression must not be null." ); - - this.taskExpr = taskExpr; - } - - @Override - public String toString() { - - StringBuffer buf; - boolean comma; - - try { - - buf = new StringBuffer(); - - buf.append( '[' ).append( channel ).append( "]apply(" ); - - if( hasTaskExpr() ) - buf.append( " task: " ).append( taskExpr ); - - comma = false; - for( NameExpr name : getNameSet() ) { - - if( comma ) - buf.append( ',' ); - comma = true; - - buf.append( ' ' ).append( name.getId() ).append( ": " ).append( getExpr( name ) ); - } - - if( rest ) - buf.append( " ~" ); - - buf.append( " )" ); - - return buf.toString(); - } - catch( NotBoundException e ) { - throw new RuntimeException( e ); - } - } - - @Override - public int getNumAtom() throws NotDerivableException { - - Prototype prototype; - NameExpr name; - - prototype = getPrototype(); - name = prototype.getOutput( channel-1 ); - - if( name instanceof ReduceVar ) - throw new NotDerivableException( "Cannot derive cardinality of reduce output variable." ); - - return 1; - } - - @Override - public boolean equals( Object obj ) { - - ApplyExpr other; - String str1, str2; - - if( !( obj instanceof ApplyExpr ) ) - return false; - - other = ( ApplyExpr )obj; - - str1 = toString(); - str1 = str1.substring( str1.indexOf( ']' ) ); - - str2 = other.toString(); - str2 = str2.substring( str2.indexOf( ']' ) ); - - return str1.equals( str2 ); - } - - @Override - public T visit( NodeVisitor visitor ) throws HasFailedException, NotBoundException { - return visitor.accept( this ); - } - -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/BaseBlock.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/BaseBlock.java deleted file mode 100644 index 8c7fde7..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/BaseBlock.java +++ /dev/null @@ -1,182 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; - -public abstract class BaseBlock implements CfNode, Cloneable { - - private Map assignMap; - private BaseBlock parent; - - public BaseBlock() { - this( null ); - } - - public BaseBlock( BaseBlock parent ) { - assignMap = new HashMap<>(); - setParent( parent ); - } - - public void clear() { - assignMap.clear(); - } - - public boolean containsName( NameExpr nameExpr ) { - return assignMap.containsKey( nameExpr ); - } - - public CompoundExpr getExpr( NameExpr name ) throws NotBoundException { - - CompoundExpr ce; - - ce = assignMap.get( name ); - - if( ce != null ) - return ce; - - if( parent == null ) - throw new NotBoundException( "A name '"+name+"' is not bound in this block." ); - - return parent.getExpr( name ); - } - - public CompoundExpr getExpr( String name ) throws NotBoundException { - return getExpr( new NameExpr( name ) ); - } - - public Set getNameSet() { - return assignMap.keySet(); - } - - public Set getFullNameSet() { - - Set set; - - set = new HashSet<>(); - set.addAll( assignMap.keySet() ); - - if( parent != null ) - set.addAll( parent.getFullNameSet() ); - - return set; - } - - public Map getParamBindMap() { - return Collections.unmodifiableMap( assignMap ); - } - - public BaseBlock getParent() { - return parent; - } - - public boolean hasParent() { - return parent != null; - } - - public boolean isEmpty() { - return assignMap.isEmpty(); - } - - public void pushRest( BaseBlock restBlock ) { - - try { - - for( NameExpr name : restBlock.getNameSet() ) - if( !containsName( name ) ) - putAssign( name, restBlock.getExpr( name ) ); - - } - catch( NotBoundException e ) { - throw new RuntimeException( e.getMessage() ); - } - } - - public void putAssign( NameExpr key, CompoundExpr value ) { - - if( key == null ) - throw new NullPointerException( "Name expression must not be null." ); - - if( value == null ) - throw new NullPointerException( "Compound expression must not be null." ); - - assignMap.put( key, value ); - } - - public void removeAssign( String name ) { - removeAssign( new NameExpr( name ) ); - } - - public void removeAssign( NameExpr nameExpr ) { - - if( assignMap.remove( nameExpr ) == null ) - throw new NullPointerException( "Cannot remove. Assignment does not exist." ); - } - - public void setParamBindMap( Map paramBindMap ) { - - if( assignMap == null ) - throw new NullPointerException( "Parameter binding map must not be null." ); - - assignMap = paramBindMap; - } - - public void setParent( BaseBlock parent ) { - this.parent = parent; - } - - @Override - public String toString() { - - StringBuffer buf; - List nameExprSet; - - buf = new StringBuffer(); - - nameExprSet = new LinkedList<>(); - - nameExprSet.addAll( assignMap.keySet() ); - Collections.sort( nameExprSet ); - - for( NameExpr nameExpr : nameExprSet ) - buf.append( nameExpr ).append( " = " ).append( assignMap.get( nameExpr ) ).append( ";\n" ); - - return buf.toString(); - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/BaseNodeVisitor.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/BaseNodeVisitor.java deleted file mode 100644 index 7c0ede2..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/BaseNodeVisitor.java +++ /dev/null @@ -1,94 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -public abstract class BaseNodeVisitor implements NodeVisitor { - - @Override - public CompoundExpr accept( Block block ) { - throw new RuntimeException( "Block is not an expression." ); - } - - @Override - public CompoundExpr accept( ForeignLambdaExpr foreignLambdaExpr ) { - return new CompoundExpr( foreignLambdaExpr ); - } - - @Override - public CompoundExpr accept( NativeLambdaExpr nativeLambdaExpr ) { - return new CompoundExpr( nativeLambdaExpr ); - } - - @Override - public CompoundExpr accept( StringExpr stringExpr ) { - return new CompoundExpr( stringExpr ); - } - - @Override - public CompoundExpr accept( QualifiedTicket qualifiedTicket ) { - return new CompoundExpr( qualifiedTicket ); - } - - @Override - public CompoundExpr accept( LambdaType lambdaType ) { - throw new RuntimeException( "Lambda type is not an expression." ); - } - - @Override - public CompoundExpr accept( DrawParam drawParam ) { - throw new RuntimeException( "Draw parameter is not an expression." ); - } - - @Override - public CompoundExpr accept( DataType dataType ) { - throw new RuntimeException( "Data type is not an expression." ); - } - - @Override - public CompoundExpr accept( CorrelParam correlParam ) { - throw new RuntimeException( "Correlated parameter is not an expression." ); - } - - @Override - public CompoundExpr accept( Prototype prototype ) { - throw new RuntimeException( "Prototype is not an expression." ); - } - - @Override - public CompoundExpr accept( ReduceVar reduceVar ) { - throw new RuntimeException( "Reduce variable is not an expression." ); - } - - - -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/Block.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/Block.java deleted file mode 100644 index ec27f1a..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/Block.java +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - - -public class Block extends BaseBlock { - - public Block() {} - - public Block( BaseBlock parent ) { - super( parent ); - } - - @Override - public T visit( NodeVisitor visitor ) { - return visitor.accept( this ); - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CfNode.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CfNode.java deleted file mode 100644 index 75940ef..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CfNode.java +++ /dev/null @@ -1,38 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - - -public interface CfNode { - public T visit(NodeVisitor visitor) throws HasFailedException, NotBoundException; -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CfSemanticModelVisitor.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CfSemanticModelVisitor.java deleted file mode 100644 index 00b93cf..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CfSemanticModelVisitor.java +++ /dev/null @@ -1,692 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -import java.util.BitSet; -import java.util.LinkedList; - -import org.antlr.v4.runtime.ANTLRErrorListener; -import org.antlr.v4.runtime.ANTLRInputStream; -import org.antlr.v4.runtime.CommonTokenStream; -import org.antlr.v4.runtime.Parser; -import org.antlr.v4.runtime.RecognitionException; -import org.antlr.v4.runtime.Recognizer; -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.atn.ATNConfigSet; -import org.antlr.v4.runtime.dfa.DFA; -import org.antlr.v4.runtime.misc.NotNull; -import org.antlr.v4.runtime.tree.ParseTree; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import de.huberlin.wbi.cuneiform.core.parser.CuneiformBaseVisitor; -import de.huberlin.wbi.cuneiform.core.parser.CuneiformLexer; -import de.huberlin.wbi.cuneiform.core.parser.CuneiformParser; -import de.huberlin.wbi.cuneiform.core.parser.CuneiformParser.NameContext; -import de.huberlin.wbi.cuneiform.core.parser.CuneiformParser.OutputContext; -import de.huberlin.wbi.cuneiform.core.parser.CuneiformParser.ParamBindContext; -import de.huberlin.wbi.cuneiform.core.parser.CuneiformParser.ParamContext; -import de.huberlin.wbi.cuneiform.core.parser.CuneiformParser.SingleExprContext; -import de.huberlin.wbi.cuneiform.core.preprocess.ParseException; - -public class CfSemanticModelVisitor extends CuneiformBaseVisitor implements ANTLRErrorListener { - - public static final String LABEL_TASK = "task"; - public static final String LABEL_FILE = "File"; - - private BaseBlock currentBlock; - private final LinkedList blockStack; - private final Log log; - - public CfSemanticModelVisitor() { - - currentBlock = new TopLevelContext(); - blockStack = new LinkedList<>(); - log = LogFactory.getLog( CfSemanticModelVisitor.class ); - } - - @Override - public CfNode visitApplyExpr( @NotNull CuneiformParser.ApplyExprContext ctx ) { - - ApplyExpr applyExpr; - int channel; - NameExpr name; - CfNode compoundExpr; - String id; - boolean rest; - - if( ctx.channel() == null ) - channel = 1; - else - channel = Integer.parseInt( ctx.channel().INT().getText() ); - - rest = ctx.TILDE() != null; - applyExpr = new ApplyExpr( channel, rest ); - - - for( ParamBindContext pbc : ctx.paramBind() ) { - - id = pbc.ID().getText(); - name = new NameExpr( id ); - compoundExpr = visit( pbc.expr() ); - - if( compoundExpr == null ) - throw new NullPointerException( "Compound expression must not be null." ); - - if( !( compoundExpr instanceof CompoundExpr ) ) - throw new RuntimeException( "Compound expression expected." ); - - if( id.equals( LABEL_TASK ) ) - applyExpr.setTaskExpr( ( CompoundExpr )compoundExpr ); - else - applyExpr.putAssign( name, ( CompoundExpr )compoundExpr ); - - } - - if( !applyExpr.hasTaskExpr() ) - throw new SemanticModelException( - applyExpr.toString(), - "Task parameter not bound." ); - - return applyExpr; - } - - - @Override - public CfNode visitAssign( @NotNull CuneiformParser.AssignContext ctx ) { - - CfNode nameExpr, compoundExpr; - CompoundExpr ce; - SingleExpr se; - ForeignLambdaExpr lambda; - - if( ctx.name().size() != 1 ) - // sorted out in the channel-phase - throw new RuntimeException( - "Illegal assignment. Left hand side must have exactly one name element." ); - - nameExpr = visit( ctx.name( 0 ) ); - - if( nameExpr == null ) - throw new NullPointerException( "Name expression must not be null." ); - - if( !( nameExpr instanceof NameExpr ) ) - throw new RuntimeException( "Expected name expression." ); - - compoundExpr = visit( ctx.expr() ); - - if( compoundExpr == null ) - throw new NullPointerException( "Compound expression must not be null." ); - - if( !( compoundExpr instanceof CompoundExpr ) ) - throw new RuntimeException( "Expected compound expression. Found "+compoundExpr.getClass().getName()+"." ); - - ce = ( CompoundExpr )compoundExpr; - - currentBlock.putAssign( ( NameExpr )nameExpr, ce ); - - // if we assigned a single foreign lambda expression, store name - if( ce.getNumSingleExpr() == 1 ) { - - se = ce.getSingleExpr( 0 ); - if( se instanceof ForeignLambdaExpr ) { - - lambda = ( ForeignLambdaExpr )se; - lambda.setOptionalTaskName( ( ( NameExpr )nameExpr ).getId() ); - } - - } - - return currentBlock; - } - - @Override - public CfNode visitBlock( @NotNull CuneiformParser.BlockContext ctx ) { - - Block block; - - block = new Block( currentBlock ); - - pushIntoBlock( block ); - visitChildren( ctx ); - popBlock(); - - return block; - } - - @Override - public CfNode visitCallExpr( @NotNull CuneiformParser.CallExprContext ctx ) { - - ApplyExpr applyExpr; - int channel; - NameExpr name; - CfNode compoundExpr; - String id; - boolean rest; - - if( ctx.channel() == null ) - channel = 1; - else - channel = Integer.parseInt( ctx.channel().INT().getText() ); - - rest = ctx.TILDE() != null; - applyExpr = new ApplyExpr( channel, rest ); - - id = ctx.ID().getText(); - applyExpr.setTaskExpr( new CompoundExpr( new NameExpr( id ) ) ); - - - for( ParamBindContext pbc : ctx.paramBind() ) { - - id = pbc.ID().getText(); - name = new NameExpr( id ); - compoundExpr = visit( pbc.expr() ); - - if( compoundExpr == null ) - throw new NullPointerException( "Compound expression must not be null." ); - - if( !( compoundExpr instanceof CompoundExpr ) ) - throw new RuntimeException( "Compound expression expected." ); - - if( id.equals( LABEL_TASK ) ) - applyExpr.setTaskExpr( ( CompoundExpr )compoundExpr ); - else - applyExpr.putAssign( name, ( CompoundExpr )compoundExpr ); - - } - - if( !applyExpr.hasTaskExpr() ) - throw new SemanticModelException( - applyExpr.toString(), - "Task parameter not bound." ); - - return applyExpr; - } - - @Override - public CfNode visitIdExpr( @NotNull CuneiformParser.IdExprContext ctx ) { - - return new NameExpr( ctx.ID().getText() ); - } - - - @Override - public CfNode visitCompoundExpr( @NotNull CuneiformParser.CompoundExprContext ctx ) { - - CompoundExpr compoundExpr; - CfNode singleExpr; - - compoundExpr = new CompoundExpr(); - - for( SingleExprContext sec : ctx.singleExpr() ) { - - singleExpr = visit( sec ); - - if( singleExpr == null ) - throw new NullPointerException( "While evaluating compound expression '"+sec.getText()+"': Single expression must not be null." ); - - - if( !( singleExpr instanceof SingleExpr ) ) - throw new RuntimeException( "Single expresssion expected." ); - - compoundExpr.addSingleExpr( ( SingleExpr )singleExpr ); - } - - return compoundExpr; - } - - @Override - public CfNode visitCondExpr( @NotNull CuneiformParser.CondExprContext ctx ) { - - CfNode ifExpr; - CfNode thenBlock; - CfNode elseBlock; - - - ifExpr = visit( ctx.expr( 0 ) ); - - if( ifExpr == null ) - throw new NullPointerException( "If expression must not be null." ); - - if( !( ifExpr instanceof CompoundExpr ) ) - throw new RuntimeException( "Compound expression expected." ); - - - - thenBlock = visit( ctx.expr( 1 ) ); - - if( thenBlock == null ) - throw new NullPointerException( "Then block must not be null." ); - - if( !( thenBlock instanceof CompoundExpr ) ) - throw new RuntimeException( "Compound expression expected." ); - - elseBlock = visit( ctx.expr( 2 ) ); - - if( elseBlock == null ) - throw new NullPointerException( "Then block must not be null." ); - - if( !( elseBlock instanceof CompoundExpr ) ) - throw new RuntimeException( "Compound expression expected." ); - - return new CondExpr( ( CompoundExpr )ifExpr, ( CompoundExpr )thenBlock, ( CompoundExpr )elseBlock ); - } - - - @Override - public CfNode visitCorrelParam( @NotNull CuneiformParser.CorrelParamContext ctx ) { - - CorrelParam correlParam; - CfNode nameExpr; - - correlParam = new CorrelParam(); - - for( NameContext nc : ctx.name() ) { - - nameExpr = visit( nc ); - - if( nameExpr == null ) - throw new NullPointerException( "Name expression must not be null." ); - - if( !( nameExpr instanceof NameExpr ) ) - throw new RuntimeException( "Name expression expected." ); - - correlParam.addName( ( NameExpr )nameExpr ); - } - - return correlParam; - } - @Override - public CfNode visitCurryExpr( @NotNull CuneiformParser.CurryExprContext ctx ) { - - CurryExpr curryExpr; - String id; - NameExpr name; - CfNode compoundExpr; - - curryExpr = new CurryExpr(); - - for( ParamBindContext pbc : ctx.paramBind() ) { - - id = pbc.ID().getText(); - name = new NameExpr( id ); - compoundExpr = visit( pbc.expr() ); - - if( compoundExpr == null ) - throw new NullPointerException( "Compound expression must not be null." ); - - if( !( compoundExpr instanceof CompoundExpr ) ) - throw new RuntimeException( "Compound expression expected." ); - - if( id.equals( LABEL_TASK ) ) - curryExpr.setTaskExpr( ( CompoundExpr )compoundExpr ); - else - curryExpr.putAssign( name, ( CompoundExpr )compoundExpr ); - - } - - if( !curryExpr.hasTaskExpr() ) - throw new SemanticModelException( - curryExpr.toString(), - "Task parameter not bound." ); - - return curryExpr; - } - - @Override - public CfNode visitDanglingExpr( @NotNull CuneiformParser.DanglingExprContext ctx ) { - // sorted out in the pre-phase - throw new RuntimeException( "Illegal dangling expression encountered." ); - } - - @Override - public CfNode visitForeignDefTask( @NotNull CuneiformParser.ForeignDefTaskContext ctx ) { - // sorted out in the pre-phase - throw new RuntimeException( "Illegal foreign task definition encountered." ); - } - - @Override - public CfNode visitForeignLambdaExpr( @NotNull CuneiformParser.ForeignLambdaExprContext ctx ) { - - CfNode prototype; - String langString; - String body; - - prototype = visit( ctx.prototype() ); - - if( prototype == null ) - throw new NullPointerException( "Prototype must not be null." ); - - if( !( prototype instanceof Prototype ) ) - throw new RuntimeException( "Prototype expected." ); - - langString = ctx.foreignBody().INLANG().getText(); - langString = langString.substring( 2 ).replace( ",", "" ).trim(); - - body = ctx.foreignBody().BODY().getText(); - body = body.substring( 2, body.length()-2 ); - - if( body.trim().isEmpty() ) - throw new SemanticModelException( - prototype+"in "+langString+" *{}*", - "Foreign body block must not be empty." ); - - for( NameExpr name : ( ( Prototype )prototype ).getOutputList() ) - if( !body.contains( name.getId() ) ) - throw new SemanticModelException( prototype+"in "+langString+" *{ "+body+" }*", "Output variable "+name.getId()+" is never bound." ); - - return new ForeignLambdaExpr( ( Prototype )prototype, langString, body ); - } - - - @Override public CfNode visitFromStackExpr( @NotNull CuneiformParser.FromStackExprContext ctx ) { - // sorted out in the pre-phase - throw new RuntimeException( "Illegal from-stack expression encountered." ); - } - - @Override - public CfNode visitImportFile( @NotNull CuneiformParser.ImportFileContext ctx ) { - throw new RuntimeException( "Illegal import statement encountered." ); - } - - @Override - public CfNode visitIntExpr( @NotNull CuneiformParser.IntExprContext ctx ) { - return new StringExpr( ctx.getText() ); - } - - - @Override - public CfNode visitNameDataType( @NotNull CuneiformParser.NameDataTypeContext ctx ) { - return new NameExpr( ctx.ID( 0 ).getText(), new DataType( ctx.ID( 1 ).getText() ) ); - } - - @Override - public CfNode visitNameDeepFnType( @NotNull CuneiformParser.NameDeepFnTypeContext ctx ) { - - CfNode prototype; - - prototype = visit( ctx.prototype() ); - - if( prototype == null ) - throw new NullPointerException( "Prototype must not be null." ); - - if( !( prototype instanceof Prototype ) ) - throw new RuntimeException( "Prototype expected." ); - - return new NameExpr( ctx.ID().getText(), ( Prototype )prototype ); - - } - - @Override - public CfNode visitNameInferredType( @NotNull CuneiformParser.NameInferredTypeContext ctx ) { - return new NameExpr( ctx.ID().getText(), null ); - } - - @Override - public CfNode visitNamePlainFnType( @NotNull CuneiformParser.NamePlainFnTypeContext ctx ) { - return new NameExpr( ctx.ID().getText(), new LambdaType() ); - } - - @Override - public CfNode visitNativeDefTask( @NotNull CuneiformParser.NativeDefTaskContext ctx ) { - // sorted out in the pre-phase - throw new RuntimeException( "Illegal native task definition exncountered." ); - } - - @Override - public CfNode visitNativeLambdaExpr( @NotNull CuneiformParser.NativeLambdaExprContext ctx ) { - - CfNode prototype; - CfNode block; - - prototype = visit( ctx.prototype() ); - - if( prototype == null ) - throw new NullPointerException( "Prototype must not be null." ); - - if( !( prototype instanceof Prototype ) ) - throw new RuntimeException( "Prototype expected." ); - - block = visit( ctx.block() ); - - if( block == null ) - throw new NullPointerException( "Symbol table must not be null." ); - - if( !( block instanceof Block ) ) - throw new RuntimeException( "Symbol table expected." ); - - return new NativeLambdaExpr( ( Prototype )prototype, ( Block )block ); - } - - - @Override - public CfNode visitNilExpr( @NotNull CuneiformParser.NilExprContext ctx ) { - return new CompoundExpr(); - } - - @Override - public CfNode visitPrototype( @NotNull CuneiformParser.PrototypeContext ctx ) { - - CfNode node; - Prototype prototype; - - prototype = new Prototype(); - - for( OutputContext oc : ctx.output() ) { - - node = visit( oc ); - - if( node == null ) - throw new NullPointerException( "Output must not be null." ); - - if( !( node instanceof NameExpr ) ) - throw new RuntimeException( "Output expected." ); - - prototype.addOutput( ( NameExpr )node ); - } - - for( ParamContext pc : ctx.param() ) { - - node = visit( pc ); - - if( node == null ) - throw new NullPointerException( "Parameter must not be null." ); - - if( !( node instanceof Param ) ) - throw new RuntimeException( "Parameter expected." ); - - prototype.addParam( ( Param )node ); - } - - return prototype; - } - - @Override - public CfNode visitReduceVar( @NotNull CuneiformParser.ReduceVarContext ctx ) { - - CfNode nameExpr; - - nameExpr = visit( ctx.name() ); - - if( nameExpr == null ) - throw new NullPointerException( "Name expression must not be null." ); - - if( !( nameExpr instanceof NameExpr ) ) - throw new RuntimeException( "Name expression expected." ); - - return ( ( NameExpr )nameExpr ).toReduceVar(); - } - - @Override - public CfNode visitScript( @NotNull CuneiformParser.ScriptContext ctx ) { - - getTopLevelContext().clearTargetList(); - - visitChildren( ctx ); - return currentBlock; - } - - @Override - public CfNode visitStringExpr( @NotNull CuneiformParser.StringExprContext ctx ) { - - String content; - - content = ctx.getText(); - - if( content.startsWith( "\"" ) ) - content = content.replace( "\\\"", "\"" ); - else - content = content.replace( "\\'", "'" ); - - content = content.substring( 1, content.length()-1 ); - content = content.replace( "\\\\", "\\" ); - - return new StringExpr( content ); - } - - - @Override - public CfNode visitTarget( @NotNull CuneiformParser.TargetContext ctx ) { - - CfNode node; - - node = visit( ctx.expr() ); - - if( node == null ) - throw new NullPointerException( "Compound expression must not be null." ); - - if( !( node instanceof CompoundExpr ) ) - throw new RuntimeException( "Expected compound expression." ); - - if( currentBlock == null ) - throw new NullPointerException( "Current symbol table must not be null." ); - - if( !( currentBlock instanceof TopLevelContext ) ) - throw new RuntimeException( "Block expected." ); - - ( ( TopLevelContext )currentBlock ).addTarget( ( CompoundExpr )node ); - - return node; - } - - private void pushIntoBlock( Block block ) { - - blockStack.push( currentBlock ); - currentBlock = block; - } - - private void popBlock() { - currentBlock = blockStack.pop(); - } - - public TopLevelContext getTopLevelContext() { - - if( !( currentBlock instanceof TopLevelContext ) ) - throw new RuntimeException( "Not in top level context." ); - - return ( TopLevelContext )currentBlock; - } - - public static TopLevelContext process( String input ) { - - ANTLRInputStream instream; - CuneiformLexer lexer; - CommonTokenStream tokenStream; - CuneiformParser parser; - ParseTree tree; - CfNode node; - CfSemanticModelVisitor calculusVisitor; - - // parse original content - instream = new ANTLRInputStream( input ); - - lexer = new CuneiformLexer( instream ); - lexer.removeErrorListeners(); - - tokenStream = new CommonTokenStream( lexer ); - - parser = new CuneiformParser( tokenStream ); - parser.removeErrorListeners(); - - calculusVisitor = new CfSemanticModelVisitor(); - lexer.addErrorListener( calculusVisitor ); - parser.addErrorListener( calculusVisitor ); - - tree = parser.script(); - - node = calculusVisitor.visit( tree ); - - if( node == null ) - throw new NullPointerException( "Node must not be null." ); - - if( !( node instanceof TopLevelContext ) ) - throw new RuntimeException( "Top level context expected." ); - - return ( TopLevelContext )node; - } - - @Override - public void syntaxError(Recognizer recognizer, - Object offendingSymbol, int line, int charPositionInLine, - String msg, RecognitionException e) { - throw new ParseException( line, charPositionInLine, ( ( Token )offendingSymbol ).getText(), msg ); - - } - - @Override - public void reportAmbiguity( Parser arg0, DFA arg1, int arg2, int arg3, - boolean arg4, BitSet arg5, ATNConfigSet arg6 ) { - - if( log.isDebugEnabled() ) - log.debug( "Ambiguity detected." ); - - } - - @Override - public void reportAttemptingFullContext( Parser arg0, DFA arg1, int arg2, - int arg3, BitSet arg4, ATNConfigSet arg5 ) { - - if( log.isTraceEnabled() ) - log.trace( "Attempting full context." ); - - } - - @Override - public void reportContextSensitivity( Parser arg0, DFA arg1, int arg2, - int arg3, int arg4, ATNConfigSet arg5) { - - if( log.isTraceEnabled() ) - log.trace( "Context sensitivity detected." ); - } - -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CompoundExpr.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CompoundExpr.java deleted file mode 100644 index 0643219..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CompoundExpr.java +++ /dev/null @@ -1,327 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -public class CompoundExpr implements CfNode { - - private List singleExprList; - - public CompoundExpr() { - singleExprList = new ArrayList<>(); - } - - public CompoundExpr( SingleExpr se ) { - this(); - addSingleExpr( se ); - } - - public CompoundExpr( CompoundExpr template ) { - - this(); - - if( template == null ) - throw new NullPointerException( "Template compound expression must not be null." ); - - for( SingleExpr se : template.singleExprList ) - singleExprList.add( copySingleExpr( se ) ); - } - - public void addCompoundExpr( CompoundExpr ce ) { - - if( ce == null ) - throw new NullPointerException( "Compound expression must not be null." ); - - singleExprList.addAll( ce.getSingleExprList() ); - } - - public void addSingleExpr( SingleExpr singleExpr ) { - - if( singleExpr == null ) - throw new NullPointerException( "Single expression must not be null." ); - - singleExprList.add( singleExpr ); - } - - public int getNumAtom() throws NotDerivableException { - - int n; - - n = 0; - - for( SingleExpr se : singleExprList ) - n += se.getNumAtom(); - - return n; - } - - public int getNumSingleExpr() { - return singleExprList.size(); - } - - public SingleExpr getSingleExpr( int i ) { - return singleExprList.get( i ); - } - - public List getSingleExprList() { - return Collections.unmodifiableList( singleExprList ); - } - - public StringExpr getStringExprValue( int idx ) throws NotDerivableException { - - int i, j, k; - - if( idx < 0 ) - throw new IndexOutOfBoundsException( - "Queried entry "+idx+". Negative indexes are not allowed." ); - - if( idx >= getNumAtom() ) - throw new IndexOutOfBoundsException( - "Queried entry "+idx+" but the compound expression has only " - +getNumAtom()+" elements: "+this ); - - j = 0; - i = idx; - - while( true ) { - - k = i-getSingleExpr( j ).getNumAtom(); - - if( k < 0 ) - return getSingleExpr( j ).getStringExprValue( i ); - - j++; - i = k; - } - } - - public boolean isNormal() { - - QualifiedTicket qt; - - for( SingleExpr se : singleExprList ) { - - if( se instanceof StringExpr ) - continue; - - if( se instanceof LambdaExpr ) - continue; - - if( !( se instanceof QualifiedTicket ) ) - return false; - - qt = ( QualifiedTicket )se; - - try { - if( !qt.getOutputValue().isNormal() ) - return false; - } catch( NotDerivableException e ) { - return false; - } - } - - return true; - } - - public List normalize() throws NotDerivableException { - - List normalList; - QualifiedTicket qt; - - normalList = new ArrayList<>(); - - for( SingleExpr se : singleExprList ) { - - if( se instanceof StringExpr ) { - - normalList.add( ( ( StringExpr )se ).getContent() ); - continue; - } - - if( se instanceof QualifiedTicket ) { - - qt = ( QualifiedTicket )se; - normalList.addAll( qt.getOutputValue().normalize() ); - continue; - } - - throw new NotDerivableException( "Non-normalizable expression encountered." ); - } - - return normalList; - } - - public void pushRest( Block restBlock ) { - - ApplyExpr applyExpr; - - for( SingleExpr se : singleExprList ) - - if( se instanceof ApplyExpr ) { - - applyExpr = ( ApplyExpr )se; - applyExpr.pushRest( restBlock ); - } - } - - public void remove( SingleExpr se ) { - if( !singleExprList.remove( se ) ) - throw new RuntimeException( "Single expression is no member of this compound expression." ); - } - - @Override - public String toString() { - - StringBuffer buf; - boolean comma; - - try { - - if( this.getNumAtom() == 0 ) - return "nil"; - - buf = new StringBuffer(); - - comma = false; - for( SingleExpr singleExpr : singleExprList ) { - - if( singleExpr.getNumAtom() == 0 ) - continue; - - if( comma ) - buf.append( ' ' ); - - comma = true; - - buf.append( singleExpr ); - } - - return buf.toString(); - } - catch( NotDerivableException e ) { - - if( singleExprList.isEmpty() ) - return "nil"; - - buf = new StringBuffer(); - - comma = false; - for( SingleExpr singleExpr : singleExprList ) { - - if( comma ) - buf.append( ' ' ); - - comma = true; - - buf.append( singleExpr ); - } - - return buf.toString(); - } - } - - @Override - public boolean equals( Object other ) { - - CompoundExpr ce; - int i, n; - - if( other == null ) - return false; - - if( !( other instanceof CompoundExpr ) ) - return false; - - ce = ( CompoundExpr )other; - - if( getNumSingleExpr() != ce.getNumSingleExpr() ) - return false; - - n = ce.getNumSingleExpr(); - for( i = 0; i < n; i++ ) - if( !ce.getSingleExpr( i ).equals( getSingleExpr( i ) ) ) - return false; - - - return true; - } - - @Override - public T visit(NodeVisitor visitor) throws HasFailedException, NotBoundException { - return visitor.accept(this); - } - - @Override - public int hashCode() { - - if( getNumSingleExpr() == 0 ) - return 0; - - return getSingleExpr( 0 ).hashCode(); - } - - private static SingleExpr copySingleExpr( SingleExpr se ) { - - if( se == null ) - throw new IllegalArgumentException( "Single expression to be copied must not be null." ); - - if( se instanceof StringExpr ) - return se; - - if( se instanceof ApplyExpr ) - return new ApplyExpr( ( ApplyExpr )se ); - - if( se instanceof NativeLambdaExpr ) - return new NativeLambdaExpr( ( NativeLambdaExpr )se ); - - if( se instanceof NameExpr ) - return se; - - if( se instanceof ForeignLambdaExpr ) - return new ForeignLambdaExpr( ( ForeignLambdaExpr )se ); - - if( se instanceof CondExpr ) - return new CondExpr( ( CondExpr )se ); - - if( se instanceof QualifiedTicket ) - return se; - - if( se instanceof CurryExpr ) - return new CurryExpr( ( CurryExpr )se ); - - throw new UnsupportedOperationException( "Copy operation unsupported for expression of type "+se.getClass() ); - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CondExpr.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CondExpr.java deleted file mode 100644 index 2346162..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CondExpr.java +++ /dev/null @@ -1,111 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - - -public class CondExpr implements SingleExpr { - - private final CompoundExpr ifExpr; - private final CompoundExpr thenExpr; - private final CompoundExpr elseExpr; - - public CondExpr( CompoundExpr ifExpr, CompoundExpr thenBlock, CompoundExpr elseBlock ) { - - if( thenBlock == null ) - throw new IllegalArgumentException( "Then expression must not be null." ); - - if( elseBlock == null ) - throw new IllegalArgumentException( "Else expression must not be null." ); - - if( ifExpr == null ) - throw new IllegalArgumentException( "Condition expression must not be null." ); - - this.ifExpr = ifExpr; - this.elseExpr = elseBlock; - this.thenExpr = thenBlock; - - } - - public CondExpr(CondExpr template ) { - - if( template == null ) - throw new IllegalArgumentException( "Template conditional expression must not be null." ); - - ifExpr = new CompoundExpr( template.ifExpr ); - thenExpr = new CompoundExpr( template.thenExpr ); - elseExpr = new CompoundExpr( template.elseExpr ); - } - - - public CompoundExpr getElseExpr() { - return elseExpr; - } - - public CompoundExpr getIfExpr() { - return ifExpr; - } - - public CompoundExpr getThenExpr() { - return thenExpr; - } - - @Override - public String toString() { - - StringBuffer buf; - - buf = new StringBuffer(); - - buf.append( "if " ); - buf.append( ifExpr ); - buf.append( " then " ).append( thenExpr ); - buf.append( " else " ).append( elseExpr ).append( " end" ); - - return buf.toString(); - } - - @Override - public int getNumAtom() throws NotDerivableException { - throw new NotDerivableException( "Cannot derive cardinality of reduce output variable." ); - } - - @Override - public T visit( NodeVisitor visitor ) throws HasFailedException, NotBoundException { - return visitor.accept( this ); - } - - @Override - public StringExpr getStringExprValue( int i ) throws NotDerivableException { - throw new NotDerivableException( "Cannot derive value for conditional expression." ); - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CorrelParam.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CorrelParam.java deleted file mode 100644 index 88092f7..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CorrelParam.java +++ /dev/null @@ -1,135 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -public class CorrelParam implements Param { - - private final Set nameExprSet; - - public CorrelParam() { - nameExprSet = new HashSet<>(); - } - - public CorrelParam( CorrelParam template ) { - - this(); - nameExprSet.addAll( template.nameExprSet ); - } - - public void addName( NameExpr nameExpr ) { - - if( nameExpr == null ) - throw new NullPointerException( "Name expression must not be null." ); - - nameExprSet.add( nameExpr ); - } - - public boolean contains( NameExpr nameExpr ) { - return nameExprSet.contains( nameExpr ); - } - - public boolean contains( String id ) { - - for( NameExpr ne : nameExprSet ) - if( ne.getId().equals( id ) ) - return true; - - return false; - } - - @Override - public int getNumParam() { - return nameExprSet.size(); - } - - public NameExpr getLastNameExpr() { - - for( NameExpr nameExpr : nameExprSet ) - return nameExpr; - - throw new RuntimeException( "Name expression set must not be empty." ); - } - - @Override - public Set getNameExprSet() { - - // the parser already prevents that situation - if( nameExprSet.isEmpty() ) - throw new RuntimeException( "Empty correlated parameter list." ); - - if( nameExprSet.size() == 1 ) - throw new RuntimeException( "Correlated parameter list must have at least 2 entries." ); - - return Collections.unmodifiableSet( nameExprSet ); - } - - public void remove( NameExpr nameExpr ) { - if( !nameExprSet.remove( nameExpr ) ) - throw new RuntimeException( "Name expression '"+nameExpr+"' not member of correlated parameter." ); - } - - @Override - public String toString() { - - StringBuffer buf; - boolean comma; - - buf = new StringBuffer(); - - buf.append( '[' ); - - comma = false; - for( NameExpr name : nameExprSet ) { - - if( comma ) - buf.append( ' ' ); - comma = true; - - buf.append( name ); - } - - buf.append( ']' ); - - return buf.toString(); - } - - - @Override - public T visit( NodeVisitor visitor ) { - return visitor.accept( this ); - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CurryExpr.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CurryExpr.java deleted file mode 100644 index 23ca610..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CurryExpr.java +++ /dev/null @@ -1,119 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - - -public class CurryExpr extends BaseBlock implements SingleExpr { - - private CompoundExpr taskExpr; - - public CurryExpr() { - // do nothing - } - - public CurryExpr( CurryExpr se ) { - - if( se == null ) - throw new NullPointerException( "Task expression must not be null." ); - - taskExpr = new CompoundExpr( se.getTaskExpr() ); - } - - @Override - public int getNumAtom() throws NotDerivableException { - return 1; - } - - public CompoundExpr getTaskExpr() { - - if( taskExpr == null ) - throw new NullPointerException( "Task expression never set." ); - - return taskExpr; - } - - public boolean hasTaskExpr() { - return taskExpr != null; - } - - - public void setTaskExpr( CompoundExpr taskExpr ) { - - if( taskExpr == null ) - throw new NullPointerException( "Task expression must not be null." ); - - this.taskExpr = taskExpr; - } - - @Override - public String toString() { - - StringBuffer buf; - boolean comma; - - buf = new StringBuffer(); - - buf.append( "curry( task: " ).append( taskExpr ).append( ',' ); - - try { - - comma = false; - for( NameExpr nameExpr : getNameSet() ) { - - if( comma ) - buf.append( ',' ); - comma = true; - - buf.append( ' ' ).append( nameExpr.getId() ).append( ": " ).append( getExpr( nameExpr ) ); - } - } - catch( NotBoundException e ) { - throw new RuntimeException( e.getMessage() ); - } - - - buf.append( " )" ); - - return buf.toString(); - } - - @Override - public T visit(NodeVisitor visitor) throws HasFailedException, NotBoundException { - return visitor.accept( this ); - } - - @Override - public StringExpr getStringExprValue(int i) throws NotDerivableException { - throw new NotDerivableException( "Cannot derive value of curry expression." ); - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/DataType.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/DataType.java deleted file mode 100644 index 77634a1..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/DataType.java +++ /dev/null @@ -1,65 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -public class DataType implements Type { - - public static final String LABEL_FILE = "File"; - - private final String id; - - public DataType( String id ) { - - if( id == null ) - throw new NullPointerException( "Id string must not be null." ); - - if( id.isEmpty() ) - throw new RuntimeException( "Id string must not be empty." ); - - this.id = id; - } - - public String getId() { - return id; - } - - @Override - public String toString() { - return "( "+id+" )"; - } - - @Override - public T visit( NodeVisitor visitor ) { - return visitor.accept( this ); - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/DrawHelper.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/DrawHelper.java deleted file mode 100644 index 2914e8f..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/DrawHelper.java +++ /dev/null @@ -1,66 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -public class DrawHelper { - - private final CompoundExpr taskExpr; - private final BaseBlock bindingBlock; - private final Prototype prototype; - - public DrawHelper( ApplyExpr applyExpr ) { - this( applyExpr.getTaskExpr(), applyExpr ); - } - - public DrawHelper( CompoundExpr taskExpr, BaseBlock bindingBlock ) { - - if( taskExpr == null ) - throw new NullPointerException( "Task expression must not be null." ); - - if( bindingBlock == null ) - throw new NullPointerException( "Binding block must not be null." ); - - this.taskExpr = taskExpr; - this.prototype = ( ( LambdaExpr )taskExpr.getSingleExpr( 0 ) ).getPrototype(); - this.bindingBlock = bindingBlock; - } - - public CompoundExpr reduceComb() { - - CompoundExpr ce; - - ce = new CompoundExpr(); - // TODO - return ce; - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/DrawParam.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/DrawParam.java deleted file mode 100644 index d33b13e..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/DrawParam.java +++ /dev/null @@ -1,55 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -import java.util.Set; - -public class DrawParam implements Param { - - @Override - public int getNumParam() { - // TODO - throw new UnsupportedOperationException( "NYI" ); - } - - @Override - public Set getNameExprSet() { - // TODO - throw new UnsupportedOperationException( "NYI" ); - } - - @Override - public T visit(NodeVisitor visitor) { - return visitor.accept( this ); - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/EnumHelper.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/EnumHelper.java deleted file mode 100644 index 7652c9a..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/EnumHelper.java +++ /dev/null @@ -1,235 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -import java.util.Set; - -public class EnumHelper { - - private final Prototype prototype; - private final BaseBlock bindingBlock; - private final CompoundExpr taskExpr; - private final Param[] paramArray; - - public EnumHelper( ApplyExpr applyExpr ) { - this( applyExpr.getTaskExpr(), applyExpr ); - } - - public EnumHelper( CompoundExpr taskExpr, BaseBlock bindingBlock ) { - - Set paramSet; - int i, n; - SingleExpr se; - - if( bindingBlock == null ) - throw new IllegalArgumentException( "Binding block must not be null." ); - - if( taskExpr == null ) - throw new IllegalArgumentException( "Task expression must not be null." ); - - if( taskExpr.getNumSingleExpr() < 1 ) - throw new IllegalArgumentException( "Task expression should not be nil." ); - - se = taskExpr.getSingleExpr( 0 ); - if( !( se instanceof LambdaExpr ) ) - throw new IllegalArgumentException( "Task expression must hold lambda expression." ); - - this.taskExpr = taskExpr; - this.prototype = ( ( LambdaExpr )se ).getPrototype(); - this.bindingBlock = bindingBlock; - - // check if parameter bindings are consistent - for( NameExpr paramName : prototype.getParamNameSet() ) { - - if( paramName.getId().equals( CfSemanticModelVisitor.LABEL_TASK ) ) - continue; - - if( !bindingBlock.containsName( paramName ) ) - throw new SemanticModelException( - bindingBlock.toString(), - "The parameter '"+paramName - +"' is unbound in task application." ); - } - - paramSet = prototype.getParamSet(); - - n = paramSet.size(); - - // impose order on parameter set - paramArray = new Param[ n ]; - i = 0; - for( Param param : paramSet ) - paramArray[ i++ ] = param; - - } - - public int getCardinality() throws NotDerivableException { - - int i; - int c; - - c = 1; - for( i = 0; i < paramArray.length; i++ ) - c *= getParamCardinality( i ); - - return c; - } - - public LambdaExpr getSingularLambdaExpr( int idx ) throws NotDerivableException { - - int k; - Param param; - int c, i, j; - NameExpr taskNameExpr; - SingleExpr se; - - i = idx; - taskNameExpr = new NameExpr( CfSemanticModelVisitor.LABEL_TASK ); - - - for( k = 0; k < paramArray.length; k++ ) { - - param = paramArray[ k ]; - - if( param instanceof ReduceVar ) - continue; - - c = getParamCardinality( k ); - j = i%c; - i /= c; - - if( !param.getNameExprSet().contains( taskNameExpr ) ) - continue; - - se = taskExpr.getSingleExpr( j ); - if( !( se instanceof LambdaExpr ) ) - throw new RuntimeException( "Expected lambda expression." ); - - return ( LambdaExpr )se; - } - - throw new RuntimeException( "Task parameter could not be addressed." ); - } - - - public Block getSingularBindingBlock( int idx ) throws NotDerivableException { - - int i, j, k, c; - Block block; - Param param; - CompoundExpr ce; - - block = new Block(); - i = idx; - - try { - for( k = 0; k < paramArray.length; k++ ) { - - param = paramArray[ k ]; - - if( param instanceof ReduceVar ) { - - block.putAssign( - ( ReduceVar )param, - bindingBlock.getExpr( ( ReduceVar )param ) ); - - continue; - } - - c = getParamCardinality( k ); - j = i%c; - i /= c; - - for( NameExpr name : param.getNameExprSet() ) { - - if( name.getId().equals( CfSemanticModelVisitor.LABEL_TASK ) ) - continue; - - ce = bindingBlock.getExpr( name ); - ce = new CompoundExpr( ce.getStringExprValue( j ) ); - - if( ce.getNumAtom() != 1 ) - throw new RuntimeException( "Enumeration resulted in non-singular expression: "+ce ); - - block.putAssign( name, ce ); - } - } - - } - catch( NotBoundException e ) { - throw new RuntimeException( e.getMessage() ); - } - - return block; - } - - private int getParamCardinality( int i ) throws NotDerivableException { - - Param param; - int n; - CompoundExpr ce; - - - try { - - param = paramArray[ i ]; - - if( param instanceof ReduceVar ) - return 1; - - for( NameExpr name : param.getNameExprSet() ) { - - - if( name.getId().equals( CfSemanticModelVisitor.LABEL_TASK ) ) - return taskExpr.getNumAtom(); - - ce = bindingBlock.getExpr( name ); - - n = ce.getNumAtom(); - - return n; - } - } - catch( NotBoundException e ) { - - System.err.println( "[task]" ); - System.err.println( taskExpr ); - System.err.println( "[binding]" ); - System.err.println( bindingBlock ); - System.err.println( "[end]" ); - throw new RuntimeException( e.getMessage() ); - } - - throw new RuntimeException( "Parameter must at least contain one parameter name." ); - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/ForeignLambdaExpr.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/ForeignLambdaExpr.java deleted file mode 100644 index 13edcc3..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/ForeignLambdaExpr.java +++ /dev/null @@ -1,163 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -public class ForeignLambdaExpr extends LambdaExpr { - - public static final String LANGID_BASH = "bash"; - public static final String LANGID_LISP = "lisp"; - public static final String LANGID_OCTAVE = "octave"; - public static final String LANGID_MATLAB = "matlab"; - public static final String LANGID_R = "r"; - public static final String LANGID_PYTHON = "python"; - public static final String LANGID_PERL = "perl"; - public static final String LANGID_JAVA = "java"; - public static final String LANGID_SCALA = "scala"; - public static final String LANGID_ERLANG = "erlang"; - public static final String LANGID_HASKELL = "haskell"; - public static final String LANGID_PEGASUS = "pegasus"; - public static final String LANGID_BEANSHELL = "beanshell"; - - private static final String[] LABEL_LANG = { - LANGID_BASH, LANGID_LISP, LANGID_OCTAVE, LANGID_MATLAB, LANGID_R, - LANGID_PYTHON, LANGID_PERL, LANGID_JAVA, LANGID_SCALA, LANGID_ERLANG, - LANGID_HASKELL, LANGID_PEGASUS, LANGID_BEANSHELL - }; - - private final int lang; - private final String body; - private String name; - - public ForeignLambdaExpr( Prototype prototype, String langLabel, String body ) { - this( prototype, labelToInt( langLabel ), body ); - } - - public ForeignLambdaExpr( Prototype prototype, int lang, String body ) { - - super( prototype ); - - if( body == null ) - throw new NullPointerException( "Body must not be null." ); - - if( body.isEmpty() ) - throw new RuntimeException( "Body must not be empty." ); - - if( lang < 0 || lang >= LABEL_LANG.length ) - throw new RuntimeException( "Language id "+lang+" not recognized. Must be a number in [0,"+( LABEL_LANG.length-1 )+"]." ); - - this.body = body; - this.lang = lang; - } - - public ForeignLambdaExpr(ForeignLambdaExpr template ) { - - super( template ); - - if( template == null ) - throw new IllegalArgumentException( "Template foreign lambda expression must not be null." ); - - lang = template.lang; - body = template.body; - name = template.name; - } - - public String getBody() { - return body; - } - - public int getLang() { - return lang; - } - - public String getLangLabel() { - return LABEL_LANG[ lang ]; - } - - public long getLambdaId() { - - long h; - - h = HashHelper.add( getPrototype().getPrototypeId(), lang ); - h = HashHelper.add( h, body ); - - return h; - } - - public String getTaskName() { - return name; - } - - public boolean hasTaskName() { - return name != null; - } - - public void setOptionalTaskName( String name ) { - - if( name == null ) - throw new NullPointerException( "Task name must not be null." ); - - if( name.isEmpty() ) - throw new RuntimeException( "Task name must not be empty." ); - - this.name = name; - } - - @Override - public String toString() { - return super.toString()+"in "+intToLabel( lang )+" *{"+body+"}*"; - } - - public static String intToLabel( int i ) { - return LABEL_LANG[ i ]; - } - - public static int labelToInt( String label ) { - - int i, n; - String l; - - l = label.toLowerCase(); - - n = LABEL_LANG.length; - for( i = 0; i < n; i++ ) - if( LABEL_LANG[ i ].equals( l ) ) - return i; - - throw new SemanticModelException( label, "Language '"+label+"' not recognized." ); - } - - @Override - public T visit( NodeVisitor visitor ) { - return visitor.accept( this ); - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/HasFailedException.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/HasFailedException.java deleted file mode 100644 index 9fd863d..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/HasFailedException.java +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -public class HasFailedException extends Exception { - - private static final long serialVersionUID = -430246437126890792L; - - public HasFailedException( String msg ) { - super( msg ); - } - -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/HashHelper.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/HashHelper.java deleted file mode 100644 index d019044..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/HashHelper.java +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -public class HashHelper { - - private static final long PRIME = 99194853094755497L; // large prime number below 9223372036854775807 - - private static int abs( int x ) { - - if( x < 0 ) - return -x; - - return x; - } - - public static long add( long a, Object b ) { - - long hash; - - hash = a<<2; - hash = hash%PRIME; - hash = ( hash+( abs( b.hashCode() ) ) )%PRIME; - - return hash; - } - -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/JsonReportEntry.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/JsonReportEntry.java deleted file mode 100644 index 3dd7e43..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/JsonReportEntry.java +++ /dev/null @@ -1,465 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -import java.util.UUID; - -import org.json.JSONException; -import org.json.JSONObject; - -public class JsonReportEntry { - - public static final String KEY_INVOC_TIME = "invoc-time"; - public static final String KEY_FILE_SIZE_STAGEIN = "file-size-stagein"; - public static final String KEY_FILE_SIZE_STAGEOUT = "file-size-stageout"; - public static final String KEY_INVOC_OUTPUT = "invoc-output"; - public static final String KEY_INVOC_STDOUT = "invoc-stdout"; - public static final String KEY_INVOC_STDERR = "invoc-stderr"; - public static final String KEY_INVOC_USER = "invoc-user"; - public static final String KEY_INVOC_EXEC = "invoc-exec"; - public static final String KEY_INVOC_SCRIPT = "invoc-script"; - public static final String KEY_REDUCTION_TIME = "reduction-time"; - - public static final String ATT_INVOCID = "invocId"; - public static final String ATT_KEY = "key"; - public static final String ATT_RUNID = "runId"; - public static final String ATT_VALUE = "value"; - public static final String ATT_TASKNAME = "taskname"; - public static final String ATT_TASKID = "taskId"; - public static final String ATT_TIMESTAMP = "timestamp"; - public static final String ATT_LANG = "lang"; - public static final String ATT_FILE = "file"; - - public static final String LABEL_REALTIME = "realTime"; - - private UUID runId; - private Long invocId; - private String key; - private String value; - private String taskname; - private Long taskId; - private long timestamp; - private String lang; - private String file; - - public JsonReportEntry( - long timestamp, UUID runId, Long taskId, String taskname, - String lang, Long invocId, String file, String key, String rawValue ) { - - setTimestamp( timestamp ); - setRunId( runId ); - setTaskId( taskId ); - setTaskname( taskname ); - setInvocId( invocId ); - setLang( lang ); - setFile( file ); - setKey( key ); - setValueFromRawString( rawValue ); - } - - public JsonReportEntry( - UUID runId, Long taskId, String taskname, - String lang, Long invocId, String file, String key, String rawValue ) { - - this( System.currentTimeMillis(), runId, taskId, taskname, lang, invocId, file, key, rawValue ); - } - - public JsonReportEntry( - UUID runId, Long taskId, String taskname, - String lang, Long invocId, String key, String rawValue ) { - - this( System.currentTimeMillis(), runId, taskId, taskname, lang, invocId, null, key, rawValue ); - } - - public JsonReportEntry( Ticket ticket, String key, String rawValue ) { - this( - ticket.getRunId(), - ticket.getLambdaId(), - ticket.getTaskName(), - ticket.getLangLabel(), - ticket.getTicketId(), - key, - rawValue ); - } - - public JsonReportEntry( - long timestamp, UUID runId, Long taskId, String taskname, - String lang, Long invocId, String file, String key, JSONObject obj ) { - - setTimestamp( timestamp ); - setRunId( runId ); - setTaskId( taskId ); - setTaskname( taskname ); - setInvocId( invocId ); - setLang( lang ); - setFile( file ); - setKey( key ); - setValueFromJsonObj( obj ); - } - - public JsonReportEntry( - UUID runId, Long taskId, String taskname, - String lang, Long invocId, String file, String key, JSONObject obj ) { - this( System.currentTimeMillis(), runId, taskId, taskname, lang, invocId, file, key, obj ); - } - - public JsonReportEntry( String raw ) throws JSONException { - - JSONObject obj, valueObj; - String valueString; - - try { - obj = new JSONObject( raw.replace( "\0", "" ) ); - - - setTimestamp( obj.getLong( ATT_TIMESTAMP ) ); - setRunId( UUID.fromString( obj.getString( ATT_RUNID ) ) ); - - if( obj.has( ATT_TASKID ) ) - if( !obj.isNull( ATT_TASKID ) ) - setTaskId( obj.getLong( ATT_TASKID ) ); - - if( obj.has( ATT_TASKNAME ) ) - if( !obj.isNull( ATT_TASKNAME ) ) - setTaskname( obj.getString( ATT_TASKNAME ) ); - - if( obj.has( ATT_LANG ) ) - if( !obj.isNull( ATT_LANG ) ) - setLang( obj.getString( ATT_LANG ) ); - - if( obj.has( ATT_INVOCID ) ) - if( !obj.isNull( ATT_INVOCID ) ) - setInvocId( obj.getLong( ATT_INVOCID ) ); - - if( obj.has( ATT_FILE ) ) - if( !obj.isNull( ATT_FILE ) ) - setFile( obj.getString( ATT_FILE ) ); - - setKey( obj.getString( ATT_KEY ) ); - - try { - valueObj = obj.getJSONObject( ATT_VALUE ); - setValueFromJsonObj( valueObj ); - } - catch( JSONException e ) { - valueString = obj.getString( ATT_VALUE ); - setValueFromRawString( valueString ); - } - } - catch( JSONException e ) { - System.err.println( "[raw]" ); - System.err.println( raw ); - throw e; - } - } - - @Override - public boolean equals( Object obj ) { - - JsonReportEntry other; - String s1, s2; - - if( obj == null ) - return false; - - if( !( obj instanceof JsonReportEntry ) ) - return false; - - other = ( JsonReportEntry )obj; - - s1 = toString(); - s2 = other.toString(); - - return s1.equals( s2 ); - } - - public String getFile() { - return file; - } - - public Long getInvocId() { - return invocId; - } - - public String getKey() { - return key.replace( "\\n", "\n" ); - } - - public String getLang() { - return lang; - } - - public UUID getRunId() { - return runId; - } - - public JSONObject getValueJsonObj() throws JSONException { - - if( !isValueJson() ) - throw new RuntimeException( "Value is not a JSON object, but a string." ); - - return new JSONObject( value ); - } - - public String getValueRawString() { - - String s; - - if( !isValueString() ) - throw new RuntimeException( "Value is not a string, but a JSON object." ); - - s = value.substring( 1, value.length()-1 ); - s = s.replace( "\\n", "\n" ); - s = s.replace( "\\\"", "\"" ); - s = s.replace( "\\\\", "\\" ); - - return s; - } - - public String getTaskName() { - return taskname; - } - - public Long getTaskId() { - return taskId; - } - - public long getTimestamp() { - return timestamp; - } - - public boolean isValueString() { - - if( value.startsWith( "\"" ) ) - return true; - - return false; - } - - public boolean hasFile() { - return file != null; - } - - public boolean hasInvocId() { - return invocId != null; - } - - public boolean hasLang() { - return lang != null; - } - - public boolean hasTaskId() { - return taskId != null; - } - - public boolean hasTaskname() { - return taskname != null; - } - - public boolean isKeyInvocStdErr() { - return key.equals( KEY_INVOC_STDERR ); - } - - public boolean isKeyInvocStdOut() { - return key.equals( KEY_INVOC_STDOUT ); - } - - public boolean isKeyInvocTime() { - return key.equals( KEY_INVOC_TIME ); - } - - public boolean isKeyInvocOutput() { - return key.equals( KEY_INVOC_OUTPUT ); - } - - public boolean isKeyInvocExec() { - return key.equals( KEY_INVOC_EXEC ); - } - - public boolean isKeyFileSizeStageIn() { - return key.equals( KEY_FILE_SIZE_STAGEIN ); - } - - public boolean isKeyFileSizeStageOut() { - return key.equals( KEY_FILE_SIZE_STAGEOUT ); - } - - public boolean isValueJson() { - return !isValueString(); - } - - public void setFile( String file ) { - - if( file == null ) { - this.file = null; - return; - } - - if( file.isEmpty() ) - throw new RuntimeException( "File name must not be empty." ); - - this.file = file; - } - - public void setInvocId( Long invocId ) { - this.invocId = invocId; - } - - public void setKey( String key ) { - - if( key == null ) - throw new NullPointerException( "Key must not be null." ); - - if( key.isEmpty() ) - throw new RuntimeException( "Key must not be empty." ); - - if( key.contains( "\n" ) ) - throw new RuntimeException( "Key must not contain newline character." ); - - if( key.contains( "\"" ) ) - throw new RuntimeException( "Key must not contain double quote character." ); - - if( key.contains( "\\" ) ) - throw new RuntimeException( "Key must not contain backslash character." ); - - this.key = key; - } - - public void setRunId( UUID runId ) { - - if( runId == null ) - throw new NullPointerException( "DAG id must not be null." ); - - this.runId = runId; - } - - public void setValueFromRawString( String value ) { - - if( value == null ) - throw new NullPointerException( "Payload must not be null." ); - - if( value.isEmpty() ) - throw new RuntimeException( "Payload must not be empty." ); - - this.value = "\""+value.replace( "\\", "\\\\" ).replace( "\n", "\\n" ).replace( "\"", "\\\"" )+"\""; - } - - public void setValueFromJsonObj( JSONObject obj ) { - - if( obj == null ) - throw new NullPointerException( "Value JSON object must not be null." ); - - value = obj.toString(); - } - - public void setLang( String lang ) { - - if( lang == null ) { - this.lang = null; - return; - } - - if( lang.isEmpty() ) - throw new RuntimeException( "Language string must not be empty." ); - - this.lang = lang; - } - - public void setTaskId( Long taskId ) { - this.taskId = taskId; - } - - public void setTaskname( String taskname ) { - - if( taskname == null ) { - this.taskname = null; - return; - } - - if( taskname.isEmpty() ) - throw new RuntimeException( "Taskname must not be empty." ); - - if( taskname.contains( "\n" ) ) - throw new RuntimeException( "Taskname id must not contain newline character." ); - - if( taskname.contains( "\"" ) ) - throw new RuntimeException( "Taskname id must not contain double quote character." ); - - if( taskname.contains( "\\" ) ) - throw new RuntimeException( "Taskname must not contain backslash character." ); - - this.taskname = taskname; - } - - public void setTimestamp( long timestamp ) { - this.timestamp = timestamp; - } - - @Override - public String toString() { - - StringBuffer buf; - - buf = new StringBuffer(); - - buf.append( '{' ); - buf.append( ATT_TIMESTAMP ).append( ':' ).append( timestamp ).append( ',' ); - buf.append( ATT_RUNID ).append( ":\"" ).append( runId ).append( "\"," ); - - if( hasTaskId() ) - buf.append( ATT_TASKID ).append( ':' ).append( taskId ).append( ',' ); - - if( hasTaskname() ) - buf.append( ATT_TASKNAME ).append( ':' ).append( "\"" ).append( taskname ).append( "\"," ); - - if( hasLang() ) - buf.append( ATT_LANG ).append( ':' ).append( "\"" ).append( lang ).append( "\"," ); - - if( hasInvocId() ) - buf.append( ATT_INVOCID ).append( ':' ).append( invocId ).append( ',' ); - - if( hasFile() ) - buf.append( ATT_FILE ).append( ":\"" ).append( file ).append( "\"," ); - - buf.append( ATT_KEY ).append( ":\"" ).append( key ).append( "\"," ); - buf.append( ATT_VALUE ).append( ':' ).append( value ); - buf.append( '}' ); - - return buf.toString(); - } - - @Override - public int hashCode() { - return toString().hashCode(); - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/LambdaExpr.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/LambdaExpr.java deleted file mode 100644 index cf83248..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/LambdaExpr.java +++ /dev/null @@ -1,78 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -public abstract class LambdaExpr implements SingleExpr { - - private final Prototype prototype; - - public LambdaExpr( Prototype prototype ) { - - if( prototype == null ) - throw new NullPointerException( "Prototype must not be null." ); - - this.prototype = prototype; - } - - public LambdaExpr( LambdaExpr template ) { - - if( template == null ) - throw new IllegalArgumentException( "Template lambda expression must not be null." ); - - if( template.prototype == null ) - throw new IllegalArgumentException( "Template lambda expression must have non-null prototype." ); - - prototype = new Prototype( template.prototype ); - } - - @Override - public int getNumAtom() throws NotDerivableException { - return 1; - } - - public Prototype getPrototype() { - return prototype; - } - - @Override - public StringExpr getStringExprValue( int i ) throws NotDerivableException { - throw new RuntimeException( "Trying to convert lambda expression value to string expression value." ); - } - - - @Override - public String toString() { - return "\\"+prototype; - } - -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/LambdaType.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/LambdaType.java deleted file mode 100644 index e51539b..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/LambdaType.java +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -public class LambdaType implements Type, Cloneable { - - @Override - public String toString() { - return "(:)"; - } - - @Override - public T visit( NodeVisitor visitor ) { - return visitor.accept( this ); - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/NameExpr.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/NameExpr.java deleted file mode 100644 index f2ebf66..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/NameExpr.java +++ /dev/null @@ -1,142 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -import java.util.HashSet; -import java.util.Set; - - -public class NameExpr implements SingleExpr, Param, Comparable { - - private final String id; - private final Type type; - - public NameExpr( String id ) { - this( id, null ); - } - - public NameExpr( String id, Type type ) { - - if( id == null ) - throw new NullPointerException( "Id string must not be null." ); - - if( id.isEmpty() ) - throw new RuntimeException( "Id string must not be empty." ); - - this.id = id; - this.type = type; - } - - @Override - public boolean equals( Object obj ) { - - NameExpr other; - - if( !( obj instanceof NameExpr ) ) - return false; - - other = ( NameExpr )obj; - return id.equals( other.getId() ); - } - - public String getId() { - return id; - } - - @Override - public int getNumParam() { - return 1; - } - - public Type getType() { - return type; - } - - @Override - public int hashCode() { - return id.hashCode(); - } - - public boolean hasType() { - return type != null; - } - - public ReduceVar toReduceVar() { - return new ReduceVar( id, type ); - } - - @Override - public String toString() { - - StringBuffer buf; - - buf = new StringBuffer(); - - buf.append( id ); - - if( type != null ) - buf.append( type ); - - return buf.toString(); - } - - @Override - public Set getNameExprSet() { - - Set nameSet; - - nameSet = new HashSet<>(); - nameSet.add( this ); - - return nameSet; - } - - @Override - public int getNumAtom() throws NotDerivableException { - throw new NotDerivableException( "Name expression cannot hold size information." ); - } - - @Override - public int compareTo( NameExpr arg0 ) { - return arg0.getId().compareTo( id ); - } - @Override - public T visit( NodeVisitor visitor ) throws HasFailedException, NotBoundException { - return visitor.accept( this ); - } - - @Override - public StringExpr getStringExprValue( int i ) throws NotDerivableException { - throw new NotDerivableException( "Cannot derive value from name expression." ); - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/NativeLambdaExpr.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/NativeLambdaExpr.java deleted file mode 100644 index a964654..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/NativeLambdaExpr.java +++ /dev/null @@ -1,84 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -public class NativeLambdaExpr extends LambdaExpr { - - private final Block bodyBlock; - - public NativeLambdaExpr( Prototype prototype, Block bodyBlock ) { - - super( prototype ); - - if( bodyBlock == null ) - throw new NullPointerException( "Body block must not be null." ); - - this.bodyBlock = bodyBlock; - } - - public NativeLambdaExpr( NativeLambdaExpr template ) { - - super( template ); - - CompoundExpr value, copiedValue; - - bodyBlock = new Block( template.bodyBlock.getParent() ); - - try { - for( NameExpr ne : template.bodyBlock.getNameSet() ) { - - value = template.getBodyBlock().getExpr( ne ); - copiedValue = new CompoundExpr( value ); - - bodyBlock.putAssign( ne, copiedValue ); - } - - } catch (NotBoundException e) { - throw new RuntimeException( e ); - } - - } - - public Block getBodyBlock() { - return bodyBlock; - } - - @Override - public String toString() { - return super.toString()+" {\n"+bodyBlock+"}"; - } - @Override - public T visit( NodeVisitor visitor ) { - return visitor.accept( this ); - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/NodeVisitor.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/NodeVisitor.java deleted file mode 100644 index 0f1994d..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/NodeVisitor.java +++ /dev/null @@ -1,61 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - - -/** - * @author jorgen - * - */ -public interface NodeVisitor { - - public T accept( StringExpr stringExpr ); - public T accept( QualifiedTicket qualifiedTicket ); - public T accept( NativeLambdaExpr nativeLambdaExpr ); - public T accept( NameExpr nameExpr ) throws HasFailedException, NotBoundException; - public T accept( LambdaType lambdaType ); - public T accept( DrawParam drawParam ); - public T accept( DataType dataType ); - public T accept( CondExpr condExpr ) throws HasFailedException, NotBoundException; - public T accept( Block block ); - public T accept( ApplyExpr applyExpr ) throws HasFailedException, NotBoundException; - public T accept( CompoundExpr compoundExpr ) throws HasFailedException, NotBoundException; - public T accept( CorrelParam correlParam ); - public T accept( ForeignLambdaExpr foreignLambdaExpr ); - public T accept( CurryExpr curryExpr ) throws HasFailedException, NotBoundException; - public T accept( Prototype prototype ); - public T accept( ReduceVar reduceVar ); - public T accept(TopLevelContext topLevelContext) throws HasFailedException, NotBoundException; - -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/NotBoundException.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/NotBoundException.java deleted file mode 100644 index 2af52cd..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/NotBoundException.java +++ /dev/null @@ -1,42 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -public class NotBoundException extends Exception { - - private static final long serialVersionUID = -9001488787382738222L; - - public NotBoundException( String msg ) { - super( msg ); - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/NotDerivableException.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/NotDerivableException.java deleted file mode 100644 index c45f6ce..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/NotDerivableException.java +++ /dev/null @@ -1,47 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -public class NotDerivableException extends Exception { - - private static final long serialVersionUID = 7155475670128340863L; - - public NotDerivableException( String msg ) { - super( msg ); - } - - public NotDerivableException( Exception e ) { - super( e ); - } - -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/Param.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/Param.java deleted file mode 100644 index 3ad748c..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/Param.java +++ /dev/null @@ -1,41 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -import java.util.Set; - -public interface Param extends CfNode { - - public int getNumParam(); - public Set getNameExprSet(); -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/Prototype.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/Prototype.java deleted file mode 100644 index 77e9386..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/Prototype.java +++ /dev/null @@ -1,262 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; - -public class Prototype extends LambdaType { - - private final List outputList; - private final Set paramSet; - - public Prototype() { - outputList = new LinkedList<>(); - paramSet = new HashSet<>(); - } - - public Prototype( Prototype template ) { - - this(); - - if( template == null ) - throw new IllegalArgumentException( "Template prototype must not be null." ); - - if( template.outputList == null ) - throw new IllegalArgumentException( "Template prototype must not have null output list." ); - - if( template.paramSet == null ) - throw new IllegalArgumentException( "Template prototype must not have null parameter set." ); - - for( NameExpr output : template.outputList ) - outputList.add( output ); - - for( Param param : template.paramSet ) - paramSet.add( copyParam( param ) ); - } - - public void addOutput( NameExpr output ) { - - if( output == null ) - throw new NullPointerException( "Output must not be null." ); - - outputList.add( output ); - } - - public void addOutput( List ol ) { - outputList.addAll( ol ); - } - - public void addParam( Param param ) { - - if( param == null ) - throw new NullPointerException( "Output must not be null." ); - - paramSet.add( param ); - } - - public void addParam( Set ps ) { - paramSet.addAll( ps ); - } - - public NameExpr getOutput( int i ) { - return outputList.get( i ); - } - - public List getOutputList() { - - if( outputList.isEmpty() ) - // parser already checks that - throw new RuntimeException( "Empty output list." ); - - return Collections.unmodifiableList( outputList ); - } - - public Set getParamSet() { - return Collections.unmodifiableSet( paramSet ); - } - - public Set getParamNameSet() { - - Set nameSet; - - nameSet = new HashSet<>(); - - for( Param param : paramSet ) - nameSet.addAll( param.getNameExprSet() ); - - return nameSet; - } - - public Set getNonReduceParamNameSet() { - - Set set; - - set = new HashSet<>(); - - for( Param param : paramSet ) - if( !( param instanceof ReduceVar ) ) - set.addAll( param.getNameExprSet() ); - - return set; - } - - public boolean isTaskCorrelated() { - - for( Param param : paramSet ) - if( param instanceof CorrelParam ) - if( ( ( CorrelParam )param ).contains( - CfSemanticModelVisitor.LABEL_TASK ) ) - - return true; - - return false; - } - - public boolean containsParam( String paramId ) { - return containsParam( new NameExpr( paramId ) ); - } - - public boolean containsParam( NameExpr paramNameExpr ) { - return getParamNameSet().contains( paramNameExpr ); - } - - public int getNumOutput() { - return outputList.size(); - } - - public int getNumParam() { - - int n; - - n = 0; - for( Param param : paramSet ) - n += param.getNumParam(); - - return n; - } - - public long getPrototypeId() { - - long h; - - h = 0; - - for( NameExpr output : outputList ) - h = HashHelper.add( h, output ); - - for( NameExpr param : getParamNameSet() ) - h = HashHelper.add( h, param ); - - return h; - } - - public void removeParam( String name ) { - removeParam( new NameExpr( name ) ); - } - - public void removeParam( NameExpr nameExpr ) { - - CorrelParam correlParam; - int n; - - for( Param param : paramSet ) - if( param instanceof NameExpr ) { - if( nameExpr.equals( param ) ) { - paramSet.remove( nameExpr ); - return; - } - } - else if( param instanceof CorrelParam ) { - - correlParam = ( CorrelParam )param; - - if( correlParam.contains( nameExpr ) ) { - - correlParam.remove( nameExpr ); - - n = correlParam.getNumParam(); - - if( n > 1 ) - return; - - if( n == 1 ) { - - paramSet.remove( correlParam ); - paramSet.add( correlParam.getLastNameExpr() ); - - return; - } - - throw new RuntimeException( - "An empty correlated parameter set should never occur." ); - } - } - - throw new RuntimeException( "Name expression '"+nameExpr+"' not member of parameter set." ); - } - - @Override - public String toString() { - - StringBuffer buf; - - buf = new StringBuffer( "( " ); - - for( NameExpr output : outputList ) - buf.append( output ).append( ' ' ); - - buf.append( ": " ); - - for( Param param : paramSet ) - buf.append( param ).append( ' ' ); - - buf.append( ')' ); - - return buf.toString(); - } - - private static Param copyParam( Param template ) { - - if( template instanceof NameExpr ) - return template; - - if( template instanceof CorrelParam ) - return new CorrelParam( ( CorrelParam )template ); - - throw new UnsupportedOperationException( "Copy operation not supported for parameter of type "+template.getClass() ); - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/QualifiedTicket.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/QualifiedTicket.java deleted file mode 100644 index a8014e7..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/QualifiedTicket.java +++ /dev/null @@ -1,106 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -import java.util.Set; - -public class QualifiedTicket implements SingleExpr { - - private final Ticket ticket; - private final int channel; - - public QualifiedTicket( Ticket ticket, int channel ) { - - if( channel < 1 ) - throw new RuntimeException( "Channel must at least be 1." ); - - if( ticket == null ) - throw new NullPointerException( "Ticket must not be null." ); - - this.ticket = ticket; - this.channel = channel; - } - - public int getChannel() { - return channel; - } - - public Ticket getTicket() { - return ticket; - } - - public Set getParamNameSet() { - return ticket.getParamNameSet(); - } - - public CompoundExpr getParamValue( NameExpr name ) throws NotBoundException { - return ticket.getExpr( name ); - } - - public CompoundExpr getOutputValue() throws NotDerivableException { - try { - return ticket.getOutputValue( channel ); - } catch( NotBoundException e ) { - throw new NotDerivableException( e ); - } - } - - @Override - public int getNumAtom() throws NotDerivableException { - return ticket.getNumAtom( channel ); - } - - - @Override - public String toString() { - - try { - return getOutputValue().toString(); - } - catch( NotDerivableException e ) { - return "["+channel+"]"+ticket; - } - - - } - - @Override - public T visit( NodeVisitor visitor ) { - return visitor.accept( this ); - } - - @Override - public StringExpr getStringExprValue( int i ) throws NotDerivableException { - return getOutputValue().getStringExprValue( i ); - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/ReduceVar.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/ReduceVar.java deleted file mode 100644 index 6665ad4..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/ReduceVar.java +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - - -public class ReduceVar extends NameExpr { - - public ReduceVar( String id, Type type ) { - super( id, type ); - } - - @Override - public String toString() { - return "<"+super.toString()+">"; - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/SemanticModelException.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/SemanticModelException.java deleted file mode 100644 index 81be366..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/SemanticModelException.java +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -import de.huberlin.wbi.cuneiform.core.preprocess.ParseException; - - -public class SemanticModelException extends ParseException { - - private static final long serialVersionUID = -826451567187918855L; - - public SemanticModelException( String near, - String msg ) { - super( null, null, near, msg ); - } - - public SemanticModelException( CfNode node, - String msg ) { - this( node.toString(), msg ); - } - -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/SingleExpr.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/SingleExpr.java deleted file mode 100644 index 108944f..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/SingleExpr.java +++ /dev/null @@ -1,39 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -public interface SingleExpr extends CfNode { - - public int getNumAtom()throws NotDerivableException; - public StringExpr getStringExprValue( int i )throws NotDerivableException; -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/StringExpr.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/StringExpr.java deleted file mode 100644 index a58a232..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/StringExpr.java +++ /dev/null @@ -1,97 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -public class StringExpr implements SingleExpr { - - private final String value; - - public StringExpr( String content ) { - - if( content == null ) - throw new NullPointerException( "Content string must not be null." ); - - this.value = content; - } - - @Override - public boolean equals( Object obj ) { - - StringExpr other; - - if( !( obj instanceof StringExpr ) ) - return false; - - other = ( StringExpr )obj; - - return other.getContent().equals( value ); - - } - - public String getContent() { - return value; - } - - @Override - public StringExpr getStringExprValue( int i ) { - - if( i != 0 ) - throw new IndexOutOfBoundsException( - "String expression has only one value with index 0. Queried index "+i ); - - return this; - } - - @Override - public int getNumAtom() throws NotDerivableException { - return 1; - } - - @Override - public String toString() { - return "'"+value+"'"; - } - - @Override - public int hashCode() { - return value.hashCode(); - } - - /* (non-Javadoc) - * @see de.huberlin.cuneiform.core.semanticmodel.Node#visit(de.huberlin.cuneiform.core.semanticmodel.NodeVisitor) - */ - @Override - public T visit( NodeVisitor visitor ) { - return visitor.accept( this ); - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/Ticket.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/Ticket.java deleted file mode 100644 index f408ab4..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/Ticket.java +++ /dev/null @@ -1,247 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; -import java.util.UUID; - -import org.json.JSONException; -import org.json.JSONObject; - - -public class Ticket extends Block { - - private final ForeignLambdaExpr lambdaExpr; - private final Block bodyBlock; - private final UUID runId; - - public Ticket( ForeignLambdaExpr lambdaExpr, BaseBlock bindingBlock, UUID runId ) { - - if( bindingBlock == null ) - throw new NullPointerException( "Binding block must not be null." ); - - if( runId == null ) - throw new NullPointerException( "Run ID must not be null." ); - - if( lambdaExpr == null ) - throw new NullPointerException( - "Foreign lambda expression must not be null." ); - - setParamBindMap( bindingBlock.getParamBindMap() ); - - this.lambdaExpr = lambdaExpr; - this.runId = runId; - - bodyBlock = new Block(); - - if( !isReady() ) - throw new RuntimeException( "Attempted to create non-ready ticket." ); - } - - - public int getNumAtom( int channel ) throws NotDerivableException { - - NameExpr outputVar; - - try { - - outputVar = getPrototype().getOutput( channel-1 ); - - if( outputVar instanceof ReduceVar ) - return bodyBlock.getExpr( getPrototype().getOutput( channel-1 ) ).getNumAtom(); - - return 1; - } - catch( NotBoundException e ) { - throw new NotDerivableException( e.getMessage() ); - } - } - - public String getBody() { - return lambdaExpr.getBody(); - } - - public JsonReportEntry getExecutableLogEntry() { - - JsonReportEntry entry; - JSONObject obj; - - - try { - - obj = new JSONObject(); - obj.put( "lambda", lambdaExpr ); - obj.put( "bind", getParamBindMap() ); - - entry = new JsonReportEntry( - runId, lambdaExpr.getLambdaId(), lambdaExpr.getTaskName(), - lambdaExpr.getLangLabel(), getTicketId(), null, - JsonReportEntry.KEY_INVOC_EXEC, obj ); - - return entry; - - } - catch( JSONException e ) { - throw new RuntimeException( e ); - } - } - - public long getLambdaId() { - return lambdaExpr.getLambdaId(); - } - - public String getLangLabel() { - return lambdaExpr.getLangLabel(); - } - - public List getOutputList() { - return lambdaExpr.getPrototype().getOutputList(); - } - - public CompoundExpr getOutputValue( int channel ) throws NotBoundException { - return bodyBlock.getExpr( lambdaExpr.getPrototype().getOutput( channel-1 ) ); - } - - public CompoundExpr getOutputValue( NameExpr name ) throws NotBoundException { - return bodyBlock.getExpr( name ); - } - - public Set getParamSet() { - return lambdaExpr.getPrototype().getParamSet(); - } - - public Set getParamNameSet() { - return lambdaExpr.getPrototype().getParamNameSet(); - } - - public Prototype getPrototype() { - return lambdaExpr.getPrototype(); - } - - public UUID getRunId() { - return runId; - } - - public String getTaskName() { - return lambdaExpr.getTaskName(); - } - - public long getTicketId() { - - long h; - - h = toString().hashCode(); - if( h < 0 ) - h = -h; - - return h; - - } - - public boolean isNormal() { - - try { - - for( NameExpr name : getNameSet() ) - if( !getExpr( name ).isNormal() ) - return false; - - return true; - } - catch( NotBoundException e ) { - throw new RuntimeException( e ); - } - } - - public boolean isReady() { - - try { - for( NameExpr name : getNameSet() ) - if( !getExpr( name ).isNormal() ) - return false; - - return true; - } - catch( NotBoundException e ) { - throw new RuntimeException( e ); - } - } - - public boolean hasTaskName() { - return lambdaExpr.hasTaskName(); - } - - public boolean isEvaluated() { - return !bodyBlock.isEmpty(); - } - - public void setValue( NameExpr outputNameExpr, CompoundExpr value ) { - bodyBlock.putAssign( outputNameExpr, value ); - } - - @Override - public String toString() { - - StringBuffer buf; - List list; - - try { - - buf = new StringBuffer(); - - buf.append( "ticket(" ); - - buf.append( " task: " ).append( lambdaExpr ); - - list = new LinkedList<>(); - for( NameExpr name : getNameSet() ) - list.add( name.getId() ); - - Collections.sort( list ); - - for( String name : list ) - buf.append( ' ' ).append( name ).append( ": " ).append( getExpr( name ) ); - - buf.append( " )" ); - - return buf.toString(); - } - catch( NotBoundException e ) { - throw new RuntimeException( e.getMessage() ); - } - } - -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/TopLevelContext.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/TopLevelContext.java deleted file mode 100644 index f577df0..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/TopLevelContext.java +++ /dev/null @@ -1,119 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -public class TopLevelContext extends BaseBlock { - - private List targetList; - - public TopLevelContext() { - super( null ); - targetList = new ArrayList<>(); - } - - public TopLevelContext( TopLevelContext template ) { - - this(); - - try { - for( CompoundExpr ce : template.targetList ) - targetList.add( new CompoundExpr( ce ) ); - - for( NameExpr ne : template.getFullNameSet() ) - putAssign( ne, new CompoundExpr( template.getExpr( ne ) ) ); - } catch (NotBoundException e) { - throw new RuntimeException( e ); - } - } - - - public void addTarget( CompoundExpr target ) { - targetList.add( target ); - } - - public void clearTargetList() { - targetList.clear(); - } - - public String getBlockString() { - return super.toString(); - } - - public List getTargetList() { - return Collections.unmodifiableList( targetList ); - } - - public CompoundExpr getTarget( int i ) { - return targetList.get( i ); - } - - public int getTargetListSize() { - return targetList.size(); - } - - public boolean isTargetListEmpty() { - return targetList.isEmpty(); - } - - public boolean removeTarget( CompoundExpr target ) { - return targetList.remove( target ); - } - - public void setTarget( int i, CompoundExpr ce ) { - targetList.set( i, ce ); - } - - @Override - public String toString() { - - StringBuffer buf; - - buf = new StringBuffer(); - - buf.append( super.toString() ); - - for( CompoundExpr target : targetList ) - buf.append( target ).append( ";\n" ); - - return buf.toString(); - } - - @Override - public T visit( NodeVisitor visitor ) throws HasFailedException, NotBoundException { - return visitor.accept( this ); - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/Type.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/Type.java deleted file mode 100644 index ccba641..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/semanticmodel/Type.java +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -public interface Type extends CfNode { - // marker interface -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/staticreduction/DotNodeVisitor.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/staticreduction/DotNodeVisitor.java deleted file mode 100644 index d9cb6f9..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/staticreduction/DotNodeVisitor.java +++ /dev/null @@ -1,406 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.staticreduction; - -import java.util.HashMap; -import java.util.Map; - -import de.huberlin.wbi.cuneiform.core.semanticmodel.ApplyExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Block; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CompoundExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CondExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CorrelParam; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CurryExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.DataType; -import de.huberlin.wbi.cuneiform.core.semanticmodel.DrawParam; -import de.huberlin.wbi.cuneiform.core.semanticmodel.ForeignLambdaExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.HasFailedException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.LambdaType; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NameExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NativeLambdaExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CfNode; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NodeVisitor; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NotBoundException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Prototype; -import de.huberlin.wbi.cuneiform.core.semanticmodel.QualifiedTicket; -import de.huberlin.wbi.cuneiform.core.semanticmodel.ReduceVar; -import de.huberlin.wbi.cuneiform.core.semanticmodel.SingleExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.StringExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.TopLevelContext; - -public class DotNodeVisitor implements NodeVisitor { - - private static final int MAX_LEN = 20; - private static final String LABEL_FOREIGN_LAMBDA_EXPR = "\\\\ {}"; - private static final String LABEL_NATIVE_LAMBDA_EXPR = "\\\\ *{}*"; - private static final String LABEL_TASK = "task"; - private static final String LABEL_APPLY = "apply"; - private static final String LABEL_CURRY = "curry"; - - private final StringBuffer buf; - private final Map exprMap; - private int nextNodeId; - - - public DotNodeVisitor() { - - buf = new StringBuffer(); - nextNodeId = 0; - exprMap = new HashMap<>(); - } - - @Override - public String toString() { - return "digraph G {\n"+buf.toString()+"}\n"; - } - - @Override - public String accept(StringExpr stringExpr) { - - String nodeId; - String value; - - if( exprMap.containsKey( stringExpr ) ) - return exprMap.get( stringExpr ); - - nodeId = popNodeId(); - value = stringExpr.getContent(); - - if( value.length() > MAX_LEN ) - value = ".."; - - buf.append( nodeId ).append( " [shape=none,label=\"'"+value+"'\"];\n" ); - - exprMap.put( stringExpr, nodeId ); - - return nodeId; - } - - - - @Override - public String accept(QualifiedTicket qualifiedTicket) { - throw new RuntimeException( "Illegal qualified ticket." ); - } - - - - @Override - public String accept(NativeLambdaExpr nativeLambdaExpr) { - - String nodeId; - - if( exprMap.containsKey( nativeLambdaExpr ) ) - return exprMap.get( nativeLambdaExpr ); - - nodeId = popNodeId(); - - buf.append( nodeId ).append( " [shape=none,label=\""+LABEL_NATIVE_LAMBDA_EXPR+"\"];\n" ); - - exprMap.put( nativeLambdaExpr, nodeId ); - - return nodeId; - } - - - - @Override - public String accept( NameExpr nameExpr ) { - - String nodeId; - String value; - - if( exprMap.containsKey( nameExpr ) ) - return exprMap.get( nameExpr ); - - nodeId = popNodeId(); - value = nameExpr.getId(); - - if( value.length() > MAX_LEN ) - value = ".."; - - buf.append( nodeId ).append( " [shape=none,label=\""+value+"\"];\n" ); - - exprMap.put( nameExpr, nodeId ); - - return nodeId; - } - - - - @Override - public String accept( LambdaType lambdaType ) { - throw new RuntimeException( "Lambda type is not an expression." ); - } - - - - @Override - public String accept(DrawParam drawParam) { - throw new RuntimeException( "Draw parameter is not an expression." ); - } - - - - @Override - public String accept( DataType dataType ) { - throw new RuntimeException( "Data type is not an expression." ); - } - - - - @Override - public String accept(CondExpr condExpr) throws HasFailedException, NotBoundException { - - String nodeId; - String parentId; - - if( exprMap.containsKey( condExpr ) ) - return exprMap.get( condExpr ); - - nodeId = popNodeId(); - - buf.append( nodeId ).append( " [label=\"cond\",shape=diamond];\n" ); - - parentId = condExpr.getIfExpr().visit( this ); - buf.append( parentId ).append( " -> " ).append( nodeId ).append( " [label=\"if\"];\n" ); - - parentId = condExpr.getThenExpr().visit( this ); - buf.append( parentId ).append( " -> " ).append( nodeId ).append( " [label=\"then\"];\n" ); - - parentId = condExpr.getElseExpr().visit( this ); - buf.append( parentId ).append( " -> " ).append( nodeId ).append( " [label=\"else\"];\n" ); - - exprMap.put( condExpr, nodeId ); - - return nodeId; - } - - - - @Override - public String accept( Block block ) { - throw new RuntimeException( "Block is not an expression." ); - } - - - - @Override - public String accept(ApplyExpr applyExpr) throws HasFailedException, NotBoundException { - - String taskNodeId, refNodeId; - SingleExpr se; - String taskName; - - if( exprMap.containsKey( applyExpr ) ) - return exprMap.get( applyExpr ); - - taskNodeId = popNodeId(); - - if( applyExpr.getTaskExpr().getNumSingleExpr() == 0 ) - throw new RuntimeException( "Task expression must not be nil." ); - - se = applyExpr.getTaskExpr().getSingleExpr( 0 ); - - if( applyExpr.getTaskExpr().getNumSingleExpr() != 1 || se instanceof CurryExpr ) { - - refNodeId = applyExpr.getTaskExpr().visit( this ); - - buf.append( taskNodeId ).append( " [shape=box,label=\""+LABEL_APPLY+"\"];\n" ); - buf.append( refNodeId ).append( " -> " ).append( taskNodeId ).append( " [label=\""+LABEL_TASK+"\"];\n" ); - } - else { - - if( se instanceof NativeLambdaExpr ) - taskName = LABEL_NATIVE_LAMBDA_EXPR; - else if( se instanceof ForeignLambdaExpr ) - taskName = LABEL_FOREIGN_LAMBDA_EXPR; - else if( se instanceof NameExpr ) - taskName = ( ( NameExpr)se ).getId(); - else - throw new RuntimeException( "Task type not recognized." ); - - buf.append( taskNodeId ).append( " [shape=box,label=\""+taskName+"\"];\n" ); - } - - for( NameExpr nameExpr : applyExpr.getNameSet() ) - - try { - - refNodeId = applyExpr.getExpr( nameExpr ).visit( this ); - - buf.append( refNodeId ).append( " -> " ).append( taskNodeId ).append( ";\n" ); - } - catch( NotBoundException e ) { - // cannot happen, because we only ask for what is there - throw new RuntimeException( e.getMessage() ); - } - - - exprMap.put( applyExpr, taskNodeId ); - - return taskNodeId; - } - - - - @Override - public String accept( CompoundExpr compoundExpr ) throws HasFailedException, NotBoundException { - - String nodeId; - int n; - - if( exprMap.containsKey( compoundExpr ) ) - return exprMap.get( compoundExpr ); - - - - n = compoundExpr.getNumSingleExpr(); - - if( n == 0 ) { - - nodeId = popNodeId(); - - buf.append( nodeId+" [shape=none,label=\"nil\"];\n" ); - - exprMap.put( compoundExpr, nodeId ); - - return nodeId; - } - - if( n > 1 ) { - - nodeId = popNodeId(); - - buf.append( nodeId ).append( " [shape=point];\n" ); - for( SingleExpr se : compoundExpr.getSingleExprList() ) - buf.append( se.visit( this ) ).append( " -> " ).append( nodeId ).append( ";\n" ); - - exprMap.put( compoundExpr, nodeId ); - - return nodeId; - } - - - return compoundExpr.getSingleExpr( 0 ).visit( this ); - } - - - - @Override - public String accept( CorrelParam correlParam ) { - throw new RuntimeException( "Correlated parameter is not an expression." ); - } - - - - @Override - public String accept(ForeignLambdaExpr foreignLambdaExpr) { - - String nodeId; - - if( exprMap.containsKey( foreignLambdaExpr ) ) - return exprMap.get( foreignLambdaExpr ); - - nodeId = popNodeId(); - - buf.append( nodeId ).append( " [shape=none,label=\""+LABEL_FOREIGN_LAMBDA_EXPR+"\"];\n" ); - - exprMap.put( foreignLambdaExpr, nodeId ); - - return nodeId; - } - - - - @Override - public String accept(CurryExpr curryExpr) throws HasFailedException, NotBoundException { - - String curryNodeId, refNodeId; - - if( exprMap.containsKey( curryExpr ) ) - return exprMap.get( curryExpr ); - - curryNodeId = popNodeId(); - - refNodeId = curryExpr.getTaskExpr().visit( this ); - - buf.append( curryNodeId ).append( " [shape=box,label=\""+LABEL_CURRY+"\"];\n" ); - buf.append( refNodeId ).append( " -> " ).append( curryNodeId ).append( " [label=\""+LABEL_TASK+"\"];\n" ); - - for( NameExpr nameExpr : curryExpr.getNameSet() ) - - try { - - refNodeId = curryExpr.getExpr( nameExpr ).visit( this ); - - buf.append( refNodeId ).append( " -> " ).append( curryNodeId ).append( ";\n" ); - } - catch( NotBoundException e ) { - throw new RuntimeException( e.getMessage() ); - } - - - exprMap.put( curryExpr, curryNodeId ); - - return curryNodeId; - } - - - - @Override - public String accept( Prototype prototype ) { - throw new RuntimeException( "Prototype is not an expression." ); - } - - - - @Override - public String accept( ReduceVar reduceVar ) { - throw new RuntimeException( "Reduce variable is not an expression." ); - } - - private String popNodeId() { - return "node"+( nextNodeId++ ); - } - - @Override - public String accept( TopLevelContext tlc ) throws HasFailedException, NotBoundException { - - for( CompoundExpr ce : tlc.getTargetList() ) - ce.visit( this ); - - return null; - } - -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/staticreduction/StaticNodeVisitor.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/staticreduction/StaticNodeVisitor.java deleted file mode 100644 index c6cf4b6..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/staticreduction/StaticNodeVisitor.java +++ /dev/null @@ -1,413 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - - -package de.huberlin.wbi.cuneiform.core.staticreduction; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; - -import de.huberlin.wbi.cuneiform.core.preprocess.ChannelListener; -import de.huberlin.wbi.cuneiform.core.preprocess.PreListener; -import de.huberlin.wbi.cuneiform.core.semanticmodel.ApplyExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.BaseBlock; -import de.huberlin.wbi.cuneiform.core.semanticmodel.BaseNodeVisitor; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Block; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CfSemanticModelVisitor; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CompoundExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CondExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CurryExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.ForeignLambdaExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.HasFailedException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.LambdaExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NameExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NativeLambdaExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NotBoundException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NotDerivableException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Prototype; -import de.huberlin.wbi.cuneiform.core.semanticmodel.SemanticModelException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.SingleExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.TopLevelContext; - -/** - * @author jorgen - * - */ -public class StaticNodeVisitor extends BaseNodeVisitor { - - private final LinkedList blockStack; - private BaseBlock currentBlock; - private final Set freeVarSet; - - public StaticNodeVisitor( BaseBlock currentBlock ) { - blockStack = new LinkedList<>(); - this.currentBlock = currentBlock; - freeVarSet = new HashSet<>(); - } - - @Override - public CompoundExpr accept( ApplyExpr applyExpr ) throws HasFailedException, NotBoundException { - SingleExpr se; - NativeLambdaExpr lambda; - NameExpr targetNameExpr; - CompoundExpr targetCompoundExpr; - int channel; - CompoundExpr taskResult, taskOriginal; - ApplyExpr applyExpr1; - boolean rest; - - - // try to reduce the task expression - taskOriginal = applyExpr.getTaskExpr(); - taskResult = taskOriginal.visit( this ); - - channel = applyExpr.getChannel(); - rest = applyExpr.hasRest(); - - applyExpr1 = new ApplyExpr( channel, rest ); - applyExpr1.setTaskExpr( taskResult ); - - // try to reduce the parameter list - try { - for( NameExpr nameExpr : applyExpr.getNameSet() ) { - CompoundExpr expr = applyExpr.getExpr( nameExpr ); - applyExpr1.putAssign( nameExpr, expr.visit( this )); - } - } - catch( NotBoundException e ) { - throw new RuntimeException( e.getMessage() ); - } - - // continue only if one single lambda expression is applied - if( taskResult.getNumSingleExpr() != 1 ) - return new CompoundExpr( applyExpr1 ); - - // fetch that lambda expression - se = taskResult.getSingleExpr( 0 ); - - if( se == null ) - throw new NullPointerException( "Expression must not be null." ); - - // continue only if that single lambda expression is native - if( se instanceof NativeLambdaExpr ) { - - lambda = ( NativeLambdaExpr )se; - applyExpr1.setParent( lambda.getBodyBlock() ); - - try { - pushIntoBlock( applyExpr1.getParamBlock() ); - } catch( NotDerivableException e2 ) { - // can't happen we already know, we have a native lambda expression in front of us - throw new RuntimeException( e2.getMessage() ); - } - - targetNameExpr = lambda.getPrototype().getOutput( channel-1 ); - - try { - targetCompoundExpr = currentBlock.getExpr( targetNameExpr ); - } - catch( NotBoundException e1 ) { - throw new SemanticModelException( applyExpr.toString(), e1.getMessage() ); - } - - try { - CompoundExpr expr = currentBlock.getExpr( targetNameExpr ); - targetCompoundExpr = expr.visit( this ); - } - catch( NotBoundException e ) { - // we rely on the parser to sort out whether the target is bound - } - - popBlock(); - - return targetCompoundExpr; - } - - - return new CompoundExpr( applyExpr1 ); - } - - @Override - public CompoundExpr accept(CompoundExpr ce) throws HasFailedException, NotBoundException { - CompoundExpr result, intermediate; - - if( ce == null ) - throw new NullPointerException( "Compound expression must not be null." ); - - result = new CompoundExpr(); - - for( SingleExpr singleExpr : ce.getSingleExprList() ) { - intermediate = singleExpr.visit( this ); - result.addCompoundExpr( intermediate ); - } - - return result; - } - - @Override - public CompoundExpr accept(CondExpr condExpr) throws HasFailedException { - return new CompoundExpr( condExpr ); - } - - @Override - public CompoundExpr accept( CurryExpr curryExpr ) throws HasFailedException, NotBoundException { - - Prototype originalPrototype; - SingleExpr se; - LambdaExpr lambdaExpr; - NativeLambdaExpr nativeLambdaExpr; - Block originalBodyBlock; - Block curriedBodyBlock; - Prototype curriedPrototype; - NativeLambdaExpr curriedLambdaExpr; - - - if( !curryExpr.hasTaskExpr() ) - throw new SemanticModelException( - curryExpr.toString(), - "Task parameter not bound." ); - - if( curryExpr.getTaskExpr().getNumSingleExpr() == 0 ) - throw new SemanticModelException( - curryExpr.toString(), - "Task expression must not be nil." ); - - if( curryExpr.getTaskExpr().getNumSingleExpr() > 1 ) - return new CompoundExpr( curryExpr ); - - CompoundExpr taskExpr = curryExpr.getTaskExpr(); - se = taskExpr.visit( this ).getSingleExpr( 0 ); - - - if( se instanceof NameExpr ) - return new CompoundExpr( curryExpr ); - - if( !( se instanceof LambdaExpr ) ) - throw new SemanticModelException( curryExpr.toString(), se+" is not a lambda expression." ); - - lambdaExpr = ( LambdaExpr )se; - - originalPrototype = lambdaExpr.getPrototype(); - - // the prototype of the curried lambda expression is derived from - // the original prototype - curriedPrototype = new Prototype( originalPrototype ); - - // from the prototype we remove all inputs that are bound by - // currying - for( NameExpr nameExpr : curryExpr.getNameSet() ) - curriedPrototype.removeParam( nameExpr ); - - if( !( lambdaExpr instanceof NativeLambdaExpr ) ) - throw new RuntimeException( "Lambda expression type not recognized." ); - - nativeLambdaExpr = ( NativeLambdaExpr )lambdaExpr; - - originalBodyBlock = nativeLambdaExpr.getBodyBlock(); - - // the body block of the curried lambda expression is derived from the - // body block of the original lambda expression - curriedBodyBlock = new Block(); - for( NameExpr ne : originalBodyBlock.getFullNameSet() ) - curriedBodyBlock.putAssign( ne, new CompoundExpr( originalBodyBlock.getExpr( ne ) ) ); - - // with the curried expression's binding block merged in - try { - for( NameExpr nameExpr : curryExpr.getNameSet() ) - curriedBodyBlock.putAssign( - nameExpr, curryExpr.getExpr( nameExpr ) ); - } - catch( NotBoundException e ) { - throw new RuntimeException( e.getMessage() ); - } - - // from the curried prototype and body expression we form the - // resulting curried lambda expression - curriedLambdaExpr = new NativeLambdaExpr( curriedPrototype, curriedBodyBlock ); - - return new CompoundExpr( curriedLambdaExpr ); - - - // reuse this commented block when in dynamic reducer - /* if( lambdaExpr instanceof ForeignLambdaExpr ) { - - applyExpr = new ApplyExpr( 1, false ); - - applyExpr.setTaskExpr( new CompoundExpr( lambdaExpr ) ); - - try { - - for( NameExpr nameExpr : originalPrototype.getParamNameExprSet() ) - - if( curryExpr.containsName( nameExpr ) ) - applyExpr.putAssign( nameExpr, curryExpr.getExpr( nameExpr ) ); - else - applyExpr.putAssign( nameExpr, new CompoundExpr( nameExpr ) ); - } - catch( NotBoundException e ) { - throw new RuntimeException( e.getMessage() ); - } - - curriedBodyBlock = new Block(); - - n = originalPrototype.getNumOutput(); - - // replicate apply expression for each output name expression - for( i = 0; i < n; i++ ) { - - ne = originalPrototype.getOutput( i ); - - ae = applyExpr.clone(); - ae.setChannel( i+1 ); - - curriedBodyBlock.putAssign( ne, new CompoundExpr( ae ) ); - } - - curriedLambdaExpr = new NativeLambdaExpr( curriedPrototype, curriedBodyBlock ); - - return new CompoundExpr( curriedLambdaExpr ); - } */ - } - - @Override - public CompoundExpr accept( NameExpr nameExpr ) throws HasFailedException { - - CompoundExpr result; - SingleExpr se; - CompoundExpr expr; - - try { - - expr = currentBlock.getExpr( nameExpr ); - result = expr.visit( this ); - - if( result.getNumSingleExpr() == 1 ) { - - se = result.getSingleExpr( 0 ); - if( se instanceof ForeignLambdaExpr ) - return new CompoundExpr( nameExpr ); - } - - return result; - } - catch( NotBoundException e ) { - freeVarSet.add( nameExpr ); - return new CompoundExpr( nameExpr ); - } - } - - @Override - public CompoundExpr accept( TopLevelContext tlc ) throws HasFailedException, NotBoundException { - - CompoundExpr result; - - freeVarSet.clear(); - - result = new CompoundExpr(); - - for( CompoundExpr ce : tlc.getTargetList() ) - result.addCompoundExpr( ce.visit( this ) ); - - return result; - } - - public Set getFreeVarSet() { - return Collections.unmodifiableSet( freeVarSet ); - } - - private void popBlock() { - currentBlock = blockStack.pop(); - } - - private void pushIntoBlock( Block block ) { - blockStack.push( currentBlock ); - currentBlock = block; - } - - public static TopLevelContext createTlc( String src ) { - - String afterPre, afterChannel; - TopLevelContext tlc; - - afterPre = PreListener.process( src ); - afterChannel = ChannelListener.process( afterPre ); - tlc = CfSemanticModelVisitor.process( afterChannel ); - - return tlc; - } - - public static List getFreeVarNameList( TopLevelContext tlc )throws HasFailedException, NotBoundException { - - StaticNodeVisitor staticVisitor; - List nameList; - - nameList = new ArrayList<>(); - - staticVisitor = new StaticNodeVisitor( tlc ); - - tlc.visit( staticVisitor ); - - for( NameExpr ne : staticVisitor.getFreeVarSet() ) - nameList.add( ne.getId() ); - - return Collections.unmodifiableList( nameList ); - } - - public static List getTargetVarNameList( TopLevelContext tlc ) { - - List nameList; - CompoundExpr ce; - - nameList = new ArrayList<>(); - - try { - for( NameExpr ne : tlc.getNameSet() ) { - - ce = tlc.getExpr( ne ); - if( ce.getNumSingleExpr() == 1 ) - if( ce.getSingleExpr( 0 ) instanceof LambdaExpr ) - continue; - - nameList.add( ne.getId() ); - } - return nameList; - } - catch ( NotBoundException e ) { - throw new RuntimeException( e ); - } - - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/ticketsrc/NodeVisitorTicketSrc.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/ticketsrc/NodeVisitorTicketSrc.java deleted file mode 100644 index 699e8a6..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/ticketsrc/NodeVisitorTicketSrc.java +++ /dev/null @@ -1,51 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.ticketsrc; - -import java.util.Set; -import java.util.UUID; - -import de.huberlin.wbi.cuneiform.core.repl.BaseRepl; -import de.huberlin.wbi.cuneiform.core.semanticmodel.ApplyExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.HasFailedException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.QualifiedTicket; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Ticket; - -public interface NodeVisitorTicketSrc { - - public UUID getRunId(); - public boolean isQueueClear( UUID queryId )throws HasFailedException; - public QualifiedTicket requestTicket( BaseRepl repl, UUID queryId, ApplyExpr applyExpr )throws HasFailedException; - public Set getTicketSet( UUID queryId ); - -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/ticketsrc/ReplTicketSrc.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/ticketsrc/ReplTicketSrc.java deleted file mode 100644 index 6755df4..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/ticketsrc/ReplTicketSrc.java +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.ticketsrc; - -public interface ReplTicketSrc extends NodeVisitorTicketSrc { - // marker interface -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/ticketsrc/TicketFailedMsg.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/ticketsrc/TicketFailedMsg.java deleted file mode 100644 index 9933234..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/ticketsrc/TicketFailedMsg.java +++ /dev/null @@ -1,151 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.ticketsrc; - -import de.huberlin.wbi.cuneiform.core.actormodel.Message; -import de.huberlin.wbi.cuneiform.core.cre.BaseCreActor; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Ticket; - -public class TicketFailedMsg extends Message { - - private final String script; - private final String stdErr; - private final String stdOut; - private final Ticket ticket; - private final Exception e; - - public TicketFailedMsg( - BaseCreActor sender, - Ticket ticket, - Exception e, - String script, - String stdOut, - String stdErr ) { - - super( sender ); - - if( script == null ) - this.script = null; - else - if( script.isEmpty() ) - this.script = null; - else - this.script = script; - - if( ticket == null ) - throw new NullPointerException( "Ticket must not be null." ); - - if( stdOut == null ) - this.stdOut = null; - else - if( stdOut.isEmpty() ) - this.stdOut = null; - else - this.stdOut = stdOut; - - if( stdErr == null ) - this.stdErr = null; - else - if( stdErr.isEmpty() ) - this.stdErr = null; - else - this.stdErr = stdErr; - - this.ticket = ticket; - this.e = e; - } - - public String getStdErr() { - return stdErr; - } - - public String getStdOut() { - return stdOut; - } - - public Exception getException() { - return e; - } - - public String getScript() { - return script; - } - - public Ticket getTicket() { - return ticket; - } - - public long getTicketId() { - return ticket.getTicketId(); - } - - public boolean hasScript() { - return script != null; - } - - public boolean hasStdErr() { - return stdErr != null; - } - - public boolean hasStdOut() { - return stdOut != null; - } - - public boolean hasException() { - return e != null; - } - - @Override - public String toString() { - - String s; - - s = ""; - - if( e != null ) { - s += " "+e.getClass().getName(); - - if( e.getMessage() != null ) - s += ": \""+e.getMessage()+"\""; - } - - if( stdOut != null ) - s += " Output channel: \""+stdOut.replace( '\n', ' ' )+"\""; - - if( stdErr != null ) - s += " Error channel: \""+stdErr.replace( '\n', ' ' )+"\""; - - - return "{ ticketFailed, "+ticket.getTicketId()+","+s+" }"; - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/ticketsrc/TicketFinishedMsg.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/ticketsrc/TicketFinishedMsg.java deleted file mode 100644 index 8337d00..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/ticketsrc/TicketFinishedMsg.java +++ /dev/null @@ -1,94 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.ticketsrc; - - -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -import de.huberlin.wbi.cuneiform.core.actormodel.Message; -import de.huberlin.wbi.cuneiform.core.cre.BaseCreActor; -import de.huberlin.wbi.cuneiform.core.semanticmodel.JsonReportEntry; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Ticket; - -public class TicketFinishedMsg extends Message { - - private final Ticket ticket; - private final Set reportEntrySet; - - public TicketFinishedMsg( BaseCreActor sender, Ticket ticket, Collection report ) { - - super( sender ); - - if( ticket == null ) - throw new NullPointerException( "Ticket must not be null." ); - - this.ticket = ticket; - - reportEntrySet = new HashSet<>(); - - addReport( report ); - } - - public void addReport( Collection report ) { - - if( report == null ) - throw new NullPointerException( "JSON report entry collection must not be null." ); - - for( JsonReportEntry entry : report ) - addReport( entry ); - } - - public void addReport( JsonReportEntry entry ) { - - if( entry == null ) - throw new NullPointerException( "JSON report entry must not be null." ); - - reportEntrySet.add( entry ); - } - - public Set getReportEntrySet() { - return Collections.unmodifiableSet( reportEntrySet ); - } - - public Ticket getTicket() { - return ticket; - } - - @Override - public String toString() { - return "{ ticketFinished, "+ticket.getTicketId()+" }"; - } -} diff --git a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/ticketsrc/TicketSrcActor.java b/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/ticketsrc/TicketSrcActor.java deleted file mode 100644 index c1da58c..0000000 --- a/cuneiform-core/src/main/java/de/huberlin/wbi/cuneiform/core/ticketsrc/TicketSrcActor.java +++ /dev/null @@ -1,334 +0,0 @@ -/******************************************************************************* - * In the Hi-WAY project we propose a novel approach of executing scientific - * workflows processing Big Data, as found in NGS applications, on distributed - * computational infrastructures. The Hi-WAY software stack comprises the func- - * tional workflow language Cuneiform as well as the Hi-WAY ApplicationMaster - * for Apache Hadoop 2.x (YARN). - * - * List of Contributors: - * - * Jörgen Brandt (HU Berlin) - * Marc Bux (HU Berlin) - * Ulf Leser (HU Berlin) - * - * Jörgen Brandt is funded by the European Commission through the BiobankCloud - * project. Marc Bux is funded by the Deutsche Forschungsgemeinschaft through - * research training group SOAMED (GRK 1651). - * - * Copyright 2014 Humboldt-Universität zu Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package de.huberlin.wbi.cuneiform.core.ticketsrc; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.UUID; - -import de.huberlin.wbi.cuneiform.core.actormodel.Actor; -import de.huberlin.wbi.cuneiform.core.actormodel.Message; -import de.huberlin.wbi.cuneiform.core.cre.BaseCreActor; -import de.huberlin.wbi.cuneiform.core.cre.TicketReadyMsg; -import de.huberlin.wbi.cuneiform.core.repl.BaseRepl; -import de.huberlin.wbi.cuneiform.core.semanticmodel.ApplyExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CompoundExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.ForeignLambdaExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.HasFailedException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NameExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NotBoundException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NotDerivableException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Prototype; -import de.huberlin.wbi.cuneiform.core.semanticmodel.QualifiedTicket; -import de.huberlin.wbi.cuneiform.core.semanticmodel.ReduceVar; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CfSemanticModelVisitor; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Ticket; - -public class TicketSrcActor extends Actor implements ReplTicketSrc { - - private final Set replSet; - private final Map> queryTicketMap; - private final Map> ticketQueryMap; - private final Map cacheMap; - private final UUID runId; - private final BaseCreActor cre; - private final Set failedQuerySet; - - - public TicketSrcActor( BaseCreActor cre ) { - if( cre == null ) - throw new NullPointerException( "CRE actor must not be null." ); - - this.cre = cre; - - queryTicketMap = new HashMap<>(); - ticketQueryMap = new HashMap<>(); - cacheMap = new HashMap<>(); - replSet = new HashSet<>(); - runId = UUID.randomUUID(); - failedQuerySet = new HashSet<>(); - - if( log.isDebugEnabled() ) - log.debug( "New TicketSrcActor's UUID: "+runId ); - } - - @Override - public UUID getRunId() { - return runId; - } - - @Override - public Set getTicketSet( UUID queryId ) { - return queryTicketMap.get( queryId ); - } - - @Override - public boolean isQueueClear( UUID queryId ) { - - Set set; - - if( queryId == null ) - throw new NullPointerException( "Run ID must not be null." ); - - set = queryTicketMap.get( queryId ); - - if( set == null ) - return true; - - return set.isEmpty(); - } - - @Override - protected void processMsg( Message msg ) { - - TicketFinishedMsg ticketFinishedMsg; - TicketFailedMsg ticketFailedMsg; - Ticket ticket; - String script, stdOut, stdErr; - long ticketId; - Exception e; - Set querySet; - - - if( msg instanceof TicketFinishedMsg ) { - - ticketFinishedMsg = ( TicketFinishedMsg )msg; - ticket = ticketFinishedMsg.getTicket(); - ticketId = ticket.getTicketId(); - querySet = ticketQueryMap.get( ticket ); - - clearTicket( ticket ); - - if( querySet != null ) - for( UUID queryId : querySet ) - for( BaseRepl repl : replSet ) - if( repl.isRunning( queryId ) ) - repl.ticketFinished( queryId, ticketId, ticketFinishedMsg.getReportEntrySet() ); - - - - return; - } - - if( msg instanceof TicketFailedMsg ) { - - ticketFailedMsg = ( TicketFailedMsg )msg; - - ticket = ticketFailedMsg.getTicket(); - ticketId = ticketFailedMsg.getTicketId(); - script = ticketFailedMsg.getScript(); - stdOut = ticketFailedMsg.getStdOut(); - stdErr = ticketFailedMsg.getStdErr(); - e = ticketFailedMsg.getException(); - querySet = ticketQueryMap.get( ticket ); - - clearTicket( ticket ); - cacheMap.remove( ticketId ); - - if( querySet != null ) { - - for( UUID queryId : querySet ) - for( BaseRepl repl : replSet ) - if( repl.isRunning( queryId ) ) - repl.queryFailed( queryId, ticketId, e, script, stdOut, stdErr ); - - for( UUID queryId : querySet ) { - clearQuery( queryId ); - failedQuerySet.add( queryId ); - } - } - - - return; - } - - throw new RuntimeException( "Message type "+msg.getClass()+" not recognized." ); - } - - @Override - public synchronized QualifiedTicket requestTicket( BaseRepl repl, UUID queryId, ApplyExpr applyExpr ) throws HasFailedException { - - CompoundExpr ce; - int channel; - ForeignLambdaExpr lambda; - Ticket ticket; - long ticketId; - QualifiedTicket qt; - Prototype prototype; - - if( queryId == null ) - throw new NullPointerException( "Query ID must not be null." ); - - if( applyExpr == null ) - throw new NullPointerException( "Apply expression must not be null." ); - - if( repl == null ) - throw new NullPointerException( "REPL actor must not be null." ); - - if( failedQuerySet.contains( queryId ) ) - throw new HasFailedException( "Query "+queryId+" has already failed. Dropping request." ); - - if( log.isDebugEnabled() ) - log.debug( "Requesting ticket for "+applyExpr.toString().replace( '\n', ' ') ); - - ce = applyExpr.getTaskExpr(); - try { - - if( ce.getNumAtom() != 1 ) - throw new RuntimeException( "Excepted singular task expression." ); - - if( !( ce.getSingleExpr( 0 ) instanceof ForeignLambdaExpr ) ) - throw new RuntimeException( "Expected foreign lambda expression." ); - - lambda = ( ForeignLambdaExpr )ce.getSingleExpr( 0 ); - } - catch( NotDerivableException e ) { - throw new RuntimeException( "Cannot derive cardinality of task expression." ); - } - - prototype = lambda.getPrototype(); - - for( NameExpr name : prototype.getParamNameSet() ) { - - if( name instanceof ReduceVar ) - continue; - - if( name.getId().equals( CfSemanticModelVisitor.LABEL_TASK ) ) - continue; - - try { - - if( applyExpr.getExpr( name ).getNumAtom() != 1 ) - throw new RuntimeException( "Expected singular application." ); - } - catch( NotDerivableException e ) { - throw new RuntimeException( "Cannot derive cardinality of parameter "+name ); - } - catch( NotBoundException e ) { - throw new RuntimeException( e.getMessage() ); - } - } - - replSet.add( repl ); - - channel = applyExpr.getChannel(); - - - - ticket = new Ticket( lambda, applyExpr, runId ); - - ticketId = ticket.getTicketId(); - - if( cacheMap.containsKey( ticketId ) ) { - - if( log.isDebugEnabled() ) - log.debug( "Returning ticket "+ticketId+" from cache." ); - - ticket = cacheMap.get( ticketId ); - putTicket( queryId, ticket ); - qt = new QualifiedTicket( ticket, channel ); - } - else { - - if( log.isDebugEnabled() ) - log.debug( "Creating new ticket "+ticketId+"." ); - - qt = new QualifiedTicket( ticket, channel ); - putTicket( queryId, ticket ); - cacheMap.put( ticketId, ticket ); - cre.sendMsg( new TicketReadyMsg( this, queryId, ticket ) ); - } - - if( log.isDebugEnabled() ) - log.debug( "Substitute with ticket: "+ticket.toString().replace( '\n', ' ' ) ); - - return qt; - } - - @Override - protected void shutdown() { - // nothing to do - } - - private void putTicket( UUID queryId, Ticket ticket ) { - - Set ticketSet; - Set uuidSet; - - if( queryId == null ) - throw new NullPointerException( "Run must not be null." ); - - if( ticket == null ) - throw new NullPointerException( "Ticket must not be null." ); - - if( ticket.isEvaluated() ) - return; - - ticketSet = queryTicketMap.get( queryId ); - if( ticketSet == null ) { - ticketSet = new HashSet<>(); - queryTicketMap.put( queryId, ticketSet ); - } - - uuidSet = ticketQueryMap.get( ticket ); - if( uuidSet == null ) { - uuidSet = new HashSet<>(); - ticketQueryMap.put( ticket, uuidSet ); - } - - if( !ticket.isNormal() ) - throw new RuntimeException( "Ticket not ready." ); - - ticketSet.add( ticket ); - uuidSet.add( queryId ); - - - } - - private void clearTicket( Ticket ticket ) { - - ticketQueryMap.remove( ticket ); - for( Set ticketSet : queryTicketMap.values() ) - ticketSet.remove( ticket ); - } - - private void clearQuery( UUID queryId ) { - - queryTicketMap.remove( queryId ); - for( Set querySet : ticketQueryMap.values() ) - querySet.remove( queryId ); - } - -} diff --git a/cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/invoc/JsonReportEntryTest.java b/cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/invoc/JsonReportEntryTest.java deleted file mode 100644 index 9b9c1d1..0000000 --- a/cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/invoc/JsonReportEntryTest.java +++ /dev/null @@ -1,70 +0,0 @@ -package de.huberlin.wbi.cuneiform.core.invoc; - -import java.util.UUID; - -import org.json.JSONException; -import org.junit.Assert; -import org.junit.Test; - -import de.huberlin.wbi.cuneiform.core.semanticmodel.JsonReportEntry; - -public class JsonReportEntryTest { - - @SuppressWarnings("static-method") - @Test - public void testRunIdIsParsed() throws JSONException { - - String line; - JsonReportEntry entry; - - line = "{timestamp:1396610901698,runId:\"ae113134-5b4f-4ab1-8da7-81507f9668c9\",taskId:3122,taskname:null,lang:null,invocId:null,key:\"wf-name\",value:\"word-count.cf\"}"; - - entry = new JsonReportEntry( line ); - Assert.assertEquals( - "Invalid run ID.", - UUID.fromString( "ae113134-5b4f-4ab1-8da7-81507f9668c9" ), - entry.getRunId() ); - } - - @SuppressWarnings("static-method") - @Test - public void testTaskIdCanBeNull() throws JSONException { - - String line; - JsonReportEntry entry; - - line = "{timestamp:1396615800633,runId:\"2281e887-5b0a-40d5-8b00-d55b482de1ef\",taskId:null,taskname:null,lang:null,invocId:null,key:\"wf-name\",value:\"montage_0\"}"; - - entry = new JsonReportEntry( line ); - Assert.assertFalse( "Entry should not have a task id.", entry.hasTaskId() ); - Assert.assertNull( "Task id should be null.", entry.getTaskId() ); - } - - @SuppressWarnings("static-method") - @Test - public void testTaskIdCanBeMissing1() throws JSONException { - - String line; - JsonReportEntry entry; - - line = "{timestamp:1398874529654,runId:\"7dbb006c-2b9b-41ce-9dde-9433d1416de0\",key:\"wf-name\",value:\"variant-call-09-setup.cf\"}"; - - entry = new JsonReportEntry( line ); - Assert.assertFalse( "Entry should not have a task id.", entry.hasTaskId() ); - Assert.assertNull( "Task id should be null.", entry.getTaskId() ); - } - - @SuppressWarnings("static-method") - @Test - public void testTaskIdCanBeMissing2() throws JSONException { - - String line; - JsonReportEntry entry; - - line = "{timestamp:1398874529676,runId:\"7dbb006c-2b9b-41ce-9dde-9433d1416de0\",key:\"hiway-event\",value:{\"priority\":\"0\",\"nodes\":[],\"type\":\"container-requested\",\"vcores\":1,\"memory\":1536}}"; - - entry = new JsonReportEntry( line ); - Assert.assertFalse( "Entry should not have a task id.", entry.hasTaskId() ); - Assert.assertNull( "Task id should be null.", entry.getTaskId() ); - } -} diff --git a/cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/repl/DynamicNodeVisitorTest.java b/cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/repl/DynamicNodeVisitorTest.java deleted file mode 100644 index 463168d..0000000 --- a/cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/repl/DynamicNodeVisitorTest.java +++ /dev/null @@ -1,209 +0,0 @@ -package de.huberlin.wbi.cuneiform.core.repl; - -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; - -import java.util.UUID; - -import org.junit.Before; -import org.junit.Test; - -import de.huberlin.wbi.cuneiform.core.semanticmodel.ApplyExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Block; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CompoundExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CondExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.ForeignLambdaExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.HasFailedException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.LambdaExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NameExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NativeLambdaExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NotBoundException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NotDerivableException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Prototype; -import de.huberlin.wbi.cuneiform.core.semanticmodel.QualifiedTicket; -import de.huberlin.wbi.cuneiform.core.semanticmodel.StringExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.TopLevelContext; -import de.huberlin.wbi.cuneiform.core.ticketsrc.NodeVisitorTicketSrc; - -public class DynamicNodeVisitorTest { - - private DynamicNodeVisitor dnv; - private CompoundExpr x; - - @Before - public void setUp() throws HasFailedException, NotDerivableException { - - NodeVisitorTicketSrc ticketSrc; - BaseRepl repl; - TopLevelContext tlc; - QualifiedTicket qt; - - x = new CompoundExpr( new StringExpr( "Z" ) ); - - qt = mock( QualifiedTicket.class ); - when( qt.getOutputValue() ).thenThrow( new NotDerivableException( "blub" ) ); - when( qt.getNumAtom() ).thenThrow( new NotDerivableException( "blub" ) ); - - ticketSrc = mock( NodeVisitorTicketSrc.class ); - when( ticketSrc.requestTicket( any( BaseRepl.class ), any( UUID.class ), any( ApplyExpr.class ) ) ). - thenReturn( qt ); - - repl = mock( BaseRepl.class ); - tlc = new TopLevelContext(); - tlc.putAssign( new NameExpr( "x" ), x ); - - dnv = new DynamicNodeVisitor( ticketSrc, repl, tlc ); - } - - @Test - public void cndFalseShouldEvalElseExpr() throws HasFailedException, NotBoundException { - - CondExpr condExpr; - CompoundExpr thenExpr, elseExpr, result; - - thenExpr = mock( CompoundExpr.class ); - elseExpr = new CompoundExpr( new StringExpr( "B" ) ); - - condExpr = new CondExpr( new CompoundExpr(), thenExpr, elseExpr ); - result = dnv.accept( condExpr ); - - assertEquals( elseExpr, result ); - - } - - @Test - public void cndEvaluatesConditionBeforeDecision1() throws HasFailedException, NotBoundException { - - Prototype sign; - Block body; - LambdaExpr lam; - ApplyExpr app; - CompoundExpr e, thenExpr, elseExpr; - CondExpr condExpr; - - sign = new Prototype(); - sign.addOutput( new NameExpr( "out" ) ); - sign.addParam( new NameExpr( "task" ) ); - - body = new Block(); - body.putAssign( new NameExpr( "out" ), new CompoundExpr() ); - - lam = new NativeLambdaExpr( sign, body ); - - app = new ApplyExpr( 1, false ); - app.setTaskExpr( new CompoundExpr( lam ) ); - - thenExpr = new CompoundExpr( new StringExpr( "A" ) ); - elseExpr = new CompoundExpr( new StringExpr( "B" ) ); - - condExpr = new CondExpr( new CompoundExpr( app ), thenExpr, elseExpr ); - - e = new CompoundExpr( condExpr ); - - assertEquals( elseExpr, dnv.accept( e ) ); - } - - @Test - public void cndEvaluatesConditionBeforeDecision2() throws HasFailedException, NotBoundException { - - Prototype sign; - Block body; - LambdaExpr lam; - ApplyExpr app; - CompoundExpr e, thenExpr, elseExpr; - CondExpr condExpr; - - sign = new Prototype(); - sign.addOutput( new NameExpr( "out" ) ); - sign.addParam( new NameExpr( "task" ) ); - - body = new Block(); - body.putAssign( new NameExpr( "out" ), new CompoundExpr( new StringExpr( "true" ) ) ); - - lam = new NativeLambdaExpr( sign, body ); - - app = new ApplyExpr( 1, false ); - app.setTaskExpr( new CompoundExpr( lam ) ); - - thenExpr = new CompoundExpr( new StringExpr( "A" ) ); - elseExpr = new CompoundExpr( new StringExpr( "B" ) ); - - condExpr = new CondExpr( new CompoundExpr( app ), thenExpr, elseExpr ); - - e = new CompoundExpr( condExpr ); - - assertEquals( thenExpr, dnv.accept( e ) ); - } - - @Test - public void cndEvaluatesOnlyOnFinalCondition() throws HasFailedException, NotBoundException { - - Prototype sign; - Block body; - LambdaExpr lam; - ApplyExpr app; - CompoundExpr e, f, thenExpr, elseExpr; - CondExpr condExpr; - - sign = new Prototype(); - sign.addOutput( new NameExpr( "out" ) ); - sign.addParam( new NameExpr( "task" ) ); - - body = new Block(); - body.putAssign( new NameExpr( "out" ), new CompoundExpr( new StringExpr( "true" ) ) ); - - lam = new ForeignLambdaExpr( sign, "bash", "blub" ); - - app = new ApplyExpr( 1, false ); - app.setTaskExpr( new CompoundExpr( lam ) ); - - thenExpr = new CompoundExpr( new StringExpr( "A" ) ); - elseExpr = new CompoundExpr( new StringExpr( "B" ) ); - - condExpr = new CondExpr( new CompoundExpr( app ), thenExpr, elseExpr ); - - e = new CompoundExpr( condExpr ); - - f = dnv.accept( e ); - assertFalse( f.isNormal() ); - assertEquals( 1, f.getNumSingleExpr() ); - assertTrue( f.getSingleExpr( 0 ) instanceof CondExpr ); - } - - @Test - public void cndEvaluatesThenExpression() throws HasFailedException, NotBoundException { - - CompoundExpr e, thenExpr, elseExpr; - CondExpr condExpr; - - - - thenExpr = new CompoundExpr( new NameExpr( "x" ) ); - elseExpr = new CompoundExpr( new StringExpr( "B" ) ); - - condExpr = new CondExpr( new CompoundExpr( new StringExpr( "X" ) ), thenExpr, elseExpr ); - - e = new CompoundExpr( condExpr ); - - assertEquals( x, dnv.accept( e ) ); - } - - @Test - public void cndEvaluatesElseExpression() throws HasFailedException, NotBoundException { - - CompoundExpr e, thenExpr, elseExpr; - CondExpr condExpr; - - - - thenExpr = new CompoundExpr( new StringExpr( "A" ) ); - elseExpr = new CompoundExpr( new NameExpr( "x" ) ); - - condExpr = new CondExpr( new CompoundExpr(), thenExpr, elseExpr ); - - e = new CompoundExpr( condExpr ); - - assertEquals( x, dnv.accept( e ) ); - } - -} diff --git a/cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/repl/ReferenceTest.java b/cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/repl/ReferenceTest.java deleted file mode 100644 index 12be6e8..0000000 --- a/cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/repl/ReferenceTest.java +++ /dev/null @@ -1,1063 +0,0 @@ -package de.huberlin.wbi.cuneiform.core.repl; - -import static org.junit.Assert.*; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.*; -import static de.huberlin.wbi.cuneiform.core.semanticmodel.ForeignLambdaExpr.LANGID_BASH; - -import java.util.UUID; - -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -import de.huberlin.wbi.cuneiform.core.semanticmodel.ApplyExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Block; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CompoundExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CondExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.CorrelParam; -import de.huberlin.wbi.cuneiform.core.semanticmodel.ForeignLambdaExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.HasFailedException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NameExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NativeLambdaExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NotBoundException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.NotDerivableException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.Prototype; -import de.huberlin.wbi.cuneiform.core.semanticmodel.QualifiedTicket; -import de.huberlin.wbi.cuneiform.core.semanticmodel.ReduceVar; -import de.huberlin.wbi.cuneiform.core.semanticmodel.SemanticModelException; -import de.huberlin.wbi.cuneiform.core.semanticmodel.StringExpr; -import de.huberlin.wbi.cuneiform.core.semanticmodel.TopLevelContext; -import de.huberlin.wbi.cuneiform.core.ticketsrc.NodeVisitorTicketSrc; - -public class ReferenceTest { - - private DynamicNodeVisitor dnv; - private TopLevelContext tlc; - private NodeVisitorTicketSrc ticketSrc; - - @Before - public void setUp() throws HasFailedException, NotDerivableException { - - BaseRepl repl; - QualifiedTicket qt; - - - qt = mock( QualifiedTicket.class ); - when( qt.getChannel() ).thenReturn( 1 ); - when( qt.getOutputValue() ).thenThrow( new NotDerivableException( "blub" ) ); - when( qt.getNumAtom() ).thenThrow( new NotDerivableException( "blub" ) ); - - ticketSrc = mock( NodeVisitorTicketSrc.class ); - when( ticketSrc.requestTicket( any( BaseRepl.class ), any( UUID.class ), any( ApplyExpr.class ) ) ). - thenReturn( qt ); - - repl = mock( BaseRepl.class ); - tlc = new TopLevelContext(); - - dnv = new DynamicNodeVisitor( ticketSrc, repl, tlc ); - } - - @Test - public void nilShouldEvalItself() throws HasFailedException, NotBoundException { - - CompoundExpr nil, result; - - nil = new CompoundExpr(); - result = dnv.accept( nil ); - assertEquals( nil, result ); - } - - @Test - public void strShouldEvalItself() throws HasFailedException, NotBoundException { - - CompoundExpr str, result; - - str = new CompoundExpr( new StringExpr( "bla" ) ); - result = dnv.accept( str ); - assertEquals( str, result ); - } - - @Test( expected=NotBoundException.class ) - public void undefVarShouldFail() throws HasFailedException, NotBoundException { - - CompoundExpr freeVar; - - freeVar = new CompoundExpr( new NameExpr( "x" ) ); - dnv.accept( freeVar ); - } - - @Test - public void defVarShouldEvalToBoundValue() throws HasFailedException, NotBoundException { - - CompoundExpr boundVar, result, content; - - content = new CompoundExpr( new StringExpr( "blub" ) ); - tlc.putAssign( new NameExpr( "x" ), content ); - - boundVar = new CompoundExpr( new NameExpr( "x" ) ); - result = dnv.accept( boundVar ); - - assertEquals( content, result ); - } - - @Test - public void defVarShouldCascadeBinding() throws HasFailedException, NotBoundException { - - CompoundExpr result, str; - - str = new CompoundExpr( new StringExpr( "blub" ) ); - - tlc.putAssign( new NameExpr( "x" ), new CompoundExpr( new NameExpr( "y" ) ) ); - tlc.putAssign( new NameExpr( "y" ), str ); - - result = dnv.accept( new CompoundExpr( new NameExpr( "x" ) ) ); - assertEquals( str, result ); - } - - @Test - public void unfinishedTicketShouldEvalToItself() throws HasFailedException, NotBoundException { - - CompoundExpr ce; - QualifiedTicket qt; - - qt = mock( QualifiedTicket.class ); - when( qt.visit( dnv ) ).thenReturn( dnv.accept( qt ) ); - - ce = new CompoundExpr( ); - - assertEquals( ce, dnv.accept( ce ) ); - } - - @Test - public void identityFnShouldEvalArg() throws HasFailedException, NotBoundException { - - CompoundExpr e, f, lamList; - Prototype sign; - Block body; - ApplyExpr ae; - - - e = new CompoundExpr( new StringExpr( "bla" ) ); - - sign = new Prototype(); - sign.addOutput( new NameExpr( "out" ) ); - sign.addParam( new NameExpr( "task" ) ); - sign.addParam( new NameExpr( "inp" ) ); - - body = new Block(); - body.putAssign( new NameExpr( "out" ), new CompoundExpr( new NameExpr( "inp" ) ) ); - - lamList = new CompoundExpr( new NativeLambdaExpr( sign, body ) ); - - ae = new ApplyExpr( 1, false ); - ae.setTaskExpr( lamList ); - ae.putAssign( new NameExpr( "inp" ), e ); - - f = new CompoundExpr( ae ); - - assertEquals( e, dnv.accept( f ) ); - } - - @Test - public void lamShouldEvalItself() throws HasFailedException, NotBoundException { - - Prototype sign; - Block body; - CompoundExpr lamList; - - sign = new Prototype(); - sign.addOutput( new NameExpr( "out" ) ); - sign.addParam( new NameExpr( "task" ) ); - - body = new Block(); - body.putAssign( new NameExpr( "out" ), new CompoundExpr( new NameExpr( "blub" ) ) ); - - lamList = new CompoundExpr( new NativeLambdaExpr( sign, body ) ); - - assertEquals( lamList, dnv.accept( lamList ) ); - } - - @Test - public void multipleOutputShouldBeBindable() throws HasFailedException, NotBoundException { - - Prototype sign; - CompoundExpr e1, e2, lamList; - ApplyExpr f1, f2; - Block body; - - - sign = new Prototype(); - sign.addOutput( new NameExpr( "out1" ) ); - sign.addOutput( new NameExpr( "out2" ) ); - sign.addParam( new NameExpr( "task" ) ); - - e1 = new CompoundExpr( new StringExpr( "bla" ) ); - e2 = new CompoundExpr( new StringExpr( "blub" ) ); - - body = new Block(); - body.putAssign( new NameExpr( "out1" ), e1 ); - body.putAssign( new NameExpr( "out2" ), e2 ); - - lamList = new CompoundExpr( new NativeLambdaExpr( sign, body ) ); - - f1 = new ApplyExpr( 1, false ); - f1.setTaskExpr( lamList ); - - f2 = new ApplyExpr( 2, false ); - f2.setTaskExpr( lamList ); - - assertEquals( e1, dnv.accept( f1 ) ); - assertEquals( e2, dnv.accept( f2 ) ); - } - - @Test( expected=SemanticModelException.class ) - public void applicationShouldIgnoreCallingContext() throws HasFailedException, NotBoundException { - - Prototype sign; - Block body; - CompoundExpr lamList; - ApplyExpr ae; - - sign = new Prototype(); - sign.addOutput( new NameExpr( "out" ) ); - sign.addParam( new NameExpr( "task" ) ); - - body = new Block(); - body.putAssign( new NameExpr( "out" ), new CompoundExpr( new NameExpr( "x" ) ) ); - - lamList = new CompoundExpr( new NativeLambdaExpr( sign, body ) ); - - ae = new ApplyExpr( 1, false ); - ae.setTaskExpr( lamList ); - - tlc.putAssign( new NameExpr( "x" ), new CompoundExpr( new StringExpr( "blub" ) ) ); - dnv.accept( new CompoundExpr( ae ) ); - } - - @Test - public void bindingShouldOverrideBody() throws HasFailedException, NotBoundException { - - CompoundExpr f, g, h, lamList; - Prototype sign; - Block body; - ApplyExpr ae; - - f = new CompoundExpr( new StringExpr( "blub" ) ); - - sign = new Prototype(); - sign.addOutput( new NameExpr( "out" ) ); - sign.addParam( new NameExpr( "task" ) ); - sign.addParam( new NameExpr( "x" ) ); - - body = new Block(); - body.putAssign( new NameExpr( "x" ), new CompoundExpr( new StringExpr( "bla" ) ) ); - body.putAssign( new NameExpr( "out" ), new CompoundExpr( new NameExpr( "x" ) ) ); - - lamList = new CompoundExpr( new NativeLambdaExpr( sign, body ) ); - - ae = new ApplyExpr( 1, false ); - ae.setTaskExpr( lamList ); - ae.putAssign( new NameExpr( "x" ), f ); - - g = new CompoundExpr( ae ); - h = dnv.accept( g ); - - assertEquals( f, h ); - } - - @Test( expected=NullPointerException.class ) - public void appWithEmptyTaskListShouldFail() throws HasFailedException, NotBoundException { - - ApplyExpr ae; - - ae = new ApplyExpr( 1, false ); - dnv.accept( new CompoundExpr( ae ) ); - } - - @Ignore - @Test - public void crossProductShouldBeDerivableFromSignature() throws HasFailedException, NotBoundException { - - Prototype sign; - CompoundExpr e1, e2, lamList, f1, f2; - Block body; - ApplyExpr ae1, ae2; - - e1 = new CompoundExpr(); - e1.addSingleExpr( new StringExpr( "A" ) ); - e1.addSingleExpr( new StringExpr( "B" ) ); - - e2 = new CompoundExpr(); - e2.addSingleExpr( new StringExpr( "1" ) ); - e2.addSingleExpr( new StringExpr( "2" ) ); - - sign = new Prototype(); - sign.addOutput( new NameExpr( "out1" ) ); - sign.addOutput( new NameExpr( "out2" ) ); - sign.addParam( new NameExpr( "task" ) ); - sign.addParam( new NameExpr( "p1" ) ); - sign.addParam( new NameExpr( "p2" ) ); - - body = new Block(); - body.putAssign( new NameExpr( "out1" ), new CompoundExpr( new NameExpr( "p1" ) ) ); - body.putAssign( new NameExpr( "out2" ), new CompoundExpr( new NameExpr( "p2" ) ) ); - - lamList = new CompoundExpr( new NativeLambdaExpr( sign, body ) ); - - ae1 = new ApplyExpr( 1, false ); - ae1.setTaskExpr( lamList ); - ae1.putAssign( new NameExpr( "p1" ), e1 ); - ae1.putAssign( new NameExpr( "p2" ), e2 ); - - ae2 = new ApplyExpr( 2, false ); - ae2.setTaskExpr( lamList ); - ae2.putAssign( new NameExpr( "p1" ), e1 ); - ae2.putAssign( new NameExpr( "p2" ), e2 ); - - f1 = new CompoundExpr(); - f1.addSingleExpr( new StringExpr( "A" ) ); - f1.addSingleExpr( new StringExpr( "A" ) ); - f1.addSingleExpr( new StringExpr( "B" ) ); - f1.addSingleExpr( new StringExpr( "B" ) ); - - f2 = new CompoundExpr(); - f2.addSingleExpr( new StringExpr( "1" ) ); - f2.addSingleExpr( new StringExpr( "2" ) ); - f2.addSingleExpr( new StringExpr( "1" ) ); - f2.addSingleExpr( new StringExpr( "2" ) ); - - assertEquals( f1, dnv.accept( new CompoundExpr( ae1 ) ) ); - assertEquals( f2, dnv.accept( new CompoundExpr( ae2 ) ) ); - } - - public void dotProductShouldBeDerivableFromSignature() throws HasFailedException, NotBoundException { - - Prototype sign; - CorrelParam correl; - CompoundExpr e1, e2, lamList; - Block body; - ApplyExpr ae1, ae2; - - - correl = new CorrelParam(); - correl.addName( new NameExpr( "p1" ) ); - correl.addName( new NameExpr( "p2" ) ); - - sign = new Prototype(); - sign.addOutput( new NameExpr( "out1" ) ); - sign.addOutput( new NameExpr( "out2" ) ); - sign.addParam( new NameExpr( "task" ) ); - sign.addParam( correl ); - - e1 = new CompoundExpr(); - e1.addSingleExpr( new StringExpr( "A" ) ); - e1.addSingleExpr( new StringExpr( "B" ) ); - - e2 = new CompoundExpr(); - e2.addSingleExpr( new StringExpr( "1" ) ); - e2.addSingleExpr( new StringExpr( "2" ) ); - - body = new Block(); - body.putAssign( new NameExpr( "out1" ), new CompoundExpr( new NameExpr( "p1" ) ) ); - body.putAssign( new NameExpr( "out2" ), new CompoundExpr( new NameExpr( "p2" ) ) ); - - lamList = new CompoundExpr( new NativeLambdaExpr( sign, body ) ); - - ae1 = new ApplyExpr( 1, false ); - ae1.setTaskExpr( lamList ); - ae1.putAssign( new NameExpr( "p1" ), e1 ); - ae1.putAssign( new NameExpr( "p2" ), e2 ); - - ae2 = new ApplyExpr( 2, false ); - ae2.setTaskExpr( lamList ); - ae2.putAssign( new NameExpr( "p1" ), e1 ); - ae2.putAssign( new NameExpr( "p2" ), e2 ); - - assertEquals( e1, dnv.accept( new CompoundExpr( ae1 ) ) ); - assertEquals( e2, dnv.accept( new CompoundExpr( ae2 ) ) ); - } - - @Test - public void aggregateShouldConsumeListAsWhole() throws HasFailedException, NotBoundException { - - Prototype sign; - CompoundExpr e1, e2, e3, e4, lamList; - Block body; - ApplyExpr ae; - - sign = new Prototype(); - sign.addOutput( new NameExpr( "out" ) ); - sign.addParam( new NameExpr( "task" ) ); - sign.addParam( new ReduceVar( "inp", null ) ); - - e1 = new CompoundExpr( new StringExpr( "A" ) ); - - e2 = new CompoundExpr(); - e2.addSingleExpr( new StringExpr( "B" ) ); - e2.addSingleExpr( new StringExpr( "C" ) ); - - e3 = new CompoundExpr(); - e3.addCompoundExpr( e1 ); - e3.addSingleExpr( new NameExpr( "inp" ) ); - - - body = new Block(); - body.putAssign( new NameExpr( "out" ), e3 ); - - lamList = new CompoundExpr( new NativeLambdaExpr( sign, body ) ); - - ae = new ApplyExpr( 1, false ); - ae.setTaskExpr( lamList ); - ae.putAssign( new NameExpr( "inp" ), e2 ); - - e4 = new CompoundExpr(); - e4.addCompoundExpr( e1 ); - e4.addCompoundExpr( e2 ); - - assertEquals( e4, dnv.accept( new CompoundExpr( ae ) ) ); - } - - // @Test - public void taskCorrelationShouldWork() throws HasFailedException, NotBoundException { - - Prototype sign; - CorrelParam correl; - Block body1, body2; - CompoundExpr e1, e2, e3, e4, e5, lamList; - ApplyExpr ae; - - correl = new CorrelParam(); - correl.addName( new NameExpr( "task" ) ); - correl.addName( new NameExpr( "c" ) ); - - sign = new Prototype(); - sign.addOutput( new NameExpr( "out" ) ); - sign.addParam( correl ); - sign.addParam( new NameExpr( "p" ) ); - - e1 = new CompoundExpr(); - e1.addSingleExpr( new NameExpr( "c" ) ); - e1.addSingleExpr( new NameExpr( "p" ) ); - - e2 = new CompoundExpr(); - e2.addSingleExpr( new NameExpr( "p" ) ); - e2.addSingleExpr( new NameExpr( "c" ) ); - - body1 = new Block(); - body1.putAssign( new NameExpr( "out" ), e1 ); - - body2 = new Block(); - body2.putAssign( new NameExpr( "out" ), e2 ); - - lamList = new CompoundExpr(); - lamList.addSingleExpr( new NativeLambdaExpr( sign, body1 ) ); - lamList.addSingleExpr( new NativeLambdaExpr( sign, body2 ) ); - - e3 = new CompoundExpr(); - e3.addSingleExpr( new StringExpr( "A" ) ); - e3.addSingleExpr( new StringExpr( "B" ) ); - - e4 = new CompoundExpr(); - e4.addSingleExpr( new StringExpr( "1" ) ); - e4.addSingleExpr( new StringExpr( "2" ) ); - - ae = new ApplyExpr( 1, false ); - ae.setTaskExpr( lamList ); - ae.putAssign( new NameExpr( "c" ), e3 ); - ae.putAssign( new NameExpr( "p" ), e4 ); - - e5 = new CompoundExpr(); - e5.addSingleExpr( new StringExpr( "A" ) ); - e5.addSingleExpr( new StringExpr( "1" ) ); - e5.addSingleExpr( new StringExpr( "A" ) ); - e5.addSingleExpr( new StringExpr( "2" ) ); - e5.addSingleExpr( new StringExpr( "1" ) ); - e5.addSingleExpr( new StringExpr( "B" ) ); - e5.addSingleExpr( new StringExpr( "2" ) ); - e5.addSingleExpr( new StringExpr( "B" ) ); - - assertEquals( e5, dnv.accept( new CompoundExpr( ae ) ) ); - } - - @Test - public void cndFalseShouldEvalElseExpr() throws HasFailedException, NotBoundException { - - CompoundExpr e, ifExpr, thenExpr, elseExpr, e1; - - e1 = new CompoundExpr( new StringExpr( "B" ) ); - - ifExpr = new CompoundExpr(); - thenExpr = new CompoundExpr( new StringExpr( "A" ) ); - elseExpr = e1; - - e = new CompoundExpr( new CondExpr( ifExpr, thenExpr, elseExpr ) ); - assertEquals( e1, dnv.accept( e ) ); - } - - @Test - public void cndEvaluatesConditionBeforeDecision1() throws HasFailedException, NotBoundException { - - Prototype sign; - Block body; - CompoundExpr lamList, e, a, b; - ApplyExpr ae; - - sign = new Prototype(); - sign.addOutput( new NameExpr( "out" ) ); - sign.addParam( new NameExpr( "task" ) ); - - body = new Block(); - body.putAssign( new NameExpr( "out" ), new CompoundExpr() ); - - lamList = new CompoundExpr( new NativeLambdaExpr( sign, body ) ); - - ae = new ApplyExpr( 1, false ); - ae.setTaskExpr( lamList ); - - a = new CompoundExpr( new StringExpr( "A" ) ); - b = new CompoundExpr( new StringExpr( "B" ) ); - - e = new CompoundExpr( new CondExpr( new CompoundExpr( ae ), a, b ) ); - - assertEquals( b, dnv.accept( e ) ); - } - - - - @Test - public void cndEvaluatesConditionBeforeDecision2() throws HasFailedException, NotBoundException { - - Prototype sign; - Block body; - CompoundExpr lamList, e, a, b, x, y; - ApplyExpr ae; - - sign = new Prototype(); - sign.addOutput( new NameExpr( "out" ) ); - sign.addParam( new NameExpr( "task" ) ); - - x = new CompoundExpr( new StringExpr( "X" ) ); - - body = new Block(); - body.putAssign( new NameExpr( "out" ), x ); - - lamList = new CompoundExpr( new NativeLambdaExpr( sign, body ) ); - - ae = new ApplyExpr( 1, false ); - ae.setTaskExpr( lamList ); - - a = new CompoundExpr( new StringExpr( "A" ) ); - b = new CompoundExpr( new StringExpr( "B" ) ); - - e = new CompoundExpr( new CondExpr( new CompoundExpr( ae ), a, b ) ); - - y = dnv.accept( e ); - - assertEquals( a, y ); - } - - @Test - public void cndEvaluatesOnlyOnFinalCondition() throws HasFailedException, NotBoundException { - - Prototype sign; - CompoundExpr lamList, e, a, b, x; - ApplyExpr ae; - CondExpr ce; - - sign = new Prototype(); - sign.addOutput( new ReduceVar( "out", null ) ); - sign.addParam( new NameExpr( "task" ) ); - - lamList = new CompoundExpr( - new ForeignLambdaExpr( - sign, ForeignLambdaExpr.LANGID_BASH, "blub" ) ); - - ae = new ApplyExpr( 1, false ); - ae.setTaskExpr( lamList ); - - a = new CompoundExpr( new NameExpr( "a" ) ); - b = new CompoundExpr( new NameExpr( "b" ) ); - - e = new CompoundExpr( new CondExpr( new CompoundExpr( ae ), a, b ) ); - - tlc.putAssign( new NameExpr( "a" ), new CompoundExpr( new StringExpr( "A" ) ) ); - tlc.putAssign( new NameExpr( "b" ), new CompoundExpr( new StringExpr( "A" ) ) ); - x = dnv.accept( e ); - - assertTrue( x.getSingleExpr( 0 ) instanceof CondExpr ); - - ce = ( CondExpr )x.getSingleExpr( 0 ); - assertEquals( a, ce.getThenExpr() ); - assertEquals( b, ce.getElseExpr() ); - - assertTrue( ce.getIfExpr().getSingleExpr( 0 ) instanceof QualifiedTicket ); - } - - @Test - public void cndEvaluatesThenExpr() throws HasFailedException, NotBoundException { - - CompoundExpr e, f, x; - - e = new CompoundExpr( new CondExpr( - new CompoundExpr( new StringExpr( "Z" ) ), - new CompoundExpr( new NameExpr( "x" ) ), - new CompoundExpr( new StringExpr( "B" ) ) ) ); - - f = new CompoundExpr( new StringExpr( "A" ) ); - - tlc.putAssign( new NameExpr( "x" ), f ); - x = dnv.accept( e ); - - assertEquals( f, x ); - } - - @Test - public void cndEvaluatesElseExpr() throws HasFailedException, NotBoundException { - - CompoundExpr e, f, x; - - e = new CompoundExpr( new CondExpr( - new CompoundExpr(), - new CompoundExpr( new StringExpr( "A" ) ), - new CompoundExpr( new NameExpr( "x" ) ) ) ); - - f = new CompoundExpr( new StringExpr( "B" ) ); - - tlc.putAssign( new NameExpr( "x" ), f ); - x = dnv.accept( e ); - - assertEquals( f, x ); - } - - - @Test - public void foreignAppWithCndParamIsLeftUntouched() throws HasFailedException, NotBoundException { - - CompoundExpr lamList, e, x; - Prototype sign; - ApplyExpr ae1, ae2, ae3; - - sign = new Prototype(); - sign.addOutput( new NameExpr( "out" ) ); - sign.addParam( new NameExpr( "task" ) ); - sign.addParam( new NameExpr( "p" ) ); - - lamList = new CompoundExpr( new ForeignLambdaExpr( - sign, LANGID_BASH, "blub" ) ); - - ae1 = new ApplyExpr( 1, false ); - ae1.setTaskExpr( lamList ); - ae1.putAssign( - new NameExpr( "p" ), new CompoundExpr( new StringExpr( "A" ) ) ); - - e = new CompoundExpr( new CondExpr( - new CompoundExpr( ae1 ), new CompoundExpr(), new CompoundExpr() ) ); - - ae2 = new ApplyExpr( 1, false ); - ae2.setTaskExpr( lamList ); - ae2.putAssign( new NameExpr( "p" ), e ); - - x = dnv.accept( new CompoundExpr( ae2 ) ); - - assertTrue( x.getSingleExpr( 0 ) instanceof ApplyExpr ); - - ae3 = ( ApplyExpr )x.getSingleExpr( 0 ); - - assertEquals( lamList, ae3.getTaskExpr() ); - } - - @Test - public void foreignAppWithSelectParamIsLeftUntouched() throws HasFailedException, NotBoundException { - - Prototype sign; - CompoundExpr lamList, x; - ApplyExpr ae1, ae2, ae3; - - sign = new Prototype(); - sign.addOutput( new NameExpr( "out" ) ); - sign.addParam( new NameExpr( "task" ) ); - sign.addParam( new NameExpr( "p" ) ); - - lamList = new CompoundExpr( new ForeignLambdaExpr( - sign, LANGID_BASH, "blub" ) ); - - ae1 = new ApplyExpr( 1, false ); - ae1.setTaskExpr( lamList ); - ae1.putAssign( new NameExpr( "p" ), new CompoundExpr( new StringExpr( "A" ) ) ); - - ae2 = new ApplyExpr( 1, false ); - ae2.setTaskExpr( lamList ); - ae2.putAssign( new NameExpr( "p" ), new CompoundExpr( ae1 ) ); - - x = dnv.accept( new CompoundExpr( ae2 ) ); - - assertTrue( x.getSingleExpr( 0 ) instanceof ApplyExpr ); - - ae3 = ( ApplyExpr )x.getSingleExpr( 0 ); - - assertEquals( lamList, ae3.getTaskExpr() ); - } - - @Test - public void cascadingAppDoesNotBreakEnum() throws HasFailedException, NotBoundException, NotDerivableException { - - Prototype sign1, sign2; - CompoundExpr lam1, lam2, out1, out2, x; - ApplyExpr ae1, ae2; - Block body2; - QualifiedTicket qt1; - - sign1 = new Prototype(); - sign1.addOutput( new ReduceVar( "out", null ) ); - sign1.addParam( new NameExpr( "task" ) ); - - lam1 = new CompoundExpr( new ForeignLambdaExpr( sign1, LANGID_BASH, "out=(1 2 3)" ) ); - - ae1 = new ApplyExpr( 1, false ); - ae1.setTaskExpr( lam1 ); - - sign2 = new Prototype(); - sign2.addOutput( new NameExpr( "out" ) ); - sign2.addParam( new NameExpr( "task" ) ); - sign2.addParam( new NameExpr( "p1" ) ); - sign2.addParam( new NameExpr( "p2" ) ); - - out1 = new CompoundExpr(); - out1.addSingleExpr( new NameExpr( "p1" ) ); - out1.addSingleExpr( new NameExpr( "p2" ) ); - - body2 = new Block(); - body2.putAssign( new NameExpr( "out" ), out1 ); - - lam2 = new CompoundExpr( new NativeLambdaExpr( sign2, body2 ) ); - - ae2 = new ApplyExpr( 1, false ); - ae2.setTaskExpr( lam2 ); - ae2.putAssign( new NameExpr( "p1" ), new CompoundExpr( new StringExpr( "A" ) ) ); - ae2.putAssign( new NameExpr( "p2" ), new CompoundExpr( ae1 ) ); - - out2 = new CompoundExpr(); - out2.addSingleExpr( new StringExpr( "1" ) ); - out2.addSingleExpr( new StringExpr( "2" ) ); - - qt1 = mock( QualifiedTicket.class ); - when( qt1.getChannel() ).thenReturn( 1 ); - when( qt1.getNumAtom() ).thenReturn( 2 ); - when( qt1.getOutputValue() ).thenReturn( out2 ); - when( qt1.getStringExprValue( 0 ) ).thenReturn( new StringExpr( "1" ) ); - when( qt1.getStringExprValue( 1 ) ).thenReturn( new StringExpr( "2" ) ); - - when( ticketSrc.requestTicket( - any( BaseRepl.class ), - any( UUID.class ), - any( ApplyExpr.class ) ) ) - .thenReturn( qt1 ); - - x = dnv.accept( new CompoundExpr( ae2 ) ); - - assertEquals( "'A' '1' 'A' '2'", x.toString() ); - } - - @Test - public void appTaskParamIsEvaluated() throws HasFailedException, NotBoundException { - - Prototype sign; - Block body; - CompoundExpr lamList, x; - ApplyExpr ae; - - - sign = new Prototype(); - sign.addOutput( new NameExpr( "out" ) ); - sign.addParam( new NameExpr( "task" ) ); - - body = new Block(); - body.putAssign( new NameExpr( "out" ), new CompoundExpr( new StringExpr( "A" ) ) ); - - lamList = new CompoundExpr( new NativeLambdaExpr( sign, body ) ); - - ae = new ApplyExpr( 1, false ); - ae.setTaskExpr( new CompoundExpr( new NameExpr( "f" ) ) ); - - tlc.putAssign( new NameExpr( "f" ), lamList ); - - x = dnv.accept( new CompoundExpr( ae ) ); - - assertEquals( new CompoundExpr( new StringExpr( "A" ) ), x ); - } - - @Test - public void appNonFinalResultPreservesApp() throws NotDerivableException, HasFailedException, NotBoundException { - - Prototype sign; - Block body; - QualifiedTicket qt1; - CompoundExpr lamList, x; - ApplyExpr ae; - - sign = new Prototype(); - sign.addOutput( new NameExpr( "out" ) ); - sign.addParam( new NameExpr( "task" ) ); - - qt1 = mock( QualifiedTicket.class ); - when( qt1.getNumAtom() ).thenThrow( new NotDerivableException( "blub" ) ); - when( qt1.getOutputValue() ).thenThrow( new NotDerivableException( "blub" ) ); - when( qt1.visit( dnv ) ).thenReturn( new CompoundExpr( qt1 ) ); - - body = new Block(); - body.putAssign( new NameExpr( "out" ), new CompoundExpr( qt1 ) ); - - lamList = new CompoundExpr( new NativeLambdaExpr( sign, body ) ); - - ae = new ApplyExpr( 1, false ); - ae.setTaskExpr( lamList ); - - x = dnv.accept( new CompoundExpr( ae ) ); - assertEquals( new CompoundExpr( ae ), x ); - } - - @Test - public void appNonFinalResultPreservesAppWithNewLam() throws HasFailedException, NotBoundException { - - Prototype cSign, sign; - CompoundExpr cLam, lam, cnd, x, val, varx; - ApplyExpr cAe, ae, ae1; - Block body, body1; - NativeLambdaExpr lam1; - CondExpr cnd1; - - - cSign = new Prototype(); - cSign.addOutput( new ReduceVar( "out", null ) ); - cSign.addParam( new NameExpr( "task" ) ); - - cLam = new CompoundExpr( new ForeignLambdaExpr( cSign, LANGID_BASH, "blub" ) ); - - cAe = new ApplyExpr( 1, false ); - cAe.setTaskExpr( cLam ); - - sign = new Prototype(); - sign.addOutput( new NameExpr( "out" ) ); - sign.addParam( new NameExpr( "task" ) ); - - varx = new CompoundExpr( new NameExpr( "x" ) ); - - cnd = new CompoundExpr( new CondExpr( new CompoundExpr( cAe ), varx, varx ) ); - - body = new Block(); - body.putAssign( new NameExpr( "out" ), cnd ); - body.putAssign( new NameExpr( "x" ), new CompoundExpr( new StringExpr( "A" ) ) ); - - lam = new CompoundExpr( new NativeLambdaExpr( sign, body ) ); - - ae = new ApplyExpr( 1, false ); - ae.setTaskExpr( lam ); - - x = dnv.accept( new CompoundExpr( ae ) ); - - assertEquals( 1, x.getNumSingleExpr() ); - assertTrue( x.getSingleExpr( 0 ) instanceof ApplyExpr ); - - ae1 = ( ApplyExpr )x.getSingleExpr( 0 ); - - assertEquals( 1, ae1.getChannel() ); - assertTrue( ae1.getTaskExpr().getSingleExpr( 0 ) instanceof NativeLambdaExpr ); - - lam1 = ( NativeLambdaExpr )ae1.getTaskExpr().getSingleExpr( 0 ); - - assertEquals( sign, lam1.getPrototype() ); - - body1 = lam1.getBodyBlock(); - val = body1.getExpr( new NameExpr( "out" ) ); - - assertEquals( 1, val.getNumSingleExpr() ); - assertTrue( val.getSingleExpr( 0 ) instanceof CondExpr ); - - cnd1 = ( CondExpr )val.getSingleExpr( 0 ); - - assertEquals( varx, cnd1.getThenExpr() ); - assertEquals( varx, cnd1.getElseExpr() ); - assertTrue( cnd1.getIfExpr().getSingleExpr( 0 ) instanceof QualifiedTicket ); - } - - @Test - public void nestedAppUndergoesReduction() throws HasFailedException, NotBoundException, NotDerivableException { - - Prototype sign; - CompoundExpr lam1, lam2, x, y, a; - ApplyExpr ae1, ae2; - Block body2; - QualifiedTicket qt1; - - sign = new Prototype(); - sign.addOutput( new NameExpr( "out" ) ); - sign.addParam( new NameExpr( "task" ) ); - - lam1 = new CompoundExpr( new ForeignLambdaExpr( sign, LANGID_BASH, "blub" ) ); - - ae1 = new ApplyExpr( 1, false ); - ae1.setTaskExpr( lam1 ); - - body2 = new Block(); - body2.putAssign( new NameExpr( "out" ), new CompoundExpr( ae1 ) ); - - lam2 = new CompoundExpr( new NativeLambdaExpr( sign, body2 ) ); - - ae2 = new ApplyExpr( 1, false ); - ae2.setTaskExpr( lam2 ); - - qt1 = mock( QualifiedTicket.class ); - when( qt1.visit( dnv ) ).thenReturn( dnv.accept( qt1 ) ); - when( qt1.getChannel() ).thenReturn( 1 ); - when( qt1.getNumAtom() ).thenThrow( new NotDerivableException( "bla" ) ); - when( qt1.getOutputValue() ).thenThrow( new NotDerivableException( "blub" ) ); - - when( ticketSrc.requestTicket( - any( BaseRepl.class ), - any( UUID.class ), - any( ApplyExpr.class ) ) ).thenReturn( qt1 ); - - x = dnv.accept( new CompoundExpr( ae2 ) ); - - assertEquals( 1, x.getNumSingleExpr() ); - assertTrue( x.getSingleExpr( 0 ) instanceof ApplyExpr ); - - a = new CompoundExpr( new StringExpr( "A" ) ); - - reset( qt1 ); - when( qt1.visit( dnv ) ).thenReturn( dnv.accept( qt1 ) ); - when( qt1.getChannel() ).thenReturn( 1 ); - when( qt1.getNumAtom() ).thenReturn( 1 ); - when( qt1.getOutputValue() ).thenReturn( a ); - - y = dnv.accept( x ); - assertEquals( a.normalize(), y.normalize() ); - } - - /*recursion_terminates( CreateTicket ) -> - DecSign = {sign, [{param, "i1", false, false}, - {param, "converge", false, true}], - [], - [{param, "i", false, false}]}, - DecBody = {forbody, bash, "blub"}, - DecLam = [{lam, ?LOC, DecSign, DecBody}], - RecSign = {sign, [{param, "out", false, true}], - [], [{param, "i", false, false}]}, - RecBody = {natbody, - #{"i1" => [{app, ?LOC, 1, DecLam, #{"i" => [{var, "i"}]}}], - "converge" => [{app, ?LOC, 2, DecLam, #{"i" => [{var, "i"}]}}], - "out" => [{cnd, [{var, "converge"}], - [{str, "last"}], - [{str, "next to"}, - {app, ?LOC, 1, [{var, "rec"}], - #{"i" => [{var, "i1"}]}}]}]}}, - RecLam = [{lam, ?LOC, RecSign, RecBody}], - App = [{app, ?LOC, 1, [{var, "rec"}], #{"i" => [{str, "2"}]}}], - Context0 = put( "rec", RecLam, #{} ), - R = eval( App, Context0, CreateTicket ), - [Ref0] = get_ticket_id_list( R ), - Context1 = put( {2, Ref0}, [], Context0 ), - S = eval( R, Context1, CreateTicket ), - [Ref1] = get_ticket_id_list( S ), - Context2 = put( {1, Ref1}, [{str, "1"}], Context1 ), - T = eval( S, Context2, CreateTicket ), - [Ref2] = get_ticket_id_list( T ), - Context3 = put( {2, Ref2}, [{str, "true"}], Context2 ), - U = eval( T, Context3, CreateTicket ), - ?_assertEqual( [{str, "next to"}, {str, "last"}], U ). */ - - @Ignore - @Test - public void recursionTerminates() throws HasFailedException, NotBoundException, NotDerivableException { - - Prototype decSign, recSign; - ForeignLambdaExpr decLam; - Block recBody; - ApplyExpr ae1, ae2, recCall, ae; - CondExpr cnd; - CompoundExpr nextToCall, r, s; - NativeLambdaExpr recLam; - QualifiedTicket qt1, qt2; - - decSign = new Prototype(); - decSign.addOutput( new NameExpr( "i1" ) ); - decSign.addOutput( new ReduceVar( "converge", null ) ); - decSign.addParam( new NameExpr( "task" ) ); - decSign.addParam( new NameExpr( "i" ) ); - - decLam = new ForeignLambdaExpr( decSign, LANGID_BASH, "blub" ); - - recSign = new Prototype(); - recSign.addOutput( new ReduceVar( "out", null ) ); - recSign.addParam( new NameExpr( "task" ) ); - recSign.addParam( new NameExpr( "i" ) ); - - ae1 = new ApplyExpr( 1, false ); - ae1.setTaskExpr( new CompoundExpr( decLam ) ); - ae1.putAssign( new NameExpr( "i" ), new CompoundExpr( new NameExpr( "i" ) ) ); - - ae2 = new ApplyExpr( 2, false ); - ae2.setTaskExpr( new CompoundExpr( decLam ) ); - ae2.putAssign( new NameExpr( "i" ), new CompoundExpr( new NameExpr( "i" ) ) ); - - recCall = new ApplyExpr( 1, false ); - recCall.setTaskExpr( new CompoundExpr( new NameExpr( "rec" ) ) ); - recCall.putAssign( new NameExpr( "i" ), new CompoundExpr( new NameExpr( "i1" ) ) ); - - nextToCall = new CompoundExpr(); - nextToCall.addSingleExpr( new StringExpr( "next to" ) ); - nextToCall.addSingleExpr( recCall ); - - cnd = new CondExpr( - new CompoundExpr( new NameExpr( "converge" ) ), - new CompoundExpr( new StringExpr( "last" ) ), - nextToCall ); - - recBody = new Block(); - recBody.putAssign( new NameExpr( "i1" ), new CompoundExpr( ae1 ) ); - recBody.putAssign( new NameExpr( "converge" ), new CompoundExpr( ae2 ) ); - recBody.putAssign( new NameExpr( "out" ), new CompoundExpr( cnd ) ); - - recLam = new NativeLambdaExpr( recSign, recBody ); - - ae = new ApplyExpr( 1, false ); - ae.setTaskExpr( new CompoundExpr( new NameExpr( "rec" ) ) ); - ae.putAssign( new NameExpr( "i" ), new CompoundExpr( new StringExpr( "2" ) ) ); - - tlc.putAssign( new NameExpr( "rec" ), new CompoundExpr( recLam ) ); - System.out.println( tlc ); - - qt1 = mock( QualifiedTicket.class ); - when( qt1.visit( dnv ) ).thenReturn( dnv.accept( qt1 ) ); - when( qt1.getChannel() ).thenReturn( 2 ); - when( qt1.getNumAtom() ).thenThrow( new NotDerivableException( "bla" ) ); - when( qt1.getOutputValue() ).thenThrow( new NotDerivableException( "blub" ) ); - - reset( ticketSrc ); - when( ticketSrc.requestTicket( any( BaseRepl.class ), any( UUID.class ), any( ApplyExpr.class ) ) ) - .thenReturn( qt1 ); - - r = dnv.accept( new CompoundExpr( ae ) ); - - reset( qt1 ); - when( qt1.visit( dnv ) ).thenReturn( dnv.accept( qt1 ) ); - when( qt1.getChannel() ).thenReturn( 2 ); - when( qt1.getNumAtom() ).thenReturn( 0 ); - when( qt1.getOutputValue() ).thenReturn( new CompoundExpr() ); - - qt2 = mock( QualifiedTicket.class ); - when( qt2.visit( dnv ) ).thenReturn( dnv.accept( qt2 ) ); - when( qt2.getChannel() ).thenReturn( 1 ); - when( qt2.getNumAtom() ).thenReturn( 1 ); - when( qt2.getOutputValue() ).thenReturn( new CompoundExpr( new StringExpr( "1" ) ) ); - - reset( ticketSrc ); - when( ticketSrc.requestTicket( any( BaseRepl.class ), any( UUID.class ), any( ApplyExpr.class ) ) ) - .thenReturn( qt2 ); - - s = dnv.accept( r ); - System.out.println( s ); - } - -} diff --git a/cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/semanticmodel/ApplyExprTest.java b/cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/semanticmodel/ApplyExprTest.java deleted file mode 100644 index d69e702..0000000 --- a/cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/semanticmodel/ApplyExprTest.java +++ /dev/null @@ -1,37 +0,0 @@ -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -import static org.junit.Assert.*; - -import org.junit.Test; - -public class ApplyExprTest { - - @SuppressWarnings("static-method") - @Test - public void copyConstructorShouldWork() { - - ApplyExpr ae1, ae2; - NativeLambdaExpr lam; - Prototype sign; - Block body; - - sign = new Prototype(); - sign.addOutput( new NameExpr( "out" ) ); - sign.addParam( new NameExpr( "task" ) ); - sign.addParam( new NameExpr( "inp" ) ); - - body = new Block(); - body.putAssign( new NameExpr( "out" ), new CompoundExpr( new NameExpr( "inp" ) ) ); - - lam = new NativeLambdaExpr( sign, body ); - - ae1 = new ApplyExpr( 1, false ); - ae1.setTaskExpr( new CompoundExpr( lam ) ); - ae1.putAssign( new NameExpr( "inp" ), new CompoundExpr( new StringExpr( "A" ) ) ); - - ae2 = new ApplyExpr( ae1 ); - - assertEquals( ae1, ae2 ); - assertNotSame( ae1, ae2 ); - } -} diff --git a/cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CompoundExprTest.java b/cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CompoundExprTest.java deleted file mode 100644 index 5c767b7..0000000 --- a/cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CompoundExprTest.java +++ /dev/null @@ -1,111 +0,0 @@ -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -import static org.junit.Assert.*; - -import org.junit.Test; - -public class CompoundExprTest { - - @SuppressWarnings("static-method") - @Test - public void equalsReturnsTrueOnCompoundExprWithEqualContent() { - - CompoundExpr a, b; - - a = new CompoundExpr( new StringExpr( "A" ) ); - b = new CompoundExpr( new StringExpr( "A" ) ); - - assertEquals( a, b ); - assertEquals( b, a ); - } - - @SuppressWarnings("static-method") - @Test - public void equalsReturnsFalseOnCompoundExprWithNonEqualContent() { - - CompoundExpr a, b; - - a = new CompoundExpr( new StringExpr( "A" ) ); - b = new CompoundExpr( new StringExpr( "B" ) ); - - assertNotEquals( a, b ); - assertNotEquals( b, a ); - } - - @SuppressWarnings("static-method") - @Test - public void equalsReturnsFalseOnNull() { - - CompoundExpr a; - - a = new CompoundExpr(); - assertNotEquals( a, null ); - } - - @SuppressWarnings("static-method") - @Test - public void equalsReturnsFalseOnCompoundExprWithDifferingSize() { - - CompoundExpr a, b; - - a = new CompoundExpr(); - b = new CompoundExpr( new StringExpr( "B" ) ); - - assertNotEquals( a, b ); - assertNotEquals( b, a ); - } - - @SuppressWarnings("static-method") - @Test - public void equalsReturnsFalseOnNonCompoundExpr() { - - CompoundExpr a; - - a = new CompoundExpr(); - assertNotEquals( a, "blub" ); - } - - @SuppressWarnings("static-method") - @Test - public void condIsNonNormal() { - - CondExpr cnd; - CompoundExpr ce; - - cnd = new CondExpr( new CompoundExpr(), new CompoundExpr(), new CompoundExpr() ); - ce = new CompoundExpr( cnd ); - - assertFalse( ce.isNormal() ); - } - - @SuppressWarnings("static-method") - @Test - public void copyApplyExprShouldWork() { - - ApplyExpr ae; - NativeLambdaExpr lam; - Prototype sign; - Block body; - CompoundExpr ce1, ce2; - - sign = new Prototype(); - sign.addOutput( new NameExpr( "out" ) ); - sign.addParam( new NameExpr( "task" ) ); - sign.addParam( new NameExpr( "inp" ) ); - - body = new Block(); - body.putAssign( new NameExpr( "out" ), new CompoundExpr( new NameExpr( "inp" ) ) ); - - lam = new NativeLambdaExpr( sign, body ); - - ae = new ApplyExpr( 1, false ); - ae.setTaskExpr( new CompoundExpr( lam ) ); - ae.putAssign( new NameExpr( "inp" ), new CompoundExpr( new StringExpr( "A" ) ) ); - - ce1 = new CompoundExpr( ae ); - ce2 = new CompoundExpr( ce1 ); - - assertEquals( ce1, ce2 ); - assertNotSame( ce1, ce2 ); - } -} diff --git a/cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CondExprTest.java b/cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CondExprTest.java deleted file mode 100644 index 7a609b5..0000000 --- a/cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/semanticmodel/CondExprTest.java +++ /dev/null @@ -1,66 +0,0 @@ -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -import org.junit.Test; - -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; - -public class CondExprTest { - - @SuppressWarnings("static-method") - @Test - public void constructorSetsThreeExpr() { - - CondExpr condExpr; - CompoundExpr ifExpr, thenExpr, elseExpr; - - ifExpr = mock( CompoundExpr.class ); - thenExpr = mock( CompoundExpr.class ); - elseExpr = mock( CompoundExpr.class ); - - condExpr = new CondExpr( ifExpr, thenExpr, elseExpr ); - assertEquals( ifExpr, condExpr.getIfExpr() ); - assertEquals( thenExpr, condExpr.getThenExpr() ); - assertEquals( elseExpr, condExpr.getElseExpr() ); - } - - @SuppressWarnings({ "static-method", "unused" }) - @Test( expected=IllegalArgumentException.class ) - public void constructorThrowsIaeOnNullIfExpr() { - - CondExpr condExpr; - CompoundExpr thenExpr, elseExpr; - - thenExpr = mock( CompoundExpr.class ); - elseExpr = mock( CompoundExpr.class ); - - condExpr = new CondExpr( null, thenExpr, elseExpr ); - } - - @SuppressWarnings({ "static-method", "unused" }) - @Test( expected=IllegalArgumentException.class ) - public void constructorThrowsIaeOnNullThenExpr() { - - CondExpr condExpr; - CompoundExpr ifExpr, elseExpr; - - ifExpr = mock( CompoundExpr.class ); - elseExpr = mock( CompoundExpr.class ); - - condExpr = new CondExpr( ifExpr, null, elseExpr ); - } - - @SuppressWarnings({ "static-method", "unused" }) - @Test( expected=IllegalArgumentException.class ) - public void constructorThrowsIaeOnNullElseExpr() { - - CondExpr condExpr; - CompoundExpr ifExpr, thenExpr; - - ifExpr = mock( CompoundExpr.class ); - thenExpr = mock( CompoundExpr.class ); - - condExpr = new CondExpr( ifExpr, thenExpr, null ); - } - -} diff --git a/cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/semanticmodel/EnumHelperTest.java b/cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/semanticmodel/EnumHelperTest.java deleted file mode 100644 index c7dc345..0000000 --- a/cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/semanticmodel/EnumHelperTest.java +++ /dev/null @@ -1,210 +0,0 @@ -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class EnumHelperTest { - - @SuppressWarnings({ "static-method", "unused" }) - @Test( expected = IllegalArgumentException.class ) - public void ConstructorShouldThrowIaeOnNullTaskExpr() { - - EnumHelper eh; - BaseBlock bindingBlock; - - bindingBlock = mock( BaseBlock.class ); - - eh = new EnumHelper( null, bindingBlock ); - } - - @SuppressWarnings({ "static-method", "unused" }) - @Test( expected = IllegalArgumentException.class ) - public void ConstructorShouldThrowIaeOnNullBindingBlock() { - - EnumHelper eh; - CompoundExpr ce; - - ce = mock( CompoundExpr.class ); - - eh = new EnumHelper( ce, null ); - } - - @SuppressWarnings({ "static-method", "unused" }) - @Test( expected = IllegalArgumentException.class ) - public void ConstructorShouldThrowIaeOnNil() { - - EnumHelper eh; - CompoundExpr ce; - BaseBlock bindingBlock; - - bindingBlock = mock( BaseBlock.class ); - ce = new CompoundExpr(); - - eh = new EnumHelper( ce, bindingBlock ); - } - - @SuppressWarnings({ "unused", "static-method" }) - @Test( expected = IllegalArgumentException.class ) - public void ConstructorShouldThrowIaeOnNonLambdaExpr() { - - EnumHelper eh; - CompoundExpr ce; - BaseBlock bindingBlock; - - bindingBlock = mock( BaseBlock.class ); - ce = new CompoundExpr( mock( NameExpr.class ) ); - - eh = new EnumHelper( ce, bindingBlock ); - } - - @SuppressWarnings("static-method") - @Test - public void getCardinalityShouldWorkWithTwoCorrelatedParameters() throws NotDerivableException { - - Prototype prototype; - CorrelParam cp; - CompoundExpr taskExpr; - LambdaExpr le; - Block bindingBlock; - NameExpr a, b, c, d; - CompoundExpr ce; - EnumHelper eh; - - // create name expressions for four parameters - a = new NameExpr( "a" ); - b = new NameExpr( "b" ); - c = new NameExpr( "c" ); - d = new NameExpr( "d" ); - - // generate prototype - prototype = new Prototype(); - - cp = new CorrelParam(); - cp.addName( a ); - cp.addName( b ); - prototype.addParam( cp ); - - cp = new CorrelParam(); - cp.addName( c ); - cp.addName( d ); - prototype.addParam( cp ); - - // create lambda expression - le = mock( LambdaExpr.class ); - when( le.getPrototype() ).thenReturn( prototype ); - - // create task expression - taskExpr = new CompoundExpr( le ); - - // bind parameter values - bindingBlock = new Block(); - - ce = new CompoundExpr(); - ce.addSingleExpr( new StringExpr( "a1" ) ); - ce.addSingleExpr( new StringExpr( "a2" ) ); - ce.addSingleExpr( new StringExpr( "a3" ) ); - bindingBlock.putAssign( a, ce ); - - ce = new CompoundExpr(); - ce.addSingleExpr( new StringExpr( "b1" ) ); - ce.addSingleExpr( new StringExpr( "b2" ) ); - ce.addSingleExpr( new StringExpr( "b3" ) ); - bindingBlock.putAssign( b, ce ); - - ce = new CompoundExpr(); - ce.addSingleExpr( new StringExpr( "c1" ) ); - ce.addSingleExpr( new StringExpr( "c2" ) ); - ce.addSingleExpr( new StringExpr( "c3" ) ); - ce.addSingleExpr( new StringExpr( "c4" ) ); - ce.addSingleExpr( new StringExpr( "c5" ) ); - bindingBlock.putAssign( c, ce ); - - ce = new CompoundExpr(); - ce.addSingleExpr( new StringExpr( "d1" ) ); - ce.addSingleExpr( new StringExpr( "d2" ) ); - ce.addSingleExpr( new StringExpr( "d3" ) ); - ce.addSingleExpr( new StringExpr( "d4" ) ); - ce.addSingleExpr( new StringExpr( "d5" ) ); - bindingBlock.putAssign( d, ce ); - - eh = new EnumHelper( taskExpr, bindingBlock ); - assertEquals( 15, eh.getCardinality() ); - } - - @SuppressWarnings("static-method") - @Test - public void getCardinalityShouldWorkWithTaskCorrelation() throws NotDerivableException { - - Prototype prototype; - CorrelParam cp; - CompoundExpr taskExpr; - LambdaExpr le1, le2; - Block bindingBlock; - NameExpr task, b, c, d; - CompoundExpr ce; - EnumHelper eh; - - // create name expressions for four parameters - task = new NameExpr( "task" ); - b = new NameExpr( "a" ); - c = new NameExpr( "b" ); - d = new NameExpr( "c" ); - - // generate prototype - prototype = new Prototype(); - - cp = new CorrelParam(); - cp.addName( task ); - cp.addName( b ); - prototype.addParam( cp ); - - cp = new CorrelParam(); - cp.addName( c ); - cp.addName( d ); - prototype.addParam( cp ); - - // create lambda expression - le1 = mock( LambdaExpr.class ); - when( le1.getPrototype() ).thenReturn( prototype ); - when( le1.getNumAtom() ).thenReturn( 1 ); - - le2 = mock( LambdaExpr.class ); - when( le2.getPrototype() ).thenReturn( prototype ); - when( le2.getNumAtom() ).thenReturn( 1 ); - - // create task expression - taskExpr = new CompoundExpr( le1 ); - taskExpr.addSingleExpr( le2 ); - - // bind parameter values - bindingBlock = new Block(); - - ce = new CompoundExpr(); - ce.addSingleExpr( new StringExpr( "b1" ) ); - ce.addSingleExpr( new StringExpr( "b2" ) ); - bindingBlock.putAssign( b, ce ); - - ce = new CompoundExpr(); - ce.addSingleExpr( new StringExpr( "c1" ) ); - ce.addSingleExpr( new StringExpr( "c2" ) ); - ce.addSingleExpr( new StringExpr( "c3" ) ); - ce.addSingleExpr( new StringExpr( "c4" ) ); - ce.addSingleExpr( new StringExpr( "c5" ) ); - bindingBlock.putAssign( c, ce ); - - ce = new CompoundExpr(); - ce.addSingleExpr( new StringExpr( "d1" ) ); - ce.addSingleExpr( new StringExpr( "d2" ) ); - ce.addSingleExpr( new StringExpr( "d3" ) ); - ce.addSingleExpr( new StringExpr( "d4" ) ); - ce.addSingleExpr( new StringExpr( "d5" ) ); - bindingBlock.putAssign( d, ce ); - - eh = new EnumHelper( taskExpr, bindingBlock ); - assertEquals( 10, eh.getCardinality() ); - } - -} diff --git a/cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/semanticmodel/HashHelperTest.java b/cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/semanticmodel/HashHelperTest.java deleted file mode 100644 index b8ad669..0000000 --- a/cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/semanticmodel/HashHelperTest.java +++ /dev/null @@ -1,60 +0,0 @@ -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -import org.junit.Test; -import static org.junit.Assert.assertNotEquals; - -import java.util.UUID; - - -public class HashHelperTest { - - - @SuppressWarnings("static-method") - @Test - public void hashPreservesDifferencesBetweenStrings() { - - String a, b; - long h1, h2; - - a = "bla"; - b = "blub"; - - h1 = HashHelper.add( 0L, a ); - h2 = HashHelper.add( 0L, b ); - - assertNotEquals( h1, h2 ); - } - - @SuppressWarnings("static-method") - @Test - public void hashPreservesDifferencesBetweenTickets() { - - Ticket a, b; - long h1, h2; - UUID uuid; - ForeignLambdaExpr lambda1, lambda2; - Block bindingBlock; - Prototype prototype; - String lang; - String body1, body2; - - uuid = UUID.randomUUID(); - bindingBlock = new Block(); - - prototype = new Prototype(); - lang = ForeignLambdaExpr.LANGID_BASH; - body1 = "bla"; - body2 = "blub"; - - lambda1 = new ForeignLambdaExpr( prototype, lang, body1 ); - lambda2 = new ForeignLambdaExpr( prototype, lang, body2 ); - - a = new Ticket( lambda1, bindingBlock, uuid ); - b = new Ticket( lambda2, bindingBlock, uuid ); - - h1 = HashHelper.add( 0L, a ); - h2 = HashHelper.add( 0L, b ); - - assertNotEquals( h1, h2 ); - } -} diff --git a/cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/semanticmodel/NativeLambdaExprTest.java b/cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/semanticmodel/NativeLambdaExprTest.java deleted file mode 100644 index 9e73c97..0000000 --- a/cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/semanticmodel/NativeLambdaExprTest.java +++ /dev/null @@ -1,5 +0,0 @@ -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -public class NativeLambdaExprTest { - -} diff --git a/cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/semanticmodel/StringExprTest.java b/cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/semanticmodel/StringExprTest.java deleted file mode 100644 index 2b60123..0000000 --- a/cuneiform-core/src/test/java/de/huberlin/wbi/cuneiform/core/semanticmodel/StringExprTest.java +++ /dev/null @@ -1,21 +0,0 @@ -package de.huberlin.wbi.cuneiform.core.semanticmodel; - -import static org.junit.Assert.*; - -import org.junit.Test; - -public class StringExprTest { - - @SuppressWarnings("static-method") - @Test - public void EqualReturnsTrueOnStringExprWithEqualContent() { - - StringExpr a, b; - - a = new StringExpr( "A" ); - b = new StringExpr( "A" ); - - assertEquals( a, b ); - assertEquals( b, a ); - } -} diff --git a/cuneiform-dist/.gitignore b/cuneiform-dist/.gitignore deleted file mode 100644 index 6afedc5..0000000 --- a/cuneiform-dist/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/target -/bin -/.classpath -/.settings -/.project diff --git a/cuneiform-dist/pom.xml b/cuneiform-dist/pom.xml deleted file mode 100644 index 76042a5..0000000 --- a/cuneiform-dist/pom.xml +++ /dev/null @@ -1,129 +0,0 @@ - - 4.0.0 - - - de.hu-berlin.wbi.cuneiform - cuneiform - 2.0.4-SNAPSHOT - - - cuneiform-dist - - - - de.hu-berlin.wbi.cuneiform - cuneiform-cmdline - ${project.version} - - - de.hu-berlin.wbi.cuneiform - cuneiform-cfide - ${project.version} - - - de.hu-berlin.wbi.cuneiform - cuneiform-logview - ${project.version} - - - - - - - - src/main/scripts - - log4j.properties - - - - - - - maven-assembly-plugin - 2.4 - - - generate-dist - package - - single - - - - - - src/main/assemblies/bin.xml - - false - - - - org.apache.maven.plugins - maven-jar-plugin - 2.6 - - - true - - true - - - development - ${project.url} - de.huberlin.wbi.cuneiform.cmdline.main.Main - - - - - - org.apache.maven.plugins - maven-shade-plugin - 2.4.2 - - - - - src/main/scripts/log4j.properties - log4j.properties - - - false - true - - - - package - - shade - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.10.3 - - - attach-javadocs - - jar - - - - - true - - de.hu-berlin.wbi.cuneiform:* - - - - - - - diff --git a/cuneiform-dist/src/main/assemblies/bin.xml b/cuneiform-dist/src/main/assemblies/bin.xml deleted file mode 100644 index d47c473..0000000 --- a/cuneiform-dist/src/main/assemblies/bin.xml +++ /dev/null @@ -1,51 +0,0 @@ - - bin - - dir - tar.gz - zip - - - - - src/main/scripts - cuneiform-${project.version} - - - - false - cuneiform-${project.version} - - - - - cuneiform-${project.version}/lib - false - true - false - false - - de.hu-berlin.wbi.cuneiform:cuneiform-cmdline - de.hu-berlin.wbi.cuneiform:cuneiform-cfide - de.hu-berlin.wbi.cuneiform:cuneiform-logview - - - - - cuneiform-${project.version}/bin - false - true - false - false - - de.hu-berlin.wbi.cuneiform:cuneiform-cmdline - de.hu-berlin.wbi.cuneiform:cuneiform-cfide - de.hu-berlin.wbi.cuneiform:cuneiform-logview - - - - - diff --git a/cuneiform-dist/src/main/cuneiform/variant-call11.cf b/cuneiform-dist/src/main/cuneiform/variant-call11.cf deleted file mode 100644 index cfad539..0000000 --- a/cuneiform-dist/src/main/cuneiform/variant-call11.cf +++ /dev/null @@ -1,193 +0,0 @@ -% VARIANT-CALL -% -% A variant calling workflow. -% -% Sample data can be obtained from: -% ftp://ftp.1000genomes.ebi.ac.uk/vol1/ftp/phase3/data/HG02025/sequence_read/ -% -% The HG38 reference genome can be downloaded from -% http://hgdownload.soe.ucsc.edu/goldenPath/hg38/chromosomes/ -% -% An Annovar HG38 database is expected to reside in -% /opt/data/annodb_hg38 -% -% In addition to a Cuneiform interpreter the following tools need to be -% installed to run this analysis: -% - FastQC 0.11.4 -% - Bowtie2 2.2.6 -% - SAMtools 1.2 -% - VarScan 2.3.9 -% - Annovar - -%% ============================================================ -%% Task definitions -%% ============================================================ - -% untar -deftask untar( : tar( File ) )in bash *{ - tar xf $tar - out=`tar tf $tar` -}* - -% gunzip -deftask gunzip( out( File ) : gz( File ) )in bash *{ - gzip -c -d $gz > $out -}* - -// fastqc -deftask fastqc( zip( File ) : fastq( File ) )in bash *{ - fastqc -f fastq --noextract -o ./ $fastq - zip=`ls *.zip` -}* - -% bowtie2 -deftask bowtie2-build( idx( File ) : fa( File ) ) -in bash *{ - bowtie2-build $fa bt2idx - tar cf $idx --remove-files bt2idx.* -}* - -deftask bowtie2-align( - bam( File ) -: idx( File ) [fastq1( File ) fastq2( File )] )in bash *{ - - tar xf $idx - bowtie2 -D 5 -R 1 -N 0 -L 22 -i S,0,2.50 --no-unal -x bt2idx \ - -1 $fastq1 -2 $fastq2 -S - | samtools view -b - > $bam - rm bt2idx.* -}* - -% samtools -deftask samtools-faidx( fai( File ) : fa( File ) )in bash *{ - samtools faidx $fa - fai=$fa.fai -}* - -deftask samtools-sort( sortedbam( File ) : bam( File ) )in bash *{ - sortedbam=alignment-sorted.bam - samtools sort -m 1G $bam alignment-sorted -}* - -deftask samtools-mpileup( - mpileup( File ) -: bam( File ) [fa( File ) fai( File )] )in bash *{ - - ln -sf $fai $fa.fai - samtools mpileup -f $fa $bam > $mpileup -}* - -deftask samtools-merge( merged( File ) : )in bash *{ - if [ ${#bam[@]} -eq "0" ] - then - echo "No files to merge." >&2 - exit -1 - else - if [ ${#bam[@]} -eq "1" ] - then - merged=$bam - else - samtools merge -f $merged ${bam[@]} - fi - fi -}* - -% varscan -deftask varscan( vcf( File ) : mpileup( File ) )in bash *{ - varscan mpileup2snp $mpileup --output-vcf --p-value 99e-02 > $vcf -}* - -% annovar -deftask annovar( - fun( File ) exonicfun( File ) -: db buildver )in bash *{ - - fun=table.variant_function - exonicfun=table.exonic_variant_function - cat ${vcf[@]} | \ - convert2annovar.pl -format vcf4 - | \ - annotate_variation.pl -buildver $buildver -geneanno -outfile table - $db -}* - -deftask per-chromosome( - vcf( File ) - : [fa( File ) fai( File ) idx( File )] - ) { - - sortedbam = per-fastq( - fa: fa, - idx: idx - fastq1: fastq1, - fastq2: fastq2 ); - - mergedbam = samtools-merge( bam: sortedbam ); - - mpileup = samtools-mpileup( - bam: mergedbam - fa: fa - fai: fai ); - - vcf = varscan( mpileup: mpileup ); -} - -deftask per-fastq( - sortedbam - : idx( File ) [fastq1( File ) fastq2( File )] ) { - - bam = bowtie2-align( - idx: idx, - fastq1: fastq1, - fastq2: fastq2 ); - - sortedbam = samtools-sort( bam: bam ); -} - - -%% ============================================================ -%% Input data -%% ============================================================ - -hg38-tar = 'hg38/hg38.tar'; - -fastq1-gz = 'kgenomes/SRR359188_1.filt.fastq.gz' - 'kgenomes/SRR359195_1.filt.fastq.gz'; - -fastq2-gz = 'kgenomes/SRR359188_2.filt.fastq.gz' - 'kgenomes/SRR359195_2.filt.fastq.gz'; - -db = '/opt/data/annodb_hg38'; - - -%% ============================================================ -%% Workflow definition -%% ============================================================ - -fa = untar( tar: hg38-tar ); -% fa = gunzip( gz: 'hg38/chr22.fa.gz' ); - -fastq1 = gunzip( gz: fastq1-gz ); -fastq2 = gunzip( gz: fastq2-gz ); - -qc = fastqc( fastq: fastq1 fastq2 ); - -bt2idx = bowtie2-build( fa: fa ); -fai = samtools-faidx( fa: fa ); - -vcf = per-chromosome( - fa: fa, - fai: fai, - idx: bt2idx, - fastq1: fastq1, - fastq2: fastq2 ); - -fun exonicfun = annovar( - vcf: vcf - db: db - buildver: 'hg38' ); - - -%% ============================================================ -%% Query -%% ============================================================ - -fun exonicfun qc; - diff --git a/cuneiform-dist/src/main/scripts/log4j.properties b/cuneiform-dist/src/main/scripts/log4j.properties deleted file mode 100644 index ad2b6d9..0000000 --- a/cuneiform-dist/src/main/scripts/log4j.properties +++ /dev/null @@ -1,15 +0,0 @@ -log4j.rootLogger=INFO, StdOut - -log4j.logger.statLogger=DEBUG, StatLog -log4j.additivity.statLogger=false - -log4j.appender.StdOut=org.apache.log4j.ConsoleAppender -log4j.appender.StdOut.layout=org.apache.log4j.PatternLayout -log4j.appender.StdOut.layout.ConversionPattern=%-5p %m%n - -log4j.appender.StatLog=org.apache.log4j.RollingFileAppender -log4j.appender.StatLog.File=/tmp/cuneiform-stat.log -log4j.appender.StatLog.MaxFileSize=100GB -log4j.appender.StatLog.MaxBackupIndex=1 -log4j.appender.StatLog.layout=org.apache.log4j.PatternLayout -log4j.appender.StatLog.layout.ConversionPattern=%m%n diff --git a/ebin/cf.app b/ebin/cf.app new file mode 100644 index 0000000..0643c3b --- /dev/null +++ b/ebin/cf.app @@ -0,0 +1,8 @@ +{application,cf, + [{description,"Cuneiform: A Functional Language for Large Scale Scientific Data Analysis"}, + {vsn,"2.2.0"}, + {registered,[]}, + {applications,[kernel,stdlib]}, + {mod,{cf_app,[]}}, + {env,[]}, + {modules,[cf,cf_lexer,cf_parser,cf_sup]}]}. diff --git a/ebin/cf.beam b/ebin/cf.beam new file mode 100644 index 0000000000000000000000000000000000000000..12a1f4e74231f5b13cf160d5fdb9c434b0bf9be8 GIT binary patch literal 1080 zcmYk5e@q-j6vtI{+ti}b1SM%rYfJ)jG3A?IfRl zv+sT9y*E3v?cF^O0pNrRKW(ce+W>6oS(5l7t2y(j)$d= zaZLF?&R~!M+f983t^+#M0HDEIo&qk=sD~ox?&886CIh8K`iae z0PtW-AR3aJ_#HZtNa_+FNSLOM&Awp;Kbb5o0jA&3$P1;hVDyXSt%2^(R&Kvs#{4ic z-4{w=Sq~}51V>k2+)Pk)#uSsTbvp{SPK`v`ODB#a7YhektkR@ILX8C>@S-O*1 z0wsK*pvWR`%1F!QaJ6KImd54{rwdd^_pMfg|vVN4n>ttaYJz zs3|%)HdguOlQ8G|v3T;}@mqu63Gs&yR&QCD{b}BQr~2gNg0y;V-&gSihhNMyUvCWD zd(W}M*HeM}qq^)%Ax{h59;pK@>Hzki|XTNDr1TJfp9Zyf}`l#v!xynR) z?hg6X+|12CVyRO$TGM>j%88LjU%PVsTzcftTN7)(Mf=abw6|jS*)ta|MRm72{eZ9c zYCX3UZ~W`?+;B@*X!nBrd>>o-`>V;t*87=Db5)HuKd$ZRteRb~CQny~Jf~~Ef3IO@ zU%d3dlD@2f->wbroEZA~nM1GlygfFP*|_>)ED-uL7JGJTv2uR@`@hb>r7v$B-w+>I z(H=iJ{y}zn`>FHN^qJ-H`n}N_`^wScPey+^vbkpQ_SH?}PnE4!$|ttiGl_8AKYUSo y<)YLw`dnepxp!|dQ@wLj0CdV4`9B*l{|<7u$(^PA-dgWEZ=E*;eE%N^4*U)O8bVh9 literal 0 HcmV?d00001 diff --git a/ebin/cf_lexer.beam b/ebin/cf_lexer.beam new file mode 100644 index 0000000000000000000000000000000000000000..a33378d46a3022f59e2a815e649fee7591f4322c GIT binary patch literal 68636 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 literal 0 HcmV?d00001 diff --git a/ebin/cf_parser.beam b/ebin/cf_parser.beam new file mode 100644 index 0000000000000000000000000000000000000000..6139fb87f009d1c83e1f1f669d54b9268264b503 GIT binary patch literal 42244 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

e;9(P)?hGlQi{X_lB!hThJ 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 VOLKEaXG`9<*z*5Rm48D_{U3+(`Ktf` literal 0 HcmV?d00001 diff --git a/ebin/cf_sup.beam b/ebin/cf_sup.beam new file mode 100644 index 0000000000000000000000000000000000000000..8f88d3a9a382974defa984858bbc1a5a96bb3bbb GIT binary patch literal 1144 zcmZ?s4>Dw6U@35Nb@X*C$l5mZoMW(Y1R3IUqU;F((hqBVe+8H$;pG#ij+2VzDb zhOwDkE5PbafMP5_%nFs~fUpgQc?t@YMOI^By$E+3IlUlaUO`nm?yv>>tO#~@ukxYk^YpB z`SW+#XMq&3C6<9yGa4Jg7ODR#XNdnPX`Kb;WrMgML7|YDlOG&i@ zY2i#t%}6ZE%r7kho1DUc6xmr>&YpQ`KnvG`-M|7;&z@gUl9``Z40jY;erZWcCeTin z)TGQjp#GH9q|$V7+5o9%%*)f@Ii=fi6o<&1TTl&&bbB)z8WY`Aa`NvqV3+G%qzXEx#yN zzqlw_AChSGfPTvYI@mF(xC9tZam@k1NV;D!CpX}<-(drRk~oKM7Ipz4p>{9b>2A7@ z`UD=G@OPPgW98c&Wm`9L$Dfm&?WCCJ|9bA+xi<~{HFvsHtY7d>*C~1R+r>&PJr#Z@ zIo7xaTAx-}sFL5BWb^ifYyVm2%VB$O>qu&OD7_O^RnK;woAhtvW7nQ+dxrF#2m9{q zuYJ_@@}zdtva(Mh?OMFm5Ay=6D;G|mV(ZRizHhZ;`&t7&P04ERw&;t}JssQcb=Kza z+?t^EFjFDgA-eJ*Uq{c6^7cP58HtJ$_bhm_rgYcFLm4yNoUE$^g|rK7n^#V;J|q2v zSA%u)2OGz2X7@6V8TU7vX3yYd=J~kSRp9iY4IAXf{F{k0Ra_x+#o{_fBGGy6}Uda-HJq$?%voc|khHWcQWtd44)x<0W$YfGwj zTY!_`*W{i1mrYUhdNCt2QE@-Rs$(~RDZ?i-50uBXffxor`3scq7=<{MIaN5d82C`5 GhXDZfG-b#D literal 0 HcmV?d00001 diff --git a/pom.xml b/pom.xml deleted file mode 100644 index b494ed1..0000000 --- a/pom.xml +++ /dev/null @@ -1,137 +0,0 @@ - - - - - - - 4.0.0 - de.hu-berlin.wbi.cuneiform - cuneiform - 2.0.4-SNAPSHOT - pom - cuneiform - A Functional Workflow Language. - -Cuneiform is a workflow specification language which makes it easy to integrate heterogeneous tools and libraries and exploit data parallelism. Users do not have to create heavy-weight wrappers for establised tools or to reimplement them. Instead, they apply their existing software to partitioned data. Using the Hi-WAY application master Cuneiform can be executed on Hadoop YARN which makes it suitable for large scale data analysis. - -Cuneiform comes in the form of a functional programming language with a Foreign Function Interface (FFI) that lets users create functions in any suitable scripting language and apply these functions in a uniform way. - -Data paralelism is expressed by applying map, cross-product, dot-product, or combinations of the aforementioned algorithmic skeletons to collections of black-box data. - https://github.com/joergen7/cuneiform - - - Apache License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - repo - - - - https://github.com/joergen7/cuneiform.git - - - - - Jörgen Brandt - brandjoe@informatik.hu-berlin.de - Humboldt-Universität zu Berlin - https://www.hu-berlin.de/ - - - Marc Bux - buxmarcn@informatik.hu-berlin.de - Humboldt-Universität zu Berlin - https://www.hu-berlin.de/ - - - Ulf Leser - leser@informatik.hu-berlin.de - Humboldt-Universität zu Berlin - https://www.hu-berlin.de/ - - - - - - ossrh - https://oss.sonatype.org/content/repositories/snapshots/ - - - ossrh - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - - - - UTF-8 - - - - cuneiform-core - cuneiform-addons - cuneiform-dist - cuneiform-cmdline - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.2 - - 1.7 - 1.7 - - - - - - - - - release-sign-artifacts - - - performRelease - true - - - - - - org.apache.maven.plugins - maven-gpg-plugin - 1.5 - - - sign-artifacts - verify - - sign - - - - - - - - - \ No newline at end of file diff --git a/rebar.config b/rebar.config new file mode 100644 index 0000000..4483aa9 --- /dev/null +++ b/rebar.config @@ -0,0 +1 @@ +{cover_enabled, true}. diff --git a/src/cf.app.src b/src/cf.app.src new file mode 100644 index 0000000..f8c3e2a --- /dev/null +++ b/src/cf.app.src @@ -0,0 +1,12 @@ +{application, cf, + [ + {description, "Cuneiform: A Functional Language for Large Scale Scientific Data Analysis"}, + {vsn, "2.2.0"}, + {registered, []}, + {applications, [ + kernel, + stdlib + ]}, + {mod, { cf_app, []}}, + {env, []} + ]}. diff --git a/src/cf.erl b/src/cf.erl new file mode 100644 index 0000000..77700a3 --- /dev/null +++ b/src/cf.erl @@ -0,0 +1,47 @@ +%% -*- erlang -*- +% +% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis +% +% Copyright 2013 Jörgen Brandt, Marc Bux, and Ulf Leser +% +% Licensed under the Apache License, Version 2.0 (the "License"); +% you may not use this file except in compliance with the License. +% You may obtain a copy of the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, +% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +% See the License for the specific language governing permissions and +% limitations under the License. + +-module( cf ). +-author( "Jörgen Brandt " ). + +-behaviour( application ). + +% Application +-export( [start/2, stop/1] ). + +% API +-export( [start/0] ). + +%% ============================================================================= +%% Application callbacks +%% ============================================================================= + +start( local, [] ) -> + cf_sup:start_link(). + +stop( _State ) -> + ok. + +%% ============================================================================= +%% API functions +%% ============================================================================= + +start() -> + start( local, [] ). + + diff --git a/src/cf_lexer.erl b/src/cf_lexer.erl new file mode 100644 index 0000000..a3ff2ae --- /dev/null +++ b/src/cf_lexer.erl @@ -0,0 +1,1749 @@ +-file("/usr/local/lib/erlang/lib/parsetools-2.1.1/include/leexinc.hrl", 0). +%% The source of this file is part of leex distribution, as such it +%% has the same Copyright as the other files in the leex +%% distribution. The Copyright is defined in the accompanying file +%% COPYRIGHT. However, the resultant scanner generated by leex is the +%% property of the creator of the scanner and is not covered by that +%% Copyright. + +-module(cf_lexer). + +-export([string/1,string/2,token/2,token/3,tokens/2,tokens/3]). +-export([format_error/1]). + +%% User code. This is placed here to allow extra attributes. +-file("src/cf_lexer.xrl", 103). + +-author( "Jörgen Brandt " ). + +-export( [yyrev/2] ). + +-ifdef( TEST ). +-include_lib( "eunit/include/eunit.hrl" ). +-endif. + +trim_body( S ) -> + string:substr( S, 3, length( S )-4 ). + +trim_strlit( S ) -> + string:substr( S, 2, length( S )-2 ). + + +-ifdef( TEST ). + + +% TEST INDEX + +token_test_() -> [ + bash_style_comment_should_be_recognized(), + c_style_comment_should_be_recognized(), + erlang_style_comment_should_be_recognized(), + multiline_comment_should_be_recognized(), + apply_should_be_recognized(), + bash_should_be_recognized(), + beginif_should_be_recognized(), + colon_should_be_recognized(), + comb_should_be_recognized(), + deftask_should_be_recognized(), + else_should_be_recognized(), + endif_should_be_recognized(), + eq_should_be_recognized(), + file_should_be_recognized(), + in_should_be_recognized(), + id_should_be_recognized(), + lisp_should_be_recognized(), + matlab_should_be_recognized(), + octave_should_be_recognized(), + perl_should_be_recognized(), + python_should_be_recognized(), + r_should_be_recognized(), + lbrace_should_be_recognized(), + lparen_should_be_recognized(), + lsquarebr_should_be_recognized(), + ltag_should_be_recognized(), + nil_should_be_recognized(), + noreplace_should_be_recognized(), + rbrace_should_be_recognized(), + rparen_should_be_recognized(), + rsquarebr_should_be_recognized(), + rtag_should_be_recognized(), + semicolon_should_be_recognized(), + string_should_be_recognized(), + task_should_be_recognized(), + then_should_be_recognized(), + intlit_should_be_recognized(), + body_should_be_recognized(), + strlit_should_be_recognized() + ]. + + + + +% ACTUAL TEST IMPLEMENTATION + +bash_style_comment_should_be_recognized() -> + ?_assertEqual( {ok, [], 1}, string( "#this is a comment" ) ). + +c_style_comment_should_be_recognized() -> + ?_assertEqual( {ok, [], 1}, string( "//this is a comment" ) ). + +erlang_style_comment_should_be_recognized() -> + ?_assertEqual( {ok, [], 1}, string( "%this is a comment" ) ). + + +multiline_comment_should_be_recognized() -> + [?_assertEqual( {ok, [], 1}, string( "/**/" ) ), + ?_assertEqual( {ok, [], 1}, string( "/*x*/" ) ), + ?_assertEqual( {ok, [], 1}, string( "/*xy*/" ) ), + ?_assertEqual( {ok, [], 2}, string( "/*x\ny*/" ) )]. + +apply_should_be_recognized() -> + ?_assertEqual( {ok, [{apply, 1, "apply"}], 1}, string( "apply" ) ). + +bash_should_be_recognized() -> + ?_assertEqual( {ok, [{bash, 1, "bash"}], 1}, string( "bash" ) ). + +beginif_should_be_recognized() -> + ?_assertEqual( {ok, [{beginif, 1, "if"}], 1}, string( "if" ) ). + +colon_should_be_recognized() -> + ?_assertEqual( {ok, [{colon, 1, ":"}], 1}, string( ":" ) ). + +comb_should_be_recognized() -> + ?_assertEqual( {ok, [{comb, 1, "comb"}], 1}, string( "comb" ) ). + +deftask_should_be_recognized() -> + ?_assertEqual( {ok, [{deftask, 1, "deftask"}], 1}, string( "deftask" ) ). + +else_should_be_recognized() -> + ?_assertEqual( {ok, [{else, 1, "else"}], 1}, string( "else" ) ). + +endif_should_be_recognized() -> + ?_assertEqual( {ok, [{endif, 1, "end"}], 1}, string( "end" ) ). + +eq_should_be_recognized() -> + ?_assertEqual( {ok, [{eq, 1, "="}], 1}, string( "=" ) ). + +file_should_be_recognized() -> + ?_assertEqual( {ok, [{file, 1, "File"}], 1}, string( "File" ) ). + +in_should_be_recognized() -> + ?_assertEqual( {ok, [{in, 1, "in"}], 1}, string( "in" ) ). + +id_should_be_recognized() -> + [?_assertEqual( {ok, [{id, 1, "inp"}], 1}, string( "inp" ) ), + ?_assertEqual( {ok, [{id, 1, "a0"}], 1}, string( "a0" ) ), + ?_assertEqual( {ok, [{id, 1, "a9"}], 1}, string( "a9" ) ), + ?_assertEqual( {ok, [{id, 1, "a."}], 1}, string( "a." ) ), + ?_assertEqual( {ok, [{id, 1, "a-"}], 1}, string( "a-" ) ), + ?_assertEqual( {ok, [{id, 1, "a_"}], 1}, string( "a_" ) ), + ?_assertEqual( {ok, [{id, 1, "a+"}], 1}, string( "a+" ) ), + ?_assertEqual( {ok, [{id, 1, "a*"}], 1}, string( "a*" ) ), + ?_assertEqual( {ok, [{id, 1, "a/"}], 1}, string( "a/" ) )]. + +lisp_should_be_recognized() -> + ?_assertEqual( {ok, [{lisp, 1, "lisp"}], 1}, string( "lisp" ) ). + +matlab_should_be_recognized() -> + ?_assertEqual( {ok, [{matlab, 1, "matlab"}], 1}, string( "matlab" ) ). + +octave_should_be_recognized() -> + ?_assertEqual( {ok, [{octave, 1, "octave"}], 1}, string( "octave" ) ). + +perl_should_be_recognized() -> + ?_assertEqual( {ok, [{perl, 1, "perl"}], 1}, string( "perl" ) ). + +python_should_be_recognized() -> + ?_assertEqual( {ok, [{python, 1, "python"}], 1}, string( "python" ) ). + +r_should_be_recognized() -> + [?_assertEqual( {ok, [{r, 1, "r"}], 1}, string( "r" ) ), + ?_assertEqual( {ok, [{r, 1, "R"}], 1}, string( "R" ) )]. + +lbrace_should_be_recognized() -> + ?_assertEqual( {ok, [{lbrace, 1, "{"}], 1}, string( "{" ) ). + +lparen_should_be_recognized() -> + ?_assertEqual( {ok, [{lparen, 1, "("}], 1}, string( "(" ) ). + +lsquarebr_should_be_recognized() -> + ?_assertEqual( {ok, [{lsquarebr, 1, "["}], 1}, string( "[" ) ). + +ltag_should_be_recognized() -> + ?_assertEqual( {ok, [{ltag, 1, "<"}], 1}, string( "<" ) ). + +nil_should_be_recognized() -> + ?_assertEqual( {ok, [{nil, 1, "nil"}], 1}, string( "nil" ) ). + +noreplace_should_be_recognized() -> + ?_assertEqual( {ok, [{noreplace, 1, "noreplace"}], 1}, + string( "noreplace" ) ). + +rbrace_should_be_recognized() -> + ?_assertEqual( {ok, [{rbrace, 1, "}"}], 1}, string( "}" ) ). + +rparen_should_be_recognized() -> + ?_assertEqual( {ok, [{rparen, 1, ")"}], 1}, string( ")" ) ). + +rsquarebr_should_be_recognized() -> + ?_assertEqual( {ok, [{rsquarebr, 1, "]"}], 1}, string( "]" ) ). + +rtag_should_be_recognized() -> + ?_assertEqual( {ok, [{rtag, 1, ">"}], 1}, string( ">" ) ). + +semicolon_should_be_recognized() -> + ?_assertEqual( {ok, [{semicolon, 1, ";"}], 1}, string( ";" ) ). + +string_should_be_recognized() -> + ?_assertEqual( {ok, [{string, 1, "String"}], 1}, string( "String" ) ). + +task_should_be_recognized() -> + ?_assertEqual( {ok, [{task, 1, "task"}], 1}, string( "task" ) ). + +then_should_be_recognized() -> + ?_assertEqual( {ok, [{then, 1, "then"}], 1}, string( "then" ) ). + +intlit_should_be_recognized() -> + [?_assertEqual( {ok, [{intlit, 1, "10"}], 1}, string( "10" ) ), + ?_assertEqual( {ok, [{intlit, 1, "-10"}], 1}, string( "-10" ) ), + ?_assertEqual( {ok, [{intlit, 1, "9"}], 1}, string( "9" ) ), + ?_assertEqual( {ok, [{intlit, 1, "0"}], 1}, string( "0" ) )]. + +body_should_be_recognized() -> + [?_assertEqual( {ok, [{body, 1, ""}], 1}, string( "*{}*" ) ), + ?_assertEqual( {ok, [{body, 1, "x"}], 1}, string( "*{x}*" ) ), + ?_assertEqual( {ok, [{body, 1, "xy"}], 1}, string( "*{xy}*" ) ), + ?_assertEqual( {ok, [{body, 1, "x\ny"}], 2}, string( "*{x\ny}*" ) )]. + +strlit_should_be_recognized() -> + [?_assertEqual( {ok, [{strlit, 1, ""}], 1}, string( "''" ) ), + ?_assertEqual( {ok, [{strlit, 1, ""}], 1}, string( "\"\"" ) ), + ?_assertEqual( {ok, [{strlit, 1, "x"}], 1}, string( "'x'" ) ), + ?_assertEqual( {ok, [{strlit, 1, "x"}], 1}, string( "\"x\"" ) ), + ?_assertEqual( {ok, [{strlit, 1, "xy"}], 1}, string( "'xy'" ) ), + ?_assertEqual( {ok, [{strlit, 1, "xy"}], 1}, string( "\"xy\"" ) )]. + + + + + +-endif. + + + +-file("/usr/local/lib/erlang/lib/parsetools-2.1.1/include/leexinc.hrl", 14). + +format_error({illegal,S}) -> ["illegal characters ",io_lib:write_string(S)]; +format_error({user,S}) -> S. + +string(String) -> string(String, 1). + +string(String, Line) -> string(String, Line, String, []). + +%% string(InChars, Line, TokenChars, Tokens) -> +%% {ok,Tokens,Line} | {error,ErrorInfo,Line}. +%% Note the line number going into yystate, L0, is line of token +%% start while line number returned is line of token end. We want line +%% of token start. + +string([], L, [], Ts) -> % No partial tokens! + {ok,yyrev(Ts),L}; +string(Ics0, L0, Tcs, Ts) -> + case yystate(yystate(), Ics0, L0, 0, reject, 0) of + {A,Alen,Ics1,L1} -> % Accepting end state + string_cont(Ics1, L1, yyaction(A, Alen, Tcs, L0), Ts); + {A,Alen,Ics1,L1,_S1} -> % Accepting transistion state + string_cont(Ics1, L1, yyaction(A, Alen, Tcs, L0), Ts); + {reject,_Alen,Tlen,_Ics1,L1,_S1} -> % After a non-accepting state + {error,{L0,?MODULE,{illegal,yypre(Tcs, Tlen+1)}},L1}; + {A,Alen,_Tlen,_Ics1,_L1,_S1} -> + string_cont(yysuf(Tcs, Alen), L0, yyaction(A, Alen, Tcs, L0), Ts) + end. + +%% string_cont(RestChars, Line, Token, Tokens) +%% Test for and remove the end token wrapper. Push back characters +%% are prepended to RestChars. + +-dialyzer({nowarn_function, string_cont/4}). + +string_cont(Rest, Line, {token,T}, Ts) -> + string(Rest, Line, Rest, [T|Ts]); +string_cont(Rest, Line, {token,T,Push}, Ts) -> + NewRest = Push ++ Rest, + string(NewRest, Line, NewRest, [T|Ts]); +string_cont(Rest, Line, {end_token,T}, Ts) -> + string(Rest, Line, Rest, [T|Ts]); +string_cont(Rest, Line, {end_token,T,Push}, Ts) -> + NewRest = Push ++ Rest, + string(NewRest, Line, NewRest, [T|Ts]); +string_cont(Rest, Line, skip_token, Ts) -> + string(Rest, Line, Rest, Ts); +string_cont(Rest, Line, {skip_token,Push}, Ts) -> + NewRest = Push ++ Rest, + string(NewRest, Line, NewRest, Ts); +string_cont(_Rest, Line, {error,S}, _Ts) -> + {error,{Line,?MODULE,{user,S}},Line}. + +%% token(Continuation, Chars) -> +%% token(Continuation, Chars, Line) -> +%% {more,Continuation} | {done,ReturnVal,RestChars}. +%% Must be careful when re-entering to append the latest characters to the +%% after characters in an accept. The continuation is: +%% {token,State,CurrLine,TokenChars,TokenLen,TokenLine,AccAction,AccLen} + +token(Cont, Chars) -> token(Cont, Chars, 1). + +token([], Chars, Line) -> + token(yystate(), Chars, Line, Chars, 0, Line, reject, 0); +token({token,State,Line,Tcs,Tlen,Tline,Action,Alen}, Chars, _) -> + token(State, Chars, Line, Tcs ++ Chars, Tlen, Tline, Action, Alen). + +%% token(State, InChars, Line, TokenChars, TokenLen, TokenLine, +%% AcceptAction, AcceptLen) -> +%% {more,Continuation} | {done,ReturnVal,RestChars}. +%% The argument order is chosen to be more efficient. + +token(S0, Ics0, L0, Tcs, Tlen0, Tline, A0, Alen0) -> + case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of + %% Accepting end state, we have a token. + {A1,Alen1,Ics1,L1} -> + token_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline)); + %% Accepting transition state, can take more chars. + {A1,Alen1,[],L1,S1} -> % Need more chars to check + {more,{token,S1,L1,Tcs,Alen1,Tline,A1,Alen1}}; + {A1,Alen1,Ics1,L1,_S1} -> % Take what we got + token_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline)); + %% After a non-accepting state, maybe reach accept state later. + {A1,Alen1,Tlen1,[],L1,S1} -> % Need more chars to check + {more,{token,S1,L1,Tcs,Tlen1,Tline,A1,Alen1}}; + {reject,_Alen1,Tlen1,eof,L1,_S1} -> % No token match + %% Check for partial token which is error. + Ret = if Tlen1 > 0 -> {error,{Tline,?MODULE, + %% Skip eof tail in Tcs. + {illegal,yypre(Tcs, Tlen1)}},L1}; + true -> {eof,L1} + end, + {done,Ret,eof}; + {reject,_Alen1,Tlen1,Ics1,L1,_S1} -> % No token match + Error = {Tline,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}}, + {done,{error,Error,L1},Ics1}; + {A1,Alen1,_Tlen1,_Ics1,_L1,_S1} -> % Use last accept match + token_cont(yysuf(Tcs, Alen1), L0, yyaction(A1, Alen1, Tcs, Tline)) + end. + +%% token_cont(RestChars, Line, Token) +%% If we have a token or error then return done, else if we have a +%% skip_token then continue. + +-dialyzer({nowarn_function, token_cont/3}). + +token_cont(Rest, Line, {token,T}) -> + {done,{ok,T,Line},Rest}; +token_cont(Rest, Line, {token,T,Push}) -> + NewRest = Push ++ Rest, + {done,{ok,T,Line},NewRest}; +token_cont(Rest, Line, {end_token,T}) -> + {done,{ok,T,Line},Rest}; +token_cont(Rest, Line, {end_token,T,Push}) -> + NewRest = Push ++ Rest, + {done,{ok,T,Line},NewRest}; +token_cont(Rest, Line, skip_token) -> + token(yystate(), Rest, Line, Rest, 0, Line, reject, 0); +token_cont(Rest, Line, {skip_token,Push}) -> + NewRest = Push ++ Rest, + token(yystate(), NewRest, Line, NewRest, 0, Line, reject, 0); +token_cont(Rest, Line, {error,S}) -> + {done,{error,{Line,?MODULE,{user,S}},Line},Rest}. + +%% tokens(Continuation, Chars, Line) -> +%% {more,Continuation} | {done,ReturnVal,RestChars}. +%% Must be careful when re-entering to append the latest characters to the +%% after characters in an accept. The continuation is: +%% {tokens,State,CurrLine,TokenChars,TokenLen,TokenLine,Tokens,AccAction,AccLen} +%% {skip_tokens,State,CurrLine,TokenChars,TokenLen,TokenLine,Error,AccAction,AccLen} + +tokens(Cont, Chars) -> tokens(Cont, Chars, 1). + +tokens([], Chars, Line) -> + tokens(yystate(), Chars, Line, Chars, 0, Line, [], reject, 0); +tokens({tokens,State,Line,Tcs,Tlen,Tline,Ts,Action,Alen}, Chars, _) -> + tokens(State, Chars, Line, Tcs ++ Chars, Tlen, Tline, Ts, Action, Alen); +tokens({skip_tokens,State,Line,Tcs,Tlen,Tline,Error,Action,Alen}, Chars, _) -> + skip_tokens(State, Chars, Line, Tcs ++ Chars, Tlen, Tline, Error, Action, Alen). + +%% tokens(State, InChars, Line, TokenChars, TokenLen, TokenLine, Tokens, +%% AcceptAction, AcceptLen) -> +%% {more,Continuation} | {done,ReturnVal,RestChars}. + +tokens(S0, Ics0, L0, Tcs, Tlen0, Tline, Ts, A0, Alen0) -> + case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of + %% Accepting end state, we have a token. + {A1,Alen1,Ics1,L1} -> + tokens_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Ts); + %% Accepting transition state, can take more chars. + {A1,Alen1,[],L1,S1} -> % Need more chars to check + {more,{tokens,S1,L1,Tcs,Alen1,Tline,Ts,A1,Alen1}}; + {A1,Alen1,Ics1,L1,_S1} -> % Take what we got + tokens_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Ts); + %% After a non-accepting state, maybe reach accept state later. + {A1,Alen1,Tlen1,[],L1,S1} -> % Need more chars to check + {more,{tokens,S1,L1,Tcs,Tlen1,Tline,Ts,A1,Alen1}}; + {reject,_Alen1,Tlen1,eof,L1,_S1} -> % No token match + %% Check for partial token which is error, no need to skip here. + Ret = if Tlen1 > 0 -> {error,{Tline,?MODULE, + %% Skip eof tail in Tcs. + {illegal,yypre(Tcs, Tlen1)}},L1}; + Ts == [] -> {eof,L1}; + true -> {ok,yyrev(Ts),L1} + end, + {done,Ret,eof}; + {reject,_Alen1,Tlen1,_Ics1,L1,_S1} -> + %% Skip rest of tokens. + Error = {L1,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}}, + skip_tokens(yysuf(Tcs, Tlen1+1), L1, Error); + {A1,Alen1,_Tlen1,_Ics1,_L1,_S1} -> + Token = yyaction(A1, Alen1, Tcs, Tline), + tokens_cont(yysuf(Tcs, Alen1), L0, Token, Ts) + end. + +%% tokens_cont(RestChars, Line, Token, Tokens) +%% If we have an end_token or error then return done, else if we have +%% a token then save it and continue, else if we have a skip_token +%% just continue. + +-dialyzer({nowarn_function, tokens_cont/4}). + +tokens_cont(Rest, Line, {token,T}, Ts) -> + tokens(yystate(), Rest, Line, Rest, 0, Line, [T|Ts], reject, 0); +tokens_cont(Rest, Line, {token,T,Push}, Ts) -> + NewRest = Push ++ Rest, + tokens(yystate(), NewRest, Line, NewRest, 0, Line, [T|Ts], reject, 0); +tokens_cont(Rest, Line, {end_token,T}, Ts) -> + {done,{ok,yyrev(Ts, [T]),Line},Rest}; +tokens_cont(Rest, Line, {end_token,T,Push}, Ts) -> + NewRest = Push ++ Rest, + {done,{ok,yyrev(Ts, [T]),Line},NewRest}; +tokens_cont(Rest, Line, skip_token, Ts) -> + tokens(yystate(), Rest, Line, Rest, 0, Line, Ts, reject, 0); +tokens_cont(Rest, Line, {skip_token,Push}, Ts) -> + NewRest = Push ++ Rest, + tokens(yystate(), NewRest, Line, NewRest, 0, Line, Ts, reject, 0); +tokens_cont(Rest, Line, {error,S}, _Ts) -> + skip_tokens(Rest, Line, {Line,?MODULE,{user,S}}). + +%%skip_tokens(InChars, Line, Error) -> {done,{error,Error,Line},Ics}. +%% Skip tokens until an end token, junk everything and return the error. + +skip_tokens(Ics, Line, Error) -> + skip_tokens(yystate(), Ics, Line, Ics, 0, Line, Error, reject, 0). + +%% skip_tokens(State, InChars, Line, TokenChars, TokenLen, TokenLine, Tokens, +%% AcceptAction, AcceptLen) -> +%% {more,Continuation} | {done,ReturnVal,RestChars}. + +skip_tokens(S0, Ics0, L0, Tcs, Tlen0, Tline, Error, A0, Alen0) -> + case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of + {A1,Alen1,Ics1,L1} -> % Accepting end state + skip_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Error); + {A1,Alen1,[],L1,S1} -> % After an accepting state + {more,{skip_tokens,S1,L1,Tcs,Alen1,Tline,Error,A1,Alen1}}; + {A1,Alen1,Ics1,L1,_S1} -> + skip_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Error); + {A1,Alen1,Tlen1,[],L1,S1} -> % After a non-accepting state + {more,{skip_tokens,S1,L1,Tcs,Tlen1,Tline,Error,A1,Alen1}}; + {reject,_Alen1,_Tlen1,eof,L1,_S1} -> + {done,{error,Error,L1},eof}; + {reject,_Alen1,Tlen1,_Ics1,L1,_S1} -> + skip_tokens(yysuf(Tcs, Tlen1+1), L1, Error); + {A1,Alen1,_Tlen1,_Ics1,L1,_S1} -> + Token = yyaction(A1, Alen1, Tcs, Tline), + skip_cont(yysuf(Tcs, Alen1), L1, Token, Error) + end. + +%% skip_cont(RestChars, Line, Token, Error) +%% Skip tokens until we have an end_token or error then return done +%% with the original rror. + +-dialyzer({nowarn_function, skip_cont/4}). + +skip_cont(Rest, Line, {token,_T}, Error) -> + skip_tokens(yystate(), Rest, Line, Rest, 0, Line, Error, reject, 0); +skip_cont(Rest, Line, {token,_T,Push}, Error) -> + NewRest = Push ++ Rest, + skip_tokens(yystate(), NewRest, Line, NewRest, 0, Line, Error, reject, 0); +skip_cont(Rest, Line, {end_token,_T}, Error) -> + {done,{error,Error,Line},Rest}; +skip_cont(Rest, Line, {end_token,_T,Push}, Error) -> + NewRest = Push ++ Rest, + {done,{error,Error,Line},NewRest}; +skip_cont(Rest, Line, skip_token, Error) -> + skip_tokens(yystate(), Rest, Line, Rest, 0, Line, Error, reject, 0); +skip_cont(Rest, Line, {skip_token,Push}, Error) -> + NewRest = Push ++ Rest, + skip_tokens(yystate(), NewRest, Line, NewRest, 0, Line, Error, reject, 0); +skip_cont(Rest, Line, {error,_S}, Error) -> + skip_tokens(yystate(), Rest, Line, Rest, 0, Line, Error, reject, 0). + +yyrev(List) -> lists:reverse(List). +yyrev(List, Tail) -> lists:reverse(List, Tail). +yypre(List, N) -> lists:sublist(List, N). +yysuf(List, N) -> lists:nthtail(N, List). + +%% yystate() -> InitialState. +%% yystate(State, InChars, Line, CurrTokLen, AcceptAction, AcceptLen) -> +%% {Action, AcceptLen, RestChars, Line} | +%% {Action, AcceptLen, RestChars, Line, State} | +%% {reject, AcceptLen, CurrTokLen, RestChars, Line, State} | +%% {Action, AcceptLen, CurrTokLen, RestChars, Line, State}. +%% Generated state transition functions. The non-accepting end state +%% return signal either an unrecognised character or end of current +%% input. + +-file("src/cf_lexer.erl", 501). +yystate() -> 69. + +yystate(72, [122|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(72, [121|Ics], Line, Tlen, _, _) -> + yystate(68, Ics, Line, Tlen+1, 27, Tlen); +yystate(72, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(72, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(72, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(72, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(72, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(72, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 120 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(72, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,72}; +yystate(71, Ics, Line, Tlen, _, _) -> + {30,Tlen,Ics,Line}; +yystate(70, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 2, Tlen); +yystate(70, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 2, Tlen); +yystate(70, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 2, Tlen); +yystate(70, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 2, Tlen); +yystate(70, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 2, Tlen); +yystate(70, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 2, Tlen); +yystate(70, Ics, Line, Tlen, _, _) -> + {2,Tlen,Ics,Line,70}; +yystate(69, [125|Ics], Line, Tlen, Action, Alen) -> + yystate(65, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [123|Ics], Line, Tlen, Action, Alen) -> + yystate(61, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [116|Ics], Line, Tlen, Action, Alen) -> + yystate(57, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [115|Ics], Line, Tlen, Action, Alen) -> + yystate(41, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [114|Ics], Line, Tlen, Action, Alen) -> + yystate(70, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [113|Ics], Line, Tlen, Action, Alen) -> + yystate(41, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [112|Ics], Line, Tlen, Action, Alen) -> + yystate(72, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [111|Ics], Line, Tlen, Action, Alen) -> + yystate(41, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [110|Ics], Line, Tlen, Action, Alen) -> + yystate(37, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [105|Ics], Line, Tlen, Action, Alen) -> + yystate(25, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [101|Ics], Line, Tlen, Action, Alen) -> + yystate(13, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [100|Ics], Line, Tlen, Action, Alen) -> + yystate(10, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [99|Ics], Line, Tlen, Action, Alen) -> + yystate(41, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [98|Ics], Line, Tlen, Action, Alen) -> + yystate(32, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [97|Ics], Line, Tlen, Action, Alen) -> + yystate(41, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [93|Ics], Line, Tlen, Action, Alen) -> + yystate(38, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [91|Ics], Line, Tlen, Action, Alen) -> + yystate(42, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [83|Ics], Line, Tlen, Action, Alen) -> + yystate(46, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [82|Ics], Line, Tlen, Action, Alen) -> + yystate(70, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [81|Ics], Line, Tlen, Action, Alen) -> + yystate(41, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [80|Ics], Line, Tlen, Action, Alen) -> + yystate(72, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [70|Ics], Line, Tlen, Action, Alen) -> + yystate(48, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [66|Ics], Line, Tlen, Action, Alen) -> + yystate(32, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [65|Ics], Line, Tlen, Action, Alen) -> + yystate(41, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [62|Ics], Line, Tlen, Action, Alen) -> + yystate(16, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [61|Ics], Line, Tlen, Action, Alen) -> + yystate(12, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [60|Ics], Line, Tlen, Action, Alen) -> + yystate(8, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [59|Ics], Line, Tlen, Action, Alen) -> + yystate(4, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [58|Ics], Line, Tlen, Action, Alen) -> + yystate(0, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [48|Ics], Line, Tlen, Action, Alen) -> + yystate(7, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [47|Ics], Line, Tlen, Action, Alen) -> + yystate(11, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [45|Ics], Line, Tlen, Action, Alen) -> + yystate(27, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [44|Ics], Line, Tlen, Action, Alen) -> + yystate(31, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [42|Ics], Line, Tlen, Action, Alen) -> + yystate(35, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [41|Ics], Line, Tlen, Action, Alen) -> + yystate(51, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [40|Ics], Line, Tlen, Action, Alen) -> + yystate(55, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [37|Ics], Line, Tlen, Action, Alen) -> + yystate(59, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [35|Ics], Line, Tlen, Action, Alen) -> + yystate(59, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [34|Ics], Line, Tlen, Action, Alen) -> + yystate(67, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [10|Ics], Line, Tlen, Action, Alen) -> + yystate(71, Ics, Line+1, Tlen+1, Action, Alen); +yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 0, C =< 9 -> + yystate(71, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 11, C =< 32 -> + yystate(71, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 49, C =< 57 -> + yystate(3, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 67, C =< 69 -> + yystate(41, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 71, C =< 79 -> + yystate(41, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 84, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 102, C =< 104 -> + yystate(41, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 106, C =< 109 -> + yystate(41, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 117, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, Action, Alen); +yystate(69, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,69}; +yystate(68, [116|Ics], Line, Tlen, _, _) -> + yystate(64, Ics, Line, Tlen+1, 27, Tlen); +yystate(68, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(68, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(68, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(68, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(68, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(68, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 115 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(68, [C|Ics], Line, Tlen, _, _) when C >= 117, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(68, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,68}; +yystate(67, [34|Ics], Line, Tlen, Action, Alen) -> + yystate(63, Ics, Line, Tlen+1, Action, Alen); +yystate(67, [10|Ics], Line, Tlen, Action, Alen) -> + yystate(67, Ics, Line+1, Tlen+1, Action, Alen); +yystate(67, [C|Ics], Line, Tlen, Action, Alen) when C >= 0, C =< 9 -> + yystate(67, Ics, Line, Tlen+1, Action, Alen); +yystate(67, [C|Ics], Line, Tlen, Action, Alen) when C >= 11, C =< 33 -> + yystate(67, Ics, Line, Tlen+1, Action, Alen); +yystate(67, [C|Ics], Line, Tlen, Action, Alen) when C >= 35 -> + yystate(67, Ics, Line, Tlen+1, Action, Alen); +yystate(67, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,67}; +yystate(66, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 25, Tlen); +yystate(66, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 25, Tlen); +yystate(66, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 25, Tlen); +yystate(66, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 25, Tlen); +yystate(66, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 25, Tlen); +yystate(66, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 25, Tlen); +yystate(66, Ics, Line, Tlen, _, _) -> + {25,Tlen,Ics,Line,66}; +yystate(65, Ics, Line, Tlen, _, _) -> + {20,Tlen,Ics,Line}; +yystate(64, [104|Ics], Line, Tlen, _, _) -> + yystate(60, Ics, Line, Tlen+1, 27, Tlen); +yystate(64, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(64, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(64, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(64, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(64, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(64, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 103 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(64, [C|Ics], Line, Tlen, _, _) when C >= 105, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(64, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,64}; +yystate(63, Ics, Line, Tlen, _, _) -> + {4,Tlen,Ics,Line}; +yystate(62, [103|Ics], Line, Tlen, _, _) -> + yystate(66, Ics, Line, Tlen+1, 27, Tlen); +yystate(62, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(62, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(62, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(62, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(62, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(62, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 102 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(62, [C|Ics], Line, Tlen, _, _) when C >= 104, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(62, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,62}; +yystate(61, Ics, Line, Tlen, _, _) -> + {15,Tlen,Ics,Line}; +yystate(60, [111|Ics], Line, Tlen, _, _) -> + yystate(56, Ics, Line, Tlen+1, 27, Tlen); +yystate(60, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(60, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(60, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(60, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(60, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(60, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 110 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(60, [C|Ics], Line, Tlen, _, _) when C >= 112, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(60, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,60}; +yystate(59, [C|Ics], Line, Tlen, _, _) when C >= 0, C =< 9 -> + yystate(59, Ics, Line, Tlen+1, 28, Tlen); +yystate(59, [C|Ics], Line, Tlen, _, _) when C >= 11 -> + yystate(59, Ics, Line, Tlen+1, 28, Tlen); +yystate(59, Ics, Line, Tlen, _, _) -> + {28,Tlen,Ics,Line,59}; +yystate(58, [110|Ics], Line, Tlen, _, _) -> + yystate(62, Ics, Line, Tlen+1, 27, Tlen); +yystate(58, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(58, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(58, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(58, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(58, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(58, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 109 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(58, [C|Ics], Line, Tlen, _, _) when C >= 111, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(58, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,58}; +yystate(57, [104|Ics], Line, Tlen, _, _) -> + yystate(53, Ics, Line, Tlen+1, 27, Tlen); +yystate(57, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(57, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(57, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(57, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(57, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(57, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 103 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(57, [C|Ics], Line, Tlen, _, _) when C >= 105, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(57, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,57}; +yystate(56, [110|Ics], Line, Tlen, _, _) -> + yystate(52, Ics, Line, Tlen+1, 27, Tlen); +yystate(56, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(56, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(56, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(56, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(56, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(56, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 109 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(56, [C|Ics], Line, Tlen, _, _) when C >= 111, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(56, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,56}; +yystate(55, Ics, Line, Tlen, _, _) -> + {16,Tlen,Ics,Line}; +yystate(54, [105|Ics], Line, Tlen, _, _) -> + yystate(58, Ics, Line, Tlen+1, 27, Tlen); +yystate(54, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(54, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(54, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(54, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(54, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(54, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 104 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(54, [C|Ics], Line, Tlen, _, _) when C >= 106, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(54, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,54}; +yystate(53, [101|Ics], Line, Tlen, _, _) -> + yystate(49, Ics, Line, Tlen+1, 27, Tlen); +yystate(53, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(53, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(53, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(53, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(53, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(53, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 100 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(53, [C|Ics], Line, Tlen, _, _) when C >= 102, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(53, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,53}; +yystate(52, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 1, Tlen); +yystate(52, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 1, Tlen); +yystate(52, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 1, Tlen); +yystate(52, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 1, Tlen); +yystate(52, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 1, Tlen); +yystate(52, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 1, Tlen); +yystate(52, Ics, Line, Tlen, _, _) -> + {1,Tlen,Ics,Line,52}; +yystate(51, Ics, Line, Tlen, _, _) -> + {21,Tlen,Ics,Line}; +yystate(50, [114|Ics], Line, Tlen, _, _) -> + yystate(54, Ics, Line, Tlen+1, 27, Tlen); +yystate(50, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(50, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(50, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(50, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(50, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(50, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 113 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(50, [C|Ics], Line, Tlen, _, _) when C >= 115, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(50, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,50}; +yystate(49, [110|Ics], Line, Tlen, _, _) -> + yystate(45, Ics, Line, Tlen+1, 27, Tlen); +yystate(49, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(49, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(49, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(49, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(49, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(49, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 109 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(49, [C|Ics], Line, Tlen, _, _) when C >= 111, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(49, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,49}; +yystate(48, [105|Ics], Line, Tlen, _, _) -> + yystate(44, Ics, Line, Tlen+1, 27, Tlen); +yystate(48, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(48, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(48, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(48, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(48, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(48, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 104 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(48, [C|Ics], Line, Tlen, _, _) when C >= 106, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(48, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,48}; +yystate(47, [125|Ics], Line, Tlen, Action, Alen) -> + yystate(39, Ics, Line, Tlen+1, Action, Alen); +yystate(47, [10|Ics], Line, Tlen, Action, Alen) -> + yystate(47, Ics, Line+1, Tlen+1, Action, Alen); +yystate(47, [C|Ics], Line, Tlen, Action, Alen) when C >= 0, C =< 9 -> + yystate(47, Ics, Line, Tlen+1, Action, Alen); +yystate(47, [C|Ics], Line, Tlen, Action, Alen) when C >= 11, C =< 124 -> + yystate(47, Ics, Line, Tlen+1, Action, Alen); +yystate(47, [C|Ics], Line, Tlen, Action, Alen) when C >= 126 -> + yystate(47, Ics, Line, Tlen+1, Action, Alen); +yystate(47, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,47}; +yystate(46, [116|Ics], Line, Tlen, _, _) -> + yystate(50, Ics, Line, Tlen+1, 27, Tlen); +yystate(46, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(46, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(46, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(46, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(46, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(46, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 115 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(46, [C|Ics], Line, Tlen, _, _) when C >= 117, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(46, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,46}; +yystate(45, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 26, Tlen); +yystate(45, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 26, Tlen); +yystate(45, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 26, Tlen); +yystate(45, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 26, Tlen); +yystate(45, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 26, Tlen); +yystate(45, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 26, Tlen); +yystate(45, Ics, Line, Tlen, _, _) -> + {26,Tlen,Ics,Line,45}; +yystate(44, [108|Ics], Line, Tlen, _, _) -> + yystate(40, Ics, Line, Tlen+1, 27, Tlen); +yystate(44, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(44, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(44, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(44, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(44, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(44, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 107 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(44, [C|Ics], Line, Tlen, _, _) when C >= 109, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(44, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,44}; +yystate(43, Ics, Line, Tlen, _, _) -> + {5,Tlen,Ics,Line}; +yystate(42, Ics, Line, Tlen, _, _) -> + {17,Tlen,Ics,Line}; +yystate(41, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(41, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(41, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(41, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(41, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(41, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(41, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,41}; +yystate(40, [101|Ics], Line, Tlen, _, _) -> + yystate(36, Ics, Line, Tlen+1, 27, Tlen); +yystate(40, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(40, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(40, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(40, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(40, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(40, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 100 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(40, [C|Ics], Line, Tlen, _, _) when C >= 102, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(40, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,40}; +yystate(39, [125|Ics], Line, Tlen, Action, Alen) -> + yystate(39, Ics, Line, Tlen+1, Action, Alen); +yystate(39, [42|Ics], Line, Tlen, Action, Alen) -> + yystate(43, Ics, Line, Tlen+1, Action, Alen); +yystate(39, [10|Ics], Line, Tlen, Action, Alen) -> + yystate(47, Ics, Line+1, Tlen+1, Action, Alen); +yystate(39, [C|Ics], Line, Tlen, Action, Alen) when C >= 0, C =< 9 -> + yystate(47, Ics, Line, Tlen+1, Action, Alen); +yystate(39, [C|Ics], Line, Tlen, Action, Alen) when C >= 11, C =< 41 -> + yystate(47, Ics, Line, Tlen+1, Action, Alen); +yystate(39, [C|Ics], Line, Tlen, Action, Alen) when C >= 43, C =< 124 -> + yystate(47, Ics, Line, Tlen+1, Action, Alen); +yystate(39, [C|Ics], Line, Tlen, Action, Alen) when C >= 126 -> + yystate(47, Ics, Line, Tlen+1, Action, Alen); +yystate(39, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,39}; +yystate(38, Ics, Line, Tlen, _, _) -> + {22,Tlen,Ics,Line}; +yystate(37, [105|Ics], Line, Tlen, _, _) -> + yystate(33, Ics, Line, Tlen+1, 27, Tlen); +yystate(37, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(37, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(37, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(37, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(37, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(37, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 104 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(37, [C|Ics], Line, Tlen, _, _) when C >= 106, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(37, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,37}; +yystate(36, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 13, Tlen); +yystate(36, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 13, Tlen); +yystate(36, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 13, Tlen); +yystate(36, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 13, Tlen); +yystate(36, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 13, Tlen); +yystate(36, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 13, Tlen); +yystate(36, Ics, Line, Tlen, _, _) -> + {13,Tlen,Ics,Line,36}; +yystate(35, [123|Ics], Line, Tlen, Action, Alen) -> + yystate(47, Ics, Line, Tlen+1, Action, Alen); +yystate(35, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,35}; +yystate(34, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 9, Tlen); +yystate(34, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 9, Tlen); +yystate(34, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 9, Tlen); +yystate(34, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 9, Tlen); +yystate(34, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 9, Tlen); +yystate(34, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 9, Tlen); +yystate(34, Ics, Line, Tlen, _, _) -> + {9,Tlen,Ics,Line,34}; +yystate(33, [108|Ics], Line, Tlen, _, _) -> + yystate(29, Ics, Line, Tlen+1, 27, Tlen); +yystate(33, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(33, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(33, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(33, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(33, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(33, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 107 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(33, [C|Ics], Line, Tlen, _, _) when C >= 109, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(33, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,33}; +yystate(32, [97|Ics], Line, Tlen, _, _) -> + yystate(28, Ics, Line, Tlen+1, 27, Tlen); +yystate(32, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(32, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(32, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(32, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(32, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(32, [C|Ics], Line, Tlen, _, _) when C >= 98, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(32, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,32}; +yystate(31, Ics, Line, Tlen, _, _) -> + {8,Tlen,Ics,Line}; +yystate(30, [107|Ics], Line, Tlen, _, _) -> + yystate(34, Ics, Line, Tlen+1, 27, Tlen); +yystate(30, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(30, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(30, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(30, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(30, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(30, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 106 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(30, [C|Ics], Line, Tlen, _, _) when C >= 108, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(30, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,30}; +yystate(29, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 19, Tlen); +yystate(29, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 19, Tlen); +yystate(29, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 19, Tlen); +yystate(29, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 19, Tlen); +yystate(29, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 19, Tlen); +yystate(29, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 19, Tlen); +yystate(29, Ics, Line, Tlen, _, _) -> + {19,Tlen,Ics,Line,29}; +yystate(28, [115|Ics], Line, Tlen, _, _) -> + yystate(24, Ics, Line, Tlen+1, 27, Tlen); +yystate(28, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(28, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(28, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(28, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(28, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(28, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 114 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(28, [C|Ics], Line, Tlen, _, _) when C >= 116, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(28, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,28}; +yystate(27, [48|Ics], Line, Tlen, Action, Alen) -> + yystate(7, Ics, Line, Tlen+1, Action, Alen); +yystate(27, [C|Ics], Line, Tlen, Action, Alen) when C >= 49, C =< 57 -> + yystate(3, Ics, Line, Tlen+1, Action, Alen); +yystate(27, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,27}; +yystate(26, [115|Ics], Line, Tlen, _, _) -> + yystate(30, Ics, Line, Tlen+1, 27, Tlen); +yystate(26, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(26, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(26, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(26, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(26, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(26, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 114 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(26, [C|Ics], Line, Tlen, _, _) when C >= 116, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(26, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,26}; +yystate(25, [110|Ics], Line, Tlen, _, _) -> + yystate(21, Ics, Line, Tlen+1, 27, Tlen); +yystate(25, [102|Ics], Line, Tlen, _, _) -> + yystate(17, Ics, Line, Tlen+1, 27, Tlen); +yystate(25, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(25, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(25, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(25, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(25, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(25, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 101 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(25, [C|Ics], Line, Tlen, _, _) when C >= 103, C =< 109 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(25, [C|Ics], Line, Tlen, _, _) when C >= 111, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(25, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,25}; +yystate(24, [104|Ics], Line, Tlen, _, _) -> + yystate(20, Ics, Line, Tlen+1, 27, Tlen); +yystate(24, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(24, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(24, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(24, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(24, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(24, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 103 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(24, [C|Ics], Line, Tlen, _, _) when C >= 105, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(24, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,24}; +yystate(23, [42|Ics], Line, Tlen, Action, Alen) -> + yystate(15, Ics, Line, Tlen+1, Action, Alen); +yystate(23, [10|Ics], Line, Tlen, Action, Alen) -> + yystate(23, Ics, Line+1, Tlen+1, Action, Alen); +yystate(23, [C|Ics], Line, Tlen, Action, Alen) when C >= 0, C =< 9 -> + yystate(23, Ics, Line, Tlen+1, Action, Alen); +yystate(23, [C|Ics], Line, Tlen, Action, Alen) when C >= 11, C =< 41 -> + yystate(23, Ics, Line, Tlen+1, Action, Alen); +yystate(23, [C|Ics], Line, Tlen, Action, Alen) when C >= 43 -> + yystate(23, Ics, Line, Tlen+1, Action, Alen); +yystate(23, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,23}; +yystate(22, [97|Ics], Line, Tlen, _, _) -> + yystate(26, Ics, Line, Tlen+1, 27, Tlen); +yystate(22, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(22, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(22, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(22, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(22, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(22, [C|Ics], Line, Tlen, _, _) when C >= 98, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(22, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,22}; +yystate(21, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 14, Tlen); +yystate(21, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 14, Tlen); +yystate(21, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 14, Tlen); +yystate(21, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 14, Tlen); +yystate(21, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 14, Tlen); +yystate(21, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 14, Tlen); +yystate(21, Ics, Line, Tlen, _, _) -> + {14,Tlen,Ics,Line,21}; +yystate(20, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 0, Tlen); +yystate(20, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 0, Tlen); +yystate(20, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 0, Tlen); +yystate(20, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 0, Tlen); +yystate(20, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 0, Tlen); +yystate(20, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 0, Tlen); +yystate(20, Ics, Line, Tlen, _, _) -> + {0,Tlen,Ics,Line,20}; +yystate(19, Ics, Line, Tlen, _, _) -> + {29,Tlen,Ics,Line}; +yystate(18, [116|Ics], Line, Tlen, _, _) -> + yystate(22, Ics, Line, Tlen+1, 27, Tlen); +yystate(18, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(18, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(18, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(18, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(18, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(18, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 115 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(18, [C|Ics], Line, Tlen, _, _) when C >= 117, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(18, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,18}; +yystate(17, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 6, Tlen); +yystate(17, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 6, Tlen); +yystate(17, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 6, Tlen); +yystate(17, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 6, Tlen); +yystate(17, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 6, Tlen); +yystate(17, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 6, Tlen); +yystate(17, Ics, Line, Tlen, _, _) -> + {6,Tlen,Ics,Line,17}; +yystate(16, Ics, Line, Tlen, _, _) -> + {23,Tlen,Ics,Line}; +yystate(15, [47|Ics], Line, Tlen, Action, Alen) -> + yystate(19, Ics, Line, Tlen+1, Action, Alen); +yystate(15, [42|Ics], Line, Tlen, Action, Alen) -> + yystate(15, Ics, Line, Tlen+1, Action, Alen); +yystate(15, [10|Ics], Line, Tlen, Action, Alen) -> + yystate(23, Ics, Line+1, Tlen+1, Action, Alen); +yystate(15, [C|Ics], Line, Tlen, Action, Alen) when C >= 0, C =< 9 -> + yystate(23, Ics, Line, Tlen+1, Action, Alen); +yystate(15, [C|Ics], Line, Tlen, Action, Alen) when C >= 11, C =< 41 -> + yystate(23, Ics, Line, Tlen+1, Action, Alen); +yystate(15, [C|Ics], Line, Tlen, Action, Alen) when C >= 43, C =< 46 -> + yystate(23, Ics, Line, Tlen+1, Action, Alen); +yystate(15, [C|Ics], Line, Tlen, Action, Alen) when C >= 48 -> + yystate(23, Ics, Line, Tlen+1, Action, Alen); +yystate(15, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,15}; +yystate(14, [102|Ics], Line, Tlen, _, _) -> + yystate(18, Ics, Line, Tlen+1, 27, Tlen); +yystate(14, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(14, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(14, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(14, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(14, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(14, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 101 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(14, [C|Ics], Line, Tlen, _, _) when C >= 103, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(14, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,14}; +yystate(13, [110|Ics], Line, Tlen, _, _) -> + yystate(9, Ics, Line, Tlen+1, 27, Tlen); +yystate(13, [109|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(13, [108|Ics], Line, Tlen, _, _) -> + yystate(1, Ics, Line, Tlen+1, 27, Tlen); +yystate(13, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(13, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(13, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(13, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(13, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(13, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 107 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(13, [C|Ics], Line, Tlen, _, _) when C >= 111, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(13, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,13}; +yystate(12, Ics, Line, Tlen, _, _) -> + {12,Tlen,Ics,Line}; +yystate(11, [47|Ics], Line, Tlen, Action, Alen) -> + yystate(59, Ics, Line, Tlen+1, Action, Alen); +yystate(11, [42|Ics], Line, Tlen, Action, Alen) -> + yystate(23, Ics, Line, Tlen+1, Action, Alen); +yystate(11, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,11}; +yystate(10, [101|Ics], Line, Tlen, _, _) -> + yystate(14, Ics, Line, Tlen+1, 27, Tlen); +yystate(10, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(10, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(10, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(10, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(10, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(10, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 100 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(10, [C|Ics], Line, Tlen, _, _) when C >= 102, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(10, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,10}; +yystate(9, [100|Ics], Line, Tlen, _, _) -> + yystate(5, Ics, Line, Tlen+1, 27, Tlen); +yystate(9, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(9, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(9, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(9, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(9, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(9, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 99 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(9, [C|Ics], Line, Tlen, _, _) when C >= 101, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(9, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,9}; +yystate(8, Ics, Line, Tlen, _, _) -> + {18,Tlen,Ics,Line}; +yystate(7, Ics, Line, Tlen, _, _) -> + {3,Tlen,Ics,Line}; +yystate(6, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 10, Tlen); +yystate(6, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 10, Tlen); +yystate(6, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 10, Tlen); +yystate(6, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 10, Tlen); +yystate(6, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 10, Tlen); +yystate(6, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 10, Tlen); +yystate(6, Ics, Line, Tlen, _, _) -> + {10,Tlen,Ics,Line,6}; +yystate(5, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 11, Tlen); +yystate(5, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 11, Tlen); +yystate(5, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 11, Tlen); +yystate(5, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 11, Tlen); +yystate(5, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 11, Tlen); +yystate(5, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 11, Tlen); +yystate(5, Ics, Line, Tlen, _, _) -> + {11,Tlen,Ics,Line,5}; +yystate(4, Ics, Line, Tlen, _, _) -> + {24,Tlen,Ics,Line}; +yystate(3, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(3, Ics, Line, Tlen+1, 3, Tlen); +yystate(3, Ics, Line, Tlen, _, _) -> + {3,Tlen,Ics,Line,3}; +yystate(2, [101|Ics], Line, Tlen, _, _) -> + yystate(6, Ics, Line, Tlen+1, 27, Tlen); +yystate(2, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(2, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(2, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(2, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(2, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(2, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 100 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(2, [C|Ics], Line, Tlen, _, _) when C >= 102, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(2, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,2}; +yystate(1, [115|Ics], Line, Tlen, _, _) -> + yystate(2, Ics, Line, Tlen+1, 27, Tlen); +yystate(1, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(1, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(1, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(1, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(1, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(1, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 114 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(1, [C|Ics], Line, Tlen, _, _) when C >= 116, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(1, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,1}; +yystate(0, Ics, Line, Tlen, _, _) -> + {7,Tlen,Ics,Line}; +yystate(S, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,S}. + +%% yyaction(Action, TokenLength, TokenChars, TokenLine) -> +%% {token,Token} | {end_token, Token} | skip_token | {error,String}. +%% Generated action function. + +yyaction(0, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_0(TokenChars, TokenLine); +yyaction(1, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_1(TokenChars, TokenLine); +yyaction(2, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_2(TokenChars, TokenLine); +yyaction(3, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_3(TokenChars, TokenLine); +yyaction(4, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_4(TokenChars, TokenLine); +yyaction(5, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_5(TokenChars, TokenLine); +yyaction(6, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_6(TokenChars, TokenLine); +yyaction(7, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_7(TokenChars, TokenLine); +yyaction(8, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_8(TokenChars, TokenLine); +yyaction(9, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_9(TokenChars, TokenLine); +yyaction(10, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_10(TokenChars, TokenLine); +yyaction(11, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_11(TokenChars, TokenLine); +yyaction(12, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_12(TokenChars, TokenLine); +yyaction(13, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_13(TokenChars, TokenLine); +yyaction(14, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_14(TokenChars, TokenLine); +yyaction(15, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_15(TokenChars, TokenLine); +yyaction(16, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_16(TokenChars, TokenLine); +yyaction(17, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_17(TokenChars, TokenLine); +yyaction(18, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_18(TokenChars, TokenLine); +yyaction(19, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_19(TokenChars, TokenLine); +yyaction(20, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_20(TokenChars, TokenLine); +yyaction(21, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_21(TokenChars, TokenLine); +yyaction(22, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_22(TokenChars, TokenLine); +yyaction(23, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_23(TokenChars, TokenLine); +yyaction(24, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_24(TokenChars, TokenLine); +yyaction(25, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_25(TokenChars, TokenLine); +yyaction(26, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_26(TokenChars, TokenLine); +yyaction(27, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_27(TokenChars, TokenLine); +yyaction(28, _, _, _) -> + yyaction_28(); +yyaction(29, _, _, _) -> + yyaction_29(); +yyaction(30, _, _, _) -> + yyaction_30(); +yyaction(_, _, _, _) -> error. + +-compile({inline,yyaction_0/2}). +-file("src/cf_lexer.xrl", 61). +yyaction_0(TokenChars, TokenLine) -> + { token, { bash, TokenLine, TokenChars } } . + +-compile({inline,yyaction_1/2}). +-file("src/cf_lexer.xrl", 62). +yyaction_1(TokenChars, TokenLine) -> + { token, { python, TokenLine, TokenChars } } . + +-compile({inline,yyaction_2/2}). +-file("src/cf_lexer.xrl", 63). +yyaction_2(TokenChars, TokenLine) -> + { token, { r, TokenLine, TokenChars } } . + +-compile({inline,yyaction_3/2}). +-file("src/cf_lexer.xrl", 65). +yyaction_3(TokenChars, TokenLine) -> + { token, { intlit, TokenLine, TokenChars } } . + +-compile({inline,yyaction_4/2}). +-file("src/cf_lexer.xrl", 66). +yyaction_4(TokenChars, TokenLine) -> + { token, { strlit, TokenLine, trim_strlit (TokenChars) } } . + +-compile({inline,yyaction_5/2}). +-file("src/cf_lexer.xrl", 67). +yyaction_5(TokenChars, TokenLine) -> + { token, { body, TokenLine, trim_body (TokenChars) } } . + +-compile({inline,yyaction_6/2}). +-file("src/cf_lexer.xrl", 68). +yyaction_6(TokenChars, TokenLine) -> + { token, { beginif, TokenLine, TokenChars } } . + +-compile({inline,yyaction_7/2}). +-file("src/cf_lexer.xrl", 69). +yyaction_7(TokenChars, TokenLine) -> + { token, { colon, TokenLine, TokenChars } } . + +-compile({inline,yyaction_8/2}). +-file("src/cf_lexer.xrl", 70). +yyaction_8(TokenChars, TokenLine) -> + { token, { comma, TokenLine, TokenChars } } . + +-compile({inline,yyaction_9/2}). +-file("src/cf_lexer.xrl", 71). +yyaction_9(TokenChars, TokenLine) -> + { token, { deftask, TokenLine, TokenChars } } . + +-compile({inline,yyaction_10/2}). +-file("src/cf_lexer.xrl", 72). +yyaction_10(TokenChars, TokenLine) -> + { token, { else, TokenLine, TokenChars } } . + +-compile({inline,yyaction_11/2}). +-file("src/cf_lexer.xrl", 73). +yyaction_11(TokenChars, TokenLine) -> + { token, { endif, TokenLine, TokenChars } } . + +-compile({inline,yyaction_12/2}). +-file("src/cf_lexer.xrl", 74). +yyaction_12(TokenChars, TokenLine) -> + { token, { eq, TokenLine, TokenChars } } . + +-compile({inline,yyaction_13/2}). +-file("src/cf_lexer.xrl", 75). +yyaction_13(TokenChars, TokenLine) -> + { token, { file, TokenLine, TokenChars } } . + +-compile({inline,yyaction_14/2}). +-file("src/cf_lexer.xrl", 76). +yyaction_14(TokenChars, TokenLine) -> + { token, { in, TokenLine, TokenChars } } . + +-compile({inline,yyaction_15/2}). +-file("src/cf_lexer.xrl", 77). +yyaction_15(TokenChars, TokenLine) -> + { token, { lbrace, TokenLine, TokenChars } } . + +-compile({inline,yyaction_16/2}). +-file("src/cf_lexer.xrl", 78). +yyaction_16(TokenChars, TokenLine) -> + { token, { lparen, TokenLine, TokenChars } } . + +-compile({inline,yyaction_17/2}). +-file("src/cf_lexer.xrl", 79). +yyaction_17(TokenChars, TokenLine) -> + { token, { lsquarebr, TokenLine, TokenChars } } . + +-compile({inline,yyaction_18/2}). +-file("src/cf_lexer.xrl", 80). +yyaction_18(TokenChars, TokenLine) -> + { token, { ltag, TokenLine, TokenChars } } . + +-compile({inline,yyaction_19/2}). +-file("src/cf_lexer.xrl", 81). +yyaction_19(TokenChars, TokenLine) -> + { token, { nil, TokenLine, TokenChars } } . + +-compile({inline,yyaction_20/2}). +-file("src/cf_lexer.xrl", 82). +yyaction_20(TokenChars, TokenLine) -> + { token, { rbrace, TokenLine, TokenChars } } . + +-compile({inline,yyaction_21/2}). +-file("src/cf_lexer.xrl", 83). +yyaction_21(TokenChars, TokenLine) -> + { token, { rparen, TokenLine, TokenChars } } . + +-compile({inline,yyaction_22/2}). +-file("src/cf_lexer.xrl", 84). +yyaction_22(TokenChars, TokenLine) -> + { token, { rsquarebr, TokenLine, TokenChars } } . + +-compile({inline,yyaction_23/2}). +-file("src/cf_lexer.xrl", 85). +yyaction_23(TokenChars, TokenLine) -> + { token, { rtag, TokenLine, TokenChars } } . + +-compile({inline,yyaction_24/2}). +-file("src/cf_lexer.xrl", 86). +yyaction_24(TokenChars, TokenLine) -> + { token, { semicolon, TokenLine, TokenChars } } . + +-compile({inline,yyaction_25/2}). +-file("src/cf_lexer.xrl", 87). +yyaction_25(TokenChars, TokenLine) -> + { token, { string, TokenLine, TokenChars } } . + +-compile({inline,yyaction_26/2}). +-file("src/cf_lexer.xrl", 88). +yyaction_26(TokenChars, TokenLine) -> + { token, { then, TokenLine, TokenChars } } . + +-compile({inline,yyaction_27/2}). +-file("src/cf_lexer.xrl", 90). +yyaction_27(TokenChars, TokenLine) -> + { token, { id, TokenLine, TokenChars } } . + +-compile({inline,yyaction_28/0}). +-file("src/cf_lexer.xrl", 92). +yyaction_28() -> + skip_token . + +-compile({inline,yyaction_29/0}). +-file("src/cf_lexer.xrl", 93). +yyaction_29() -> + skip_token . + +-compile({inline,yyaction_30/0}). +-file("src/cf_lexer.xrl", 94). +yyaction_30() -> + skip_token . + +-file("/usr/local/lib/erlang/lib/parsetools-2.1.1/include/leexinc.hrl", 290). diff --git a/src/cf_lexer.xrl b/src/cf_lexer.xrl new file mode 100644 index 0000000..51b6cf9 --- /dev/null +++ b/src/cf_lexer.xrl @@ -0,0 +1,320 @@ +%% -*- erlang -*- +% +% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis +% +% Copyright 2013 Jörgen Brandt, Marc Bux, and Ulf Leser +% +% Licensed under the Apache License, Version 2.0 (the "License"); +% you may not use this file except in compliance with the License. +% You may obtain a copy of the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, +% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +% See the License for the specific language governing permissions and +% limitations under the License. + +Definitions. + +BASH = [Bb]ash +PYTHON = [Pp]ython +R = [Rr] + +BEGINIF = if +COLON = : +COMMA = , +DEFTASK = deftask +ELSE = else +ENDIF = end +EQ = = +FILE = File +IN = in +LBRACE = \{ +LPAREN = \( +LSQUAREBR = \[ +LTAG = < +NIL = nil +RBRACE = \} +RPAREN = \) +RSQUAREBR = \] +RTAG = > +SEMICOLON = ; +STRING = String +THEN = then + +ID = [A-Za-z][A-Za-z0-9.\-_]* +INTLIT = -?([0-9]|[1-9][0-9]*) +STRLIT = "[^"]*" +BODY = \*\{([^}]|\}+[^}*])*\}+\* + + +COMMENT1 = (#|//|%).* +COMMENT2 = /\*([^*]|\*+[^/*])*\*+/ +WS = [\000-\s] + + + + + +Rules. + +{BASH} : {token, {bash, TokenLine, TokenChars}}. +{PYTHON} : {token, {python, TokenLine, TokenChars}}. +{R} : {token, {r, TokenLine, TokenChars}}. + +{INTLIT} : {token, {intlit, TokenLine, TokenChars}}. +{STRLIT} : {token, {strlit, TokenLine, trim_strlit( TokenChars )}}. +{BODY} : {token, {body, TokenLine, trim_body( TokenChars )}}. +{BEGINIF} : {token, {beginif, TokenLine, TokenChars}}. +{COLON} : {token, {colon, TokenLine, TokenChars}}. +{COMMA} : {token, {comma, TokenLine, TokenChars}}. +{DEFTASK} : {token, {deftask, TokenLine, TokenChars}}. +{ELSE} : {token, {else, TokenLine, TokenChars}}. +{ENDIF} : {token, {endif, TokenLine, TokenChars}}. +{EQ} : {token, {eq, TokenLine, TokenChars}}. +{FILE} : {token, {file, TokenLine, TokenChars}}. +{IN} : {token, {in, TokenLine, TokenChars}}. +{LBRACE} : {token, {lbrace, TokenLine, TokenChars}}. +{LPAREN} : {token, {lparen, TokenLine, TokenChars}}. +{LSQUAREBR} : {token, {lsquarebr, TokenLine, TokenChars}}. +{LTAG} : {token, {ltag, TokenLine, TokenChars}}. +{NIL} : {token, {nil, TokenLine, TokenChars}}. +{RBRACE} : {token, {rbrace, TokenLine, TokenChars}}. +{RPAREN} : {token, {rparen, TokenLine, TokenChars}}. +{RSQUAREBR} : {token, {rsquarebr, TokenLine, TokenChars}}. +{RTAG} : {token, {rtag, TokenLine, TokenChars}}. +{SEMICOLON} : {token, {semicolon, TokenLine, TokenChars}}. +{STRING} : {token, {string, TokenLine, TokenChars}}. +{THEN} : {token, {then, TokenLine, TokenChars}}. + +{ID} : {token, {id, TokenLine, TokenChars}}. + +{COMMENT1} : skip_token. +{COMMENT2} : skip_token. +{WS} : skip_token. + + + + + + +Erlang code. + +-author( "Jörgen Brandt " ). + +-export( [yyrev/2] ). + +-ifdef( TEST ). +-include_lib( "eunit/include/eunit.hrl" ). +-endif. + +trim_body( S ) -> + string:substr( S, 3, length( S )-4 ). + +trim_strlit( S ) -> + string:substr( S, 2, length( S )-2 ). + + +-ifdef( TEST ). + + +% TEST INDEX + +token_test_() -> [ + bash_style_comment_should_be_recognized(), + c_style_comment_should_be_recognized(), + erlang_style_comment_should_be_recognized(), + multiline_comment_should_be_recognized(), + apply_should_be_recognized(), + bash_should_be_recognized(), + beginif_should_be_recognized(), + colon_should_be_recognized(), + comb_should_be_recognized(), + deftask_should_be_recognized(), + else_should_be_recognized(), + endif_should_be_recognized(), + eq_should_be_recognized(), + file_should_be_recognized(), + in_should_be_recognized(), + id_should_be_recognized(), + lisp_should_be_recognized(), + matlab_should_be_recognized(), + octave_should_be_recognized(), + perl_should_be_recognized(), + python_should_be_recognized(), + r_should_be_recognized(), + lbrace_should_be_recognized(), + lparen_should_be_recognized(), + lsquarebr_should_be_recognized(), + ltag_should_be_recognized(), + nil_should_be_recognized(), + noreplace_should_be_recognized(), + rbrace_should_be_recognized(), + rparen_should_be_recognized(), + rsquarebr_should_be_recognized(), + rtag_should_be_recognized(), + semicolon_should_be_recognized(), + string_should_be_recognized(), + task_should_be_recognized(), + then_should_be_recognized(), + intlit_should_be_recognized(), + body_should_be_recognized(), + strlit_should_be_recognized() + ]. + + + + +% ACTUAL TEST IMPLEMENTATION + +bash_style_comment_should_be_recognized() -> + ?_assertEqual( {ok, [], 1}, string( "#this is a comment" ) ). + +c_style_comment_should_be_recognized() -> + ?_assertEqual( {ok, [], 1}, string( "//this is a comment" ) ). + +erlang_style_comment_should_be_recognized() -> + ?_assertEqual( {ok, [], 1}, string( "%this is a comment" ) ). + + +multiline_comment_should_be_recognized() -> + [?_assertEqual( {ok, [], 1}, string( "/**/" ) ), + ?_assertEqual( {ok, [], 1}, string( "/*x*/" ) ), + ?_assertEqual( {ok, [], 1}, string( "/*xy*/" ) ), + ?_assertEqual( {ok, [], 2}, string( "/*x\ny*/" ) )]. + +apply_should_be_recognized() -> + ?_assertEqual( {ok, [{apply, 1, "apply"}], 1}, string( "apply" ) ). + +bash_should_be_recognized() -> + ?_assertEqual( {ok, [{bash, 1, "bash"}], 1}, string( "bash" ) ). + +beginif_should_be_recognized() -> + ?_assertEqual( {ok, [{beginif, 1, "if"}], 1}, string( "if" ) ). + +colon_should_be_recognized() -> + ?_assertEqual( {ok, [{colon, 1, ":"}], 1}, string( ":" ) ). + +comb_should_be_recognized() -> + ?_assertEqual( {ok, [{comb, 1, "comb"}], 1}, string( "comb" ) ). + +deftask_should_be_recognized() -> + ?_assertEqual( {ok, [{deftask, 1, "deftask"}], 1}, string( "deftask" ) ). + +else_should_be_recognized() -> + ?_assertEqual( {ok, [{else, 1, "else"}], 1}, string( "else" ) ). + +endif_should_be_recognized() -> + ?_assertEqual( {ok, [{endif, 1, "end"}], 1}, string( "end" ) ). + +eq_should_be_recognized() -> + ?_assertEqual( {ok, [{eq, 1, "="}], 1}, string( "=" ) ). + +file_should_be_recognized() -> + ?_assertEqual( {ok, [{file, 1, "File"}], 1}, string( "File" ) ). + +in_should_be_recognized() -> + ?_assertEqual( {ok, [{in, 1, "in"}], 1}, string( "in" ) ). + +id_should_be_recognized() -> + [?_assertEqual( {ok, [{id, 1, "inp"}], 1}, string( "inp" ) ), + ?_assertEqual( {ok, [{id, 1, "a0"}], 1}, string( "a0" ) ), + ?_assertEqual( {ok, [{id, 1, "a9"}], 1}, string( "a9" ) ), + ?_assertEqual( {ok, [{id, 1, "a."}], 1}, string( "a." ) ), + ?_assertEqual( {ok, [{id, 1, "a-"}], 1}, string( "a-" ) ), + ?_assertEqual( {ok, [{id, 1, "a_"}], 1}, string( "a_" ) ), + ?_assertEqual( {ok, [{id, 1, "a+"}], 1}, string( "a+" ) ), + ?_assertEqual( {ok, [{id, 1, "a*"}], 1}, string( "a*" ) ), + ?_assertEqual( {ok, [{id, 1, "a/"}], 1}, string( "a/" ) )]. + +lisp_should_be_recognized() -> + ?_assertEqual( {ok, [{lisp, 1, "lisp"}], 1}, string( "lisp" ) ). + +matlab_should_be_recognized() -> + ?_assertEqual( {ok, [{matlab, 1, "matlab"}], 1}, string( "matlab" ) ). + +octave_should_be_recognized() -> + ?_assertEqual( {ok, [{octave, 1, "octave"}], 1}, string( "octave" ) ). + +perl_should_be_recognized() -> + ?_assertEqual( {ok, [{perl, 1, "perl"}], 1}, string( "perl" ) ). + +python_should_be_recognized() -> + ?_assertEqual( {ok, [{python, 1, "python"}], 1}, string( "python" ) ). + +r_should_be_recognized() -> + [?_assertEqual( {ok, [{r, 1, "r"}], 1}, string( "r" ) ), + ?_assertEqual( {ok, [{r, 1, "R"}], 1}, string( "R" ) )]. + +lbrace_should_be_recognized() -> + ?_assertEqual( {ok, [{lbrace, 1, "{"}], 1}, string( "{" ) ). + +lparen_should_be_recognized() -> + ?_assertEqual( {ok, [{lparen, 1, "("}], 1}, string( "(" ) ). + +lsquarebr_should_be_recognized() -> + ?_assertEqual( {ok, [{lsquarebr, 1, "["}], 1}, string( "[" ) ). + +ltag_should_be_recognized() -> + ?_assertEqual( {ok, [{ltag, 1, "<"}], 1}, string( "<" ) ). + +nil_should_be_recognized() -> + ?_assertEqual( {ok, [{nil, 1, "nil"}], 1}, string( "nil" ) ). + +noreplace_should_be_recognized() -> + ?_assertEqual( {ok, [{noreplace, 1, "noreplace"}], 1}, + string( "noreplace" ) ). + +rbrace_should_be_recognized() -> + ?_assertEqual( {ok, [{rbrace, 1, "}"}], 1}, string( "}" ) ). + +rparen_should_be_recognized() -> + ?_assertEqual( {ok, [{rparen, 1, ")"}], 1}, string( ")" ) ). + +rsquarebr_should_be_recognized() -> + ?_assertEqual( {ok, [{rsquarebr, 1, "]"}], 1}, string( "]" ) ). + +rtag_should_be_recognized() -> + ?_assertEqual( {ok, [{rtag, 1, ">"}], 1}, string( ">" ) ). + +semicolon_should_be_recognized() -> + ?_assertEqual( {ok, [{semicolon, 1, ";"}], 1}, string( ";" ) ). + +string_should_be_recognized() -> + ?_assertEqual( {ok, [{string, 1, "String"}], 1}, string( "String" ) ). + +task_should_be_recognized() -> + ?_assertEqual( {ok, [{task, 1, "task"}], 1}, string( "task" ) ). + +then_should_be_recognized() -> + ?_assertEqual( {ok, [{then, 1, "then"}], 1}, string( "then" ) ). + +intlit_should_be_recognized() -> + [?_assertEqual( {ok, [{intlit, 1, "10"}], 1}, string( "10" ) ), + ?_assertEqual( {ok, [{intlit, 1, "-10"}], 1}, string( "-10" ) ), + ?_assertEqual( {ok, [{intlit, 1, "9"}], 1}, string( "9" ) ), + ?_assertEqual( {ok, [{intlit, 1, "0"}], 1}, string( "0" ) )]. + +body_should_be_recognized() -> + [?_assertEqual( {ok, [{body, 1, ""}], 1}, string( "*{}*" ) ), + ?_assertEqual( {ok, [{body, 1, "x"}], 1}, string( "*{x}*" ) ), + ?_assertEqual( {ok, [{body, 1, "xy"}], 1}, string( "*{xy}*" ) ), + ?_assertEqual( {ok, [{body, 1, "x\ny"}], 2}, string( "*{x\ny}*" ) )]. + +strlit_should_be_recognized() -> + [?_assertEqual( {ok, [{strlit, 1, ""}], 1}, string( "''" ) ), + ?_assertEqual( {ok, [{strlit, 1, ""}], 1}, string( "\"\"" ) ), + ?_assertEqual( {ok, [{strlit, 1, "x"}], 1}, string( "'x'" ) ), + ?_assertEqual( {ok, [{strlit, 1, "x"}], 1}, string( "\"x\"" ) ), + ?_assertEqual( {ok, [{strlit, 1, "xy"}], 1}, string( "'xy'" ) ), + ?_assertEqual( {ok, [{strlit, 1, "xy"}], 1}, string( "\"xy\"" ) )]. + + + + + +-endif. + + diff --git a/src/cf_parser.erl b/src/cf_parser.erl new file mode 100644 index 0000000..30abc95 --- /dev/null +++ b/src/cf_parser.erl @@ -0,0 +1,1594 @@ +-module(cf_parser). +-export([parse/1, parse_and_scan/1, format_error/1]). +-file("src/cf_parser.yrl", 99). + +-author( "Jörgen Brandt " ). + +-ifdef( TEST ). +-include_lib( "eunit/include/eunit.hrl" ). +-endif. + + + + + + +combine( {Target1, Rho1, Global1}, {Target2, Rho2, Global2} ) -> + {Target1++Target2, maps:merge( Rho1, Rho2 ), maps:merge( Global1, Global2 )}. + +mk_var( {id, Line, Name} ) -> {var, Line, Name}. + +mk_str( {intlit, Line, N} ) -> {str, Line, N}; +mk_str( {strlit, Line, S} ) -> {str, Line, S}. + +get_line( {_, Line, _} ) -> Line. + +get_name( {id, _Line, Name} ) -> Name. + +mk_binding( {id, _, Name}, ExprList ) -> + #{Name => ExprList}. + +mk_assign( [], _ExprList, _Channel ) -> #{}; + +mk_assign( [{var, _Line, Name}|Rest], ExprList, Channel ) -> + Rho = mk_assign( Rest, ExprList, Channel+1 ), + Value = lists:flatmap( fun( E ) -> set_channel( E, Channel ) end, ExprList ), + Rho#{Name => Value}; + +mk_assign( [E|_Rest], _ExprList, _Channel ) -> + error( {parser, nonvar_expr_left_of_eq, element( 1, E ), element( 2, E )} ). + + +set_channel( {app, Line, _Channel, LamList, Binding}, N ) -> [{app, Line, N, LamList, Binding}]; +set_channel( E, 1 ) -> [E]; +set_channel( E, _ ) -> error( {parser, cannot_set_channel_on_nonapp_expr, element( 1, E ), element( 2, E )} ). + +mk_natlam( {deftask, Line, _}, {id, _, Name}, Sign, Block ) -> + #{Name => [{lam, Line, Name, Sign, {natbody, Block}}]}. + +mk_forlam( {deftask, Line, _}, {id, _, Name}, Sign, Lang, {body, _, Code} ) -> + #{Name => [{lam, Line, Name, Sign, {forbody, Lang, Code}}]}. + + +-ifdef( TEST ). + +% TEST INDEX + +parse_test_() -> [nil_should_be_recognized(), + var_should_be_recognized(), + multi_element_compoundexpr_should_be_recognized(), + multiple_targets_should_be_joined(), + strlit_should_be_recognized(), + intlit_should_be_recognized(), + cnd_should_be_recognized(), + apply_should_be_recognized(), + call_should_be_recognized(), + assign_should_be_recognized(), + native_deftask_should_be_recognized(), + foreign_deftask_should_be_recognized(), + sign_with_inparam_should_be_recognized(), + param_should_be_recognized(), + task_correl_should_be_recognized(), + correl_inparam_should_be_recognized(), + comb_noreplace_should_be_recognized() + ]. + + +% ACTUAL TEST IMPLEMENTATION + +nil_should_be_recognized() -> + ?_assertEqual( {[], #{}, #{}}, parse_string( "nil;" ) ). + +var_should_be_recognized() -> + ?_assertEqual( {[{var, 1, "blub"}], #{}, #{}}, parse_string( "blub;" ) ). + +multi_element_compoundexpr_should_be_recognized() -> + ?_assertEqual( {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}, + parse_string( "bla blub;" ) ). + +multiple_targets_should_be_joined() -> + ?_assertEqual( {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}, + parse_string( "bla; blub;" ) ). + +strlit_should_be_recognized() -> + ?_assertEqual( {[{str, 1, "bla"}], #{}, #{}}, parse_string( "'bla';" ) ). + +intlit_should_be_recognized() -> + ?_assertEqual( {[{str, 1, "-5"}], #{}, #{}}, parse_string( "-5;" ) ). + +cnd_should_be_recognized() -> + ?_assertEqual( {[{cnd, 1, [], [{str, 1, "bla"}], [{str, 1, "blub"}]}], + #{}, #{}}, + parse_string( "if nil then 'bla' else 'blub' end;" ) ). + +apply_should_be_recognized() -> + [?_assertEqual( {[{app, 1, 1, [{var, 1, "f"}], #{}}], #{}, #{}}, + parse_string( "apply( task: f );" ) ), + ?_assertEqual( {[{app, 1, 1, [{var, 1, "f"}], #{"x" => [{var, 1, "x"}]}}], + #{}, #{}}, + parse_string( "apply( task: f, x: x );" ) ), + ?_assertEqual( {[{app, 1, 1, [{var, 1, "f"}], #{"x" => [{var, 1, "x"}], + "y" => [{str, 1, "y"}]}}], + #{}, #{}}, + parse_string( "apply( task: f, x: x, y: 'y' );" ) ), + ?_assertEqual( {[{app, 1, 1, [{var, 1, "f"}, {var, 1, "g"}], + #{"x" => [{var, 1, "x"}]}}], #{}, #{}}, + parse_string( "apply( task: f g, x: x );" ) )]. + +call_should_be_recognized() -> + [?_assertEqual( {[{app, 1, 1, [{var, 1, "f"}], #{}}], #{}, #{}}, + parse_string( "f();" ) ), + ?_assertEqual( {[{app, 1, 1, [{var, 1, "f"}], #{"x" => [{var, 1, "x"}]}}], + #{}, #{}}, parse_string( "f( x: x );" ) ), + ?_assertEqual( {[{app, 1, 1, [{var, 1, "f"}], + #{"x" => [{var, 1, "x"}], + "y" => [{str, 1, "y"}]}}], #{}, #{}}, + parse_string( "f( x: x, y: 'y' );" ) )]. + + +assign_should_be_recognized() -> + [?_assertEqual( {[], #{"x" => [{str, 1, "x"}]}, #{}}, parse_string( "x = 'x';" ) ), + ?_assertEqual( {[], #{"x" => [{app, 1, 1, [{var, 1, "f"}], #{}}], "y" => [{app, 1, 2, [{var, 1, "f"}], #{}}]}, #{}}, parse_string( "x y = f();" ) ), + ?_assertError( {parser, cannot_set_channel_on_nonapp_expr, str, 1}, parse_string( "x y = 'A';" ) ), + ?_assertError( {parser, nonvar_expr_left_of_eq, str, 1}, parse_string( "'a' = 'A';" ) )]. + +native_deftask_should_be_recognized() -> + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [], []}, + {natbody, #{"out" => [{str, 1, "A"}]}}}]}}, + parse_string( "deftask f( out : ) { out = 'A'; }" ) ). + +foreign_deftask_should_be_recognized() -> + [?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [], []}, + {forbody, bash, "out=A"}}]}}, + parse_string( "deftask f( out : )in bash *{out=A}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [], []}, + {forbody, r, "out=\"A\""}}]}}, + parse_string( "deftask f( out : )in R *{out=\"A\"}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [], []}, + {forbody, matlab, "out=\"A\""}}]}}, + parse_string( "deftask f( out : )in matlab *{out=\"A\"}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [], []}, + {forbody, octave, "out=\"A\""}}]}}, + parse_string( "deftask f( out : )in octave *{out=\"A\"}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [], []}, + {forbody, perl, ""}}]}}, + parse_string( "deftask f( out : )in perl *{}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [], []}, + {forbody, python, ""}}]}}, + parse_string( "deftask f( out : )in python *{}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [], []}, + {forbody, lisp, "(defparameter out \"A\")"}}]}}, + parse_string( "deftask f( out : )in lisp *{(defparameter out \"A\")}*" ) )]. + +sign_with_inparam_should_be_recognized() -> + [?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [], + [{param, {name, "inp", false}, false}]}, + {forbody, lisp, "(defparameter out \"A\")"}}]}}, + parse_string( "deftask f( out : inp )in lisp *{(defparameter out \"A\")}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [], + [{param, {name, "a", false}, false}, + {param, {name, "b", false}, false}]}, + {forbody, lisp, "(defparameter out \"A\")"}}]}}, + parse_string( "deftask f( out : a b )in lisp *{(defparameter out \"A\")}*" ) )]. + +param_should_be_recognized() -> + [?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [], + [{param, {name, "inp", false}, false}]}, + {forbody, bash, "blub"}}]}}, + parse_string( "deftask f( out( String ) : inp( String ) )in bash *{blub}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", true}, false}], + [], + [{param, {name, "inp", true}, false}]}, + {forbody, bash, "blub"}}]}}, + parse_string( "deftask f( out( File ) : inp( File ) )in bash *{blub}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, true}], + [], + [{param, {name, "inp", false}, true}]}, + {forbody, bash, "blub"}}]}}, + parse_string( "deftask f( : )in bash *{blub}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, true}], + [], + [{param, {name, "inp", false}, true}]}, + {forbody, bash, "blub"}}]}}, + parse_string( "deftask f( : )in bash *{blub}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", true}, true}], + [], + [{param, {name, "inp", true}, true}]}, + {forbody, bash, "blub"}}]}}, + parse_string( "deftask f( : )in bash *{blub}*" ) )]. + +task_correl_should_be_recognized() -> + [?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [{name, "a", false}], + [{param, {name, "b", false}, false}]}, + {forbody, bash, "blub"}}]}}, + parse_string( "deftask f( out : [task a] b )in bash *{blub}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [{name, "a", false}, + {name, "b", false}], + []}, + {forbody, bash, "blub"}}]}}, + parse_string( "deftask f( out : [task a b] )in bash *{blub}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [{name, "a", false}], + [{param, {name, "b", false}, false}]}, + {forbody, bash, "blub"}}]}}, + parse_string( "deftask f( out : [task a( String )] b )in bash *{blub}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [{name, "a", false}, + {name, "b", false}], + []}, + {forbody, bash, "blub"}}]}}, + parse_string( "deftask f( out : [task a( String ) b( String )] )in bash *{blub}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [{name, "a", true}], + [{param, {name, "b", false}, false}]}, + {forbody, bash, "blub"}}]}}, + parse_string( "deftask f( out : [task a( File )] b )in bash *{blub}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [{name, "a", true}, + {name, "b", true}], + []}, + {forbody, bash, "blub"}}]}}, + parse_string( "deftask f( out : [task a( File ) b( File )] )in bash *{blub}*" ) )]. + +correl_inparam_should_be_recognized() -> + [?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [], + [{correl, [{name, "a", true}, + {name, "b", true}]}]}, + {forbody, bash, "blub"}}]}}, + parse_string( "deftask f( out : [a( File ) b( File )] )in bash *{blub}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [], + [{correl, [{name, "a", true}, + {name, "b", true}]}, + {param, {name, "c", false}, false}]}, + {forbody, bash, "blub"}}]}}, + parse_string( "deftask f( out : [a( File ) b( File )] c )in bash *{blub}*" ) )]. + +comb_noreplace_should_be_recognized() -> + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [], + [{comb, cnr, {name, "x", true}, ["a", "b", "c"]}]}, + {forbody, bash, "blub"}}]}}, + parse_string( "deftask f( out : {comb noreplace x( File ): a b c} )in bash *{blub}*" ) ). + + + + + + + +parse_string( S ) -> + {ok, TokenList, _} = cuneiform_lexer:string( S ), + {ok, ParseTree} = cuneiform_parser:parse( TokenList ), + ParseTree. + + + +-endif. + + + +-file("/usr/local/lib/erlang/lib/parsetools-2.1.1/include/yeccpre.hrl", 0). +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1996-2015. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%% +%% %CopyrightEnd% +%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% The parser generator will insert appropriate declarations before this line.% + +-type yecc_ret() :: {'error', _} | {'ok', _}. + +-spec parse(Tokens :: list()) -> yecc_ret(). +parse(Tokens) -> + yeccpars0(Tokens, {no_func, no_line}, 0, [], []). + +-spec parse_and_scan({function() | {atom(), atom()}, [_]} + | {atom(), atom(), [_]}) -> yecc_ret(). +parse_and_scan({F, A}) -> + yeccpars0([], {{F, A}, no_line}, 0, [], []); +parse_and_scan({M, F, A}) -> + Arity = length(A), + yeccpars0([], {{fun M:F/Arity, A}, no_line}, 0, [], []). + +-spec format_error(any()) -> [char() | list()]. +format_error(Message) -> + case io_lib:deep_char_list(Message) of + true -> + Message; + _ -> + io_lib:write(Message) + end. + +%% To be used in grammar files to throw an error message to the parser +%% toplevel. Doesn't have to be exported! +-compile({nowarn_unused_function, return_error/2}). +-spec return_error(integer(), any()) -> no_return(). +return_error(Line, Message) -> + throw({error, {Line, ?MODULE, Message}}). + +-define(CODE_VERSION, "1.4"). + +yeccpars0(Tokens, Tzr, State, States, Vstack) -> + try yeccpars1(Tokens, Tzr, State, States, Vstack) + catch + error: Error -> + Stacktrace = erlang:get_stacktrace(), + try yecc_error_type(Error, Stacktrace) of + Desc -> + erlang:raise(error, {yecc_bug, ?CODE_VERSION, Desc}, + Stacktrace) + catch _:_ -> erlang:raise(error, Error, Stacktrace) + end; + %% Probably thrown from return_error/2: + throw: {error, {_Line, ?MODULE, _M}} = Error -> + Error + end. + +yecc_error_type(function_clause, [{?MODULE,F,ArityOrArgs,_} | _]) -> + case atom_to_list(F) of + "yeccgoto_" ++ SymbolL -> + {ok,[{atom,_,Symbol}],_} = erl_scan:string(SymbolL), + State = case ArityOrArgs of + [S,_,_,_,_,_,_] -> S; + _ -> state_is_unknown + end, + {Symbol, State, missing_in_goto_table} + end. + +yeccpars1([Token | Tokens], Tzr, State, States, Vstack) -> + yeccpars2(State, element(1, Token), States, Vstack, Token, Tokens, Tzr); +yeccpars1([], {{F, A},_Line}, State, States, Vstack) -> + case apply(F, A) of + {ok, Tokens, Endline} -> + yeccpars1(Tokens, {{F, A}, Endline}, State, States, Vstack); + {eof, Endline} -> + yeccpars1([], {no_func, Endline}, State, States, Vstack); + {error, Descriptor, _Endline} -> + {error, Descriptor} + end; +yeccpars1([], {no_func, no_line}, State, States, Vstack) -> + Line = 999999, + yeccpars2(State, '$end', States, Vstack, yecc_end(Line), [], + {no_func, Line}); +yeccpars1([], {no_func, Endline}, State, States, Vstack) -> + yeccpars2(State, '$end', States, Vstack, yecc_end(Endline), [], + {no_func, Endline}). + +%% yeccpars1/7 is called from generated code. +%% +%% When using the {includefile, Includefile} option, make sure that +%% yeccpars1/7 can be found by parsing the file without following +%% include directives. yecc will otherwise assume that an old +%% yeccpre.hrl is included (one which defines yeccpars1/5). +yeccpars1(State1, State, States, Vstack, Token0, [Token | Tokens], Tzr) -> + yeccpars2(State, element(1, Token), [State1 | States], + [Token0 | Vstack], Token, Tokens, Tzr); +yeccpars1(State1, State, States, Vstack, Token0, [], {{_F,_A}, _Line}=Tzr) -> + yeccpars1([], Tzr, State, [State1 | States], [Token0 | Vstack]); +yeccpars1(State1, State, States, Vstack, Token0, [], {no_func, no_line}) -> + Line = yecctoken_end_location(Token0), + yeccpars2(State, '$end', [State1 | States], [Token0 | Vstack], + yecc_end(Line), [], {no_func, Line}); +yeccpars1(State1, State, States, Vstack, Token0, [], {no_func, Line}) -> + yeccpars2(State, '$end', [State1 | States], [Token0 | Vstack], + yecc_end(Line), [], {no_func, Line}). + +%% For internal use only. +yecc_end({Line,_Column}) -> + {'$end', Line}; +yecc_end(Line) -> + {'$end', Line}. + +yecctoken_end_location(Token) -> + try erl_anno:end_location(element(2, Token)) of + undefined -> yecctoken_location(Token); + Loc -> Loc + catch _:_ -> yecctoken_location(Token) + end. + +-compile({nowarn_unused_function, yeccerror/1}). +yeccerror(Token) -> + Text = yecctoken_to_string(Token), + Location = yecctoken_location(Token), + {error, {Location, ?MODULE, ["syntax error before: ", Text]}}. + +-compile({nowarn_unused_function, yecctoken_to_string/1}). +yecctoken_to_string(Token) -> + try erl_scan:text(Token) of + undefined -> yecctoken2string(Token); + Txt -> Txt + catch _:_ -> yecctoken2string(Token) + end. + +yecctoken_location(Token) -> + try erl_scan:location(Token) + catch _:_ -> element(2, Token) + end. + +-compile({nowarn_unused_function, yecctoken2string/1}). +yecctoken2string({atom, _, A}) -> io_lib:write(A); +yecctoken2string({integer,_,N}) -> io_lib:write(N); +yecctoken2string({float,_,F}) -> io_lib:write(F); +yecctoken2string({char,_,C}) -> io_lib:write_char(C); +yecctoken2string({var,_,V}) -> io_lib:format("~s", [V]); +yecctoken2string({string,_,S}) -> io_lib:write_string(S); +yecctoken2string({reserved_symbol, _, A}) -> io_lib:write(A); +yecctoken2string({_Cat, _, Val}) -> io_lib:format("~p",[Val]); +yecctoken2string({dot, _}) -> "'.'"; +yecctoken2string({'$end', _}) -> + []; +yecctoken2string({Other, _}) when is_atom(Other) -> + io_lib:write(Other); +yecctoken2string(Other) -> + io_lib:write(Other). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + +-file("src/cf_parser.erl", 483). + +-dialyzer({nowarn_function, yeccpars2/7}). +yeccpars2(0=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_0(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(1=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_1(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(2=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_2(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(3=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_3(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(4=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_4(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(5=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_5(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(6=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_6(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(7=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_7(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(8=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_8(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(9=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_9(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(10=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_10(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(11=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_11(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(12=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_12(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(13=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_13(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(14=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_14(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(15=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_15(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(16=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_16(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(17=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_17(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(18=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_18(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(19=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_19(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(20=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_20(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(21=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_21(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(22=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_11(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(23=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_23(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(24=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_24(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(25=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_25(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(26=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_26(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(27=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_27(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(28=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_28(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(29=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_29(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(30=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_30(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(31=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_31(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(32=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_32(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(33=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_33(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(34=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_34(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(35=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_35(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(36=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_36(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(37=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_37(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(38=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_38(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(39=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_39(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(40=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_40(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(41=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_41(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(42=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_42(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(43=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_43(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(44=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_44(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(45=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(46=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_46(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(47=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_47(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(48=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_35(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(49=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_49(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(50=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_50(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(51=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_51(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(52=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_52(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(53=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_53(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(54=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_54(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(55=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_55(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(56=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_56(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(57=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_57(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(58=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_58(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(59=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_59(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(60=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_60(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(61=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_61(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(62=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_62(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(63=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_11(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(64=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_64(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(65=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_65(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(66=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_66(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(67=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_67(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(68=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_68(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(69=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_69(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(70=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_70(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(71=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_71(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(72=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_11(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(73=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_73(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(74=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_11(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(75=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_75(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(76=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_76(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(77=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_77(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(78=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_78(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(79=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_79(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(Other, _, _, _, _, _, _) -> + erlang:error({yecc_bug,"1.4",{missing_state_in_action_table, Other}}). + +yeccpars2_0(S, deftask, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr); +yeccpars2_0(S, nil, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 15, Ss, Stack, T, Ts, Tzr); +yeccpars2_0(S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_57(S, Cat, Ss, Stack, T, Ts, Tzr). + +yeccpars2_1(S, beginif, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr); +yeccpars2_1(S, deftask, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr); +yeccpars2_1(S, id, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 13, Ss, Stack, T, Ts, Tzr); +yeccpars2_1(S, intlit, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 14, Ss, Stack, T, Ts, Tzr); +yeccpars2_1(S, nil, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 15, Ss, Stack, T, Ts, Tzr); +yeccpars2_1(S, strlit, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 16, Ss, Stack, T, Ts, Tzr); +yeccpars2_1(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccgoto_script(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). + +-dialyzer({nowarn_function, yeccpars2_2/7}). +yeccpars2_2(_S, '$end', _Ss, Stack, _T, _Ts, _Tzr) -> + {ok, hd(Stack)}; +yeccpars2_2(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_3(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_3_(Stack), + yeccgoto_stat(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +yeccpars2_4(S, eq, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 63, Ss, Stack, T, Ts, Tzr); +yeccpars2_4(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccgoto_compoundexpr(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). + +yeccpars2_5(S, beginif, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr); +yeccpars2_5(S, id, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 13, Ss, Stack, T, Ts, Tzr); +yeccpars2_5(S, intlit, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 14, Ss, Stack, T, Ts, Tzr); +yeccpars2_5(S, strlit, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 16, Ss, Stack, T, Ts, Tzr); +yeccpars2_5(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_5_(Stack), + yeccgoto_exprlist(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +yeccpars2_6(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_6_(Stack), + yeccgoto_stat(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +-dialyzer({nowarn_function, yeccpars2_7/7}). +yeccpars2_7(S, semicolon, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 77, Ss, Stack, T, Ts, Tzr); +yeccpars2_7(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccgoto_expr(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). + +yeccpars2_9(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_9_(Stack), + yeccgoto_stat(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccgoto_expr(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). + +yeccpars2_11(S, nil, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 15, Ss, Stack, T, Ts, Tzr); +yeccpars2_11(S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_57(S, Cat, Ss, Stack, T, Ts, Tzr). + +-dialyzer({nowarn_function, yeccpars2_12/7}). +yeccpars2_12(S, id, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 28, Ss, Stack, T, Ts, Tzr); +yeccpars2_12(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_13(S, lparen, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 17, Ss, Stack, T, Ts, Tzr); +yeccpars2_13(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_13_(Stack), + yeccgoto_expr(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_14_(Stack), + yeccgoto_expr(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_15_(Stack), + yeccgoto_compoundexpr(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_16_(Stack), + yeccgoto_expr(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +-dialyzer({nowarn_function, yeccpars2_17/7}). +yeccpars2_17(S, id, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 20, Ss, Stack, T, Ts, Tzr); +yeccpars2_17(S, rparen, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 21, Ss, Stack, T, Ts, Tzr); +yeccpars2_17(_, _, _, _, T, _, _) -> + yeccerror(T). + +-dialyzer({nowarn_function, yeccpars2_18/7}). +yeccpars2_18(S, rparen, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 27, Ss, Stack, T, Ts, Tzr); +yeccpars2_18(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_19(S, comma, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 25, Ss, Stack, T, Ts, Tzr); +yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccgoto_bindinglist(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). + +-dialyzer({nowarn_function, yeccpars2_20/7}). +yeccpars2_20(S, colon, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 22, Ss, Stack, T, Ts, Tzr); +yeccpars2_20(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_,_|Nss] = Ss, + NewStack = yeccpars2_21_(Stack), + yeccgoto_app(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +%% yeccpars2_22: see yeccpars2_11 + +yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccgoto_compoundexpr(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). + +yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_,_|Nss] = Ss, + NewStack = yeccpars2_24_(Stack), + yeccgoto_binding(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +-dialyzer({nowarn_function, yeccpars2_25/7}). +yeccpars2_25(S, id, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 20, Ss, Stack, T, Ts, Tzr); +yeccpars2_25(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_26(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_,_|Nss] = Ss, + NewStack = yeccpars2_26_(Stack), + yeccgoto_bindinglist(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +yeccpars2_27(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_,_,_|Nss] = Ss, + NewStack = yeccpars2_27_(Stack), + yeccgoto_app(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +-dialyzer({nowarn_function, yeccpars2_28/7}). +yeccpars2_28(S, lparen, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 30, Ss, Stack, T, Ts, Tzr); +yeccpars2_28(_, _, _, _, T, _, _) -> + yeccerror(T). + +-dialyzer({nowarn_function, yeccpars2_29/7}). +yeccpars2_29(S, in, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 56, Ss, Stack, T, Ts, Tzr); +yeccpars2_29(S, lbrace, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 57, Ss, Stack, T, Ts, Tzr); +yeccpars2_29(_, _, _, _, T, _, _) -> + yeccerror(T). + +-dialyzer({nowarn_function, yeccpars2_30/7}). +yeccpars2_30(S, id, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr); +yeccpars2_30(S, ltag, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 35, Ss, Stack, T, Ts, Tzr); +yeccpars2_30(_, _, _, _, T, _, _) -> + yeccerror(T). + +-dialyzer({nowarn_function, yeccpars2_31/7}). +yeccpars2_31(S, colon, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 44, Ss, Stack, T, Ts, Tzr); +yeccpars2_31(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_32(S, id, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr); +yeccpars2_32(S, ltag, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 35, Ss, Stack, T, Ts, Tzr); +yeccpars2_32(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_32_(Stack), + yeccgoto_paramlist(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +yeccpars2_33(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_33_(Stack), + yeccgoto_param(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +yeccpars2_34(S, lparen, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 38, Ss, Stack, T, Ts, Tzr); +yeccpars2_34(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_34_(Stack), + yeccgoto_name(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +-dialyzer({nowarn_function, yeccpars2_35/7}). +yeccpars2_35(S, id, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr); +yeccpars2_35(_, _, _, _, T, _, _) -> + yeccerror(T). + +-dialyzer({nowarn_function, yeccpars2_36/7}). +yeccpars2_36(S, rtag, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 37, Ss, Stack, T, Ts, Tzr); +yeccpars2_36(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_37(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_,_|Nss] = Ss, + NewStack = yeccpars2_37_(Stack), + yeccgoto_param(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +-dialyzer({nowarn_function, yeccpars2_38/7}). +yeccpars2_38(S, file, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 39, Ss, Stack, T, Ts, Tzr); +yeccpars2_38(S, string, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 40, Ss, Stack, T, Ts, Tzr); +yeccpars2_38(_, _, _, _, T, _, _) -> + yeccerror(T). + +-dialyzer({nowarn_function, yeccpars2_39/7}). +yeccpars2_39(S, rparen, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 42, Ss, Stack, T, Ts, Tzr); +yeccpars2_39(_, _, _, _, T, _, _) -> + yeccerror(T). + +-dialyzer({nowarn_function, yeccpars2_40/7}). +yeccpars2_40(S, rparen, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 41, Ss, Stack, T, Ts, Tzr); +yeccpars2_40(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_,_,_|Nss] = Ss, + NewStack = yeccpars2_41_(Stack), + yeccgoto_name(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_,_,_|Nss] = Ss, + NewStack = yeccpars2_42_(Stack), + yeccgoto_name(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_|Nss] = Ss, + NewStack = yeccpars2_43_(Stack), + yeccgoto_paramlist(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +-dialyzer({nowarn_function, yeccpars2_44/7}). +yeccpars2_44(S, id, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr); +yeccpars2_44(S, lsquarebr, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 48, Ss, Stack, T, Ts, Tzr); +yeccpars2_44(S, ltag, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 35, Ss, Stack, T, Ts, Tzr); +yeccpars2_44(S, rparen, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 49, Ss, Stack, T, Ts, Tzr); +yeccpars2_44(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_45(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccgoto_inparam(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). + +-dialyzer({nowarn_function, yeccpars2_46/7}). +yeccpars2_46(S, rparen, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 55, Ss, Stack, T, Ts, Tzr); +yeccpars2_46(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_47(S, id, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr); +yeccpars2_47(S, lsquarebr, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 48, Ss, Stack, T, Ts, Tzr); +yeccpars2_47(S, ltag, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 35, Ss, Stack, T, Ts, Tzr); +yeccpars2_47(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_47_(Stack), + yeccgoto_inparamlist(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +%% yeccpars2_48: see yeccpars2_35 + +yeccpars2_49(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_,_,_|Nss] = Ss, + NewStack = yeccpars2_49_(Stack), + yeccgoto_sign(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +-dialyzer({nowarn_function, yeccpars2_50/7}). +yeccpars2_50(S, rsquarebr, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 53, Ss, Stack, T, Ts, Tzr); +yeccpars2_50(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_51(S, id, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr); +yeccpars2_51(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_51_(Stack), + yeccgoto_namelist(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +yeccpars2_52(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_|Nss] = Ss, + NewStack = yeccpars2_52_(Stack), + yeccgoto_namelist(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +yeccpars2_53(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_,_|Nss] = Ss, + NewStack = yeccpars2_53_(Stack), + yeccgoto_inparam(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +yeccpars2_54(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_|Nss] = Ss, + NewStack = yeccpars2_54_(Stack), + yeccgoto_inparamlist(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +yeccpars2_55(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_,_,_,_|Nss] = Ss, + NewStack = yeccpars2_55_(Stack), + yeccgoto_sign(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +-dialyzer({nowarn_function, yeccpars2_56/7}). +yeccpars2_56(S, bash, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 67, Ss, Stack, T, Ts, Tzr); +yeccpars2_56(S, python, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 68, Ss, Stack, T, Ts, Tzr); +yeccpars2_56(S, r, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 69, Ss, Stack, T, Ts, Tzr); +yeccpars2_56(_, _, _, _, T, _, _) -> + yeccerror(T). + +-dialyzer({nowarn_function, yeccpars2_57/7}). +yeccpars2_57(S, beginif, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr); +yeccpars2_57(S, id, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 13, Ss, Stack, T, Ts, Tzr); +yeccpars2_57(S, intlit, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 14, Ss, Stack, T, Ts, Tzr); +yeccpars2_57(S, strlit, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 16, Ss, Stack, T, Ts, Tzr); +yeccpars2_57(_, _, _, _, T, _, _) -> + yeccerror(T). + +-dialyzer({nowarn_function, yeccpars2_58/7}). +yeccpars2_58(S, eq, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 63, Ss, Stack, T, Ts, Tzr); +yeccpars2_58(_, _, _, _, T, _, _) -> + yeccerror(T). + +-dialyzer({nowarn_function, yeccpars2_59/7}). +yeccpars2_59(S, rbrace, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 62, Ss, Stack, T, Ts, Tzr); +yeccpars2_59(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_60(S, beginif, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr); +yeccpars2_60(S, id, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 13, Ss, Stack, T, Ts, Tzr); +yeccpars2_60(S, intlit, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 14, Ss, Stack, T, Ts, Tzr); +yeccpars2_60(S, strlit, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 16, Ss, Stack, T, Ts, Tzr); +yeccpars2_60(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccgoto_assignlist(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). + +yeccpars2_61(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_|Nss] = Ss, + NewStack = yeccpars2_61_(Stack), + yeccgoto_assignlist(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +yeccpars2_62(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_,_,_,_,_|Nss] = Ss, + NewStack = yeccpars2_62_(Stack), + yeccgoto_defun(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +%% yeccpars2_63: see yeccpars2_11 + +-dialyzer({nowarn_function, yeccpars2_64/7}). +yeccpars2_64(S, semicolon, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 65, Ss, Stack, T, Ts, Tzr); +yeccpars2_64(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_65(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_,_,_|Nss] = Ss, + NewStack = yeccpars2_65_(Stack), + yeccgoto_assign(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +-dialyzer({nowarn_function, yeccpars2_66/7}). +yeccpars2_66(S, body, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 70, Ss, Stack, T, Ts, Tzr); +yeccpars2_66(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_67(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_67_(Stack), + yeccgoto_lang(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +yeccpars2_68(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_68_(Stack), + yeccgoto_lang(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +yeccpars2_69(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_69_(Stack), + yeccgoto_lang(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +yeccpars2_70(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_,_,_,_,_|Nss] = Ss, + NewStack = yeccpars2_70_(Stack), + yeccgoto_defun(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +-dialyzer({nowarn_function, yeccpars2_71/7}). +yeccpars2_71(S, then, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 72, Ss, Stack, T, Ts, Tzr); +yeccpars2_71(_, _, _, _, T, _, _) -> + yeccerror(T). + +%% yeccpars2_72: see yeccpars2_11 + +-dialyzer({nowarn_function, yeccpars2_73/7}). +yeccpars2_73(S, else, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 74, Ss, Stack, T, Ts, Tzr); +yeccpars2_73(_, _, _, _, T, _, _) -> + yeccerror(T). + +%% yeccpars2_74: see yeccpars2_11 + +-dialyzer({nowarn_function, yeccpars2_75/7}). +yeccpars2_75(S, endif, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 76, Ss, Stack, T, Ts, Tzr); +yeccpars2_75(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_76(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_,_,_,_,_,_|Nss] = Ss, + NewStack = yeccpars2_76_(Stack), + yeccgoto_cnd(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +yeccpars2_77(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_|Nss] = Ss, + NewStack = yeccpars2_77_(Stack), + yeccgoto_query(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +yeccpars2_78(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_|Nss] = Ss, + NewStack = yeccpars2_78_(Stack), + yeccgoto_exprlist(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +yeccpars2_79(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_|Nss] = Ss, + NewStack = yeccpars2_79_(Stack), + yeccgoto_script(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +yeccgoto_app(0=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_app(1=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_app(5=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_app(11=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_app(22=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_app(57=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_app(60=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_app(63=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_app(72=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_app(74=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_assign(0=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_9(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_assign(1=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_9(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_assign(57, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_60(60, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_assign(60, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_60(60, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_assignlist(57, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_59(59, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_assignlist(60=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_61(_S, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_binding(17, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_19(19, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_binding(25, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_19(19, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_bindinglist(17, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_18(18, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_bindinglist(25=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_26(_S, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_cnd(0=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_cnd(1=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_cnd(5=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_cnd(11=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_cnd(22=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_cnd(57=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_cnd(60=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_cnd(63=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_cnd(72=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_cnd(74=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_compoundexpr(0, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_7(7, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_compoundexpr(1, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_7(7, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_compoundexpr(11, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_71(71, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_compoundexpr(22=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_compoundexpr(63, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_64(64, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_compoundexpr(72, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_73(73, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_compoundexpr(74, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_75(75, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_defun(0=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_6(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_defun(1=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_6(_S, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_expr(0, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_expr(1, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_expr(5, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_expr(11, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_expr(22, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_expr(57, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_expr(60, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_expr(63, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_expr(72, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_expr(74, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_exprlist(0, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_4(4, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_exprlist(1, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_4(4, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_exprlist(5=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_78(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_exprlist(11=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_exprlist(22=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_exprlist(57, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_58(58, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_exprlist(60, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_58(58, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_exprlist(63=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_exprlist(72=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_exprlist(74=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_inparam(44, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_47(47, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_inparam(47, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_47(47, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_inparamlist(44, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_46(46, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_inparamlist(47=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_54(_S, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_lang(56, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_66(66, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_name(30=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_33(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_name(32=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_33(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_name(35, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_name(44=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_33(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_name(47=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_33(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_name(48, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_51(51, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_name(51, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_51(51, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_namelist(48, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_50(50, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_namelist(51=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_52(_S, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_param(30, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_param(32, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_param(44=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_45(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_param(47=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_45(_S, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_paramlist(30, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_31(31, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_paramlist(32=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_query(0=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_3(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_query(1=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_3(_S, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_script(0, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_2(2, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_script(1=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_79(_S, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_sign(28, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_stat(0, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_1(1, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_stat(1, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_1(1, Cat, Ss, Stack, T, Ts, Tzr). + +-compile({inline,yeccpars2_3_/1}). +-file("src/cf_parser.yrl", 31). +yeccpars2_3_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + { __1 , # { } , # { } } + end | __Stack]. + +-compile({inline,yeccpars2_5_/1}). +-file("src/cf_parser.yrl", 58). +yeccpars2_5_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + [ __1 ] + end | __Stack]. + +-compile({inline,yeccpars2_6_/1}). +-file("src/cf_parser.yrl", 33). +yeccpars2_6_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + { [ ] , # { } , __1 } + end | __Stack]. + +-compile({inline,yeccpars2_9_/1}). +-file("src/cf_parser.yrl", 32). +yeccpars2_9_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + { [ ] , __1 , # { } } + end | __Stack]. + +-compile({inline,yeccpars2_13_/1}). +-file("src/cf_parser.yrl", 54). +yeccpars2_13_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + mk_var ( __1 ) + end | __Stack]. + +-compile({inline,yeccpars2_14_/1}). +-file("src/cf_parser.yrl", 52). +yeccpars2_14_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + mk_str ( __1 ) + end | __Stack]. + +-compile({inline,yeccpars2_15_/1}). +-file("src/cf_parser.yrl", 49). +yeccpars2_15_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + [ ] + end | __Stack]. + +-compile({inline,yeccpars2_16_/1}). +-file("src/cf_parser.yrl", 53). +yeccpars2_16_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + mk_str ( __1 ) + end | __Stack]. + +-compile({inline,yeccpars2_21_/1}). +-file("src/cf_parser.yrl", 64). +yeccpars2_21_(__Stack0) -> + [__3,__2,__1 | __Stack] = __Stack0, + [begin + { app , get_line ( __1 ) , 1 , [ mk_var ( __1 ) ] , # { } } + end | __Stack]. + +-compile({inline,yeccpars2_24_/1}). +-file("src/cf_parser.yrl", 67). +yeccpars2_24_(__Stack0) -> + [__3,__2,__1 | __Stack] = __Stack0, + [begin + mk_binding ( __1 , __3 ) + end | __Stack]. + +-compile({inline,yeccpars2_26_/1}). +-file("src/cf_parser.yrl", 70). +yeccpars2_26_(__Stack0) -> + [__3,__2,__1 | __Stack] = __Stack0, + [begin + maps : merge ( __1 , __3 ) + end | __Stack]. + +-compile({inline,yeccpars2_27_/1}). +-file("src/cf_parser.yrl", 65). +yeccpars2_27_(__Stack0) -> + [__4,__3,__2,__1 | __Stack] = __Stack0, + [begin + { app , get_line ( __1 ) , 1 , [ mk_var ( __1 ) ] , __3 } + end | __Stack]. + +-compile({inline,yeccpars2_32_/1}). +-file("src/cf_parser.yrl", 84). +yeccpars2_32_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + [ __1 ] + end | __Stack]. + +-compile({inline,yeccpars2_33_/1}). +-file("src/cf_parser.yrl", 81). +yeccpars2_33_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + { param , __1 , false } + end | __Stack]. + +-compile({inline,yeccpars2_34_/1}). +-file("src/cf_parser.yrl", 87). +yeccpars2_34_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + { name , get_name ( __1 ) , false } + end | __Stack]. + +-compile({inline,yeccpars2_37_/1}). +-file("src/cf_parser.yrl", 82). +yeccpars2_37_(__Stack0) -> + [__3,__2,__1 | __Stack] = __Stack0, + [begin + { param , __2 , true } + end | __Stack]. + +-compile({inline,yeccpars2_41_/1}). +-file("src/cf_parser.yrl", 88). +yeccpars2_41_(__Stack0) -> + [__4,__3,__2,__1 | __Stack] = __Stack0, + [begin + { name , get_name ( __1 ) , false } + end | __Stack]. + +-compile({inline,yeccpars2_42_/1}). +-file("src/cf_parser.yrl", 89). +yeccpars2_42_(__Stack0) -> + [__4,__3,__2,__1 | __Stack] = __Stack0, + [begin + { name , get_name ( __1 ) , true } + end | __Stack]. + +-compile({inline,yeccpars2_43_/1}). +-file("src/cf_parser.yrl", 85). +yeccpars2_43_(__Stack0) -> + [__2,__1 | __Stack] = __Stack0, + [begin + [ __1 | __2 ] + end | __Stack]. + +-compile({inline,yeccpars2_47_/1}). +-file("src/cf_parser.yrl", 78). +yeccpars2_47_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + [ __1 ] + end | __Stack]. + +-compile({inline,yeccpars2_49_/1}). +-file("src/cf_parser.yrl", 72). +yeccpars2_49_(__Stack0) -> + [__4,__3,__2,__1 | __Stack] = __Stack0, + [begin + { sign , __2 , [ ] , [ ] } + end | __Stack]. + +-compile({inline,yeccpars2_51_/1}). +-file("src/cf_parser.yrl", 91). +yeccpars2_51_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + [ __1 ] + end | __Stack]. + +-compile({inline,yeccpars2_52_/1}). +-file("src/cf_parser.yrl", 92). +yeccpars2_52_(__Stack0) -> + [__2,__1 | __Stack] = __Stack0, + [begin + [ __1 | __2 ] + end | __Stack]. + +-compile({inline,yeccpars2_53_/1}). +-file("src/cf_parser.yrl", 76). +yeccpars2_53_(__Stack0) -> + [__3,__2,__1 | __Stack] = __Stack0, + [begin + { correl , __2 } + end | __Stack]. + +-compile({inline,yeccpars2_54_/1}). +-file("src/cf_parser.yrl", 79). +yeccpars2_54_(__Stack0) -> + [__2,__1 | __Stack] = __Stack0, + [begin + [ __1 | __2 ] + end | __Stack]. + +-compile({inline,yeccpars2_55_/1}). +-file("src/cf_parser.yrl", 73). +yeccpars2_55_(__Stack0) -> + [__5,__4,__3,__2,__1 | __Stack] = __Stack0, + [begin + { sign , __2 , [ ] , __4 } + end | __Stack]. + +-compile({inline,yeccpars2_61_/1}). +-file("src/cf_parser.yrl", 40). +yeccpars2_61_(__Stack0) -> + [__2,__1 | __Stack] = __Stack0, + [begin + maps : merge ( __1 , __2 ) + end | __Stack]. + +-compile({inline,yeccpars2_62_/1}). +-file("src/cf_parser.yrl", 42). +yeccpars2_62_(__Stack0) -> + [__6,__5,__4,__3,__2,__1 | __Stack] = __Stack0, + [begin + mk_natlam ( __1 , __2 , __3 , __5 ) + end | __Stack]. + +-compile({inline,yeccpars2_65_/1}). +-file("src/cf_parser.yrl", 37). +yeccpars2_65_(__Stack0) -> + [__4,__3,__2,__1 | __Stack] = __Stack0, + [begin + mk_assign ( __1 , __3 , 1 ) + end | __Stack]. + +-compile({inline,yeccpars2_67_/1}). +-file("src/cf_parser.yrl", 45). +yeccpars2_67_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + bash + end | __Stack]. + +-compile({inline,yeccpars2_68_/1}). +-file("src/cf_parser.yrl", 46). +yeccpars2_68_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + python + end | __Stack]. + +-compile({inline,yeccpars2_69_/1}). +-file("src/cf_parser.yrl", 47). +yeccpars2_69_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + r + end | __Stack]. + +-compile({inline,yeccpars2_70_/1}). +-file("src/cf_parser.yrl", 43). +yeccpars2_70_(__Stack0) -> + [__6,__5,__4,__3,__2,__1 | __Stack] = __Stack0, + [begin + mk_forlam ( __1 , __2 , __3 , __5 , __6 ) + end | __Stack]. + +-compile({inline,yeccpars2_76_/1}). +-file("src/cf_parser.yrl", 62). +yeccpars2_76_(__Stack0) -> + [__7,__6,__5,__4,__3,__2,__1 | __Stack] = __Stack0, + [begin + { cnd , get_line ( __1 ) , __2 , __4 , __6 } + end | __Stack]. + +-compile({inline,yeccpars2_77_/1}). +-file("src/cf_parser.yrl", 35). +yeccpars2_77_(__Stack0) -> + [__2,__1 | __Stack] = __Stack0, + [begin + __1 + end | __Stack]. + +-compile({inline,yeccpars2_78_/1}). +-file("src/cf_parser.yrl", 59). +yeccpars2_78_(__Stack0) -> + [__2,__1 | __Stack] = __Stack0, + [begin + [ __1 | __2 ] + end | __Stack]. + +-compile({inline,yeccpars2_79_/1}). +-file("src/cf_parser.yrl", 29). +yeccpars2_79_(__Stack0) -> + [__2,__1 | __Stack] = __Stack0, + [begin + combine ( __1 , __2 ) + end | __Stack]. + + +-file("src/cf_parser.yrl", 404). diff --git a/src/cf_parser.yrl b/src/cf_parser.yrl new file mode 100644 index 0000000..300819d --- /dev/null +++ b/src/cf_parser.yrl @@ -0,0 +1,403 @@ +%% -*- erlang -*- +% +% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis +% +% Copyright 2013 Jörgen Brandt, Marc Bux, and Ulf Leser +% +% Licensed under the Apache License, Version 2.0 (the "License"); +% you may not use this file except in compliance with the License. +% You may obtain a copy of the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, +% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +% See the License for the specific language governing permissions and +% limitations under the License. + +Nonterminals + script stat assign exprlist expr binding assignlist sign query app cnd + paramlist param inparamlist inparam namelist name defun lang bindinglist + compoundexpr. + +Terminals + intlit strlit body bash beginif colon comma deftask else endif eq file in + python r lbrace lparen lsquarebr ltag nil rbrace rparen rsquarebr rtag + semicolon string then id. + + +Rootsymbol script. + +script -> stat : '$1'. +script -> stat script : combine( '$1', '$2' ). + +stat -> query : {'$1', #{}, #{}}. +stat -> assign : {[], '$1', #{}}. +stat -> defun : {[], #{}, '$1'}. + +query -> compoundexpr semicolon : '$1'. + +assign -> exprlist eq compoundexpr semicolon : mk_assign( '$1', '$3', 1 ). + +assignlist -> assign : '$1'. +assignlist -> assign assignlist : maps:merge( '$1', '$2' ). + +defun -> deftask id sign lbrace assignlist rbrace : mk_natlam( '$1', '$2', '$3', '$5' ). +defun -> deftask id sign in lang body : mk_forlam( '$1', '$2', '$3', '$5', '$6' ). + +lang -> bash : bash. +lang -> python : python. +lang -> r : r. + +compoundexpr -> nil : []. +compoundexpr -> exprlist : '$1'. + +expr -> intlit : mk_str( '$1' ). +expr -> strlit : mk_str( '$1' ). +expr -> id : mk_var( '$1' ). +expr -> cnd : '$1'. +expr -> app : '$1'. + +exprlist -> expr : ['$1']. +exprlist -> expr exprlist : ['$1'|'$2']. + +cnd -> beginif compoundexpr then compoundexpr else + compoundexpr endif : {cnd, get_line( '$1' ), '$2', '$4', '$6'}. + +app -> id lparen rparen : {app, get_line( '$1' ), 1, [mk_var( '$1' )], #{}}. +app -> id lparen bindinglist rparen : {app, get_line( '$1' ), 1, [mk_var( '$1' )], '$3'}. + +binding -> id colon compoundexpr : mk_binding( '$1', '$3' ). + +bindinglist -> binding : '$1'. +bindinglist -> binding comma bindinglist : maps:merge( '$1', '$3' ). + +sign -> lparen paramlist colon rparen : {sign, '$2', [], []}. +sign -> lparen paramlist colon inparamlist rparen : {sign, '$2', [], '$4'}. + +inparam -> param : '$1'. +inparam -> lsquarebr namelist rsquarebr : {correl, '$2'}. + +inparamlist -> inparam : ['$1']. +inparamlist -> inparam inparamlist : ['$1'|'$2']. + +param -> name : {param, '$1', false}. +param -> ltag name rtag : {param, '$2', true}. + +paramlist -> param : ['$1']. +paramlist -> param paramlist : ['$1'|'$2']. + +name -> id : {name, get_name( '$1' ), false}. +name -> id lparen string rparen : {name, get_name( '$1' ), false}. +name -> id lparen file rparen : {name, get_name( '$1' ), true}. + +namelist -> name : ['$1']. +namelist -> name namelist : ['$1'|'$2']. + + +Erlang code. + +-author( "Jörgen Brandt " ). + +-ifdef( TEST ). +-include_lib( "eunit/include/eunit.hrl" ). +-endif. + + + + + + +combine( {Target1, Rho1, Global1}, {Target2, Rho2, Global2} ) -> + {Target1++Target2, maps:merge( Rho1, Rho2 ), maps:merge( Global1, Global2 )}. + +mk_var( {id, Line, Name} ) -> {var, Line, Name}. + +mk_str( {intlit, Line, N} ) -> {str, Line, N}; +mk_str( {strlit, Line, S} ) -> {str, Line, S}. + +get_line( {_, Line, _} ) -> Line. + +get_name( {id, _Line, Name} ) -> Name. + +mk_binding( {id, _, Name}, ExprList ) -> + #{Name => ExprList}. + +mk_assign( [], _ExprList, _Channel ) -> #{}; + +mk_assign( [{var, _Line, Name}|Rest], ExprList, Channel ) -> + Rho = mk_assign( Rest, ExprList, Channel+1 ), + Value = lists:flatmap( fun( E ) -> set_channel( E, Channel ) end, ExprList ), + Rho#{Name => Value}; + +mk_assign( [E|_Rest], _ExprList, _Channel ) -> + error( {parser, nonvar_expr_left_of_eq, element( 1, E ), element( 2, E )} ). + + +set_channel( {app, Line, _Channel, LamList, Binding}, N ) -> [{app, Line, N, LamList, Binding}]; +set_channel( E, 1 ) -> [E]; +set_channel( E, _ ) -> error( {parser, cannot_set_channel_on_nonapp_expr, element( 1, E ), element( 2, E )} ). + +mk_natlam( {deftask, Line, _}, {id, _, Name}, Sign, Block ) -> + #{Name => [{lam, Line, Name, Sign, {natbody, Block}}]}. + +mk_forlam( {deftask, Line, _}, {id, _, Name}, Sign, Lang, {body, _, Code} ) -> + #{Name => [{lam, Line, Name, Sign, {forbody, Lang, Code}}]}. + + +-ifdef( TEST ). + +% TEST INDEX + +parse_test_() -> [nil_should_be_recognized(), + var_should_be_recognized(), + multi_element_compoundexpr_should_be_recognized(), + multiple_targets_should_be_joined(), + strlit_should_be_recognized(), + intlit_should_be_recognized(), + cnd_should_be_recognized(), + apply_should_be_recognized(), + call_should_be_recognized(), + assign_should_be_recognized(), + native_deftask_should_be_recognized(), + foreign_deftask_should_be_recognized(), + sign_with_inparam_should_be_recognized(), + param_should_be_recognized(), + task_correl_should_be_recognized(), + correl_inparam_should_be_recognized(), + comb_noreplace_should_be_recognized() + ]. + + +% ACTUAL TEST IMPLEMENTATION + +nil_should_be_recognized() -> + ?_assertEqual( {[], #{}, #{}}, parse_string( "nil;" ) ). + +var_should_be_recognized() -> + ?_assertEqual( {[{var, 1, "blub"}], #{}, #{}}, parse_string( "blub;" ) ). + +multi_element_compoundexpr_should_be_recognized() -> + ?_assertEqual( {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}, + parse_string( "bla blub;" ) ). + +multiple_targets_should_be_joined() -> + ?_assertEqual( {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}, + parse_string( "bla; blub;" ) ). + +strlit_should_be_recognized() -> + ?_assertEqual( {[{str, 1, "bla"}], #{}, #{}}, parse_string( "'bla';" ) ). + +intlit_should_be_recognized() -> + ?_assertEqual( {[{str, 1, "-5"}], #{}, #{}}, parse_string( "-5;" ) ). + +cnd_should_be_recognized() -> + ?_assertEqual( {[{cnd, 1, [], [{str, 1, "bla"}], [{str, 1, "blub"}]}], + #{}, #{}}, + parse_string( "if nil then 'bla' else 'blub' end;" ) ). + +apply_should_be_recognized() -> + [?_assertEqual( {[{app, 1, 1, [{var, 1, "f"}], #{}}], #{}, #{}}, + parse_string( "apply( task: f );" ) ), + ?_assertEqual( {[{app, 1, 1, [{var, 1, "f"}], #{"x" => [{var, 1, "x"}]}}], + #{}, #{}}, + parse_string( "apply( task: f, x: x );" ) ), + ?_assertEqual( {[{app, 1, 1, [{var, 1, "f"}], #{"x" => [{var, 1, "x"}], + "y" => [{str, 1, "y"}]}}], + #{}, #{}}, + parse_string( "apply( task: f, x: x, y: 'y' );" ) ), + ?_assertEqual( {[{app, 1, 1, [{var, 1, "f"}, {var, 1, "g"}], + #{"x" => [{var, 1, "x"}]}}], #{}, #{}}, + parse_string( "apply( task: f g, x: x );" ) )]. + +call_should_be_recognized() -> + [?_assertEqual( {[{app, 1, 1, [{var, 1, "f"}], #{}}], #{}, #{}}, + parse_string( "f();" ) ), + ?_assertEqual( {[{app, 1, 1, [{var, 1, "f"}], #{"x" => [{var, 1, "x"}]}}], + #{}, #{}}, parse_string( "f( x: x );" ) ), + ?_assertEqual( {[{app, 1, 1, [{var, 1, "f"}], + #{"x" => [{var, 1, "x"}], + "y" => [{str, 1, "y"}]}}], #{}, #{}}, + parse_string( "f( x: x, y: 'y' );" ) )]. + + +assign_should_be_recognized() -> + [?_assertEqual( {[], #{"x" => [{str, 1, "x"}]}, #{}}, parse_string( "x = 'x';" ) ), + ?_assertEqual( {[], #{"x" => [{app, 1, 1, [{var, 1, "f"}], #{}}], "y" => [{app, 1, 2, [{var, 1, "f"}], #{}}]}, #{}}, parse_string( "x y = f();" ) ), + ?_assertError( {parser, cannot_set_channel_on_nonapp_expr, str, 1}, parse_string( "x y = 'A';" ) ), + ?_assertError( {parser, nonvar_expr_left_of_eq, str, 1}, parse_string( "'a' = 'A';" ) )]. + +native_deftask_should_be_recognized() -> + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [], []}, + {natbody, #{"out" => [{str, 1, "A"}]}}}]}}, + parse_string( "deftask f( out : ) { out = 'A'; }" ) ). + +foreign_deftask_should_be_recognized() -> + [?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [], []}, + {forbody, bash, "out=A"}}]}}, + parse_string( "deftask f( out : )in bash *{out=A}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [], []}, + {forbody, r, "out=\"A\""}}]}}, + parse_string( "deftask f( out : )in R *{out=\"A\"}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [], []}, + {forbody, matlab, "out=\"A\""}}]}}, + parse_string( "deftask f( out : )in matlab *{out=\"A\"}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [], []}, + {forbody, octave, "out=\"A\""}}]}}, + parse_string( "deftask f( out : )in octave *{out=\"A\"}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [], []}, + {forbody, perl, ""}}]}}, + parse_string( "deftask f( out : )in perl *{}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [], []}, + {forbody, python, ""}}]}}, + parse_string( "deftask f( out : )in python *{}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [], []}, + {forbody, lisp, "(defparameter out \"A\")"}}]}}, + parse_string( "deftask f( out : )in lisp *{(defparameter out \"A\")}*" ) )]. + +sign_with_inparam_should_be_recognized() -> + [?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [], + [{param, {name, "inp", false}, false}]}, + {forbody, lisp, "(defparameter out \"A\")"}}]}}, + parse_string( "deftask f( out : inp )in lisp *{(defparameter out \"A\")}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [], + [{param, {name, "a", false}, false}, + {param, {name, "b", false}, false}]}, + {forbody, lisp, "(defparameter out \"A\")"}}]}}, + parse_string( "deftask f( out : a b )in lisp *{(defparameter out \"A\")}*" ) )]. + +param_should_be_recognized() -> + [?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [], + [{param, {name, "inp", false}, false}]}, + {forbody, bash, "blub"}}]}}, + parse_string( "deftask f( out( String ) : inp( String ) )in bash *{blub}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", true}, false}], + [], + [{param, {name, "inp", true}, false}]}, + {forbody, bash, "blub"}}]}}, + parse_string( "deftask f( out( File ) : inp( File ) )in bash *{blub}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, true}], + [], + [{param, {name, "inp", false}, true}]}, + {forbody, bash, "blub"}}]}}, + parse_string( "deftask f( : )in bash *{blub}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, true}], + [], + [{param, {name, "inp", false}, true}]}, + {forbody, bash, "blub"}}]}}, + parse_string( "deftask f( : )in bash *{blub}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", true}, true}], + [], + [{param, {name, "inp", true}, true}]}, + {forbody, bash, "blub"}}]}}, + parse_string( "deftask f( : )in bash *{blub}*" ) )]. + +task_correl_should_be_recognized() -> + [?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [{name, "a", false}], + [{param, {name, "b", false}, false}]}, + {forbody, bash, "blub"}}]}}, + parse_string( "deftask f( out : [task a] b )in bash *{blub}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [{name, "a", false}, + {name, "b", false}], + []}, + {forbody, bash, "blub"}}]}}, + parse_string( "deftask f( out : [task a b] )in bash *{blub}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [{name, "a", false}], + [{param, {name, "b", false}, false}]}, + {forbody, bash, "blub"}}]}}, + parse_string( "deftask f( out : [task a( String )] b )in bash *{blub}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [{name, "a", false}, + {name, "b", false}], + []}, + {forbody, bash, "blub"}}]}}, + parse_string( "deftask f( out : [task a( String ) b( String )] )in bash *{blub}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [{name, "a", true}], + [{param, {name, "b", false}, false}]}, + {forbody, bash, "blub"}}]}}, + parse_string( "deftask f( out : [task a( File )] b )in bash *{blub}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [{name, "a", true}, + {name, "b", true}], + []}, + {forbody, bash, "blub"}}]}}, + parse_string( "deftask f( out : [task a( File ) b( File )] )in bash *{blub}*" ) )]. + +correl_inparam_should_be_recognized() -> + [?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [], + [{correl, [{name, "a", true}, + {name, "b", true}]}]}, + {forbody, bash, "blub"}}]}}, + parse_string( "deftask f( out : [a( File ) b( File )] )in bash *{blub}*" ) ), + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [], + [{correl, [{name, "a", true}, + {name, "b", true}]}, + {param, {name, "c", false}, false}]}, + {forbody, bash, "blub"}}]}}, + parse_string( "deftask f( out : [a( File ) b( File )] c )in bash *{blub}*" ) )]. + +comb_noreplace_should_be_recognized() -> + ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [], + [{comb, cnr, {name, "x", true}, ["a", "b", "c"]}]}, + {forbody, bash, "blub"}}]}}, + parse_string( "deftask f( out : {comb noreplace x( File ): a b c} )in bash *{blub}*" ) ). + + + + + + + +parse_string( S ) -> + {ok, TokenList, _} = cuneiform_lexer:string( S ), + {ok, ParseTree} = cuneiform_parser:parse( TokenList ), + ParseTree. + + + +-endif. + + diff --git a/src/cf_sup.erl b/src/cf_sup.erl new file mode 100644 index 0000000..58a462d --- /dev/null +++ b/src/cf_sup.erl @@ -0,0 +1,44 @@ +%% -*- erlang -*- +% +% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis +% +% Copyright 2013 Jörgen Brandt, Marc Bux, and Ulf Leser +% +% Licensed under the Apache License, Version 2.0 (the "License"); +% you may not use this file except in compliance with the License. +% You may obtain a copy of the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, +% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +% See the License for the specific language governing permissions and +% limitations under the License. + +-module(cf_sup). +-author( "Jörgen Brandt " ). + +-behaviour(supervisor). + +%% API +-export( [start_link/0] ). + +%% Supervisor callbacks +-export([init/1]). + + +%% ============================================================================= +%% API functions +%% ============================================================================= + +start_link() -> + supervisor:start_link( {local, ?MODULE}, ?MODULE, [] ). + +%% ============================================================================= +%% Supervisor callbacks +%% ============================================================================= + +init( [] ) -> + {ok, { {one_for_one, 5, 10}, []} }. + From 523b2d74d2be5af6663fc41dca79af885c369d13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Wed, 17 Feb 2016 12:45:18 +0100 Subject: [PATCH 02/78] Semantics added. --- .gitignore | 1 + Makefile | 8 + ebin/cf.app | 8 - ebin/cf.beam | Bin 1080 -> 0 bytes ebin/cf_lexer.beam | Bin 68636 -> 0 bytes ebin/cf_parser.beam | Bin 42244 -> 0 bytes ebin/cf_sup.beam | Bin 1144 -> 0 bytes src/cf.erl | 4 +- src/cf_lexer.erl | 317 +++++++++++++++----------------------- src/cf_lexer.xrl | 262 ++++++++++++------------------- src/cf_parser.erl | 345 ++++++++++++++--------------------------- src/cf_parser.yrl | 277 +++++++++++---------------------- src/cf_sem.erl | 355 +++++++++++++++++++++++++++++++++++++++++++ test/cf_sem_test.erl | 282 ++++++++++++++++++++++++++++++++++ 14 files changed, 1072 insertions(+), 787 deletions(-) create mode 100644 Makefile delete mode 100644 ebin/cf.app delete mode 100644 ebin/cf.beam delete mode 100644 ebin/cf_lexer.beam delete mode 100644 ebin/cf_parser.beam delete mode 100644 ebin/cf_sup.beam create mode 100644 src/cf_sem.erl create mode 100644 test/cf_sem_test.erl diff --git a/.gitignore b/.gitignore index b93e9cd..29553ed 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ rel/example_project *~ src/cf_lexer.erl src/cf_parser.erl +doc diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a56a55a --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +all: .rebar/cf_18.2.1_plt + rebar co eu dialyze doc + +clean: + rebar clean + +.rebar/cf_18.2.1_plt: + rebar build-plt \ No newline at end of file diff --git a/ebin/cf.app b/ebin/cf.app deleted file mode 100644 index 0643c3b..0000000 --- a/ebin/cf.app +++ /dev/null @@ -1,8 +0,0 @@ -{application,cf, - [{description,"Cuneiform: A Functional Language for Large Scale Scientific Data Analysis"}, - {vsn,"2.2.0"}, - {registered,[]}, - {applications,[kernel,stdlib]}, - {mod,{cf_app,[]}}, - {env,[]}, - {modules,[cf,cf_lexer,cf_parser,cf_sup]}]}. diff --git a/ebin/cf.beam b/ebin/cf.beam deleted file mode 100644 index 12a1f4e74231f5b13cf160d5fdb9c434b0bf9be8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1080 zcmYk5e@q-j6vtI{+ti}b1SM%rYfJ)jG3A?IfRl zv+sT9y*E3v?cF^O0pNrRKW(ce+W>6oS(5l7t2y(j)$d= zaZLF?&R~!M+f983t^+#M0HDEIo&qk=sD~ox?&886CIh8K`iae z0PtW-AR3aJ_#HZtNa_+FNSLOM&Awp;Kbb5o0jA&3$P1;hVDyXSt%2^(R&Kvs#{4ic z-4{w=Sq~}51V>k2+)Pk)#uSsTbvp{SPK`v`ODB#a7YhektkR@ILX8C>@S-O*1 z0wsK*pvWR`%1F!QaJ6KImd54{rwdd^_pMfg|vVN4n>ttaYJz zs3|%)HdguOlQ8G|v3T;}@mqu63Gs&yR&QCD{b}BQr~2gNg0y;V-&gSihhNMyUvCWD zd(W}M*HeM}qq^)%Ax{h59;pK@>Hzki|XTNDr1TJfp9Zyf}`l#v!xynR) z?hg6X+|12CVyRO$TGM>j%88LjU%PVsTzcftTN7)(Mf=abw6|jS*)ta|MRm72{eZ9c zYCX3UZ~W`?+;B@*X!nBrd>>o-`>V;t*87=Db5)HuKd$ZRteRb~CQny~Jf~~Ef3IO@ zU%d3dlD@2f->wbroEZA~nM1GlygfFP*|_>)ED-uL7JGJTv2uR@`@hb>r7v$B-w+>I z(H=iJ{y}zn`>FHN^qJ-H`n}N_`^wScPey+^vbkpQ_SH?}PnE4!$|ttiGl_8AKYUSo y<)YLw`dnepxp!|dQ@wLj0CdV4`9B*l{|<7u$(^PA-dgWEZ=E*;eE%N^4*U)O8bVh9 diff --git a/ebin/cf_lexer.beam b/ebin/cf_lexer.beam deleted file mode 100644 index a33378d46a3022f59e2a815e649fee7591f4322c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68636 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 diff --git a/ebin/cf_parser.beam b/ebin/cf_parser.beam deleted file mode 100644 index 6139fb87f009d1c83e1f1f669d54b9268264b503..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 42244 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

e;9(P)?hGlQi{X_lB!hThJ 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 VOLKEaXG`9<*z*5Rm48D_{U3+(`Ktf` diff --git a/ebin/cf_sup.beam b/ebin/cf_sup.beam deleted file mode 100644 index 8f88d3a9a382974defa984858bbc1a5a96bb3bbb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1144 zcmZ?s4>Dw6U@35Nb@X*C$l5mZoMW(Y1R3IUqU;F((hqBVe+8H$;pG#ij+2VzDb zhOwDkE5PbafMP5_%nFs~fUpgQc?t@YMOI^By$E+3IlUlaUO`nm?yv>>tO#~@ukxYk^YpB z`SW+#XMq&3C6<9yGa4Jg7ODR#XNdnPX`Kb;WrMgML7|YDlOG&i@ zY2i#t%}6ZE%r7kho1DUc6xmr>&YpQ`KnvG`-M|7;&z@gUl9``Z40jY;erZWcCeTin z)TGQjp#GH9q|$V7+5o9%%*)f@Ii=fi6o<&1TTl&&bbB)z8WY`Aa`NvqV3+G%qzXEx#yN zzqlw_AChSGfPTvYI@mF(xC9tZam@k1NV;D!CpX}<-(drRk~oKM7Ipz4p>{9b>2A7@ z`UD=G@OPPgW98c&Wm`9L$Dfm&?WCCJ|9bA+xi<~{HFvsHtY7d>*C~1R+r>&PJr#Z@ zIo7xaTAx-}sFL5BWb^ifYyVm2%VB$O>qu&OD7_O^RnK;woAhtvW7nQ+dxrF#2m9{q zuYJ_@@}zdtva(Mh?OMFm5Ay=6D;G|mV(ZRizHhZ;`&t7&P04ERw&;t}JssQcb=Kza z+?t^EFjFDgA-eJ*Uq{c6^7cP58HtJ$_bhm_rgYcFLm4yNoUE$^g|rK7n^#V;J|q2v zSA%u)2OGz2X7@6V8TU7vX3yYd=J~kSRp9iY4IAXf{F{k0Ra_x+#o{_fBGGy6}Uda-HJq$?%voc|khHWcQWtd44)x<0W$YfGwj zTY!_`*W{i1mrYUhdNCt2QE@-Rs$(~RDZ?i-50uBXffxor`3scq7=<{MIaN5d82C`5 GhXDZfG-b#D diff --git a/src/cf.erl b/src/cf.erl index 77700a3..426307c 100644 --- a/src/cf.erl +++ b/src/cf.erl @@ -31,7 +31,7 @@ %% Application callbacks %% ============================================================================= -start( local, [] ) -> +start( normal, [] ) -> cf_sup:start_link(). stop( _State ) -> @@ -42,6 +42,6 @@ stop( _State ) -> %% ============================================================================= start() -> - start( local, [] ). + start( normal, [] ). diff --git a/src/cf_lexer.erl b/src/cf_lexer.erl index a3ff2ae..f7eb4e3 100644 --- a/src/cf_lexer.erl +++ b/src/cf_lexer.erl @@ -12,7 +12,7 @@ -export([format_error/1]). %% User code. This is placed here to allow extra attributes. --file("src/cf_lexer.xrl", 103). +-file("src/cf_lexer.xrl", 114). -author( "Jörgen Brandt " ). @@ -28,200 +28,127 @@ trim_body( S ) -> trim_strlit( S ) -> string:substr( S, 2, length( S )-2 ). + + +%% ============================================================================= +%% Unit Tests +%% ============================================================================= + -ifdef( TEST ). -% TEST INDEX - -token_test_() -> [ - bash_style_comment_should_be_recognized(), - c_style_comment_should_be_recognized(), - erlang_style_comment_should_be_recognized(), - multiline_comment_should_be_recognized(), - apply_should_be_recognized(), - bash_should_be_recognized(), - beginif_should_be_recognized(), - colon_should_be_recognized(), - comb_should_be_recognized(), - deftask_should_be_recognized(), - else_should_be_recognized(), - endif_should_be_recognized(), - eq_should_be_recognized(), - file_should_be_recognized(), - in_should_be_recognized(), - id_should_be_recognized(), - lisp_should_be_recognized(), - matlab_should_be_recognized(), - octave_should_be_recognized(), - perl_should_be_recognized(), - python_should_be_recognized(), - r_should_be_recognized(), - lbrace_should_be_recognized(), - lparen_should_be_recognized(), - lsquarebr_should_be_recognized(), - ltag_should_be_recognized(), - nil_should_be_recognized(), - noreplace_should_be_recognized(), - rbrace_should_be_recognized(), - rparen_should_be_recognized(), - rsquarebr_should_be_recognized(), - rtag_should_be_recognized(), - semicolon_should_be_recognized(), - string_should_be_recognized(), - task_should_be_recognized(), - then_should_be_recognized(), - intlit_should_be_recognized(), - body_should_be_recognized(), - strlit_should_be_recognized() - ]. - - - - -% ACTUAL TEST IMPLEMENTATION - -bash_style_comment_should_be_recognized() -> - ?_assertEqual( {ok, [], 1}, string( "#this is a comment" ) ). - -c_style_comment_should_be_recognized() -> - ?_assertEqual( {ok, [], 1}, string( "//this is a comment" ) ). - -erlang_style_comment_should_be_recognized() -> - ?_assertEqual( {ok, [], 1}, string( "%this is a comment" ) ). + +bash_style_comment_should_be_recognized_test() -> + ?assertEqual( {ok, [], 1}, string( "#this is a comment" ) ). +c_style_comment_should_be_recognized_test() -> + ?assertEqual( {ok, [], 1}, string( "//this is a comment" ) ). -multiline_comment_should_be_recognized() -> - [?_assertEqual( {ok, [], 1}, string( "/**/" ) ), - ?_assertEqual( {ok, [], 1}, string( "/*x*/" ) ), - ?_assertEqual( {ok, [], 1}, string( "/*xy*/" ) ), - ?_assertEqual( {ok, [], 2}, string( "/*x\ny*/" ) )]. +erlang_style_comment_should_be_recognized_test() -> + ?assertEqual( {ok, [], 1}, string( "%this is a comment" ) ). -apply_should_be_recognized() -> - ?_assertEqual( {ok, [{apply, 1, "apply"}], 1}, string( "apply" ) ). -bash_should_be_recognized() -> - ?_assertEqual( {ok, [{bash, 1, "bash"}], 1}, string( "bash" ) ). +multiline_comment_should_be_recognized_test() -> + [?assertEqual( {ok, [], 1}, string( "/**/" ) ), + ?assertEqual( {ok, [], 1}, string( "/*x*/" ) ), + ?assertEqual( {ok, [], 1}, string( "/*xy*/" ) ), + ?assertEqual( {ok, [], 2}, string( "/*x\ny*/" ) )]. + +bash_should_be_recognized_test() -> + ?assertEqual( {ok, [{bash, 1, "bash"}], 1}, string( "bash" ) ). -beginif_should_be_recognized() -> - ?_assertEqual( {ok, [{beginif, 1, "if"}], 1}, string( "if" ) ). +beginif_should_be_recognized_test() -> + ?assertEqual( {ok, [{beginif, 1, "if"}], 1}, string( "if" ) ). -colon_should_be_recognized() -> - ?_assertEqual( {ok, [{colon, 1, ":"}], 1}, string( ":" ) ). +colon_should_be_recognized_test() -> + ?assertEqual( {ok, [{colon, 1, ":"}], 1}, string( ":" ) ). -comb_should_be_recognized() -> - ?_assertEqual( {ok, [{comb, 1, "comb"}], 1}, string( "comb" ) ). +deftask_should_be_recognized_test() -> + ?assertEqual( {ok, [{deftask, 1, "deftask"}], 1}, string( "deftask" ) ). -deftask_should_be_recognized() -> - ?_assertEqual( {ok, [{deftask, 1, "deftask"}], 1}, string( "deftask" ) ). +else_should_be_recognized_test() -> + ?assertEqual( {ok, [{else, 1, "else"}], 1}, string( "else" ) ). -else_should_be_recognized() -> - ?_assertEqual( {ok, [{else, 1, "else"}], 1}, string( "else" ) ). +endif_should_be_recognized_test() -> + ?assertEqual( {ok, [{endif, 1, "end"}], 1}, string( "end" ) ). -endif_should_be_recognized() -> - ?_assertEqual( {ok, [{endif, 1, "end"}], 1}, string( "end" ) ). +eq_should_be_recognized_test() -> + ?assertEqual( {ok, [{eq, 1, "="}], 1}, string( "=" ) ). -eq_should_be_recognized() -> - ?_assertEqual( {ok, [{eq, 1, "="}], 1}, string( "=" ) ). +file_should_be_recognized_test() -> + ?assertEqual( {ok, [{file, 1, "File"}], 1}, string( "File" ) ). -file_should_be_recognized() -> - ?_assertEqual( {ok, [{file, 1, "File"}], 1}, string( "File" ) ). - -in_should_be_recognized() -> - ?_assertEqual( {ok, [{in, 1, "in"}], 1}, string( "in" ) ). - -id_should_be_recognized() -> - [?_assertEqual( {ok, [{id, 1, "inp"}], 1}, string( "inp" ) ), - ?_assertEqual( {ok, [{id, 1, "a0"}], 1}, string( "a0" ) ), - ?_assertEqual( {ok, [{id, 1, "a9"}], 1}, string( "a9" ) ), - ?_assertEqual( {ok, [{id, 1, "a."}], 1}, string( "a." ) ), - ?_assertEqual( {ok, [{id, 1, "a-"}], 1}, string( "a-" ) ), - ?_assertEqual( {ok, [{id, 1, "a_"}], 1}, string( "a_" ) ), - ?_assertEqual( {ok, [{id, 1, "a+"}], 1}, string( "a+" ) ), - ?_assertEqual( {ok, [{id, 1, "a*"}], 1}, string( "a*" ) ), - ?_assertEqual( {ok, [{id, 1, "a/"}], 1}, string( "a/" ) )]. +in_should_be_recognized_test() -> + ?assertEqual( {ok, [{in, 1, "in"}], 1}, string( "in" ) ). -lisp_should_be_recognized() -> - ?_assertEqual( {ok, [{lisp, 1, "lisp"}], 1}, string( "lisp" ) ). +id_should_be_recognized_test() -> + [?assertEqual( {ok, [{id, 1, "inp"}], 1}, string( "inp" ) ), + ?assertEqual( {ok, [{id, 1, "a0"}], 1}, string( "a0" ) ), + ?assertEqual( {ok, [{id, 1, "a9"}], 1}, string( "a9" ) ), + ?assertEqual( {ok, [{id, 1, "a."}], 1}, string( "a." ) ), + ?assertEqual( {ok, [{id, 1, "a-"}], 1}, string( "a-" ) ), + ?assertEqual( {ok, [{id, 1, "a_"}], 1}, string( "a_" ) )]. + +python_should_be_recognized_test() -> + ?assertEqual( {ok, [{python, 1, "python"}], 1}, string( "python" ) ). -matlab_should_be_recognized() -> - ?_assertEqual( {ok, [{matlab, 1, "matlab"}], 1}, string( "matlab" ) ). - -octave_should_be_recognized() -> - ?_assertEqual( {ok, [{octave, 1, "octave"}], 1}, string( "octave" ) ). - -perl_should_be_recognized() -> - ?_assertEqual( {ok, [{perl, 1, "perl"}], 1}, string( "perl" ) ). - -python_should_be_recognized() -> - ?_assertEqual( {ok, [{python, 1, "python"}], 1}, string( "python" ) ). - -r_should_be_recognized() -> - [?_assertEqual( {ok, [{r, 1, "r"}], 1}, string( "r" ) ), - ?_assertEqual( {ok, [{r, 1, "R"}], 1}, string( "R" ) )]. +r_should_be_recognized_test() -> + [?assertEqual( {ok, [{r, 1, "r"}], 1}, string( "r" ) ), + ?assertEqual( {ok, [{r, 1, "R"}], 1}, string( "R" ) )]. -lbrace_should_be_recognized() -> - ?_assertEqual( {ok, [{lbrace, 1, "{"}], 1}, string( "{" ) ). +lbrace_should_be_recognized_test() -> + ?assertEqual( {ok, [{lbrace, 1, "{"}], 1}, string( "{" ) ). -lparen_should_be_recognized() -> - ?_assertEqual( {ok, [{lparen, 1, "("}], 1}, string( "(" ) ). +lparen_should_be_recognized_test() -> + ?assertEqual( {ok, [{lparen, 1, "("}], 1}, string( "(" ) ). -lsquarebr_should_be_recognized() -> - ?_assertEqual( {ok, [{lsquarebr, 1, "["}], 1}, string( "[" ) ). +lsquarebr_should_be_recognized_test() -> + ?assertEqual( {ok, [{lsquarebr, 1, "["}], 1}, string( "[" ) ). -ltag_should_be_recognized() -> - ?_assertEqual( {ok, [{ltag, 1, "<"}], 1}, string( "<" ) ). +ltag_should_be_recognized_test() -> + ?assertEqual( {ok, [{ltag, 1, "<"}], 1}, string( "<" ) ). -nil_should_be_recognized() -> - ?_assertEqual( {ok, [{nil, 1, "nil"}], 1}, string( "nil" ) ). +nil_should_be_recognized_test() -> + ?assertEqual( {ok, [{nil, 1, "nil"}], 1}, string( "nil" ) ). + +rbrace_should_be_recognized_test() -> + ?assertEqual( {ok, [{rbrace, 1, "}"}], 1}, string( "}" ) ). -noreplace_should_be_recognized() -> - ?_assertEqual( {ok, [{noreplace, 1, "noreplace"}], 1}, - string( "noreplace" ) ). +rparen_should_be_recognized_test() -> + ?assertEqual( {ok, [{rparen, 1, ")"}], 1}, string( ")" ) ). -rbrace_should_be_recognized() -> - ?_assertEqual( {ok, [{rbrace, 1, "}"}], 1}, string( "}" ) ). +rsquarebr_should_be_recognized_test() -> + ?assertEqual( {ok, [{rsquarebr, 1, "]"}], 1}, string( "]" ) ). -rparen_should_be_recognized() -> - ?_assertEqual( {ok, [{rparen, 1, ")"}], 1}, string( ")" ) ). +rtag_should_be_recognized_test() -> + ?assertEqual( {ok, [{rtag, 1, ">"}], 1}, string( ">" ) ). -rsquarebr_should_be_recognized() -> - ?_assertEqual( {ok, [{rsquarebr, 1, "]"}], 1}, string( "]" ) ). +semicolon_should_be_recognized_test() -> + ?assertEqual( {ok, [{semicolon, 1, ";"}], 1}, string( ";" ) ). -rtag_should_be_recognized() -> - ?_assertEqual( {ok, [{rtag, 1, ">"}], 1}, string( ">" ) ). +string_should_be_recognized_test() -> + ?assertEqual( {ok, [{string, 1, "String"}], 1}, string( "String" ) ). -semicolon_should_be_recognized() -> - ?_assertEqual( {ok, [{semicolon, 1, ";"}], 1}, string( ";" ) ). +then_should_be_recognized_test() -> + ?assertEqual( {ok, [{then, 1, "then"}], 1}, string( "then" ) ). -string_should_be_recognized() -> - ?_assertEqual( {ok, [{string, 1, "String"}], 1}, string( "String" ) ). - -task_should_be_recognized() -> - ?_assertEqual( {ok, [{task, 1, "task"}], 1}, string( "task" ) ). - -then_should_be_recognized() -> - ?_assertEqual( {ok, [{then, 1, "then"}], 1}, string( "then" ) ). - -intlit_should_be_recognized() -> - [?_assertEqual( {ok, [{intlit, 1, "10"}], 1}, string( "10" ) ), - ?_assertEqual( {ok, [{intlit, 1, "-10"}], 1}, string( "-10" ) ), - ?_assertEqual( {ok, [{intlit, 1, "9"}], 1}, string( "9" ) ), - ?_assertEqual( {ok, [{intlit, 1, "0"}], 1}, string( "0" ) )]. +intlit_should_be_recognized_test() -> + [?assertEqual( {ok, [{intlit, 1, "10"}], 1}, string( "10" ) ), + ?assertEqual( {ok, [{intlit, 1, "-10"}], 1}, string( "-10" ) ), + ?assertEqual( {ok, [{intlit, 1, "9"}], 1}, string( "9" ) ), + ?assertEqual( {ok, [{intlit, 1, "0"}], 1}, string( "0" ) )]. -body_should_be_recognized() -> - [?_assertEqual( {ok, [{body, 1, ""}], 1}, string( "*{}*" ) ), - ?_assertEqual( {ok, [{body, 1, "x"}], 1}, string( "*{x}*" ) ), - ?_assertEqual( {ok, [{body, 1, "xy"}], 1}, string( "*{xy}*" ) ), - ?_assertEqual( {ok, [{body, 1, "x\ny"}], 2}, string( "*{x\ny}*" ) )]. +body_should_be_recognized_test() -> + [?assertEqual( {ok, [{body, 1, ""}], 1}, string( "*{}*" ) ), + ?assertEqual( {ok, [{body, 1, "x"}], 1}, string( "*{x}*" ) ), + ?assertEqual( {ok, [{body, 1, "xy"}], 1}, string( "*{xy}*" ) ), + ?assertEqual( {ok, [{body, 1, "x\ny"}], 2}, string( "*{x\ny}*" ) )]. -strlit_should_be_recognized() -> - [?_assertEqual( {ok, [{strlit, 1, ""}], 1}, string( "''" ) ), - ?_assertEqual( {ok, [{strlit, 1, ""}], 1}, string( "\"\"" ) ), - ?_assertEqual( {ok, [{strlit, 1, "x"}], 1}, string( "'x'" ) ), - ?_assertEqual( {ok, [{strlit, 1, "x"}], 1}, string( "\"x\"" ) ), - ?_assertEqual( {ok, [{strlit, 1, "xy"}], 1}, string( "'xy'" ) ), - ?_assertEqual( {ok, [{strlit, 1, "xy"}], 1}, string( "\"xy\"" ) )]. +strlit_should_be_recognized_test() -> + [?assertEqual( {ok, [{strlit, 1, ""}], 1}, string( "\"\"" ) ), + ?assertEqual( {ok, [{strlit, 1, "x"}], 1}, string( "\"x\"" ) ), + ?assertEqual( {ok, [{strlit, 1, "xy"}], 1}, string( "\"xy\"" ) )]. @@ -499,7 +426,7 @@ yysuf(List, N) -> lists:nthtail(N, List). %% return signal either an unrecognised character or end of current %% input. --file("src/cf_lexer.erl", 501). +-file("src/cf_lexer.erl", 428). yystate() -> 69. yystate(72, [122|Ics], Line, Tlen, _, _) -> @@ -1592,157 +1519,157 @@ yyaction(30, _, _, _) -> yyaction(_, _, _, _) -> error. -compile({inline,yyaction_0/2}). --file("src/cf_lexer.xrl", 61). +-file("src/cf_lexer.xrl", 69). yyaction_0(TokenChars, TokenLine) -> { token, { bash, TokenLine, TokenChars } } . -compile({inline,yyaction_1/2}). --file("src/cf_lexer.xrl", 62). +-file("src/cf_lexer.xrl", 70). yyaction_1(TokenChars, TokenLine) -> { token, { python, TokenLine, TokenChars } } . -compile({inline,yyaction_2/2}). --file("src/cf_lexer.xrl", 63). +-file("src/cf_lexer.xrl", 71). yyaction_2(TokenChars, TokenLine) -> { token, { r, TokenLine, TokenChars } } . -compile({inline,yyaction_3/2}). --file("src/cf_lexer.xrl", 65). +-file("src/cf_lexer.xrl", 73). yyaction_3(TokenChars, TokenLine) -> { token, { intlit, TokenLine, TokenChars } } . -compile({inline,yyaction_4/2}). --file("src/cf_lexer.xrl", 66). +-file("src/cf_lexer.xrl", 74). yyaction_4(TokenChars, TokenLine) -> { token, { strlit, TokenLine, trim_strlit (TokenChars) } } . -compile({inline,yyaction_5/2}). --file("src/cf_lexer.xrl", 67). +-file("src/cf_lexer.xrl", 75). yyaction_5(TokenChars, TokenLine) -> { token, { body, TokenLine, trim_body (TokenChars) } } . -compile({inline,yyaction_6/2}). --file("src/cf_lexer.xrl", 68). +-file("src/cf_lexer.xrl", 76). yyaction_6(TokenChars, TokenLine) -> { token, { beginif, TokenLine, TokenChars } } . -compile({inline,yyaction_7/2}). --file("src/cf_lexer.xrl", 69). +-file("src/cf_lexer.xrl", 77). yyaction_7(TokenChars, TokenLine) -> { token, { colon, TokenLine, TokenChars } } . -compile({inline,yyaction_8/2}). --file("src/cf_lexer.xrl", 70). +-file("src/cf_lexer.xrl", 78). yyaction_8(TokenChars, TokenLine) -> { token, { comma, TokenLine, TokenChars } } . -compile({inline,yyaction_9/2}). --file("src/cf_lexer.xrl", 71). +-file("src/cf_lexer.xrl", 79). yyaction_9(TokenChars, TokenLine) -> { token, { deftask, TokenLine, TokenChars } } . -compile({inline,yyaction_10/2}). --file("src/cf_lexer.xrl", 72). +-file("src/cf_lexer.xrl", 80). yyaction_10(TokenChars, TokenLine) -> { token, { else, TokenLine, TokenChars } } . -compile({inline,yyaction_11/2}). --file("src/cf_lexer.xrl", 73). +-file("src/cf_lexer.xrl", 81). yyaction_11(TokenChars, TokenLine) -> { token, { endif, TokenLine, TokenChars } } . -compile({inline,yyaction_12/2}). --file("src/cf_lexer.xrl", 74). +-file("src/cf_lexer.xrl", 82). yyaction_12(TokenChars, TokenLine) -> { token, { eq, TokenLine, TokenChars } } . -compile({inline,yyaction_13/2}). --file("src/cf_lexer.xrl", 75). +-file("src/cf_lexer.xrl", 83). yyaction_13(TokenChars, TokenLine) -> { token, { file, TokenLine, TokenChars } } . -compile({inline,yyaction_14/2}). --file("src/cf_lexer.xrl", 76). +-file("src/cf_lexer.xrl", 84). yyaction_14(TokenChars, TokenLine) -> { token, { in, TokenLine, TokenChars } } . -compile({inline,yyaction_15/2}). --file("src/cf_lexer.xrl", 77). +-file("src/cf_lexer.xrl", 85). yyaction_15(TokenChars, TokenLine) -> { token, { lbrace, TokenLine, TokenChars } } . -compile({inline,yyaction_16/2}). --file("src/cf_lexer.xrl", 78). +-file("src/cf_lexer.xrl", 86). yyaction_16(TokenChars, TokenLine) -> { token, { lparen, TokenLine, TokenChars } } . -compile({inline,yyaction_17/2}). --file("src/cf_lexer.xrl", 79). +-file("src/cf_lexer.xrl", 87). yyaction_17(TokenChars, TokenLine) -> { token, { lsquarebr, TokenLine, TokenChars } } . -compile({inline,yyaction_18/2}). --file("src/cf_lexer.xrl", 80). +-file("src/cf_lexer.xrl", 88). yyaction_18(TokenChars, TokenLine) -> { token, { ltag, TokenLine, TokenChars } } . -compile({inline,yyaction_19/2}). --file("src/cf_lexer.xrl", 81). +-file("src/cf_lexer.xrl", 89). yyaction_19(TokenChars, TokenLine) -> { token, { nil, TokenLine, TokenChars } } . -compile({inline,yyaction_20/2}). --file("src/cf_lexer.xrl", 82). +-file("src/cf_lexer.xrl", 90). yyaction_20(TokenChars, TokenLine) -> { token, { rbrace, TokenLine, TokenChars } } . -compile({inline,yyaction_21/2}). --file("src/cf_lexer.xrl", 83). +-file("src/cf_lexer.xrl", 91). yyaction_21(TokenChars, TokenLine) -> { token, { rparen, TokenLine, TokenChars } } . -compile({inline,yyaction_22/2}). --file("src/cf_lexer.xrl", 84). +-file("src/cf_lexer.xrl", 92). yyaction_22(TokenChars, TokenLine) -> { token, { rsquarebr, TokenLine, TokenChars } } . -compile({inline,yyaction_23/2}). --file("src/cf_lexer.xrl", 85). +-file("src/cf_lexer.xrl", 93). yyaction_23(TokenChars, TokenLine) -> { token, { rtag, TokenLine, TokenChars } } . -compile({inline,yyaction_24/2}). --file("src/cf_lexer.xrl", 86). +-file("src/cf_lexer.xrl", 94). yyaction_24(TokenChars, TokenLine) -> { token, { semicolon, TokenLine, TokenChars } } . -compile({inline,yyaction_25/2}). --file("src/cf_lexer.xrl", 87). +-file("src/cf_lexer.xrl", 95). yyaction_25(TokenChars, TokenLine) -> { token, { string, TokenLine, TokenChars } } . -compile({inline,yyaction_26/2}). --file("src/cf_lexer.xrl", 88). +-file("src/cf_lexer.xrl", 96). yyaction_26(TokenChars, TokenLine) -> { token, { then, TokenLine, TokenChars } } . -compile({inline,yyaction_27/2}). --file("src/cf_lexer.xrl", 90). +-file("src/cf_lexer.xrl", 98). yyaction_27(TokenChars, TokenLine) -> { token, { id, TokenLine, TokenChars } } . -compile({inline,yyaction_28/0}). --file("src/cf_lexer.xrl", 92). +-file("src/cf_lexer.xrl", 100). yyaction_28() -> skip_token . -compile({inline,yyaction_29/0}). --file("src/cf_lexer.xrl", 93). +-file("src/cf_lexer.xrl", 101). yyaction_29() -> skip_token . -compile({inline,yyaction_30/0}). --file("src/cf_lexer.xrl", 94). +-file("src/cf_lexer.xrl", 102). yyaction_30() -> skip_token . diff --git a/src/cf_lexer.xrl b/src/cf_lexer.xrl index 51b6cf9..1bb685f 100644 --- a/src/cf_lexer.xrl +++ b/src/cf_lexer.xrl @@ -16,6 +16,11 @@ % See the License for the specific language governing permissions and % limitations under the License. +%% ============================================================================= +%% Definitions +%% ============================================================================= + + Definitions. BASH = [Bb]ash @@ -57,6 +62,9 @@ WS = [\000-\s] +%% ============================================================================= +%% Rules +%% ============================================================================= Rules. @@ -98,6 +106,9 @@ Rules. +%% ============================================================================= +%% Erlang Code +%% ============================================================================= Erlang code. @@ -116,200 +127,127 @@ trim_body( S ) -> trim_strlit( S ) -> string:substr( S, 2, length( S )-2 ). + + +%% ============================================================================= +%% Unit Tests +%% ============================================================================= + -ifdef( TEST ). -% TEST INDEX - -token_test_() -> [ - bash_style_comment_should_be_recognized(), - c_style_comment_should_be_recognized(), - erlang_style_comment_should_be_recognized(), - multiline_comment_should_be_recognized(), - apply_should_be_recognized(), - bash_should_be_recognized(), - beginif_should_be_recognized(), - colon_should_be_recognized(), - comb_should_be_recognized(), - deftask_should_be_recognized(), - else_should_be_recognized(), - endif_should_be_recognized(), - eq_should_be_recognized(), - file_should_be_recognized(), - in_should_be_recognized(), - id_should_be_recognized(), - lisp_should_be_recognized(), - matlab_should_be_recognized(), - octave_should_be_recognized(), - perl_should_be_recognized(), - python_should_be_recognized(), - r_should_be_recognized(), - lbrace_should_be_recognized(), - lparen_should_be_recognized(), - lsquarebr_should_be_recognized(), - ltag_should_be_recognized(), - nil_should_be_recognized(), - noreplace_should_be_recognized(), - rbrace_should_be_recognized(), - rparen_should_be_recognized(), - rsquarebr_should_be_recognized(), - rtag_should_be_recognized(), - semicolon_should_be_recognized(), - string_should_be_recognized(), - task_should_be_recognized(), - then_should_be_recognized(), - intlit_should_be_recognized(), - body_should_be_recognized(), - strlit_should_be_recognized() - ]. - - - - -% ACTUAL TEST IMPLEMENTATION - -bash_style_comment_should_be_recognized() -> - ?_assertEqual( {ok, [], 1}, string( "#this is a comment" ) ). - -c_style_comment_should_be_recognized() -> - ?_assertEqual( {ok, [], 1}, string( "//this is a comment" ) ). - -erlang_style_comment_should_be_recognized() -> - ?_assertEqual( {ok, [], 1}, string( "%this is a comment" ) ). + +bash_style_comment_should_be_recognized_test() -> + ?assertEqual( {ok, [], 1}, string( "#this is a comment" ) ). +c_style_comment_should_be_recognized_test() -> + ?assertEqual( {ok, [], 1}, string( "//this is a comment" ) ). -multiline_comment_should_be_recognized() -> - [?_assertEqual( {ok, [], 1}, string( "/**/" ) ), - ?_assertEqual( {ok, [], 1}, string( "/*x*/" ) ), - ?_assertEqual( {ok, [], 1}, string( "/*xy*/" ) ), - ?_assertEqual( {ok, [], 2}, string( "/*x\ny*/" ) )]. +erlang_style_comment_should_be_recognized_test() -> + ?assertEqual( {ok, [], 1}, string( "%this is a comment" ) ). -apply_should_be_recognized() -> - ?_assertEqual( {ok, [{apply, 1, "apply"}], 1}, string( "apply" ) ). -bash_should_be_recognized() -> - ?_assertEqual( {ok, [{bash, 1, "bash"}], 1}, string( "bash" ) ). +multiline_comment_should_be_recognized_test() -> + [?assertEqual( {ok, [], 1}, string( "/**/" ) ), + ?assertEqual( {ok, [], 1}, string( "/*x*/" ) ), + ?assertEqual( {ok, [], 1}, string( "/*xy*/" ) ), + ?assertEqual( {ok, [], 2}, string( "/*x\ny*/" ) )]. + +bash_should_be_recognized_test() -> + ?assertEqual( {ok, [{bash, 1, "bash"}], 1}, string( "bash" ) ). -beginif_should_be_recognized() -> - ?_assertEqual( {ok, [{beginif, 1, "if"}], 1}, string( "if" ) ). +beginif_should_be_recognized_test() -> + ?assertEqual( {ok, [{beginif, 1, "if"}], 1}, string( "if" ) ). -colon_should_be_recognized() -> - ?_assertEqual( {ok, [{colon, 1, ":"}], 1}, string( ":" ) ). +colon_should_be_recognized_test() -> + ?assertEqual( {ok, [{colon, 1, ":"}], 1}, string( ":" ) ). -comb_should_be_recognized() -> - ?_assertEqual( {ok, [{comb, 1, "comb"}], 1}, string( "comb" ) ). - -deftask_should_be_recognized() -> - ?_assertEqual( {ok, [{deftask, 1, "deftask"}], 1}, string( "deftask" ) ). +deftask_should_be_recognized_test() -> + ?assertEqual( {ok, [{deftask, 1, "deftask"}], 1}, string( "deftask" ) ). -else_should_be_recognized() -> - ?_assertEqual( {ok, [{else, 1, "else"}], 1}, string( "else" ) ). +else_should_be_recognized_test() -> + ?assertEqual( {ok, [{else, 1, "else"}], 1}, string( "else" ) ). -endif_should_be_recognized() -> - ?_assertEqual( {ok, [{endif, 1, "end"}], 1}, string( "end" ) ). +endif_should_be_recognized_test() -> + ?assertEqual( {ok, [{endif, 1, "end"}], 1}, string( "end" ) ). -eq_should_be_recognized() -> - ?_assertEqual( {ok, [{eq, 1, "="}], 1}, string( "=" ) ). +eq_should_be_recognized_test() -> + ?assertEqual( {ok, [{eq, 1, "="}], 1}, string( "=" ) ). -file_should_be_recognized() -> - ?_assertEqual( {ok, [{file, 1, "File"}], 1}, string( "File" ) ). +file_should_be_recognized_test() -> + ?assertEqual( {ok, [{file, 1, "File"}], 1}, string( "File" ) ). -in_should_be_recognized() -> - ?_assertEqual( {ok, [{in, 1, "in"}], 1}, string( "in" ) ). +in_should_be_recognized_test() -> + ?assertEqual( {ok, [{in, 1, "in"}], 1}, string( "in" ) ). -id_should_be_recognized() -> - [?_assertEqual( {ok, [{id, 1, "inp"}], 1}, string( "inp" ) ), - ?_assertEqual( {ok, [{id, 1, "a0"}], 1}, string( "a0" ) ), - ?_assertEqual( {ok, [{id, 1, "a9"}], 1}, string( "a9" ) ), - ?_assertEqual( {ok, [{id, 1, "a."}], 1}, string( "a." ) ), - ?_assertEqual( {ok, [{id, 1, "a-"}], 1}, string( "a-" ) ), - ?_assertEqual( {ok, [{id, 1, "a_"}], 1}, string( "a_" ) ), - ?_assertEqual( {ok, [{id, 1, "a+"}], 1}, string( "a+" ) ), - ?_assertEqual( {ok, [{id, 1, "a*"}], 1}, string( "a*" ) ), - ?_assertEqual( {ok, [{id, 1, "a/"}], 1}, string( "a/" ) )]. +id_should_be_recognized_test() -> + [?assertEqual( {ok, [{id, 1, "inp"}], 1}, string( "inp" ) ), + ?assertEqual( {ok, [{id, 1, "a0"}], 1}, string( "a0" ) ), + ?assertEqual( {ok, [{id, 1, "a9"}], 1}, string( "a9" ) ), + ?assertEqual( {ok, [{id, 1, "a."}], 1}, string( "a." ) ), + ?assertEqual( {ok, [{id, 1, "a-"}], 1}, string( "a-" ) ), + ?assertEqual( {ok, [{id, 1, "a_"}], 1}, string( "a_" ) )]. + +python_should_be_recognized_test() -> + ?assertEqual( {ok, [{python, 1, "python"}], 1}, string( "python" ) ). -lisp_should_be_recognized() -> - ?_assertEqual( {ok, [{lisp, 1, "lisp"}], 1}, string( "lisp" ) ). - -matlab_should_be_recognized() -> - ?_assertEqual( {ok, [{matlab, 1, "matlab"}], 1}, string( "matlab" ) ). - -octave_should_be_recognized() -> - ?_assertEqual( {ok, [{octave, 1, "octave"}], 1}, string( "octave" ) ). - -perl_should_be_recognized() -> - ?_assertEqual( {ok, [{perl, 1, "perl"}], 1}, string( "perl" ) ). - -python_should_be_recognized() -> - ?_assertEqual( {ok, [{python, 1, "python"}], 1}, string( "python" ) ). - -r_should_be_recognized() -> - [?_assertEqual( {ok, [{r, 1, "r"}], 1}, string( "r" ) ), - ?_assertEqual( {ok, [{r, 1, "R"}], 1}, string( "R" ) )]. +r_should_be_recognized_test() -> + [?assertEqual( {ok, [{r, 1, "r"}], 1}, string( "r" ) ), + ?assertEqual( {ok, [{r, 1, "R"}], 1}, string( "R" ) )]. -lbrace_should_be_recognized() -> - ?_assertEqual( {ok, [{lbrace, 1, "{"}], 1}, string( "{" ) ). - -lparen_should_be_recognized() -> - ?_assertEqual( {ok, [{lparen, 1, "("}], 1}, string( "(" ) ). - -lsquarebr_should_be_recognized() -> - ?_assertEqual( {ok, [{lsquarebr, 1, "["}], 1}, string( "[" ) ). - -ltag_should_be_recognized() -> - ?_assertEqual( {ok, [{ltag, 1, "<"}], 1}, string( "<" ) ). +lbrace_should_be_recognized_test() -> + ?assertEqual( {ok, [{lbrace, 1, "{"}], 1}, string( "{" ) ). -nil_should_be_recognized() -> - ?_assertEqual( {ok, [{nil, 1, "nil"}], 1}, string( "nil" ) ). +lparen_should_be_recognized_test() -> + ?assertEqual( {ok, [{lparen, 1, "("}], 1}, string( "(" ) ). -noreplace_should_be_recognized() -> - ?_assertEqual( {ok, [{noreplace, 1, "noreplace"}], 1}, - string( "noreplace" ) ). +lsquarebr_should_be_recognized_test() -> + ?assertEqual( {ok, [{lsquarebr, 1, "["}], 1}, string( "[" ) ). -rbrace_should_be_recognized() -> - ?_assertEqual( {ok, [{rbrace, 1, "}"}], 1}, string( "}" ) ). +ltag_should_be_recognized_test() -> + ?assertEqual( {ok, [{ltag, 1, "<"}], 1}, string( "<" ) ). -rparen_should_be_recognized() -> - ?_assertEqual( {ok, [{rparen, 1, ")"}], 1}, string( ")" ) ). +nil_should_be_recognized_test() -> + ?assertEqual( {ok, [{nil, 1, "nil"}], 1}, string( "nil" ) ). + +rbrace_should_be_recognized_test() -> + ?assertEqual( {ok, [{rbrace, 1, "}"}], 1}, string( "}" ) ). -rsquarebr_should_be_recognized() -> - ?_assertEqual( {ok, [{rsquarebr, 1, "]"}], 1}, string( "]" ) ). +rparen_should_be_recognized_test() -> + ?assertEqual( {ok, [{rparen, 1, ")"}], 1}, string( ")" ) ). -rtag_should_be_recognized() -> - ?_assertEqual( {ok, [{rtag, 1, ">"}], 1}, string( ">" ) ). +rsquarebr_should_be_recognized_test() -> + ?assertEqual( {ok, [{rsquarebr, 1, "]"}], 1}, string( "]" ) ). -semicolon_should_be_recognized() -> - ?_assertEqual( {ok, [{semicolon, 1, ";"}], 1}, string( ";" ) ). +rtag_should_be_recognized_test() -> + ?assertEqual( {ok, [{rtag, 1, ">"}], 1}, string( ">" ) ). -string_should_be_recognized() -> - ?_assertEqual( {ok, [{string, 1, "String"}], 1}, string( "String" ) ). +semicolon_should_be_recognized_test() -> + ?assertEqual( {ok, [{semicolon, 1, ";"}], 1}, string( ";" ) ). -task_should_be_recognized() -> - ?_assertEqual( {ok, [{task, 1, "task"}], 1}, string( "task" ) ). +string_should_be_recognized_test() -> + ?assertEqual( {ok, [{string, 1, "String"}], 1}, string( "String" ) ). -then_should_be_recognized() -> - ?_assertEqual( {ok, [{then, 1, "then"}], 1}, string( "then" ) ). +then_should_be_recognized_test() -> + ?assertEqual( {ok, [{then, 1, "then"}], 1}, string( "then" ) ). -intlit_should_be_recognized() -> - [?_assertEqual( {ok, [{intlit, 1, "10"}], 1}, string( "10" ) ), - ?_assertEqual( {ok, [{intlit, 1, "-10"}], 1}, string( "-10" ) ), - ?_assertEqual( {ok, [{intlit, 1, "9"}], 1}, string( "9" ) ), - ?_assertEqual( {ok, [{intlit, 1, "0"}], 1}, string( "0" ) )]. +intlit_should_be_recognized_test() -> + [?assertEqual( {ok, [{intlit, 1, "10"}], 1}, string( "10" ) ), + ?assertEqual( {ok, [{intlit, 1, "-10"}], 1}, string( "-10" ) ), + ?assertEqual( {ok, [{intlit, 1, "9"}], 1}, string( "9" ) ), + ?assertEqual( {ok, [{intlit, 1, "0"}], 1}, string( "0" ) )]. -body_should_be_recognized() -> - [?_assertEqual( {ok, [{body, 1, ""}], 1}, string( "*{}*" ) ), - ?_assertEqual( {ok, [{body, 1, "x"}], 1}, string( "*{x}*" ) ), - ?_assertEqual( {ok, [{body, 1, "xy"}], 1}, string( "*{xy}*" ) ), - ?_assertEqual( {ok, [{body, 1, "x\ny"}], 2}, string( "*{x\ny}*" ) )]. +body_should_be_recognized_test() -> + [?assertEqual( {ok, [{body, 1, ""}], 1}, string( "*{}*" ) ), + ?assertEqual( {ok, [{body, 1, "x"}], 1}, string( "*{x}*" ) ), + ?assertEqual( {ok, [{body, 1, "xy"}], 1}, string( "*{xy}*" ) ), + ?assertEqual( {ok, [{body, 1, "x\ny"}], 2}, string( "*{x\ny}*" ) )]. -strlit_should_be_recognized() -> - [?_assertEqual( {ok, [{strlit, 1, ""}], 1}, string( "''" ) ), - ?_assertEqual( {ok, [{strlit, 1, ""}], 1}, string( "\"\"" ) ), - ?_assertEqual( {ok, [{strlit, 1, "x"}], 1}, string( "'x'" ) ), - ?_assertEqual( {ok, [{strlit, 1, "x"}], 1}, string( "\"x\"" ) ), - ?_assertEqual( {ok, [{strlit, 1, "xy"}], 1}, string( "'xy'" ) ), - ?_assertEqual( {ok, [{strlit, 1, "xy"}], 1}, string( "\"xy\"" ) )]. +strlit_should_be_recognized_test() -> + [?assertEqual( {ok, [{strlit, 1, ""}], 1}, string( "\"\"" ) ), + ?assertEqual( {ok, [{strlit, 1, "x"}], 1}, string( "\"x\"" ) ), + ?assertEqual( {ok, [{strlit, 1, "xy"}], 1}, string( "\"xy\"" ) )]. diff --git a/src/cf_parser.erl b/src/cf_parser.erl index 30abc95..3b98c98 100644 --- a/src/cf_parser.erl +++ b/src/cf_parser.erl @@ -1,13 +1,19 @@ -module(cf_parser). -export([parse/1, parse_and_scan/1, format_error/1]). --file("src/cf_parser.yrl", 99). +-file("src/cf_parser.yrl", 111). -author( "Jörgen Brandt " ). +-export( [parse_string/1] ). + -ifdef( TEST ). -include_lib( "eunit/include/eunit.hrl" ). -endif. +parse_string( S ) -> + {ok, TokenList, _} = cf_lexer:string( S ), + {ok, ParseTree} = cf_parser:parse( TokenList ), + ParseTree. @@ -49,259 +55,138 @@ mk_natlam( {deftask, Line, _}, {id, _, Name}, Sign, Block ) -> mk_forlam( {deftask, Line, _}, {id, _, Name}, Sign, Lang, {body, _, Code} ) -> #{Name => [{lam, Line, Name, Sign, {forbody, Lang, Code}}]}. - + +%% ============================================================================= +%% Unit Tests +%% ============================================================================= + -ifdef( TEST ). -% TEST INDEX - -parse_test_() -> [nil_should_be_recognized(), - var_should_be_recognized(), - multi_element_compoundexpr_should_be_recognized(), - multiple_targets_should_be_joined(), - strlit_should_be_recognized(), - intlit_should_be_recognized(), - cnd_should_be_recognized(), - apply_should_be_recognized(), - call_should_be_recognized(), - assign_should_be_recognized(), - native_deftask_should_be_recognized(), - foreign_deftask_should_be_recognized(), - sign_with_inparam_should_be_recognized(), - param_should_be_recognized(), - task_correl_should_be_recognized(), - correl_inparam_should_be_recognized(), - comb_noreplace_should_be_recognized() - ]. - - -% ACTUAL TEST IMPLEMENTATION - -nil_should_be_recognized() -> - ?_assertEqual( {[], #{}, #{}}, parse_string( "nil;" ) ). +nil_should_be_recognized_test() -> + ?assertEqual( {[], #{}, #{}}, parse_string( "nil;" ) ). -var_should_be_recognized() -> - ?_assertEqual( {[{var, 1, "blub"}], #{}, #{}}, parse_string( "blub;" ) ). +var_should_be_recognized_test() -> + ?assertEqual( {[{var, 1, "blub"}], #{}, #{}}, parse_string( "blub;" ) ). -multi_element_compoundexpr_should_be_recognized() -> - ?_assertEqual( {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}, +multi_element_compoundexpr_should_be_recognized_test() -> + ?assertEqual( {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}, parse_string( "bla blub;" ) ). -multiple_targets_should_be_joined() -> - ?_assertEqual( {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}, +multiple_targets_should_be_joined_test() -> + ?assertEqual( {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}, parse_string( "bla; blub;" ) ). -strlit_should_be_recognized() -> - ?_assertEqual( {[{str, 1, "bla"}], #{}, #{}}, parse_string( "'bla';" ) ). +strlit_should_be_recognized_test() -> + ?assertEqual( {[{str, 1, "bla"}], #{}, #{}}, parse_string( "\"bla\";" ) ). -intlit_should_be_recognized() -> - ?_assertEqual( {[{str, 1, "-5"}], #{}, #{}}, parse_string( "-5;" ) ). +intlit_should_be_recognized_test() -> + ?assertEqual( {[{str, 1, "-5"}], #{}, #{}}, parse_string( "-5;" ) ). -cnd_should_be_recognized() -> - ?_assertEqual( {[{cnd, 1, [], [{str, 1, "bla"}], [{str, 1, "blub"}]}], +cnd_should_be_recognized_test() -> + ?assertEqual( {[{cnd, 1, [], [{str, 1, "bla"}], [{str, 1, "blub"}]}], #{}, #{}}, - parse_string( "if nil then 'bla' else 'blub' end;" ) ). - -apply_should_be_recognized() -> - [?_assertEqual( {[{app, 1, 1, [{var, 1, "f"}], #{}}], #{}, #{}}, - parse_string( "apply( task: f );" ) ), - ?_assertEqual( {[{app, 1, 1, [{var, 1, "f"}], #{"x" => [{var, 1, "x"}]}}], - #{}, #{}}, - parse_string( "apply( task: f, x: x );" ) ), - ?_assertEqual( {[{app, 1, 1, [{var, 1, "f"}], #{"x" => [{var, 1, "x"}], - "y" => [{str, 1, "y"}]}}], - #{}, #{}}, - parse_string( "apply( task: f, x: x, y: 'y' );" ) ), - ?_assertEqual( {[{app, 1, 1, [{var, 1, "f"}, {var, 1, "g"}], - #{"x" => [{var, 1, "x"}]}}], #{}, #{}}, - parse_string( "apply( task: f g, x: x );" ) )]. - -call_should_be_recognized() -> - [?_assertEqual( {[{app, 1, 1, [{var, 1, "f"}], #{}}], #{}, #{}}, + parse_string( "if nil then \"bla\" else \"blub\" end;" ) ). + +app_should_be_recognized_test() -> + [?assertEqual( {[{app, 1, 1, {var, 1, "f"}, #{}}], #{}, #{}}, parse_string( "f();" ) ), - ?_assertEqual( {[{app, 1, 1, [{var, 1, "f"}], #{"x" => [{var, 1, "x"}]}}], + ?assertEqual( {[{app, 1, 1, {var, 1, "f"}, #{"x" => [{var, 1, "x"}]}}], #{}, #{}}, parse_string( "f( x: x );" ) ), - ?_assertEqual( {[{app, 1, 1, [{var, 1, "f"}], + ?assertEqual( {[{app, 1, 1, {var, 1, "f"}, #{"x" => [{var, 1, "x"}], "y" => [{str, 1, "y"}]}}], #{}, #{}}, - parse_string( "f( x: x, y: 'y' );" ) )]. + parse_string( "f( x: x, y: \"y\" );" ) )]. -assign_should_be_recognized() -> - [?_assertEqual( {[], #{"x" => [{str, 1, "x"}]}, #{}}, parse_string( "x = 'x';" ) ), - ?_assertEqual( {[], #{"x" => [{app, 1, 1, [{var, 1, "f"}], #{}}], "y" => [{app, 1, 2, [{var, 1, "f"}], #{}}]}, #{}}, parse_string( "x y = f();" ) ), - ?_assertError( {parser, cannot_set_channel_on_nonapp_expr, str, 1}, parse_string( "x y = 'A';" ) ), - ?_assertError( {parser, nonvar_expr_left_of_eq, str, 1}, parse_string( "'a' = 'A';" ) )]. +assign_should_be_recognized_test() -> + [?assertEqual( {[], #{"x" => [{str, 1, "x"}]}, #{}}, parse_string( "x = \"x\";" ) ), + ?assertEqual( {[], #{"x" => [{app, 1, 1, {var, 1, "f"}, #{}}], "y" => [{app, 1, 2, {var, 1, "f"}, #{}}]}, #{}}, parse_string( "x y = f();" ) ), + ?assertError( {parser, cannot_set_channel_on_nonapp_expr, str, 1}, parse_string( "x y = \"A\";" ) ), + ?assertError( {parser, nonvar_expr_left_of_eq, str, 1}, parse_string( "\"a\" = \"A\";" ) )]. -native_deftask_should_be_recognized() -> - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", +native_deftask_should_be_recognized_test() -> + ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", {sign, [{param, {name, "out", false}, false}], - [], []}, + []}, {natbody, #{"out" => [{str, 1, "A"}]}}}]}}, - parse_string( "deftask f( out : ) { out = 'A'; }" ) ). + parse_string( "deftask f( out : ) { out = \"A\"; }" ) ). -foreign_deftask_should_be_recognized() -> - [?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", +foreign_deftask_should_be_recognized_test() -> + [?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", {sign, [{param, {name, "out", false}, false}], - [], []}, + []}, {forbody, bash, "out=A"}}]}}, parse_string( "deftask f( out : )in bash *{out=A}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", {sign, [{param, {name, "out", false}, false}], - [], []}, + []}, {forbody, r, "out=\"A\""}}]}}, parse_string( "deftask f( out : )in R *{out=\"A\"}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", {sign, [{param, {name, "out", false}, false}], - [], []}, - {forbody, matlab, "out=\"A\""}}]}}, - parse_string( "deftask f( out : )in matlab *{out=\"A\"}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [], []}, - {forbody, octave, "out=\"A\""}}]}}, - parse_string( "deftask f( out : )in octave *{out=\"A\"}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [], []}, - {forbody, perl, ""}}]}}, - parse_string( "deftask f( out : )in perl *{}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [], []}, + []}, {forbody, python, ""}}]}}, - parse_string( "deftask f( out : )in python *{}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [], []}, - {forbody, lisp, "(defparameter out \"A\")"}}]}}, - parse_string( "deftask f( out : )in lisp *{(defparameter out \"A\")}*" ) )]. - -sign_with_inparam_should_be_recognized() -> - [?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + parse_string( "deftask f( out : )in python *{}*" ) )]. + +sign_with_inparam_should_be_recognized_test() -> + [?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", {sign, [{param, {name, "out", false}, false}], - [], [{param, {name, "inp", false}, false}]}, - {forbody, lisp, "(defparameter out \"A\")"}}]}}, - parse_string( "deftask f( out : inp )in lisp *{(defparameter out \"A\")}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {forbody, python, "(defparameter out \"A\")"}}]}}, + parse_string( "deftask f( out : inp )in python *{(defparameter out \"A\")}*" ) ), + ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", {sign, [{param, {name, "out", false}, false}], - [], [{param, {name, "a", false}, false}, {param, {name, "b", false}, false}]}, - {forbody, lisp, "(defparameter out \"A\")"}}]}}, - parse_string( "deftask f( out : a b )in lisp *{(defparameter out \"A\")}*" ) )]. + {forbody, python, "(defparameter out \"A\")"}}]}}, + parse_string( "deftask f( out : a b )in python *{(defparameter out \"A\")}*" ) )]. -param_should_be_recognized() -> - [?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", +%% ============================================================================= +%% Failing Tests +%% ============================================================================= + +param_should_be_recognized_test() -> + [?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", {sign, [{param, {name, "out", false}, false}], - [], [{param, {name, "inp", false}, false}]}, {forbody, bash, "blub"}}]}}, parse_string( "deftask f( out( String ) : inp( String ) )in bash *{blub}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", {sign, [{param, {name, "out", true}, false}], - [], [{param, {name, "inp", true}, false}]}, {forbody, bash, "blub"}}]}}, parse_string( "deftask f( out( File ) : inp( File ) )in bash *{blub}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", {sign, [{param, {name, "out", false}, true}], - [], [{param, {name, "inp", false}, true}]}, {forbody, bash, "blub"}}]}}, parse_string( "deftask f( : )in bash *{blub}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", {sign, [{param, {name, "out", false}, true}], - [], [{param, {name, "inp", false}, true}]}, {forbody, bash, "blub"}}]}}, parse_string( "deftask f( : )in bash *{blub}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", {sign, [{param, {name, "out", true}, true}], - [], [{param, {name, "inp", true}, true}]}, {forbody, bash, "blub"}}]}}, parse_string( "deftask f( : )in bash *{blub}*" ) )]. - -task_correl_should_be_recognized() -> - [?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [{name, "a", false}], - [{param, {name, "b", false}, false}]}, - {forbody, bash, "blub"}}]}}, - parse_string( "deftask f( out : [task a] b )in bash *{blub}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + +correl_inparam_should_be_recognized_test() -> + [?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", {sign, [{param, {name, "out", false}, false}], - [{name, "a", false}, - {name, "b", false}], - []}, - {forbody, bash, "blub"}}]}}, - parse_string( "deftask f( out : [task a b] )in bash *{blub}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [{name, "a", false}], - [{param, {name, "b", false}, false}]}, - {forbody, bash, "blub"}}]}}, - parse_string( "deftask f( out : [task a( String )] b )in bash *{blub}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [{name, "a", false}, - {name, "b", false}], - []}, - {forbody, bash, "blub"}}]}}, - parse_string( "deftask f( out : [task a( String ) b( String )] )in bash *{blub}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [{name, "a", true}], - [{param, {name, "b", false}, false}]}, - {forbody, bash, "blub"}}]}}, - parse_string( "deftask f( out : [task a( File )] b )in bash *{blub}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [{name, "a", true}, - {name, "b", true}], - []}, - {forbody, bash, "blub"}}]}}, - parse_string( "deftask f( out : [task a( File ) b( File )] )in bash *{blub}*" ) )]. - -correl_inparam_should_be_recognized() -> - [?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [], [{correl, [{name, "a", true}, {name, "b", true}]}]}, {forbody, bash, "blub"}}]}}, parse_string( "deftask f( out : [a( File ) b( File )] )in bash *{blub}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", {sign, [{param, {name, "out", false}, false}], - [], [{correl, [{name, "a", true}, {name, "b", true}]}, {param, {name, "c", false}, false}]}, {forbody, bash, "blub"}}]}}, parse_string( "deftask f( out : [a( File ) b( File )] c )in bash *{blub}*" ) )]. -comb_noreplace_should_be_recognized() -> - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [], - [{comb, cnr, {name, "x", true}, ["a", "b", "c"]}]}, - {forbody, bash, "blub"}}]}}, - parse_string( "deftask f( out : {comb noreplace x( File ): a b c} )in bash *{blub}*" ) ). - - - - - - - -parse_string( S ) -> - {ok, TokenList, _} = cuneiform_lexer:string( S ), - {ok, ParseTree} = cuneiform_parser:parse( TokenList ), - ParseTree. - - - -endif. @@ -480,7 +365,7 @@ yecctoken2string(Other) -> --file("src/cf_parser.erl", 483). +-file("src/cf_parser.erl", 368). -dialyzer({nowarn_function, yeccpars2/7}). yeccpars2(0=S, Cat, Ss, Stack, T, Ts, Tzr) -> @@ -1295,7 +1180,7 @@ yeccgoto_stat(1, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_1(1, Cat, Ss, Stack, T, Ts, Tzr). -compile({inline,yeccpars2_3_/1}). --file("src/cf_parser.yrl", 31). +-file("src/cf_parser.yrl", 40). yeccpars2_3_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1303,7 +1188,7 @@ yeccpars2_3_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_5_/1}). --file("src/cf_parser.yrl", 58). +-file("src/cf_parser.yrl", 67). yeccpars2_5_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1311,7 +1196,7 @@ yeccpars2_5_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_6_/1}). --file("src/cf_parser.yrl", 33). +-file("src/cf_parser.yrl", 42). yeccpars2_6_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1319,7 +1204,7 @@ yeccpars2_6_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_9_/1}). --file("src/cf_parser.yrl", 32). +-file("src/cf_parser.yrl", 41). yeccpars2_9_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1327,7 +1212,7 @@ yeccpars2_9_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_13_/1}). --file("src/cf_parser.yrl", 54). +-file("src/cf_parser.yrl", 63). yeccpars2_13_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1335,7 +1220,7 @@ yeccpars2_13_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_14_/1}). --file("src/cf_parser.yrl", 52). +-file("src/cf_parser.yrl", 61). yeccpars2_14_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1343,7 +1228,7 @@ yeccpars2_14_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_15_/1}). --file("src/cf_parser.yrl", 49). +-file("src/cf_parser.yrl", 58). yeccpars2_15_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1351,7 +1236,7 @@ yeccpars2_15_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_16_/1}). --file("src/cf_parser.yrl", 53). +-file("src/cf_parser.yrl", 62). yeccpars2_16_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1359,15 +1244,15 @@ yeccpars2_16_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_21_/1}). --file("src/cf_parser.yrl", 64). +-file("src/cf_parser.yrl", 73). yeccpars2_21_(__Stack0) -> [__3,__2,__1 | __Stack] = __Stack0, [begin - { app , get_line ( __1 ) , 1 , [ mk_var ( __1 ) ] , # { } } + { app , get_line ( __1 ) , 1 , mk_var ( __1 ) , # { } } end | __Stack]. -compile({inline,yeccpars2_24_/1}). --file("src/cf_parser.yrl", 67). +-file("src/cf_parser.yrl", 76). yeccpars2_24_(__Stack0) -> [__3,__2,__1 | __Stack] = __Stack0, [begin @@ -1375,7 +1260,7 @@ yeccpars2_24_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_26_/1}). --file("src/cf_parser.yrl", 70). +-file("src/cf_parser.yrl", 79). yeccpars2_26_(__Stack0) -> [__3,__2,__1 | __Stack] = __Stack0, [begin @@ -1383,15 +1268,15 @@ yeccpars2_26_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_27_/1}). --file("src/cf_parser.yrl", 65). +-file("src/cf_parser.yrl", 74). yeccpars2_27_(__Stack0) -> [__4,__3,__2,__1 | __Stack] = __Stack0, [begin - { app , get_line ( __1 ) , 1 , [ mk_var ( __1 ) ] , __3 } + { app , get_line ( __1 ) , 1 , mk_var ( __1 ) , __3 } end | __Stack]. -compile({inline,yeccpars2_32_/1}). --file("src/cf_parser.yrl", 84). +-file("src/cf_parser.yrl", 93). yeccpars2_32_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1399,7 +1284,7 @@ yeccpars2_32_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_33_/1}). --file("src/cf_parser.yrl", 81). +-file("src/cf_parser.yrl", 90). yeccpars2_33_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1407,7 +1292,7 @@ yeccpars2_33_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_34_/1}). --file("src/cf_parser.yrl", 87). +-file("src/cf_parser.yrl", 96). yeccpars2_34_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1415,7 +1300,7 @@ yeccpars2_34_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_37_/1}). --file("src/cf_parser.yrl", 82). +-file("src/cf_parser.yrl", 91). yeccpars2_37_(__Stack0) -> [__3,__2,__1 | __Stack] = __Stack0, [begin @@ -1423,7 +1308,7 @@ yeccpars2_37_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_41_/1}). --file("src/cf_parser.yrl", 88). +-file("src/cf_parser.yrl", 97). yeccpars2_41_(__Stack0) -> [__4,__3,__2,__1 | __Stack] = __Stack0, [begin @@ -1431,7 +1316,7 @@ yeccpars2_41_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_42_/1}). --file("src/cf_parser.yrl", 89). +-file("src/cf_parser.yrl", 98). yeccpars2_42_(__Stack0) -> [__4,__3,__2,__1 | __Stack] = __Stack0, [begin @@ -1439,7 +1324,7 @@ yeccpars2_42_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_43_/1}). --file("src/cf_parser.yrl", 85). +-file("src/cf_parser.yrl", 94). yeccpars2_43_(__Stack0) -> [__2,__1 | __Stack] = __Stack0, [begin @@ -1447,7 +1332,7 @@ yeccpars2_43_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_47_/1}). --file("src/cf_parser.yrl", 78). +-file("src/cf_parser.yrl", 87). yeccpars2_47_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1455,15 +1340,15 @@ yeccpars2_47_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_49_/1}). --file("src/cf_parser.yrl", 72). +-file("src/cf_parser.yrl", 81). yeccpars2_49_(__Stack0) -> [__4,__3,__2,__1 | __Stack] = __Stack0, [begin - { sign , __2 , [ ] , [ ] } + { sign , __2 , [ ] } end | __Stack]. -compile({inline,yeccpars2_51_/1}). --file("src/cf_parser.yrl", 91). +-file("src/cf_parser.yrl", 100). yeccpars2_51_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1471,7 +1356,7 @@ yeccpars2_51_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_52_/1}). --file("src/cf_parser.yrl", 92). +-file("src/cf_parser.yrl", 101). yeccpars2_52_(__Stack0) -> [__2,__1 | __Stack] = __Stack0, [begin @@ -1479,7 +1364,7 @@ yeccpars2_52_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_53_/1}). --file("src/cf_parser.yrl", 76). +-file("src/cf_parser.yrl", 85). yeccpars2_53_(__Stack0) -> [__3,__2,__1 | __Stack] = __Stack0, [begin @@ -1487,7 +1372,7 @@ yeccpars2_53_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_54_/1}). --file("src/cf_parser.yrl", 79). +-file("src/cf_parser.yrl", 88). yeccpars2_54_(__Stack0) -> [__2,__1 | __Stack] = __Stack0, [begin @@ -1495,15 +1380,15 @@ yeccpars2_54_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_55_/1}). --file("src/cf_parser.yrl", 73). +-file("src/cf_parser.yrl", 82). yeccpars2_55_(__Stack0) -> [__5,__4,__3,__2,__1 | __Stack] = __Stack0, [begin - { sign , __2 , [ ] , __4 } + { sign , __2 , __4 } end | __Stack]. -compile({inline,yeccpars2_61_/1}). --file("src/cf_parser.yrl", 40). +-file("src/cf_parser.yrl", 49). yeccpars2_61_(__Stack0) -> [__2,__1 | __Stack] = __Stack0, [begin @@ -1511,7 +1396,7 @@ yeccpars2_61_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_62_/1}). --file("src/cf_parser.yrl", 42). +-file("src/cf_parser.yrl", 51). yeccpars2_62_(__Stack0) -> [__6,__5,__4,__3,__2,__1 | __Stack] = __Stack0, [begin @@ -1519,7 +1404,7 @@ yeccpars2_62_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_65_/1}). --file("src/cf_parser.yrl", 37). +-file("src/cf_parser.yrl", 46). yeccpars2_65_(__Stack0) -> [__4,__3,__2,__1 | __Stack] = __Stack0, [begin @@ -1527,7 +1412,7 @@ yeccpars2_65_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_67_/1}). --file("src/cf_parser.yrl", 45). +-file("src/cf_parser.yrl", 54). yeccpars2_67_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1535,7 +1420,7 @@ yeccpars2_67_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_68_/1}). --file("src/cf_parser.yrl", 46). +-file("src/cf_parser.yrl", 55). yeccpars2_68_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1543,7 +1428,7 @@ yeccpars2_68_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_69_/1}). --file("src/cf_parser.yrl", 47). +-file("src/cf_parser.yrl", 56). yeccpars2_69_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1551,7 +1436,7 @@ yeccpars2_69_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_70_/1}). --file("src/cf_parser.yrl", 43). +-file("src/cf_parser.yrl", 52). yeccpars2_70_(__Stack0) -> [__6,__5,__4,__3,__2,__1 | __Stack] = __Stack0, [begin @@ -1559,7 +1444,7 @@ yeccpars2_70_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_76_/1}). --file("src/cf_parser.yrl", 62). +-file("src/cf_parser.yrl", 71). yeccpars2_76_(__Stack0) -> [__7,__6,__5,__4,__3,__2,__1 | __Stack] = __Stack0, [begin @@ -1567,7 +1452,7 @@ yeccpars2_76_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_77_/1}). --file("src/cf_parser.yrl", 35). +-file("src/cf_parser.yrl", 44). yeccpars2_77_(__Stack0) -> [__2,__1 | __Stack] = __Stack0, [begin @@ -1575,7 +1460,7 @@ yeccpars2_77_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_78_/1}). --file("src/cf_parser.yrl", 59). +-file("src/cf_parser.yrl", 68). yeccpars2_78_(__Stack0) -> [__2,__1 | __Stack] = __Stack0, [begin @@ -1583,7 +1468,7 @@ yeccpars2_78_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_79_/1}). --file("src/cf_parser.yrl", 29). +-file("src/cf_parser.yrl", 38). yeccpars2_79_(__Stack0) -> [__2,__1 | __Stack] = __Stack0, [begin @@ -1591,4 +1476,4 @@ yeccpars2_79_(__Stack0) -> end | __Stack]. --file("src/cf_parser.yrl", 404). +-file("src/cf_parser.yrl", 301). diff --git a/src/cf_parser.yrl b/src/cf_parser.yrl index 300819d..a7cd85b 100644 --- a/src/cf_parser.yrl +++ b/src/cf_parser.yrl @@ -16,6 +16,10 @@ % See the License for the specific language governing permissions and % limitations under the License. +%% ============================================================================= +%% Symbol Declaration +%% ============================================================================= + Nonterminals script stat assign exprlist expr binding assignlist sign query app cnd paramlist param inparamlist inparam namelist name defun lang bindinglist @@ -27,8 +31,13 @@ Terminals semicolon string then id. +%% ============================================================================= +%% Syntax Definition +%% ============================================================================= + Rootsymbol script. + script -> stat : '$1'. script -> stat script : combine( '$1', '$2' ). @@ -65,16 +74,16 @@ exprlist -> expr exprlist : ['$1'|'$2']. cnd -> beginif compoundexpr then compoundexpr else compoundexpr endif : {cnd, get_line( '$1' ), '$2', '$4', '$6'}. -app -> id lparen rparen : {app, get_line( '$1' ), 1, [mk_var( '$1' )], #{}}. -app -> id lparen bindinglist rparen : {app, get_line( '$1' ), 1, [mk_var( '$1' )], '$3'}. +app -> id lparen rparen : {app, get_line( '$1' ), 1, mk_var( '$1' ), #{}}. +app -> id lparen bindinglist rparen : {app, get_line( '$1' ), 1, mk_var( '$1' ), '$3'}. binding -> id colon compoundexpr : mk_binding( '$1', '$3' ). bindinglist -> binding : '$1'. bindinglist -> binding comma bindinglist : maps:merge( '$1', '$3' ). -sign -> lparen paramlist colon rparen : {sign, '$2', [], []}. -sign -> lparen paramlist colon inparamlist rparen : {sign, '$2', [], '$4'}. +sign -> lparen paramlist colon rparen : {sign, '$2', []}. +sign -> lparen paramlist colon inparamlist rparen : {sign, '$2', '$4'}. inparam -> param : '$1'. inparam -> lsquarebr namelist rsquarebr : {correl, '$2'}. @@ -95,15 +104,24 @@ name -> id lparen file rparen : {name, get_name( '$1' ), true}. namelist -> name : ['$1']. namelist -> name namelist : ['$1'|'$2']. +%% ============================================================================= +%% Erlang Code +%% ============================================================================= Erlang code. -author( "Jörgen Brandt " ). +-export( [parse_string/1] ). + -ifdef( TEST ). -include_lib( "eunit/include/eunit.hrl" ). -endif. +parse_string( S ) -> + {ok, TokenList, _} = cf_lexer:string( S ), + {ok, ParseTree} = cf_parser:parse( TokenList ), + ParseTree. @@ -145,259 +163,138 @@ mk_natlam( {deftask, Line, _}, {id, _, Name}, Sign, Block ) -> mk_forlam( {deftask, Line, _}, {id, _, Name}, Sign, Lang, {body, _, Code} ) -> #{Name => [{lam, Line, Name, Sign, {forbody, Lang, Code}}]}. - + +%% ============================================================================= +%% Unit Tests +%% ============================================================================= + -ifdef( TEST ). -% TEST INDEX - -parse_test_() -> [nil_should_be_recognized(), - var_should_be_recognized(), - multi_element_compoundexpr_should_be_recognized(), - multiple_targets_should_be_joined(), - strlit_should_be_recognized(), - intlit_should_be_recognized(), - cnd_should_be_recognized(), - apply_should_be_recognized(), - call_should_be_recognized(), - assign_should_be_recognized(), - native_deftask_should_be_recognized(), - foreign_deftask_should_be_recognized(), - sign_with_inparam_should_be_recognized(), - param_should_be_recognized(), - task_correl_should_be_recognized(), - correl_inparam_should_be_recognized(), - comb_noreplace_should_be_recognized() - ]. - - -% ACTUAL TEST IMPLEMENTATION - -nil_should_be_recognized() -> - ?_assertEqual( {[], #{}, #{}}, parse_string( "nil;" ) ). +nil_should_be_recognized_test() -> + ?assertEqual( {[], #{}, #{}}, parse_string( "nil;" ) ). -var_should_be_recognized() -> - ?_assertEqual( {[{var, 1, "blub"}], #{}, #{}}, parse_string( "blub;" ) ). +var_should_be_recognized_test() -> + ?assertEqual( {[{var, 1, "blub"}], #{}, #{}}, parse_string( "blub;" ) ). -multi_element_compoundexpr_should_be_recognized() -> - ?_assertEqual( {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}, +multi_element_compoundexpr_should_be_recognized_test() -> + ?assertEqual( {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}, parse_string( "bla blub;" ) ). -multiple_targets_should_be_joined() -> - ?_assertEqual( {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}, +multiple_targets_should_be_joined_test() -> + ?assertEqual( {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}, parse_string( "bla; blub;" ) ). -strlit_should_be_recognized() -> - ?_assertEqual( {[{str, 1, "bla"}], #{}, #{}}, parse_string( "'bla';" ) ). +strlit_should_be_recognized_test() -> + ?assertEqual( {[{str, 1, "bla"}], #{}, #{}}, parse_string( "\"bla\";" ) ). -intlit_should_be_recognized() -> - ?_assertEqual( {[{str, 1, "-5"}], #{}, #{}}, parse_string( "-5;" ) ). +intlit_should_be_recognized_test() -> + ?assertEqual( {[{str, 1, "-5"}], #{}, #{}}, parse_string( "-5;" ) ). -cnd_should_be_recognized() -> - ?_assertEqual( {[{cnd, 1, [], [{str, 1, "bla"}], [{str, 1, "blub"}]}], +cnd_should_be_recognized_test() -> + ?assertEqual( {[{cnd, 1, [], [{str, 1, "bla"}], [{str, 1, "blub"}]}], #{}, #{}}, - parse_string( "if nil then 'bla' else 'blub' end;" ) ). - -apply_should_be_recognized() -> - [?_assertEqual( {[{app, 1, 1, [{var, 1, "f"}], #{}}], #{}, #{}}, - parse_string( "apply( task: f );" ) ), - ?_assertEqual( {[{app, 1, 1, [{var, 1, "f"}], #{"x" => [{var, 1, "x"}]}}], - #{}, #{}}, - parse_string( "apply( task: f, x: x );" ) ), - ?_assertEqual( {[{app, 1, 1, [{var, 1, "f"}], #{"x" => [{var, 1, "x"}], - "y" => [{str, 1, "y"}]}}], - #{}, #{}}, - parse_string( "apply( task: f, x: x, y: 'y' );" ) ), - ?_assertEqual( {[{app, 1, 1, [{var, 1, "f"}, {var, 1, "g"}], - #{"x" => [{var, 1, "x"}]}}], #{}, #{}}, - parse_string( "apply( task: f g, x: x );" ) )]. - -call_should_be_recognized() -> - [?_assertEqual( {[{app, 1, 1, [{var, 1, "f"}], #{}}], #{}, #{}}, + parse_string( "if nil then \"bla\" else \"blub\" end;" ) ). + +app_should_be_recognized_test() -> + [?assertEqual( {[{app, 1, 1, {var, 1, "f"}, #{}}], #{}, #{}}, parse_string( "f();" ) ), - ?_assertEqual( {[{app, 1, 1, [{var, 1, "f"}], #{"x" => [{var, 1, "x"}]}}], + ?assertEqual( {[{app, 1, 1, {var, 1, "f"}, #{"x" => [{var, 1, "x"}]}}], #{}, #{}}, parse_string( "f( x: x );" ) ), - ?_assertEqual( {[{app, 1, 1, [{var, 1, "f"}], + ?assertEqual( {[{app, 1, 1, {var, 1, "f"}, #{"x" => [{var, 1, "x"}], "y" => [{str, 1, "y"}]}}], #{}, #{}}, - parse_string( "f( x: x, y: 'y' );" ) )]. + parse_string( "f( x: x, y: \"y\" );" ) )]. -assign_should_be_recognized() -> - [?_assertEqual( {[], #{"x" => [{str, 1, "x"}]}, #{}}, parse_string( "x = 'x';" ) ), - ?_assertEqual( {[], #{"x" => [{app, 1, 1, [{var, 1, "f"}], #{}}], "y" => [{app, 1, 2, [{var, 1, "f"}], #{}}]}, #{}}, parse_string( "x y = f();" ) ), - ?_assertError( {parser, cannot_set_channel_on_nonapp_expr, str, 1}, parse_string( "x y = 'A';" ) ), - ?_assertError( {parser, nonvar_expr_left_of_eq, str, 1}, parse_string( "'a' = 'A';" ) )]. +assign_should_be_recognized_test() -> + [?assertEqual( {[], #{"x" => [{str, 1, "x"}]}, #{}}, parse_string( "x = \"x\";" ) ), + ?assertEqual( {[], #{"x" => [{app, 1, 1, {var, 1, "f"}, #{}}], "y" => [{app, 1, 2, {var, 1, "f"}, #{}}]}, #{}}, parse_string( "x y = f();" ) ), + ?assertError( {parser, cannot_set_channel_on_nonapp_expr, str, 1}, parse_string( "x y = \"A\";" ) ), + ?assertError( {parser, nonvar_expr_left_of_eq, str, 1}, parse_string( "\"a\" = \"A\";" ) )]. -native_deftask_should_be_recognized() -> - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", +native_deftask_should_be_recognized_test() -> + ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", {sign, [{param, {name, "out", false}, false}], - [], []}, + []}, {natbody, #{"out" => [{str, 1, "A"}]}}}]}}, - parse_string( "deftask f( out : ) { out = 'A'; }" ) ). + parse_string( "deftask f( out : ) { out = \"A\"; }" ) ). -foreign_deftask_should_be_recognized() -> - [?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", +foreign_deftask_should_be_recognized_test() -> + [?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", {sign, [{param, {name, "out", false}, false}], - [], []}, + []}, {forbody, bash, "out=A"}}]}}, parse_string( "deftask f( out : )in bash *{out=A}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", {sign, [{param, {name, "out", false}, false}], - [], []}, + []}, {forbody, r, "out=\"A\""}}]}}, parse_string( "deftask f( out : )in R *{out=\"A\"}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [], []}, - {forbody, matlab, "out=\"A\""}}]}}, - parse_string( "deftask f( out : )in matlab *{out=\"A\"}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [], []}, - {forbody, octave, "out=\"A\""}}]}}, - parse_string( "deftask f( out : )in octave *{out=\"A\"}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [], []}, - {forbody, perl, ""}}]}}, - parse_string( "deftask f( out : )in perl *{}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", {sign, [{param, {name, "out", false}, false}], - [], []}, + []}, {forbody, python, ""}}]}}, - parse_string( "deftask f( out : )in python *{}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [], []}, - {forbody, lisp, "(defparameter out \"A\")"}}]}}, - parse_string( "deftask f( out : )in lisp *{(defparameter out \"A\")}*" ) )]. - -sign_with_inparam_should_be_recognized() -> - [?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + parse_string( "deftask f( out : )in python *{}*" ) )]. + +sign_with_inparam_should_be_recognized_test() -> + [?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", {sign, [{param, {name, "out", false}, false}], - [], [{param, {name, "inp", false}, false}]}, - {forbody, lisp, "(defparameter out \"A\")"}}]}}, - parse_string( "deftask f( out : inp )in lisp *{(defparameter out \"A\")}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + {forbody, python, "(defparameter out \"A\")"}}]}}, + parse_string( "deftask f( out : inp )in python *{(defparameter out \"A\")}*" ) ), + ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", {sign, [{param, {name, "out", false}, false}], - [], [{param, {name, "a", false}, false}, {param, {name, "b", false}, false}]}, - {forbody, lisp, "(defparameter out \"A\")"}}]}}, - parse_string( "deftask f( out : a b )in lisp *{(defparameter out \"A\")}*" ) )]. + {forbody, python, "(defparameter out \"A\")"}}]}}, + parse_string( "deftask f( out : a b )in python *{(defparameter out \"A\")}*" ) )]. -param_should_be_recognized() -> - [?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", +%% ============================================================================= +%% Failing Tests +%% ============================================================================= + +param_should_be_recognized_test() -> + [?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", {sign, [{param, {name, "out", false}, false}], - [], [{param, {name, "inp", false}, false}]}, {forbody, bash, "blub"}}]}}, parse_string( "deftask f( out( String ) : inp( String ) )in bash *{blub}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", {sign, [{param, {name, "out", true}, false}], - [], [{param, {name, "inp", true}, false}]}, {forbody, bash, "blub"}}]}}, parse_string( "deftask f( out( File ) : inp( File ) )in bash *{blub}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", {sign, [{param, {name, "out", false}, true}], - [], [{param, {name, "inp", false}, true}]}, {forbody, bash, "blub"}}]}}, parse_string( "deftask f( : )in bash *{blub}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", {sign, [{param, {name, "out", false}, true}], - [], [{param, {name, "inp", false}, true}]}, {forbody, bash, "blub"}}]}}, parse_string( "deftask f( : )in bash *{blub}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", {sign, [{param, {name, "out", true}, true}], - [], [{param, {name, "inp", true}, true}]}, {forbody, bash, "blub"}}]}}, parse_string( "deftask f( : )in bash *{blub}*" ) )]. - -task_correl_should_be_recognized() -> - [?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [{name, "a", false}], - [{param, {name, "b", false}, false}]}, - {forbody, bash, "blub"}}]}}, - parse_string( "deftask f( out : [task a] b )in bash *{blub}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [{name, "a", false}, - {name, "b", false}], - []}, - {forbody, bash, "blub"}}]}}, - parse_string( "deftask f( out : [task a b] )in bash *{blub}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [{name, "a", false}], - [{param, {name, "b", false}, false}]}, - {forbody, bash, "blub"}}]}}, - parse_string( "deftask f( out : [task a( String )] b )in bash *{blub}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [{name, "a", false}, - {name, "b", false}], - []}, - {forbody, bash, "blub"}}]}}, - parse_string( "deftask f( out : [task a( String ) b( String )] )in bash *{blub}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [{name, "a", true}], - [{param, {name, "b", false}, false}]}, - {forbody, bash, "blub"}}]}}, - parse_string( "deftask f( out : [task a( File )] b )in bash *{blub}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [{name, "a", true}, - {name, "b", true}], - []}, - {forbody, bash, "blub"}}]}}, - parse_string( "deftask f( out : [task a( File ) b( File )] )in bash *{blub}*" ) )]. - -correl_inparam_should_be_recognized() -> - [?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + +correl_inparam_should_be_recognized_test() -> + [?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", {sign, [{param, {name, "out", false}, false}], - [], [{correl, [{name, "a", true}, {name, "b", true}]}]}, {forbody, bash, "blub"}}]}}, parse_string( "deftask f( out : [a( File ) b( File )] )in bash *{blub}*" ) ), - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", {sign, [{param, {name, "out", false}, false}], - [], [{correl, [{name, "a", true}, {name, "b", true}]}, {param, {name, "c", false}, false}]}, {forbody, bash, "blub"}}]}}, parse_string( "deftask f( out : [a( File ) b( File )] c )in bash *{blub}*" ) )]. -comb_noreplace_should_be_recognized() -> - ?_assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [], - [{comb, cnr, {name, "x", true}, ["a", "b", "c"]}]}, - {forbody, bash, "blub"}}]}}, - parse_string( "deftask f( out : {comb noreplace x( File ): a b c} )in bash *{blub}*" ) ). - - - - - - - -parse_string( S ) -> - {ok, TokenList, _} = cuneiform_lexer:string( S ), - {ok, ParseTree} = cuneiform_parser:parse( TokenList ), - ParseTree. - - - -endif. diff --git a/src/cf_sem.erl b/src/cf_sem.erl new file mode 100644 index 0000000..29f8d5f --- /dev/null +++ b/src/cf_sem.erl @@ -0,0 +1,355 @@ +%% -*- erlang -*- + +-module( cf_sem ). +-author( "Jörgen Brandt " ). + +-export( [eval/2] ). + +-ifdef( TEST ). +-include_lib( "eunit/include/eunit.hrl" ). +-endif. + + + +%% ============================================================================= +%% Abstract Syntax +%% ============================================================================= + +%% Expression %% =============================================================== + +-type expr() :: str() | var() | select() | cnd() | app(). % (1) +-type str() :: {str, Line::pos_integer(), S::string()}. % (2) +-type var() :: {var, Line::pos_integer(), N::string()}. % (3) +-type select() :: {select, Line::pos_integer(), C::pos_integer(), U::fut()}. % (4) +-type fut() :: {fut, Line::pos_integer(), Name::string(), R::pos_integer(), % (5) + Lp::[boolean()]}. +-type cnd() :: {cnd, Line::pos_integer(), % (6) + Xc::[expr()], Xt::[expr()], Xe::[expr()]}. +-type app() :: {app, Line::pos_integer(), C::pos_integer(), % (7) + Lambda::lam() | var(), Fa::#{string() => [expr()]}}. + +%% Lambda %% =================================================================== + +-type lam() :: {lam, Line::pos_integer(), Name::string(), S::sign(), B::body()}. % (8) + +% Task Signature +-type sign() :: {sign, Lo::[param()], Li::[inparam()]}. % (9) +-type param() :: {param, N::string(), Pl::boolean()}. % (10) +-type inparam() :: param() | correl(). % (11) +-type correl() :: {correl, Lc::[string()]}. % (12) + +% Body +-type body() :: natbody() | forbody(). % (13) +-type natbody() :: {natbody, Fb::#{string() => [expr()]}}. % (14) +-type forbody() :: {forbody, L::lang(), S::string()}. % (15) +-type lang() :: bash | python | r. % (16) + +%% Argument Pair %% ============================================================ + +-type argpair() :: {L0::[inparam()], F::#{string() => [expr()]}}. % (17) + +%% Evaluation Context %% ======================================================= + +-type ctx() :: {Rho :: #{string() => [expr()]}, % (18) + Mu :: fun( ( app() ) -> fut() ), + Gamma :: #{string() => lam()}, + Omega :: #{select() => [expr()]}}. + + +%% ============================================================================= +%% Predicates +%% ============================================================================= + +%% Finality %% ================================================================= + +-spec pfinal( X ) -> boolean() % (19) +when X :: #{string() => [expr()]} | [expr()] | expr(). + +pfinal( F ) when is_map( F ) -> pfinal( maps:values( F ) ); % (20) +pfinal( L ) when is_list( L ) -> lists:all( fun pfinal/1, L ); % (21,22) +pfinal( {str, _, _S} ) -> true; % (23) +pfinal( _T ) -> false. + +%% Singularity %% ============================================================== + +-spec psing( A::app() ) -> boolean(). % (24) + +psing( {app, _, _C, {lam, _, _, {sign, _Lo, Li}, _B}, Fa} ) -> % (25) + psing_argpair( {Li, Fa} ). + +-spec psing_argpair( Z::argpair() ) -> boolean(). % (26) + +psing_argpair( {[], _F} ) -> true; % (27) +psing_argpair( {[{param, _N, Pl}|T], F} ) when Pl -> psing_argpair( {T, F} ); % (28) +psing_argpair( {[{param, N, _Pl}|T], F} ) -> % (29) + case length( maps:get( N, F ) ) of + 1 -> psing_argpair( {T, F} ); + _ -> false + end; +psing_argpair( _Z ) -> false. + +%% Enumerability %% ============================================================ + +-spec pen( X::expr()|[expr()] ) -> boolean(). % (30) + +pen( X )when is_list( X ) -> lists:all( fun pen/1, X ); % (31,32) +pen( {str, _, _S} ) -> true; % (33) +pen( {cnd, _, _Xc, Xt, Xe} )when length( Xt ) =:= 1, length( Xe ) =:= 1 -> % (34) + pen( Xt ) andalso pen( Xe ); +pen( X={app, _, C, {lam, _, _, {sign, Lo, _Li}, _B}, _Fb} ) -> % (35) + case psing( X ) of + false -> false; + true -> + {param, _N, Pl} = lists:nth( C, Lo ), + not Pl + end; +pen( {select, _, C, {fut, _, _, _R, Lp}} ) -> not lists:nth( C, Lp ); % (36) +pen( _T ) -> false. + +%% ============================================================================= +%% Evaluation +%% ============================================================================= + +%% The eval Function %% ======================================================== + +-spec eval( X::[expr()], Theta::ctx() ) -> [expr()]. % (37) + +eval( X, Theta ) -> + X1 = step( X, Theta ), + case X1 of + X -> X; % (38) + _ -> eval( X1, Theta ) % (39) + end. + +%% Reduction Rules %% ========================================================== + +-spec step_assoc( F, Theta ) -> #{string() => [expr()]} % (40) +when F :: #{string() => [expr()]}, + Theta :: ctx(). + +step_assoc( F, Theta ) when is_map( F ) -> % (41) + maps:map( fun( _N, X ) -> step( X, Theta ) end, F ). + + +-spec step( X, Theta ) -> [expr()] % (42) +when X :: #{string() => [expr()]} | [expr()] | expr(), + Theta :: ctx(). + + +% Expression List +step( X, Theta ) when is_list( X ) -> % (43,44) + lists:flatmap( fun( Y ) -> step( Y, Theta ) end, X ); + +% String Literal +step( X={str, _, _S}, _Theta ) -> [X]; % (45) + +% Variable +step( {var, _, N}, {Rho, _Mu, _Gamma, _Omega} ) -> % (46) + maps:get( N, Rho ); + +% Future Channel Selection +step( S={select, _, _C, _Fut}, {_Rho, _Mu, _Gamma, Omega} ) -> % (47,48) + maps:get( S, Omega, [S] ); + +% Conditional +step( {cnd, _, [], _Xt, Xe}, _Theta ) -> Xe; % (49) +step( {cnd, Line, Xc=[_|_], Xt, Xe}, Theta ) -> + case pfinal( Xc ) of + false -> [{cnd, Line, step( Xc, Theta ), Xt, Xe}]; % (50) + true -> Xt % (51) + end; + +% Application +step( {app, Line, C, {var, _, N}, Fa}, {_Rho, _Mu, Gamma, _Omega} ) -> + [{app, Line, C, maps:get( N, Gamma ), Fa}]; + +step( X={app, AppLine, C, Lambda={lam, LamLine, LamName, S={sign, Lo, _Li}, B}, Fa}, + Theta={_Rho, Mu, Gamma, Omega} ) -> + case psing( X ) of + false -> enum_app( {app, AppLine, C, Lambda, step_assoc( Fa, Theta )} ); % (53) + true -> + case B of + {forbody, _L, _Z} -> + case pfinal( Fa ) of + false -> [{app, AppLine, C, Lambda, step_assoc( Fa, Theta )}]; % (54) + true -> [{select, AppLine, C, apply( Mu, [X] )}] % (55) + end; + {natbody, Fb} -> + {param, K, Pl} = lists:nth( C, Lo ), + V0 = maps:get( K, Fb ), + V1 = step( V0, {maps:merge( Fb, Fa ), Mu, Gamma, Omega} ), + case pfinal( V1 ) of + false -> [{app, AppLine, C, {lam, LamLine, LamName, S, % (56) + {natbody, Fb#{ K => V1}}}, Fa}]; + true -> + case Pl orelse length( V1 ) =:= 1 of + true -> V1; % (57) + false -> error( output_sign_mismatch ) + end + end + end + end. + + + +%% ============================================================================= +%% Enumeration +%% ============================================================================= + +%% The enum Function %% + +-spec enum_app( A::app() ) -> [app()]. % (58) + +enum_app( {app, AppLine, C, {lam, LamLine, LamName, {sign, Lo, Li}, B}, Fa} ) ->% (59) + [{app, AppLine, C, + {lam, LamLine, LamName, + {sign, Lo, L1}, B}, F1} || {L1, F1} <- enum( [{Li, Fa}] )]. + +-spec enum( Z::[argpair()] ) -> [argpair()]. % (60) + +enum( Z ) -> + Z1 = estep( Z ), + case Z1 of + Z -> Z; % (61) + _ -> enum( Z1 ) % (62) + end. + +%% Enumeration Rules %% + +-spec estep( Z::[argpair()] ) -> [argpair()]. % (63) + +estep( Z ) -> % (64,65) + lists:flatmap( fun( {Li, F} ) -> estep( Li, F ) end, Z ). + +-spec estep( Li::[inparam()], F::#{string() => [expr()]} ) -> [argpair()]. % (66) + +estep( [], F ) -> [{[], F}]; % (67) +estep( [H={param, _N, Pl}|T], F ) when Pl -> aug( estep( T, F ), H ); % (68) +estep( L=[H={param, N, _Pl}|T], F ) -> + V = maps:get( N, F ), + case pen( V ) of + false -> [{L, F}]; % (69) + true -> + case length( V ) of + 1 -> aug( estep( T, F ), H ); % (70) + _ -> [{L, maps:put( N, [X], F )} || X <- V] % (71) + end + end; +estep( L=[H={correl, Lc}|T], F ) when length( Lc ) > 1 -> + Pen = pen( [maps:get( N, F ) || N <- Lc] ), + case Pen of + false -> [{L, F}]; % (72) + true -> + Z = corrstep( Lc, F, F ), + aug( [{T, G} || G <- Z], H ) % (73) + end. + + + +%% Augmentation %% + +-spec aug( Z::[argpair()], A::inparam() ) -> [argpair()]. % (74) + +aug( Z, A ) -> [aug_argpair( Y, A ) || Y <- Z]. % (75) + +-spec aug_argpair( Y::argpair(), A::inparam() ) -> argpair(). % (76) + +aug_argpair( {L0, F}, A={param, _N, _Pl} ) -> {[A|L0], F}; % (77) +aug_argpair( {L0, F}, {correl, Lc} ) -> % (78) + L1 = [{param, N, false} || N <- Lc], + {L1++L0, F}. + +%% Correlation %% + +-spec corrstep( Lc, Facc, F0 ) -> [#{string() => [expr()]}] % (79) +when Lc :: [string()], + Facc :: #{string() => [expr()]}, + F0 :: #{string() => [expr()]}. + +corrstep( [], Facc, F0 ) -> [Facc, F0]; % (80) +corrstep( [H|T], Facc, F0 ) -> + case maps:get( H, F0 ) of + [] -> []; % (81) + [A|B] -> corrstep( T, Facc#{H => [A]}, F0#{H => B}) % (82) + end. + + + + +%% ============================================================================= +%% Unit Tests +%% ============================================================================= + +-ifdef( TEST ). + +%% The enum Function %% + +enum_app_without_app_does_nothing_test() -> + S = {sign, [{param, "out", false}], []}, + B = {forbody, bash, "shalala"}, + Lam = {lam, 1, "f", S, B}, + App = {app, 2, 1, Lam, #{}}, + ?assertEqual( [App], enum_app( App ) ). + +%% Enumeration Rules %% + +%% Augmentation %% + +can_aug_argpair_with_param_test() -> + L0 = [{param, "b", false}, {param, "c", false}], + F = #{"a" => [{str, 1, "1"}], "b" => [{str, 2, "2"}], "c" => [{str, 3, "3"}]}, + Pair = {L0, F}, + I = {param, "a", false}, + L1 = [I|L0], + ?assertEqual( {L1, F}, aug_argpair( Pair, I ) ). + +can_aug_argpair_with_correl_test() -> + L0 = [{param, "b", false}, {param, "c", false}], + F = #{"a1" => [{str, 1, "11"}], + "a2" => [{str, 2, "12"}], + "b" => [{str, 3, "2"}], + "c" => [{str, 4, "3"}]}, + Pair = {L0, F}, + I = {correl, ["a1", "a2"]}, + L1 = [{param, "a1", false}, {param, "a2", false}|L0], + ?assertEqual( {L1, F}, aug_argpair( Pair, I ) ). + +can_augment_empty_argpairlist_with_param_test() -> + F1 = #{"a" => [{str, 1, "x1"}]}, + F2 = #{"a" => [{str, 2, "y1"}]}, + PairList = [{[], F1}, {[], F2}], + I = {param, "a", false}, + L1 = [{param, "a", false}], + ?assertEqual( [{L1, F1}, {L1, F2}], aug( PairList, I ) ). + +can_augment_argpairlist_with_param_test() -> + L0 = [{param, "b", false}, {param, "c", false}], + F1 = #{"a" => [{str, 1, "x1"}], "b" => [{str, 2, "x2"}], "c" => [{str, 3, "x3"}]}, + F2 = #{"a" => [{str, 4, "y1"}], "b" => [{str, 5, "y2"}], "c" => [{str, 6, "y3"}]}, + PairList = [{L0, F1}, {L0, F2}], + I = {param, "a", false}, + L1 = [{param, "a", false}|L0], + ?assertEqual( [{L1, F1}, {L1, F2}], aug( PairList, I ) ). + +can_augment_argpairlist_with_correl_test() -> + L0 = [{param, "b", false}, {param, "c", false}], + F1 = #{"a1" => [{str, 1, "x11"}], + "a2" => [{str, 2, "x12"}], + "b" => [{str, 3, "x2"}], + "c" => [{str, 4, "x3"}]}, + F2 = #{"a1" => [{str, 5, "y11"}], + "a2" => [{str, 6, "y12"}], + "b" => [{str, 7, "y2"}], + "c" => [{str, 8, "y3"}]}, + PairList = [{L0, F1}, {L0, F2}], + I = {correl, ["a1", "a2"]}, + L1 = [{param, "a1", false}, {param, "a2", false}|L0], + ?assertEqual( [{L1, F1}, {L1, F2}], aug( PairList, I ) ). + +%% Correlation %% + + + + + +-endif. \ No newline at end of file diff --git a/test/cf_sem_test.erl b/test/cf_sem_test.erl new file mode 100644 index 0000000..be6925e --- /dev/null +++ b/test/cf_sem_test.erl @@ -0,0 +1,282 @@ +-module( cf_sem_test ). +-author( "Jörgen Brandt " ). + +-include_lib( "eunit/include/eunit.hrl" ). + +-define( THETA0, {#{}, fun mu/1, #{}, #{}} ). + +mu( {app, _L, _C, {lam, Line, Name, {sign, Lo, _Li}, _B}, _Fa} ) -> + V = [Pl || {param, _N, Pl} <- Lo], + {fut, Line, Name, random:uniform( 1000000000 ), V}. + +nil_should_eval_itself_test() -> + ?assertEqual( [], cf_sem:eval( [], ?THETA0 ) ). + +str_should_eval_itself_test() -> + E = [{str, 1, "bla"}], + ?assertEqual( E, cf_sem:eval( E, ?THETA0 ) ). + +undef_var_should_fail_test() -> + E = [{var, 1, "x"}], + ?assertError( {badkey, "x"}, cf_sem:eval( E, ?THETA0 ) ). + +def_var_should_eval_to_bound_value_test() -> + E = [{str, 1, "blub"}], + X = cf_sem:eval( [{var, 2, "x"}], {#{"x" => E}, fun mu/1, #{}, #{}} ), + ?assertEqual( E, X ). + +def_var_should_cascade_binding_test() -> + E = [{str, 1, "blub"}], + Theta = {#{"x" => [{var, 2, "y"}], "y" => E}, fun mu/1, #{}, #{}}, + X = cf_sem:eval( [{var, 3, "x"}], Theta ), + ?assertEqual( E, X ). + +def_var_should_cascade_binding_twice_test() -> + A = [{str, 1, "A"}], + Rho = #{"x" => [{var, 2, "y"}], "y" => [{var, 3, "z"}], "z" => A}, + ?assertEqual( A, cf_sem:eval( [{var, 4, "x"}], {Rho, fun mu/1, #{}, #{}} ) ). + +unfinished_fut_should_eval_to_itself_test() -> + Fut = {fut, 1, 1234, [false]}, + E = [{select, 2, 1, Fut}], + X = cf_sem:eval( E, ?THETA0 ), + ?assertEqual( E, X ). + + +finished_fut_should_eval_to_result_test() -> + Fut = {fut, 1, "f", 1234, [false]}, + S = {select, 2, 1, Fut}, + F = [{str, 3, "blub"}], + Theta = {#{}, fun mu/1, #{}, #{S => F}}, + X = cf_sem:eval( [S], Theta ), + ?assertEqual( F, X ). + +noarg_fn_should_eval_plain_test() -> + E = [{str, 1, "bla"}], + Sign = {sign, [{param, "out", false}], []}, + Body = {natbody, #{"out" => E}}, + Lam = {lam, 2, "f", Sign, Body}, + F = [{app, 3, 1, Lam, #{}}], + ?assertEqual( E, cf_sem:eval( F, ?THETA0 ) ). + +noarg_fn_should_eval_body_test() -> + E = [{str, 1, "bla"}], + Sign = {sign, [{param, "out", false}], []}, + Body = {natbody, #{"out" => [{var, 2, "x"}], "x" => E}}, + Lam = {lam, 3, "f", Sign, Body}, + F = [{app, 4, 1, Lam, #{}}], + ?assertEqual( E, cf_sem:eval( F, ?THETA0 ) ). + +fn_call_should_insert_lam_test() -> + E = [{str, 1, "bla"}], + Sign = {sign, [{param, "out", false}], []}, + Body = {natbody, #{"out" => E}}, + Lam = {lam, 2, "f", Sign, Body}, + F = [{app, 3, 1, {var, 4, "f"}, #{}}], + Theta = {#{}, fun mu/1, #{"f" => Lam}, #{}}, + ?assertEqual( E, cf_sem:eval( F, Theta ) ). + +app_with_unbound_lam_should_fail_test() -> + F = [{app, 1, 1, {var, 2, "f"}, #{}}], + ?assertError( {badkey, "f"}, cf_sem:eval( F, ?THETA0 ) ). + +identity_fn_should_eval_arg_test() -> + E = [{str, 1, "bla"}], + Sign = {sign, [{param, "out", false}], [{param, "inp", false}]}, + Body = {natbody, #{"out" => [{var, 2, "inp"}]}}, + Lam = {lam, 3, "f", Sign, Body}, + F = [{app, 4, 1, Lam, #{"inp" => E}}], + ?assertEqual( E, cf_sem:eval( F, ?THETA0 ) ). + +multiple_output_should_be_bindable_test() -> + Sign = {sign, [{param, "out1", false}, {param, "out2", false}], []}, + E1 = [{str, 1, "bla"}], + E2 = [{str, 2, "blub"}], + Body = {natbody, #{"out1" => E1, "out2" => E2}}, + Lam = {lam, 3, "f", Sign, Body}, + F1 = [{app, 4, 1, Lam, #{}}], + F2 = [{app, 5, 2, Lam, #{}}], + [?assertEqual( E1, cf_sem:eval( F1, ?THETA0 ) ), + ?assertEqual( E2, cf_sem:eval( F2, ?THETA0 ) )]. + +app_should_ignore_calling_context_test() -> + Sign = {sign, [{param, "out", false}], []}, + Body = {natbody, #{"out" => [{var, 1, "x"}]}}, + Lam = {lam, 2, "f", Sign, Body}, + X = [{app, 3, 1, Lam, #{}}], + Rho = #{"x" => [{str, 4, "blub"}]}, + ?assertError( {badkey, "x"}, cf_sem:eval( X, {Rho, fun mu/1, #{}, #{}} ) ). + +app_should_hand_down_gamma_test() -> + Sign = {sign, [{param, "out", false}], []}, + Body = {natbody, #{"out" => [{app, 1, 1, {var, 2, "f"}, #{}}]}}, + Lam = {lam, 3, "g", Sign, Body}, + X = [{app, 4, 1, Lam, #{}}], + E = [{str, 5, "blub"}], + Gamma = #{"f" => {lam, 6, "f", Sign, {natbody, #{"out" => E}}}}, + Theta = {#{}, fun mu/1, Gamma, #{}}, + ?assertEqual( E, cf_sem:eval( X, Theta ) ). + +binding_should_override_body_test() -> + F = [{str, 1, "blub"}], + Sign = {sign, [{param, "out", false}], [{param, "x", false}]}, + Body = {natbody, #{"x" => [{str, 2, "bla"}], "out" => [{var, 3, "x"}]}}, + Lam = {lam, 4, "f", Sign, Body}, + X = [{app, 5, 1, Lam, #{"x" => F}}], + ?assertEqual( F, cf_sem:eval( X, ?THETA0 ) ). + +returning_empty_list_on_nonlist_output_channel_should_fail_test() -> + S = {sign, [{param, "out", false}], []}, + B = {natbody, #{"out" => []}}, + Lam = {lam, 1, "f", S, B}, + X = [{app, 2, 1, Lam, #{}}], + ?assertError( output_sign_mismatch, cf_sem:eval( X, ?THETA0 ) ). + +cross_product_should_be_derivable_test() -> + Sign = {sign, [{param, "out1", false}, {param, "out2", false}], + [{param, "p1", false}, {param, "p2", false}]}, + E1 = [{str, 1, "A"}, {str, 2, "B"}], + E2 = [{str, 3, "1"}, {str, 4, "2"}], + Body = {natbody, #{"out1" => [{var, 5, "p1"}], "out2" => [{var, 6, "p2"}]}}, + Lam = {lam, 7, "f", Sign, Body}, + Binding = #{"p1" => E1, "p2" => E2}, + App1 = [{app, 8, 1, Lam, Binding}], + App2 = [{app, 9, 2, Lam, Binding}], + F1 = [{str, 1, "A"}, {str, 1, "A"}, {str, 2, "B"}, {str, 2, "B"}], + F2 = [{str, 3, "1"}, {str, 4, "2"}, {str, 3, "1"}, {str, 4, "2"}], + [?assertEqual( F1, cf_sem:eval( App1, ?THETA0 ) ), + ?assertEqual( F2, cf_sem:eval( App2, ?THETA0 ) )]. + +dot_product_should_be_derivable_test() -> + Sign = {sign, [{param, "out1", false}, {param, "out2", false}], + [{correl, ["p1", "p2"]}]}, + E1 = [{str, 1, "A"}, {str, 2, "B"}], + E2 = [{str, 3, "1"}, {str, 4, "2"}], + Body = {natbody, #{"out1" => [{var, 5, "p1"}], "out2" => [{var, 6, "p2"}]}}, + Lam = {lam, 7, "f", Sign, Body}, + Binding = #{"p1" => E1, "p2" => E2}, + App1 = [{app, 8, 1, Lam, Binding}], + App2 = [{app, 9, 2, Lam, Binding}], + [?assertEqual( E1, cf_sem:eval( App1, ?THETA0 ) ), + ?assertEqual( E2, cf_sem:eval( App2, ?THETA0 ) )]. + +aggregate_should_consume_whole_list_test() -> + Sign = {sign, [{param, "out", true}], + [{param, "inp", true}]}, + E1 = [{str, 1, "A"}], + E2 = [{str, 2, "B"}, {str, 3, "C"}], + Body = {natbody, #{"out" => E1++[{var, 4, "inp"}]}}, + Lam = {lam, 5, "f", Sign, Body}, + Binding = #{"inp" => E2}, + App = [{app, 6, 1, Lam, Binding}], + ?assertEqual( E1++E2, cf_sem:eval( App, ?THETA0 ) ). + +cnd_false_should_eval_else_expr_test() -> + E = [{cnd, 1, [], [{str, 2, "A"}], [{str, 3, "B"}]}], + ?assertEqual( [{str, 3, "B"}], cf_sem:eval( E, ?THETA0 ) ). + +cnd_evaluates_condition_before_decision1_test() -> + Sign = {sign, [{param, "out", true}], []}, + Body = {natbody, #{"out" => []}}, + Lam = {lam, 1, "f", Sign, Body}, + App = [{app, 2, 1, Lam, #{}}], + E = [{cnd, 3, App, [{str, 4, "A"}], [{str, 5, "B"}]}], + ?assertEqual( [{str, 5, "B"}], cf_sem:eval( E, ?THETA0 ) ). + +cnd_evaluates_condition_before_decision2_test() -> + Sign = {sign, [{param, "out", true}], []}, + Body = {natbody, #{"out" => [{str, 1, "X"}]}}, + Lam = {lam, 2, "f", Sign, Body}, + App = [{app, 3, 1, Lam, #{}}], + E = [{cnd, 4, App, [{str, 5, "A"}], [{str, 6, "B"}]}], + ?assertEqual( [{str, 5, "A"}], cf_sem:eval( E, ?THETA0 ) ). + +cnd_evaluates_only_on_final_condition_test() -> + Sign = {sign, [{param, "out", true}], []}, + Lam = {lam, 1, "f", Sign, {forbody, bash, "shalala"}}, + App = [{app, 2, 1, Lam, #{}}], + A = [{var, 3, "a"}], + B = [{var, 4, "b"}], + E = [{cnd, 5, App, A, B}], + Rho = #{"a" => [{str, 6, "A"}], "b" => [{str, 7, "B"}]}, + X = cf_sem:eval( E, {Rho, fun mu/1, #{}, #{}} ), + ?assertMatch( [{cnd, 5, [{select, 2, 1, _}], A, B}], X ). + +cnd_evaluates_then_expr_test() -> + E = [{cnd, 1, [{str, 2, "Z"}], [{var, 3, "x"}], [{str, 4, "B"}]}], + F = [{str, 5, "A"}], + Theta = {#{"x" => F}, fun mu/1, #{}, #{}}, + ?assertEqual( F, cf_sem:eval( E, Theta ) ). + +cnd_evaluates_else_expr_test() -> + E = [{cnd, 1, [], [{str, 2, "B"}], [{var, 3, "x"}]}], + F = [{str, 4, "A"}], + Theta = {#{"x" => F}, fun mu/1, #{}, #{}}, + ?assertEqual( F, cf_sem:eval( E, Theta ) ). + +foreign_app_with_cnd_param_is_left_untouched_test() -> + Sign = {sign, [{param, "out", false}], [{param, "p", false}]}, + Lam = {lam, 1, "f", Sign, {forbody, bash, "shalala"}}, + App1 = [{app, 2, 1, Lam, #{"p" => [{str, 3, "A"}]}}], + E = [{cnd, 4, App1, [], []}], + App2 = [{app, 5, 1, Lam, #{"p" => E}}], + X = cf_sem:eval( App2, ?THETA0 ), + ?assertMatch( [{app, 5, 1, Lam, _}], X ). + +foreign_app_with_select_param_is_left_untouched_test() -> + Sign = {sign, [{param, "out", false}], + [{param, "p", false}]}, + Lam = {lam, 1, "f", Sign, {forbody, bash, "shalala"}}, + App1 = [{app, 2, 1, Lam, #{"p" => [{str, 3, "A"}]}}], + App2 = [{app, 4, 1, Lam, #{"p" => App1}}], + X = cf_sem:eval( App2, ?THETA0 ), + ?assertMatch( [{app, 4, 1, Lam, _}], X ). + +app_non_final_result_preserves_app_test() -> + Sign = {sign, [{param, "out", false}], []}, + Body = {natbody, #{"out" => [{select, 1, 1, {fut, 2, "f", 1234, [false]}}]}}, + Lam = {lam, 3, "g", Sign, Body}, + App = [{app, 4, 1, Lam, #{}}], + X = cf_sem:eval( App, ?THETA0 ), + ?assertMatch( App, X ). + +app_non_final_result_preserves_app_with_new_lam_test() -> + CSign = {sign, [{param, "out", true}], []}, + CLam = {lam, 1, "f", CSign, {forbody, bash, "shalala"}}, + CApp = [{app, 2, 1, CLam, #{}}], + Sign = {sign, [{param, "out", false}], []}, + Body = {natbody, #{"out" => [{cnd, 3, CApp, [{var, 4, "x"}], [{var, 5, "x"}]}], + "x" => [{str, 6, "A"}]}}, + Lam = {lam, 7, "f", Sign, Body}, + App = [{app, 8, 1, Lam, #{}}], + X = cf_sem:eval( App, ?THETA0 ), + [{app, 8, 1, {lam, 7, "f", Sign, {natbody, BodyMap1}}, #{}}] = X, + Val = maps:get( "out", BodyMap1 ), + ?assertMatch( [{cnd, 3, [{select, 2, 1, _}], [{var, 4, "x"}], [{var, 5, "x"}]}], Val ). + +nested_app_undergoes_reduction_test() -> + Sign = {sign, [{param, "out", false}], []}, + Lam1 = {lam, 1, "f", Sign, {forbody, bash, "shalala"}}, + App1 = [{app, 2, 1, Lam1, #{}}], + Body2 = {natbody, #{"out" => App1}}, + Lam2 = {lam, 3, "g", Sign, Body2}, + App2 = [{app, 4, 1, Lam2, #{}}], + X = cf_sem:eval( App2, ?THETA0 ), + [{app, 4, 1, {lam, 3, "g", _, {natbody, Fb}}, _}] = X, + [{select, 2, 1, {fut, 1, "f", R, _}}] = maps:get( "out", Fb ), + Omega = #{{select, 2, 1, {fut, 1, "f", R, [false]}} => [{str, 5, "A"}]}, + Y = cf_sem:eval( X, {#{}, fun mu/1, #{}, Omega} ), + ?assertEqual( [{str, 5, "A"}], Y ). + +app_select_param_is_enumerated_test() -> + Sign1 = {sign, [{param, "out", false}], []}, + Lam1 = {lam, 1, "f", Sign1, {forbody, bash, "shalala"}}, + Sign2 = {sign, [{param, "out", false}], + [{param, "inp", false}]}, + Body2 = {natbody, #{"out" => [{var, 2, "inp"}]}}, + Lam2 = {lam, 3, "g", Sign2, Body2}, + A0 = {app, 4, 1, Lam1, #{}}, + A = [A0, A0], + B = [{app, 5, 1, Lam2, #{"inp" => A}}], + X = cf_sem:eval( B, ?THETA0 ), + ?assertMatch( [{app, 5, 1, _, _}, {app, 5, 1, _, _}], X ). From 7abe5e341c311899b57ac5a91a68b66e412b4d14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Wed, 17 Feb 2016 13:23:02 +0100 Subject: [PATCH 03/78] .travis.yml added. --- .travis.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..4cf8cb0 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,6 @@ +language: erlang +otp_release: + - 18.2.1 + - 18.2 + - 18.1 + - 18.0 From 05f11fbbaac6723fcd1bc3564765e66ec6c63dd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Wed, 17 Feb 2016 13:24:48 +0100 Subject: [PATCH 04/78] .travis.yml fixed. --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4cf8cb0..d00a957 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: erlang otp_release: - - 18.2.1 - - 18.2 - - 18.1 - - 18.0 + - 18.2.1 + - 18.2 + - 18.1 + - 18.0 From 8971db646416dc14ee8d428a2535dca7a20f7248 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Wed, 17 Feb 2016 17:16:37 +0100 Subject: [PATCH 05/78] Parser and semantics plugged together. --- src/cf.erl | 14 +++++++++++- src/cf_parser.erl | 56 +++++++++++++++++++++++------------------------ src/cf_parser.yrl | 56 +++++++++++++++++++++++------------------------ 3 files changed, 69 insertions(+), 57 deletions(-) diff --git a/src/cf.erl b/src/cf.erl index 426307c..77f2793 100644 --- a/src/cf.erl +++ b/src/cf.erl @@ -25,7 +25,7 @@ -export( [start/2, stop/1] ). % API --export( [start/0] ). +-export( [start/0, string/1] ). %% ============================================================================= %% Application callbacks @@ -45,3 +45,15 @@ start() -> start( normal, [] ). +string( S ) -> + {Query, Rho, Gamma} = cf_parser:parse_string( S ), + cf_sem:eval( Query, {Rho, fun get_future/1, Gamma, #{}} ). + +%% ============================================================================= +%% Internal Functions +%% ============================================================================= + +get_future( App ) -> + gen_server:call( cre, {submit, App} ). + + diff --git a/src/cf_parser.erl b/src/cf_parser.erl index 3b98c98..efe4661 100644 --- a/src/cf_parser.erl +++ b/src/cf_parser.erl @@ -50,10 +50,10 @@ set_channel( E, 1 ) -> [E]; set_channel( E, _ ) -> error( {parser, cannot_set_channel_on_nonapp_expr, element( 1, E ), element( 2, E )} ). mk_natlam( {deftask, Line, _}, {id, _, Name}, Sign, Block ) -> - #{Name => [{lam, Line, Name, Sign, {natbody, Block}}]}. + #{Name => {lam, Line, Name, Sign, {natbody, Block}}}. mk_forlam( {deftask, Line, _}, {id, _, Name}, Sign, Lang, {body, _, Code} ) -> - #{Name => [{lam, Line, Name, Sign, {forbody, Lang, Code}}]}. + #{Name => {lam, Line, Name, Sign, {forbody, Lang, Code}}}. %% ============================================================================= @@ -105,40 +105,40 @@ assign_should_be_recognized_test() -> ?assertError( {parser, nonvar_expr_left_of_eq, str, 1}, parse_string( "\"a\" = \"A\";" ) )]. native_deftask_should_be_recognized_test() -> - ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, - {natbody, #{"out" => [{str, 1, "A"}]}}}]}}, + {natbody, #{"out" => [{str, 1, "A"}]}}}}}, parse_string( "deftask f( out : ) { out = \"A\"; }" ) ). foreign_deftask_should_be_recognized_test() -> - [?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, - {forbody, bash, "out=A"}}]}}, + {forbody, bash, "out=A"}}}}, parse_string( "deftask f( out : )in bash *{out=A}*" ) ), - ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, - {forbody, r, "out=\"A\""}}]}}, + {forbody, r, "out=\"A\""}}}}, parse_string( "deftask f( out : )in R *{out=\"A\"}*" ) ), - ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, - {forbody, python, ""}}]}}, + {forbody, python, ""}}}}, parse_string( "deftask f( out : )in python *{}*" ) )]. sign_with_inparam_should_be_recognized_test() -> - [?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], [{param, {name, "inp", false}, false}]}, - {forbody, python, "(defparameter out \"A\")"}}]}}, + {forbody, python, "(defparameter out \"A\")"}}}}, parse_string( "deftask f( out : inp )in python *{(defparameter out \"A\")}*" ) ), - ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], [{param, {name, "a", false}, false}, {param, {name, "b", false}, false}]}, - {forbody, python, "(defparameter out \"A\")"}}]}}, + {forbody, python, "(defparameter out \"A\")"}}}}, parse_string( "deftask f( out : a b )in python *{(defparameter out \"A\")}*" ) )]. %% ============================================================================= @@ -146,45 +146,45 @@ sign_with_inparam_should_be_recognized_test() -> %% ============================================================================= param_should_be_recognized_test() -> - [?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], [{param, {name, "inp", false}, false}]}, - {forbody, bash, "blub"}}]}}, + {forbody, bash, "blub"}}}}, parse_string( "deftask f( out( String ) : inp( String ) )in bash *{blub}*" ) ), - ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", true}, false}], [{param, {name, "inp", true}, false}]}, - {forbody, bash, "blub"}}]}}, + {forbody, bash, "blub"}}}}, parse_string( "deftask f( out( File ) : inp( File ) )in bash *{blub}*" ) ), - ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, true}], [{param, {name, "inp", false}, true}]}, - {forbody, bash, "blub"}}]}}, + {forbody, bash, "blub"}}}}, parse_string( "deftask f( : )in bash *{blub}*" ) ), - ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, true}], [{param, {name, "inp", false}, true}]}, - {forbody, bash, "blub"}}]}}, + {forbody, bash, "blub"}}}}, parse_string( "deftask f( : )in bash *{blub}*" ) ), - ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", true}, true}], [{param, {name, "inp", true}, true}]}, - {forbody, bash, "blub"}}]}}, + {forbody, bash, "blub"}}}}, parse_string( "deftask f( : )in bash *{blub}*" ) )]. correl_inparam_should_be_recognized_test() -> - [?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], [{correl, [{name, "a", true}, {name, "b", true}]}]}, - {forbody, bash, "blub"}}]}}, + {forbody, bash, "blub"}}}}, parse_string( "deftask f( out : [a( File ) b( File )] )in bash *{blub}*" ) ), - ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], [{correl, [{name, "a", true}, {name, "b", true}]}, {param, {name, "c", false}, false}]}, - {forbody, bash, "blub"}}]}}, + {forbody, bash, "blub"}}}}, parse_string( "deftask f( out : [a( File ) b( File )] c )in bash *{blub}*" ) )]. -endif. diff --git a/src/cf_parser.yrl b/src/cf_parser.yrl index a7cd85b..2f27035 100644 --- a/src/cf_parser.yrl +++ b/src/cf_parser.yrl @@ -158,10 +158,10 @@ set_channel( E, 1 ) -> [E]; set_channel( E, _ ) -> error( {parser, cannot_set_channel_on_nonapp_expr, element( 1, E ), element( 2, E )} ). mk_natlam( {deftask, Line, _}, {id, _, Name}, Sign, Block ) -> - #{Name => [{lam, Line, Name, Sign, {natbody, Block}}]}. + #{Name => {lam, Line, Name, Sign, {natbody, Block}}}. mk_forlam( {deftask, Line, _}, {id, _, Name}, Sign, Lang, {body, _, Code} ) -> - #{Name => [{lam, Line, Name, Sign, {forbody, Lang, Code}}]}. + #{Name => {lam, Line, Name, Sign, {forbody, Lang, Code}}}. %% ============================================================================= @@ -213,40 +213,40 @@ assign_should_be_recognized_test() -> ?assertError( {parser, nonvar_expr_left_of_eq, str, 1}, parse_string( "\"a\" = \"A\";" ) )]. native_deftask_should_be_recognized_test() -> - ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, - {natbody, #{"out" => [{str, 1, "A"}]}}}]}}, + {natbody, #{"out" => [{str, 1, "A"}]}}}}}, parse_string( "deftask f( out : ) { out = \"A\"; }" ) ). foreign_deftask_should_be_recognized_test() -> - [?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, - {forbody, bash, "out=A"}}]}}, + {forbody, bash, "out=A"}}}}, parse_string( "deftask f( out : )in bash *{out=A}*" ) ), - ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, - {forbody, r, "out=\"A\""}}]}}, + {forbody, r, "out=\"A\""}}}}, parse_string( "deftask f( out : )in R *{out=\"A\"}*" ) ), - ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, - {forbody, python, ""}}]}}, + {forbody, python, ""}}}}, parse_string( "deftask f( out : )in python *{}*" ) )]. sign_with_inparam_should_be_recognized_test() -> - [?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], [{param, {name, "inp", false}, false}]}, - {forbody, python, "(defparameter out \"A\")"}}]}}, + {forbody, python, "(defparameter out \"A\")"}}}}, parse_string( "deftask f( out : inp )in python *{(defparameter out \"A\")}*" ) ), - ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], [{param, {name, "a", false}, false}, {param, {name, "b", false}, false}]}, - {forbody, python, "(defparameter out \"A\")"}}]}}, + {forbody, python, "(defparameter out \"A\")"}}}}, parse_string( "deftask f( out : a b )in python *{(defparameter out \"A\")}*" ) )]. %% ============================================================================= @@ -254,45 +254,45 @@ sign_with_inparam_should_be_recognized_test() -> %% ============================================================================= param_should_be_recognized_test() -> - [?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], [{param, {name, "inp", false}, false}]}, - {forbody, bash, "blub"}}]}}, + {forbody, bash, "blub"}}}}, parse_string( "deftask f( out( String ) : inp( String ) )in bash *{blub}*" ) ), - ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", true}, false}], [{param, {name, "inp", true}, false}]}, - {forbody, bash, "blub"}}]}}, + {forbody, bash, "blub"}}}}, parse_string( "deftask f( out( File ) : inp( File ) )in bash *{blub}*" ) ), - ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, true}], [{param, {name, "inp", false}, true}]}, - {forbody, bash, "blub"}}]}}, + {forbody, bash, "blub"}}}}, parse_string( "deftask f( : )in bash *{blub}*" ) ), - ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, true}], [{param, {name, "inp", false}, true}]}, - {forbody, bash, "blub"}}]}}, + {forbody, bash, "blub"}}}}, parse_string( "deftask f( : )in bash *{blub}*" ) ), - ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", true}, true}], [{param, {name, "inp", true}, true}]}, - {forbody, bash, "blub"}}]}}, + {forbody, bash, "blub"}}}}, parse_string( "deftask f( : )in bash *{blub}*" ) )]. correl_inparam_should_be_recognized_test() -> - [?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], [{correl, [{name, "a", true}, {name, "b", true}]}]}, - {forbody, bash, "blub"}}]}}, + {forbody, bash, "blub"}}}}, parse_string( "deftask f( out : [a( File ) b( File )] )in bash *{blub}*" ) ), - ?assertEqual( {[], #{}, #{"f" => [{lam, 1, "f", + ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], [{correl, [{name, "a", true}, {name, "b", true}]}, {param, {name, "c", false}, false}]}, - {forbody, bash, "blub"}}]}}, + {forbody, bash, "blub"}}}}, parse_string( "deftask f( out : [a( File ) b( File )] c )in bash *{blub}*" ) )]. -endif. From a2ff2ad1d7a4f90a4c65dce6a2edb46b8f8e27c5 Mon Sep 17 00:00:00 2001 From: Jorgen Brandt Date: Wed, 17 Feb 2016 23:10:41 +0100 Subject: [PATCH 06/78] Model simplified. --- src/cf.erl | 13 +++++- src/cf_sem.erl | 72 ++++++++++++++++----------------- test/cf_sem_test.erl | 94 ++++++++++++++++++++++---------------------- 3 files changed, 95 insertions(+), 84 deletions(-) diff --git a/src/cf.erl b/src/cf.erl index 77f2793..a6dda40 100644 --- a/src/cf.erl +++ b/src/cf.erl @@ -47,7 +47,18 @@ start() -> string( S ) -> {Query, Rho, Gamma} = cf_parser:parse_string( S ), - cf_sem:eval( Query, {Rho, fun get_future/1, Gamma, #{}} ). + reduce( Query, Rho, Gamma ). + +reduce( X0, Rho, Gamma ) -> + X1 = cf_sem:eval( X0, {Rho, fun get_future/1, Gamma, #{}} ), + case cf_sem:pfinal( X1 ) of + true -> X1; + false -> + receive + % TODO + X -> X + end + end. %% ============================================================================= %% Internal Functions diff --git a/src/cf_sem.erl b/src/cf_sem.erl index 29f8d5f..a44de3a 100644 --- a/src/cf_sem.erl +++ b/src/cf_sem.erl @@ -3,7 +3,7 @@ -module( cf_sem ). -author( "Jörgen Brandt " ). --export( [eval/2] ). +-export( [eval/2, pfinal/1] ). -ifdef( TEST ). -include_lib( "eunit/include/eunit.hrl" ). @@ -18,19 +18,19 @@ %% Expression %% =============================================================== -type expr() :: str() | var() | select() | cnd() | app(). % (1) --type str() :: {str, Line::pos_integer(), S::string()}. % (2) --type var() :: {var, Line::pos_integer(), N::string()}. % (3) --type select() :: {select, Line::pos_integer(), C::pos_integer(), U::fut()}. % (4) --type fut() :: {fut, Line::pos_integer(), Name::string(), R::pos_integer(), % (5) - Lp::[boolean()]}. --type cnd() :: {cnd, Line::pos_integer(), % (6) +-type str() :: {str, S::string()}. % (2) +-type var() :: {var, Line::pos_integer(), N::string()}. % (3) +-type select() :: {select, Line::pos_integer(), C::pos_integer(), U::fut()}. % (4) +-type fut() :: {fut, Name::string(), R::pos_integer(), Lp::[boolean()]}. % (5) +-type cnd() :: {cnd, Line::pos_integer(), % (6) Xc::[expr()], Xt::[expr()], Xe::[expr()]}. --type app() :: {app, Line::pos_integer(), C::pos_integer(), % (7) +-type app() :: {app, Line::pos_integer(), C::pos_integer(), % (7) Lambda::lam() | var(), Fa::#{string() => [expr()]}}. %% Lambda %% =================================================================== --type lam() :: {lam, Line::pos_integer(), Name::string(), S::sign(), B::body()}. % (8) +-type lam() :: {lam, Line::pos_integer(), Name::string(), % (8) + S::sign(), B::body()}. % Task Signature -type sign() :: {sign, Lo::[param()], Li::[inparam()]}. % (9) @@ -53,7 +53,7 @@ -type ctx() :: {Rho :: #{string() => [expr()]}, % (18) Mu :: fun( ( app() ) -> fut() ), Gamma :: #{string() => lam()}, - Omega :: #{select() => [expr()]}}. + Omega :: #{{pos_integer(), pos_integer()} => [expr()]}}. %% ============================================================================= @@ -65,10 +65,10 @@ -spec pfinal( X ) -> boolean() % (19) when X :: #{string() => [expr()]} | [expr()] | expr(). -pfinal( F ) when is_map( F ) -> pfinal( maps:values( F ) ); % (20) -pfinal( L ) when is_list( L ) -> lists:all( fun pfinal/1, L ); % (21,22) -pfinal( {str, _, _S} ) -> true; % (23) -pfinal( _T ) -> false. +pfinal( F ) when is_map( F ) -> pfinal( maps:values( F ) ); % (20) +pfinal( L ) when is_list( L ) -> lists:all( fun pfinal/1, L ); % (21,22) +pfinal( {str, _S} ) -> true; % (23) +pfinal( _T ) -> false. %% Singularity %% ============================================================== @@ -93,7 +93,7 @@ psing_argpair( _Z ) -> false. -spec pen( X::expr()|[expr()] ) -> boolean(). % (30) pen( X )when is_list( X ) -> lists:all( fun pen/1, X ); % (31,32) -pen( {str, _, _S} ) -> true; % (33) +pen( {str, _S} ) -> true; % (33) pen( {cnd, _, _Xc, Xt, Xe} )when length( Xt ) =:= 1, length( Xe ) =:= 1 -> % (34) pen( Xt ) andalso pen( Xe ); pen( X={app, _, C, {lam, _, _, {sign, Lo, _Li}, _B}, _Fb} ) -> % (35) @@ -103,7 +103,7 @@ pen( X={app, _, C, {lam, _, _, {sign, Lo, _Li}, _B}, _Fb} ) -> {param, _N, Pl} = lists:nth( C, Lo ), not Pl end; -pen( {select, _, C, {fut, _, _, _R, Lp}} ) -> not lists:nth( C, Lp ); % (36) +pen( {select, _, C, {fut, _, _R, Lp}} ) -> not lists:nth( C, Lp ); % (36) pen( _T ) -> false. %% ============================================================================= @@ -141,15 +141,15 @@ step( X, Theta ) when is_list( X ) -> lists:flatmap( fun( Y ) -> step( Y, Theta ) end, X ); % String Literal -step( X={str, _, _S}, _Theta ) -> [X]; % (45) +step( X={str, _S}, _Theta ) -> [X]; % (45) % Variable step( {var, _, N}, {Rho, _Mu, _Gamma, _Omega} ) -> % (46) maps:get( N, Rho ); % Future Channel Selection -step( S={select, _, _C, _Fut}, {_Rho, _Mu, _Gamma, Omega} ) -> % (47,48) - maps:get( S, Omega, [S] ); +step( S={select, _, C, {fut, _, R, _}}, {_Rho, _Mu, _Gamma, Omega} ) -> % (47,48) + maps:get( {C, R}, Omega, [S] ); % Conditional step( {cnd, _, [], _Xt, Xe}, _Theta ) -> Xe; % (49) @@ -297,7 +297,7 @@ enum_app_without_app_does_nothing_test() -> can_aug_argpair_with_param_test() -> L0 = [{param, "b", false}, {param, "c", false}], - F = #{"a" => [{str, 1, "1"}], "b" => [{str, 2, "2"}], "c" => [{str, 3, "3"}]}, + F = #{"a" => [{str, "1"}], "b" => [{str, "2"}], "c" => [{str, "3"}]}, Pair = {L0, F}, I = {param, "a", false}, L1 = [I|L0], @@ -305,18 +305,18 @@ can_aug_argpair_with_param_test() -> can_aug_argpair_with_correl_test() -> L0 = [{param, "b", false}, {param, "c", false}], - F = #{"a1" => [{str, 1, "11"}], - "a2" => [{str, 2, "12"}], - "b" => [{str, 3, "2"}], - "c" => [{str, 4, "3"}]}, + F = #{"a1" => [{str, "11"}], + "a2" => [{str, "12"}], + "b" => [{str, "2"}], + "c" => [{str, "3"}]}, Pair = {L0, F}, I = {correl, ["a1", "a2"]}, L1 = [{param, "a1", false}, {param, "a2", false}|L0], ?assertEqual( {L1, F}, aug_argpair( Pair, I ) ). can_augment_empty_argpairlist_with_param_test() -> - F1 = #{"a" => [{str, 1, "x1"}]}, - F2 = #{"a" => [{str, 2, "y1"}]}, + F1 = #{"a" => [{str, "x1"}]}, + F2 = #{"a" => [{str, "y1"}]}, PairList = [{[], F1}, {[], F2}], I = {param, "a", false}, L1 = [{param, "a", false}], @@ -324,8 +324,8 @@ can_augment_empty_argpairlist_with_param_test() -> can_augment_argpairlist_with_param_test() -> L0 = [{param, "b", false}, {param, "c", false}], - F1 = #{"a" => [{str, 1, "x1"}], "b" => [{str, 2, "x2"}], "c" => [{str, 3, "x3"}]}, - F2 = #{"a" => [{str, 4, "y1"}], "b" => [{str, 5, "y2"}], "c" => [{str, 6, "y3"}]}, + F1 = #{"a" => [{str, "x1"}], "b" => [{str, "x2"}], "c" => [{str, "x3"}]}, + F2 = #{"a" => [{str, "y1"}], "b" => [{str, "y2"}], "c" => [{str, "y3"}]}, PairList = [{L0, F1}, {L0, F2}], I = {param, "a", false}, L1 = [{param, "a", false}|L0], @@ -333,14 +333,14 @@ can_augment_argpairlist_with_param_test() -> can_augment_argpairlist_with_correl_test() -> L0 = [{param, "b", false}, {param, "c", false}], - F1 = #{"a1" => [{str, 1, "x11"}], - "a2" => [{str, 2, "x12"}], - "b" => [{str, 3, "x2"}], - "c" => [{str, 4, "x3"}]}, - F2 = #{"a1" => [{str, 5, "y11"}], - "a2" => [{str, 6, "y12"}], - "b" => [{str, 7, "y2"}], - "c" => [{str, 8, "y3"}]}, + F1 = #{"a1" => [{str, "x11"}], + "a2" => [{str, "x12"}], + "b" => [{str, "x2"}], + "c" => [{str, "x3"}]}, + F2 = #{"a1" => [{str, "y11"}], + "a2" => [{str, "y12"}], + "b" => [{str, "y2"}], + "c" => [{str, "y3"}]}, PairList = [{L0, F1}, {L0, F2}], I = {correl, ["a1", "a2"]}, L1 = [{param, "a1", false}, {param, "a2", false}|L0], diff --git a/test/cf_sem_test.erl b/test/cf_sem_test.erl index be6925e..75128f0 100644 --- a/test/cf_sem_test.erl +++ b/test/cf_sem_test.erl @@ -5,15 +5,15 @@ -define( THETA0, {#{}, fun mu/1, #{}, #{}} ). -mu( {app, _L, _C, {lam, Line, Name, {sign, Lo, _Li}, _B}, _Fa} ) -> +mu( {app, _AppLine, _C, {lam, _LamLine, Name, {sign, Lo, _Li}, _B}, _Fa} ) -> V = [Pl || {param, _N, Pl} <- Lo], - {fut, Line, Name, random:uniform( 1000000000 ), V}. + {fut, Name, random:uniform( 1000000000 ), V}. nil_should_eval_itself_test() -> ?assertEqual( [], cf_sem:eval( [], ?THETA0 ) ). str_should_eval_itself_test() -> - E = [{str, 1, "bla"}], + E = [{str, "bla"}], ?assertEqual( E, cf_sem:eval( E, ?THETA0 ) ). undef_var_should_fail_test() -> @@ -21,38 +21,38 @@ undef_var_should_fail_test() -> ?assertError( {badkey, "x"}, cf_sem:eval( E, ?THETA0 ) ). def_var_should_eval_to_bound_value_test() -> - E = [{str, 1, "blub"}], + E = [{str, "blub"}], X = cf_sem:eval( [{var, 2, "x"}], {#{"x" => E}, fun mu/1, #{}, #{}} ), ?assertEqual( E, X ). def_var_should_cascade_binding_test() -> - E = [{str, 1, "blub"}], + E = [{str, "blub"}], Theta = {#{"x" => [{var, 2, "y"}], "y" => E}, fun mu/1, #{}, #{}}, X = cf_sem:eval( [{var, 3, "x"}], Theta ), ?assertEqual( E, X ). def_var_should_cascade_binding_twice_test() -> - A = [{str, 1, "A"}], + A = [{str, "A"}], Rho = #{"x" => [{var, 2, "y"}], "y" => [{var, 3, "z"}], "z" => A}, ?assertEqual( A, cf_sem:eval( [{var, 4, "x"}], {Rho, fun mu/1, #{}, #{}} ) ). unfinished_fut_should_eval_to_itself_test() -> - Fut = {fut, 1, 1234, [false]}, + Fut = {fut, "f", 1234, [false]}, E = [{select, 2, 1, Fut}], X = cf_sem:eval( E, ?THETA0 ), ?assertEqual( E, X ). finished_fut_should_eval_to_result_test() -> - Fut = {fut, 1, "f", 1234, [false]}, + Fut = {fut, "f", 1234, [false]}, S = {select, 2, 1, Fut}, - F = [{str, 3, "blub"}], - Theta = {#{}, fun mu/1, #{}, #{S => F}}, + F = [{str, "blub"}], + Theta = {#{}, fun mu/1, #{}, #{{1, 1234} => F}}, X = cf_sem:eval( [S], Theta ), ?assertEqual( F, X ). noarg_fn_should_eval_plain_test() -> - E = [{str, 1, "bla"}], + E = [{str, "bla"}], Sign = {sign, [{param, "out", false}], []}, Body = {natbody, #{"out" => E}}, Lam = {lam, 2, "f", Sign, Body}, @@ -60,7 +60,7 @@ noarg_fn_should_eval_plain_test() -> ?assertEqual( E, cf_sem:eval( F, ?THETA0 ) ). noarg_fn_should_eval_body_test() -> - E = [{str, 1, "bla"}], + E = [{str, "bla"}], Sign = {sign, [{param, "out", false}], []}, Body = {natbody, #{"out" => [{var, 2, "x"}], "x" => E}}, Lam = {lam, 3, "f", Sign, Body}, @@ -68,7 +68,7 @@ noarg_fn_should_eval_body_test() -> ?assertEqual( E, cf_sem:eval( F, ?THETA0 ) ). fn_call_should_insert_lam_test() -> - E = [{str, 1, "bla"}], + E = [{str, "bla"}], Sign = {sign, [{param, "out", false}], []}, Body = {natbody, #{"out" => E}}, Lam = {lam, 2, "f", Sign, Body}, @@ -81,7 +81,7 @@ app_with_unbound_lam_should_fail_test() -> ?assertError( {badkey, "f"}, cf_sem:eval( F, ?THETA0 ) ). identity_fn_should_eval_arg_test() -> - E = [{str, 1, "bla"}], + E = [{str, "bla"}], Sign = {sign, [{param, "out", false}], [{param, "inp", false}]}, Body = {natbody, #{"out" => [{var, 2, "inp"}]}}, Lam = {lam, 3, "f", Sign, Body}, @@ -90,8 +90,8 @@ identity_fn_should_eval_arg_test() -> multiple_output_should_be_bindable_test() -> Sign = {sign, [{param, "out1", false}, {param, "out2", false}], []}, - E1 = [{str, 1, "bla"}], - E2 = [{str, 2, "blub"}], + E1 = [{str, "bla"}], + E2 = [{str, "blub"}], Body = {natbody, #{"out1" => E1, "out2" => E2}}, Lam = {lam, 3, "f", Sign, Body}, F1 = [{app, 4, 1, Lam, #{}}], @@ -104,7 +104,7 @@ app_should_ignore_calling_context_test() -> Body = {natbody, #{"out" => [{var, 1, "x"}]}}, Lam = {lam, 2, "f", Sign, Body}, X = [{app, 3, 1, Lam, #{}}], - Rho = #{"x" => [{str, 4, "blub"}]}, + Rho = #{"x" => [{str, "blub"}]}, ?assertError( {badkey, "x"}, cf_sem:eval( X, {Rho, fun mu/1, #{}, #{}} ) ). app_should_hand_down_gamma_test() -> @@ -112,15 +112,15 @@ app_should_hand_down_gamma_test() -> Body = {natbody, #{"out" => [{app, 1, 1, {var, 2, "f"}, #{}}]}}, Lam = {lam, 3, "g", Sign, Body}, X = [{app, 4, 1, Lam, #{}}], - E = [{str, 5, "blub"}], + E = [{str, "blub"}], Gamma = #{"f" => {lam, 6, "f", Sign, {natbody, #{"out" => E}}}}, Theta = {#{}, fun mu/1, Gamma, #{}}, ?assertEqual( E, cf_sem:eval( X, Theta ) ). binding_should_override_body_test() -> - F = [{str, 1, "blub"}], + F = [{str, "blub"}], Sign = {sign, [{param, "out", false}], [{param, "x", false}]}, - Body = {natbody, #{"x" => [{str, 2, "bla"}], "out" => [{var, 3, "x"}]}}, + Body = {natbody, #{"x" => [{str, "bla"}], "out" => [{var, 3, "x"}]}}, Lam = {lam, 4, "f", Sign, Body}, X = [{app, 5, 1, Lam, #{"x" => F}}], ?assertEqual( F, cf_sem:eval( X, ?THETA0 ) ). @@ -135,23 +135,23 @@ returning_empty_list_on_nonlist_output_channel_should_fail_test() -> cross_product_should_be_derivable_test() -> Sign = {sign, [{param, "out1", false}, {param, "out2", false}], [{param, "p1", false}, {param, "p2", false}]}, - E1 = [{str, 1, "A"}, {str, 2, "B"}], - E2 = [{str, 3, "1"}, {str, 4, "2"}], + E1 = [{str, "A"}, {str, "B"}], + E2 = [{str, "1"}, {str, "2"}], Body = {natbody, #{"out1" => [{var, 5, "p1"}], "out2" => [{var, 6, "p2"}]}}, Lam = {lam, 7, "f", Sign, Body}, Binding = #{"p1" => E1, "p2" => E2}, App1 = [{app, 8, 1, Lam, Binding}], App2 = [{app, 9, 2, Lam, Binding}], - F1 = [{str, 1, "A"}, {str, 1, "A"}, {str, 2, "B"}, {str, 2, "B"}], - F2 = [{str, 3, "1"}, {str, 4, "2"}, {str, 3, "1"}, {str, 4, "2"}], + F1 = [{str, "A"}, {str, "A"}, {str, "B"}, {str, "B"}], + F2 = [{str, "1"}, {str, "2"}, {str, "1"}, {str, "2"}], [?assertEqual( F1, cf_sem:eval( App1, ?THETA0 ) ), ?assertEqual( F2, cf_sem:eval( App2, ?THETA0 ) )]. dot_product_should_be_derivable_test() -> Sign = {sign, [{param, "out1", false}, {param, "out2", false}], [{correl, ["p1", "p2"]}]}, - E1 = [{str, 1, "A"}, {str, 2, "B"}], - E2 = [{str, 3, "1"}, {str, 4, "2"}], + E1 = [{str, "A"}, {str, "B"}], + E2 = [{str, "1"}, {str, "2"}], Body = {natbody, #{"out1" => [{var, 5, "p1"}], "out2" => [{var, 6, "p2"}]}}, Lam = {lam, 7, "f", Sign, Body}, Binding = #{"p1" => E1, "p2" => E2}, @@ -163,8 +163,8 @@ dot_product_should_be_derivable_test() -> aggregate_should_consume_whole_list_test() -> Sign = {sign, [{param, "out", true}], [{param, "inp", true}]}, - E1 = [{str, 1, "A"}], - E2 = [{str, 2, "B"}, {str, 3, "C"}], + E1 = [{str, "A"}], + E2 = [{str, "B"}, {str, "C"}], Body = {natbody, #{"out" => E1++[{var, 4, "inp"}]}}, Lam = {lam, 5, "f", Sign, Body}, Binding = #{"inp" => E2}, @@ -172,24 +172,24 @@ aggregate_should_consume_whole_list_test() -> ?assertEqual( E1++E2, cf_sem:eval( App, ?THETA0 ) ). cnd_false_should_eval_else_expr_test() -> - E = [{cnd, 1, [], [{str, 2, "A"}], [{str, 3, "B"}]}], - ?assertEqual( [{str, 3, "B"}], cf_sem:eval( E, ?THETA0 ) ). + E = [{cnd, 1, [], [{str, "A"}], [{str, "B"}]}], + ?assertEqual( [{str, "B"}], cf_sem:eval( E, ?THETA0 ) ). cnd_evaluates_condition_before_decision1_test() -> Sign = {sign, [{param, "out", true}], []}, Body = {natbody, #{"out" => []}}, Lam = {lam, 1, "f", Sign, Body}, App = [{app, 2, 1, Lam, #{}}], - E = [{cnd, 3, App, [{str, 4, "A"}], [{str, 5, "B"}]}], - ?assertEqual( [{str, 5, "B"}], cf_sem:eval( E, ?THETA0 ) ). + E = [{cnd, 3, App, [{str, "A"}], [{str, "B"}]}], + ?assertEqual( [{str, "B"}], cf_sem:eval( E, ?THETA0 ) ). cnd_evaluates_condition_before_decision2_test() -> Sign = {sign, [{param, "out", true}], []}, - Body = {natbody, #{"out" => [{str, 1, "X"}]}}, + Body = {natbody, #{"out" => [{str, "X"}]}}, Lam = {lam, 2, "f", Sign, Body}, App = [{app, 3, 1, Lam, #{}}], - E = [{cnd, 4, App, [{str, 5, "A"}], [{str, 6, "B"}]}], - ?assertEqual( [{str, 5, "A"}], cf_sem:eval( E, ?THETA0 ) ). + E = [{cnd, 4, App, [{str, "A"}], [{str, "B"}]}], + ?assertEqual( [{str, "A"}], cf_sem:eval( E, ?THETA0 ) ). cnd_evaluates_only_on_final_condition_test() -> Sign = {sign, [{param, "out", true}], []}, @@ -198,26 +198,26 @@ cnd_evaluates_only_on_final_condition_test() -> A = [{var, 3, "a"}], B = [{var, 4, "b"}], E = [{cnd, 5, App, A, B}], - Rho = #{"a" => [{str, 6, "A"}], "b" => [{str, 7, "B"}]}, + Rho = #{"a" => [{str, "A"}], "b" => [{str, "B"}]}, X = cf_sem:eval( E, {Rho, fun mu/1, #{}, #{}} ), ?assertMatch( [{cnd, 5, [{select, 2, 1, _}], A, B}], X ). cnd_evaluates_then_expr_test() -> - E = [{cnd, 1, [{str, 2, "Z"}], [{var, 3, "x"}], [{str, 4, "B"}]}], - F = [{str, 5, "A"}], + E = [{cnd, 1, [{str, "Z"}], [{var, 3, "x"}], [{str, "B"}]}], + F = [{str, "A"}], Theta = {#{"x" => F}, fun mu/1, #{}, #{}}, ?assertEqual( F, cf_sem:eval( E, Theta ) ). cnd_evaluates_else_expr_test() -> - E = [{cnd, 1, [], [{str, 2, "B"}], [{var, 3, "x"}]}], - F = [{str, 4, "A"}], + E = [{cnd, 1, [], [{str, "B"}], [{var, 3, "x"}]}], + F = [{str, "A"}], Theta = {#{"x" => F}, fun mu/1, #{}, #{}}, ?assertEqual( F, cf_sem:eval( E, Theta ) ). foreign_app_with_cnd_param_is_left_untouched_test() -> Sign = {sign, [{param, "out", false}], [{param, "p", false}]}, Lam = {lam, 1, "f", Sign, {forbody, bash, "shalala"}}, - App1 = [{app, 2, 1, Lam, #{"p" => [{str, 3, "A"}]}}], + App1 = [{app, 2, 1, Lam, #{"p" => [{str, "A"}]}}], E = [{cnd, 4, App1, [], []}], App2 = [{app, 5, 1, Lam, #{"p" => E}}], X = cf_sem:eval( App2, ?THETA0 ), @@ -227,14 +227,14 @@ foreign_app_with_select_param_is_left_untouched_test() -> Sign = {sign, [{param, "out", false}], [{param, "p", false}]}, Lam = {lam, 1, "f", Sign, {forbody, bash, "shalala"}}, - App1 = [{app, 2, 1, Lam, #{"p" => [{str, 3, "A"}]}}], + App1 = [{app, 2, 1, Lam, #{"p" => [{str, "A"}]}}], App2 = [{app, 4, 1, Lam, #{"p" => App1}}], X = cf_sem:eval( App2, ?THETA0 ), ?assertMatch( [{app, 4, 1, Lam, _}], X ). app_non_final_result_preserves_app_test() -> Sign = {sign, [{param, "out", false}], []}, - Body = {natbody, #{"out" => [{select, 1, 1, {fut, 2, "f", 1234, [false]}}]}}, + Body = {natbody, #{"out" => [{select, 1, 1, {fut, "f", 1234, [false]}}]}}, Lam = {lam, 3, "g", Sign, Body}, App = [{app, 4, 1, Lam, #{}}], X = cf_sem:eval( App, ?THETA0 ), @@ -246,7 +246,7 @@ app_non_final_result_preserves_app_with_new_lam_test() -> CApp = [{app, 2, 1, CLam, #{}}], Sign = {sign, [{param, "out", false}], []}, Body = {natbody, #{"out" => [{cnd, 3, CApp, [{var, 4, "x"}], [{var, 5, "x"}]}], - "x" => [{str, 6, "A"}]}}, + "x" => [{str, "A"}]}}, Lam = {lam, 7, "f", Sign, Body}, App = [{app, 8, 1, Lam, #{}}], X = cf_sem:eval( App, ?THETA0 ), @@ -263,10 +263,10 @@ nested_app_undergoes_reduction_test() -> App2 = [{app, 4, 1, Lam2, #{}}], X = cf_sem:eval( App2, ?THETA0 ), [{app, 4, 1, {lam, 3, "g", _, {natbody, Fb}}, _}] = X, - [{select, 2, 1, {fut, 1, "f", R, _}}] = maps:get( "out", Fb ), - Omega = #{{select, 2, 1, {fut, 1, "f", R, [false]}} => [{str, 5, "A"}]}, + [{select, 2, 1, {fut, "f", R, _}}] = maps:get( "out", Fb ), + Omega = #{{1, R} => [{str, "A"}]}, Y = cf_sem:eval( X, {#{}, fun mu/1, #{}, Omega} ), - ?assertEqual( [{str, 5, "A"}], Y ). + ?assertEqual( [{str, "A"}], Y ). app_select_param_is_enumerated_test() -> Sign1 = {sign, [{param, "out", false}], []}, From cd7a68e12a48910556842b7dc4310cf072dbe014 Mon Sep 17 00:00:00 2001 From: Jorgen Brandt Date: Wed, 17 Feb 2016 23:20:18 +0100 Subject: [PATCH 07/78] Boiler plate notes added. --- src/cf_sem.erl | 16 ++++++++++++++++ test/cf_sem_test.erl | 18 ++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/cf_sem.erl b/src/cf_sem.erl index a44de3a..99659eb 100644 --- a/src/cf_sem.erl +++ b/src/cf_sem.erl @@ -1,4 +1,20 @@ %% -*- erlang -*- +% +% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis +% +% Copyright 2013 Jörgen Brandt, Marc Bux, and Ulf Leser +% +% Licensed under the Apache License, Version 2.0 (the "License"); +% you may not use this file except in compliance with the License. +% You may obtain a copy of the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, +% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +% See the License for the specific language governing permissions and +% limitations under the License. -module( cf_sem ). -author( "Jörgen Brandt " ). diff --git a/test/cf_sem_test.erl b/test/cf_sem_test.erl index 75128f0..d06ad27 100644 --- a/test/cf_sem_test.erl +++ b/test/cf_sem_test.erl @@ -1,3 +1,21 @@ +%% -*- erlang -*- +% +% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis +% +% Copyright 2013 Jörgen Brandt, Marc Bux, and Ulf Leser +% +% Licensed under the Apache License, Version 2.0 (the "License"); +% you may not use this file except in compliance with the License. +% You may obtain a copy of the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, +% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +% See the License for the specific language governing permissions and +% limitations under the License. + -module( cf_sem_test ). -author( "Jörgen Brandt " ). From f19408852822080735e41ba22cd18fb8a3675acb Mon Sep 17 00:00:00 2001 From: Jorgen Brandt Date: Thu, 18 Feb 2016 11:39:26 +0100 Subject: [PATCH 08/78] Boiler plate code updated. --- src/cf.erl | 2 +- src/cf_lexer.xrl | 2 +- src/cf_parser.yrl | 2 +- src/cf_sem.erl | 13 +++++++------ src/cf_sup.erl | 2 +- test/cf_sem_test.erl | 2 +- 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/cf.erl b/src/cf.erl index a6dda40..46d9593 100644 --- a/src/cf.erl +++ b/src/cf.erl @@ -2,7 +2,7 @@ % % Cuneiform: A Functional Language for Large Scale Scientific Data Analysis % -% Copyright 2013 Jörgen Brandt, Marc Bux, and Ulf Leser +% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser % % Licensed under the Apache License, Version 2.0 (the "License"); % you may not use this file except in compliance with the License. diff --git a/src/cf_lexer.xrl b/src/cf_lexer.xrl index 1bb685f..8959230 100644 --- a/src/cf_lexer.xrl +++ b/src/cf_lexer.xrl @@ -2,7 +2,7 @@ % % Cuneiform: A Functional Language for Large Scale Scientific Data Analysis % -% Copyright 2013 Jörgen Brandt, Marc Bux, and Ulf Leser +% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser % % Licensed under the Apache License, Version 2.0 (the "License"); % you may not use this file except in compliance with the License. diff --git a/src/cf_parser.yrl b/src/cf_parser.yrl index 2f27035..e6fcfb8 100644 --- a/src/cf_parser.yrl +++ b/src/cf_parser.yrl @@ -2,7 +2,7 @@ % % Cuneiform: A Functional Language for Large Scale Scientific Data Analysis % -% Copyright 2013 Jörgen Brandt, Marc Bux, and Ulf Leser +% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser % % Licensed under the Apache License, Version 2.0 (the "License"); % you may not use this file except in compliance with the License. diff --git a/src/cf_sem.erl b/src/cf_sem.erl index 99659eb..c78d28d 100644 --- a/src/cf_sem.erl +++ b/src/cf_sem.erl @@ -2,7 +2,7 @@ % % Cuneiform: A Functional Language for Large Scale Scientific Data Analysis % -% Copyright 2013 Jörgen Brandt, Marc Bux, and Ulf Leser +% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser % % Licensed under the Apache License, Version 2.0 (the "License"); % you may not use this file except in compliance with the License. @@ -109,7 +109,7 @@ psing_argpair( _Z ) -> false. -spec pen( X::expr()|[expr()] ) -> boolean(). % (30) pen( X )when is_list( X ) -> lists:all( fun pen/1, X ); % (31,32) -pen( {str, _S} ) -> true; % (33) +pen( {str, _S} ) -> true; % (33) pen( {cnd, _, _Xc, Xt, Xe} )when length( Xt ) =:= 1, length( Xe ) =:= 1 -> % (34) pen( Xt ) andalso pen( Xe ); pen( X={app, _, C, {lam, _, _, {sign, Lo, _Li}, _B}, _Fb} ) -> % (35) @@ -119,7 +119,7 @@ pen( X={app, _, C, {lam, _, _, {sign, Lo, _Li}, _B}, _Fb} ) -> {param, _N, Pl} = lists:nth( C, Lo ), not Pl end; -pen( {select, _, C, {fut, _, _R, Lp}} ) -> not lists:nth( C, Lp ); % (36) +pen( {select, _, C, {fut, _, _R, Lp}} ) -> not lists:nth( C, Lp ); % (36) pen( _T ) -> false. %% ============================================================================= @@ -157,7 +157,7 @@ step( X, Theta ) when is_list( X ) -> lists:flatmap( fun( Y ) -> step( Y, Theta ) end, X ); % String Literal -step( X={str, _S}, _Theta ) -> [X]; % (45) +step( X={str, _S}, _Theta ) -> [X]; % (45) % Variable step( {var, _, N}, {Rho, _Mu, _Gamma, _Omega} ) -> % (46) @@ -179,7 +179,8 @@ step( {cnd, Line, Xc=[_|_], Xt, Xe}, Theta ) -> step( {app, Line, C, {var, _, N}, Fa}, {_Rho, _Mu, Gamma, _Omega} ) -> [{app, Line, C, maps:get( N, Gamma ), Fa}]; -step( X={app, AppLine, C, Lambda={lam, LamLine, LamName, S={sign, Lo, _Li}, B}, Fa}, +step( X={app, AppLine, C, + Lambda={lam, LamLine, LamName, S={sign, Lo, _Li}, B}, Fa}, Theta={_Rho, Mu, Gamma, Omega} ) -> case psing( X ) of false -> enum_app( {app, AppLine, C, Lambda, step_assoc( Fa, Theta )} ); % (53) @@ -257,7 +258,7 @@ estep( L=[H={correl, Lc}|T], F ) when length( Lc ) > 1 -> false -> [{L, F}]; % (72) true -> Z = corrstep( Lc, F, F ), - aug( [{T, G} || G <- Z], H ) % (73) + aug( [{T, G} || G <- Z], H ) % (73) end. diff --git a/src/cf_sup.erl b/src/cf_sup.erl index 58a462d..c01484c 100644 --- a/src/cf_sup.erl +++ b/src/cf_sup.erl @@ -2,7 +2,7 @@ % % Cuneiform: A Functional Language for Large Scale Scientific Data Analysis % -% Copyright 2013 Jörgen Brandt, Marc Bux, and Ulf Leser +% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser % % Licensed under the Apache License, Version 2.0 (the "License"); % you may not use this file except in compliance with the License. diff --git a/test/cf_sem_test.erl b/test/cf_sem_test.erl index d06ad27..70969a1 100644 --- a/test/cf_sem_test.erl +++ b/test/cf_sem_test.erl @@ -2,7 +2,7 @@ % % Cuneiform: A Functional Language for Large Scale Scientific Data Analysis % -% Copyright 2013 Jörgen Brandt, Marc Bux, and Ulf Leser +% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser % % Licensed under the Apache License, Version 2.0 (the "License"); % you may not use this file except in compliance with the License. From 8a644732943064c47a151de9b4c948ecf89cfc9a Mon Sep 17 00:00:00 2001 From: Jorgen Brandt Date: Thu, 18 Feb 2016 12:33:39 +0100 Subject: [PATCH 09/78] Cre dependency added. --- Makefile | 7 +++++-- rebar.config | 3 +++ src/cf.erl | 4 +--- src/cf_sem.erl | 5 +---- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index a56a55a..6b7a427 100644 --- a/Makefile +++ b/Makefile @@ -4,5 +4,8 @@ all: .rebar/cf_18.2.1_plt clean: rebar clean -.rebar/cf_18.2.1_plt: - rebar build-plt \ No newline at end of file +.rebar/cf_18.2.1_plt: deps/cre/src/cre.erl + rebar build-plt + +deps/cre/src/cre.erl: + rebar get-deps \ No newline at end of file diff --git a/rebar.config b/rebar.config index 4483aa9..dc20cf4 100644 --- a/rebar.config +++ b/rebar.config @@ -1 +1,4 @@ {cover_enabled, true}. +{deps, [ + {cre, "0.1.0", {git, "https://github.com/joergen7/cre.git"}} + ]}. diff --git a/src/cf.erl b/src/cf.erl index 46d9593..104d7ae 100644 --- a/src/cf.erl +++ b/src/cf.erl @@ -50,7 +50,7 @@ string( S ) -> reduce( Query, Rho, Gamma ). reduce( X0, Rho, Gamma ) -> - X1 = cf_sem:eval( X0, {Rho, fun get_future/1, Gamma, #{}} ), + X1 = cf_sem:eval( X0, {Rho, fun cre:submit/1, Gamma, #{}} ), case cf_sem:pfinal( X1 ) of true -> X1; false -> @@ -64,7 +64,5 @@ reduce( X0, Rho, Gamma ) -> %% Internal Functions %% ============================================================================= -get_future( App ) -> - gen_server:call( cre, {submit, App} ). diff --git a/src/cf_sem.erl b/src/cf_sem.erl index c78d28d..27c84db 100644 --- a/src/cf_sem.erl +++ b/src/cf_sem.erl @@ -25,8 +25,6 @@ -include_lib( "eunit/include/eunit.hrl" ). -endif. - - %% ============================================================================= %% Abstract Syntax %% ============================================================================= @@ -70,8 +68,7 @@ Mu :: fun( ( app() ) -> fut() ), Gamma :: #{string() => lam()}, Omega :: #{{pos_integer(), pos_integer()} => [expr()]}}. - - + %% ============================================================================= %% Predicates %% ============================================================================= From 7984ed372c39172855fcb4faf31bb28346ab6a78 Mon Sep 17 00:00:00 2001 From: Jorgen Brandt Date: Thu, 18 Feb 2016 14:36:28 +0100 Subject: [PATCH 10/78] Representation altered. --- src/cf.erl | 42 +++++++++++++++++++++++++++++++++--------- src/cf_sem.erl | 21 +++++++++++---------- test/cf_sem_test.erl | 12 ++++++------ 3 files changed, 50 insertions(+), 25 deletions(-) diff --git a/src/cf.erl b/src/cf.erl index 104d7ae..c8f0851 100644 --- a/src/cf.erl +++ b/src/cf.erl @@ -44,25 +44,49 @@ stop( _State ) -> start() -> start( normal, [] ). +-spec string( S::string() ) -> [cf_sem:str()]. string( S ) -> {Query, Rho, Gamma} = cf_parser:parse_string( S ), reduce( Query, Rho, Gamma ). + + +%% ============================================================================= +%% Internal Functions +%% ============================================================================= + + +-spec reduce( X0, Rho, Gamma ) -> [cf_sem:str()] +when X0 :: [cf_sem:expr()], + Rho :: #{string() => [cf_sem:expr()]}, + Gamma :: #{string() => cf_sem:lam()}. + reduce( X0, Rho, Gamma ) -> X1 = cf_sem:eval( X0, {Rho, fun cre:submit/1, Gamma, #{}} ), case cf_sem:pfinal( X1 ) of - true -> X1; - false -> + true -> X1; + false -> receive - % TODO - X -> X - end - end. + {failed, ActScript, Out} -> {failed, ActScript, Out}; + {finished, Summary} -> + Ret = maps:get( ret, Summary ), + Prefix = maps:get( prefix, Summary ), + Delta = lists:foldl( + fun( N, Delta0 ) -> + acc_delta( N, Delta0, Ret, Prefix ) + end, + #{}, maps:keys( Ret ) ) -%% ============================================================================= -%% Internal Functions -%% ============================================================================= + end + end. +-spec acc_delta( N, Delta0, Ret, Prefix ) -> #{string() => [cf_sem:str()]} +when N :: string(), + Delta0 :: #{string() => [cf_sem:str()]}, + Ret :: #{string() => [string()]}, + Prefix :: string(). +acc_delta( N, Delta0, Ret, Prefix ) -> + Delta0#{{N, Prefix} => [{str, S} || S <- maps:get( N, Ret )]}. \ No newline at end of file diff --git a/src/cf_sem.erl b/src/cf_sem.erl index 27c84db..6d9eaea 100644 --- a/src/cf_sem.erl +++ b/src/cf_sem.erl @@ -34,8 +34,9 @@ -type expr() :: str() | var() | select() | cnd() | app(). % (1) -type str() :: {str, S::string()}. % (2) -type var() :: {var, Line::pos_integer(), N::string()}. % (3) --type select() :: {select, Line::pos_integer(), C::pos_integer(), U::fut()}. % (4) --type fut() :: {fut, Name::string(), R::pos_integer(), Lp::[boolean()]}. % (5) +-type select() :: {select, Line::pos_integer(), N::string(), U::fut()}. % (4) +-type fut() :: {fut, Name::string(), R::string(), % (5) + Fp::#{string() => boolean()}}. -type cnd() :: {cnd, Line::pos_integer(), % (6) Xc::[expr()], Xt::[expr()], Xe::[expr()]}. -type app() :: {app, Line::pos_integer(), C::pos_integer(), % (7) @@ -67,7 +68,7 @@ -type ctx() :: {Rho :: #{string() => [expr()]}, % (18) Mu :: fun( ( app() ) -> fut() ), Gamma :: #{string() => lam()}, - Omega :: #{{pos_integer(), pos_integer()} => [expr()]}}. + Omega :: #{{string(), string()} => [expr()]}}. %% ============================================================================= %% Predicates @@ -116,7 +117,7 @@ pen( X={app, _, C, {lam, _, _, {sign, Lo, _Li}, _B}, _Fb} ) -> {param, _N, Pl} = lists:nth( C, Lo ), not Pl end; -pen( {select, _, C, {fut, _, _R, Lp}} ) -> not lists:nth( C, Lp ); % (36) +pen( {select, _, N, {fut, _, _R, Fp}} ) -> not maps:get( N, Fp ); % (36) pen( _T ) -> false. %% ============================================================================= @@ -161,8 +162,8 @@ step( {var, _, N}, {Rho, _Mu, _Gamma, _Omega} ) -> maps:get( N, Rho ); % Future Channel Selection -step( S={select, _, C, {fut, _, R, _}}, {_Rho, _Mu, _Gamma, Omega} ) -> % (47,48) - maps:get( {C, R}, Omega, [S] ); +step( S={select, _, N, {fut, _, R, _}}, {_Rho, _Mu, _Gamma, Omega} ) -> % (47,48) + maps:get( {N, R}, Omega, [S] ); % Conditional step( {cnd, _, [], _Xt, Xe}, _Theta ) -> Xe; % (49) @@ -182,19 +183,19 @@ step( X={app, AppLine, C, case psing( X ) of false -> enum_app( {app, AppLine, C, Lambda, step_assoc( Fa, Theta )} ); % (53) true -> + {param, N, Pl} = lists:nth( C, Lo ), case B of {forbody, _L, _Z} -> case pfinal( Fa ) of false -> [{app, AppLine, C, Lambda, step_assoc( Fa, Theta )}]; % (54) - true -> [{select, AppLine, C, apply( Mu, [X] )}] % (55) + true -> [{select, AppLine, N, apply( Mu, [X] )}] % (55) end; {natbody, Fb} -> - {param, K, Pl} = lists:nth( C, Lo ), - V0 = maps:get( K, Fb ), + V0 = maps:get( N, Fb ), V1 = step( V0, {maps:merge( Fb, Fa ), Mu, Gamma, Omega} ), case pfinal( V1 ) of false -> [{app, AppLine, C, {lam, LamLine, LamName, S, % (56) - {natbody, Fb#{ K => V1}}}, Fa}]; + {natbody, Fb#{ N => V1}}}, Fa}]; true -> case Pl orelse length( V1 ) =:= 1 of true -> V1; % (57) diff --git a/test/cf_sem_test.erl b/test/cf_sem_test.erl index 70969a1..cc2f251 100644 --- a/test/cf_sem_test.erl +++ b/test/cf_sem_test.erl @@ -24,8 +24,8 @@ -define( THETA0, {#{}, fun mu/1, #{}, #{}} ). mu( {app, _AppLine, _C, {lam, _LamLine, Name, {sign, Lo, _Li}, _B}, _Fa} ) -> - V = [Pl || {param, _N, Pl} <- Lo], - {fut, Name, random:uniform( 1000000000 ), V}. + V = [{N, Pl} || {param, N, Pl} <- Lo], + {fut, Name, lists:flatten( io_lib:format( "~B", [random:uniform( 1000000000 )] )), maps:from_list( V )}. nil_should_eval_itself_test() -> ?assertEqual( [], cf_sem:eval( [], ?THETA0 ) ). @@ -218,7 +218,7 @@ cnd_evaluates_only_on_final_condition_test() -> E = [{cnd, 5, App, A, B}], Rho = #{"a" => [{str, "A"}], "b" => [{str, "B"}]}, X = cf_sem:eval( E, {Rho, fun mu/1, #{}, #{}} ), - ?assertMatch( [{cnd, 5, [{select, 2, 1, _}], A, B}], X ). + ?assertMatch( [{cnd, 5, [{select, 2, "out", _}], A, B}], X ). cnd_evaluates_then_expr_test() -> E = [{cnd, 1, [{str, "Z"}], [{var, 3, "x"}], [{str, "B"}]}], @@ -270,7 +270,7 @@ app_non_final_result_preserves_app_with_new_lam_test() -> X = cf_sem:eval( App, ?THETA0 ), [{app, 8, 1, {lam, 7, "f", Sign, {natbody, BodyMap1}}, #{}}] = X, Val = maps:get( "out", BodyMap1 ), - ?assertMatch( [{cnd, 3, [{select, 2, 1, _}], [{var, 4, "x"}], [{var, 5, "x"}]}], Val ). + ?assertMatch( [{cnd, 3, [{select, 2, "out", _}], [{var, 4, "x"}], [{var, 5, "x"}]}], Val ). nested_app_undergoes_reduction_test() -> Sign = {sign, [{param, "out", false}], []}, @@ -281,8 +281,8 @@ nested_app_undergoes_reduction_test() -> App2 = [{app, 4, 1, Lam2, #{}}], X = cf_sem:eval( App2, ?THETA0 ), [{app, 4, 1, {lam, 3, "g", _, {natbody, Fb}}, _}] = X, - [{select, 2, 1, {fut, "f", R, _}}] = maps:get( "out", Fb ), - Omega = #{{1, R} => [{str, "A"}]}, + [{select, 2, "out", {fut, "f", R, _}}] = maps:get( "out", Fb ), + Omega = #{{"out", R} => [{str, "A"}]}, Y = cf_sem:eval( X, {#{}, fun mu/1, #{}, Omega} ), ?assertEqual( [{str, "A"}], Y ). From afc491789199cfb13c30ef4975a41b59b57a3b9d Mon Sep 17 00:00:00 2001 From: Jorgen Brandt Date: Thu, 18 Feb 2016 15:54:16 +0100 Subject: [PATCH 11/78] Changes. --- src/cf.erl | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/cf.erl b/src/cf.erl index c8f0851..6836a78 100644 --- a/src/cf.erl +++ b/src/cf.erl @@ -56,6 +56,7 @@ string( S ) -> %% Internal Functions %% ============================================================================= +%% Reduction %% -spec reduce( X0, Rho, Gamma ) -> [cf_sem:str()] when X0 :: [cf_sem:expr()], @@ -63,12 +64,19 @@ when X0 :: [cf_sem:expr()], Gamma :: #{string() => cf_sem:lam()}. reduce( X0, Rho, Gamma ) -> + reduce( X0, {Rho, fun cre:submit/1, Gamma, #{}} ). + +-spec reduce( X0, Theta ) -> [cf_sem:str()] +when X0 :: [cf_sem:expr()], + Theta :: cf_sem:ctx(). + +reduce( X0, {Rho, Mu, Gamma, Omega} ) -> X1 = cf_sem:eval( X0, {Rho, fun cre:submit/1, Gamma, #{}} ), case cf_sem:pfinal( X1 ) of true -> X1; false -> receive - {failed, ActScript, Out} -> {failed, ActScript, Out}; + {failed, ActScript, Out} -> error( {failed, ActScript, Out} ); {finished, Summary} -> Ret = maps:get( ret, Summary ), Prefix = maps:get( prefix, Summary ), @@ -76,9 +84,8 @@ reduce( X0, Rho, Gamma ) -> fun( N, Delta0 ) -> acc_delta( N, Delta0, Ret, Prefix ) end, - #{}, maps:keys( Ret ) ) - - + #{}, maps:keys( Ret ) ), + reduce( X1, {Rho, Mu, Gamma, maps:merge( Omega, Delta )} ) end end. From cda01d9cd722f444aec82cc8d9ec6b31dd5af669 Mon Sep 17 00:00:00 2001 From: Jorgen Brandt Date: Thu, 18 Feb 2016 20:27:17 +0100 Subject: [PATCH 12/78] Representation fixed. --- src/cf_sem.erl | 14 ++++++++------ test/cf_sem_test.erl | 11 +++++------ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/cf_sem.erl b/src/cf_sem.erl index 6d9eaea..2225005 100644 --- a/src/cf_sem.erl +++ b/src/cf_sem.erl @@ -34,7 +34,7 @@ -type expr() :: str() | var() | select() | cnd() | app(). % (1) -type str() :: {str, S::string()}. % (2) -type var() :: {var, Line::pos_integer(), N::string()}. % (3) --type select() :: {select, Line::pos_integer(), N::string(), U::fut()}. % (4) +-type select() :: {select, Line::pos_integer(), C::pos_integer(), U::fut()}. % (4) -type fut() :: {fut, Name::string(), R::string(), % (5) Fp::#{string() => boolean()}}. -type cnd() :: {cnd, Line::pos_integer(), % (6) @@ -117,7 +117,9 @@ pen( X={app, _, C, {lam, _, _, {sign, Lo, _Li}, _B}, _Fb} ) -> {param, _N, Pl} = lists:nth( C, Lo ), not Pl end; -pen( {select, _, N, {fut, _, _R, Fp}} ) -> not maps:get( N, Fp ); % (36) +pen( {select, _, C, {fut, _, _R, Lo}} ) -> % (36) + {param, _N, Pl} = lists:nth( C, Lo ), + not Pl; pen( _T ) -> false. %% ============================================================================= @@ -162,8 +164,8 @@ step( {var, _, N}, {Rho, _Mu, _Gamma, _Omega} ) -> maps:get( N, Rho ); % Future Channel Selection -step( S={select, _, N, {fut, _, R, _}}, {_Rho, _Mu, _Gamma, Omega} ) -> % (47,48) - maps:get( {N, R}, Omega, [S] ); +step( S={select, _, C, {fut, _, R, _}}, {_Rho, _Mu, _Gamma, Omega} ) -> % (47,48) + maps:get( {C, R}, Omega, [S] ); % Conditional step( {cnd, _, [], _Xt, Xe}, _Theta ) -> Xe; % (49) @@ -183,14 +185,14 @@ step( X={app, AppLine, C, case psing( X ) of false -> enum_app( {app, AppLine, C, Lambda, step_assoc( Fa, Theta )} ); % (53) true -> - {param, N, Pl} = lists:nth( C, Lo ), case B of {forbody, _L, _Z} -> case pfinal( Fa ) of false -> [{app, AppLine, C, Lambda, step_assoc( Fa, Theta )}]; % (54) - true -> [{select, AppLine, N, apply( Mu, [X] )}] % (55) + true -> [{select, AppLine, C, apply( Mu, [X] )}] % (55) end; {natbody, Fb} -> + {param, N, Pl} = lists:nth( C, Lo ), V0 = maps:get( N, Fb ), V1 = step( V0, {maps:merge( Fb, Fa ), Mu, Gamma, Omega} ), case pfinal( V1 ) of diff --git a/test/cf_sem_test.erl b/test/cf_sem_test.erl index cc2f251..32987ff 100644 --- a/test/cf_sem_test.erl +++ b/test/cf_sem_test.erl @@ -24,8 +24,7 @@ -define( THETA0, {#{}, fun mu/1, #{}, #{}} ). mu( {app, _AppLine, _C, {lam, _LamLine, Name, {sign, Lo, _Li}, _B}, _Fa} ) -> - V = [{N, Pl} || {param, N, Pl} <- Lo], - {fut, Name, lists:flatten( io_lib:format( "~B", [random:uniform( 1000000000 )] )), maps:from_list( V )}. + {fut, Name, lists:flatten( io_lib:format( "~B", [random:uniform( 1000000000 )] )), Lo}. nil_should_eval_itself_test() -> ?assertEqual( [], cf_sem:eval( [], ?THETA0 ) ). @@ -218,7 +217,7 @@ cnd_evaluates_only_on_final_condition_test() -> E = [{cnd, 5, App, A, B}], Rho = #{"a" => [{str, "A"}], "b" => [{str, "B"}]}, X = cf_sem:eval( E, {Rho, fun mu/1, #{}, #{}} ), - ?assertMatch( [{cnd, 5, [{select, 2, "out", _}], A, B}], X ). + ?assertMatch( [{cnd, 5, [{select, 2, 1, _}], A, B}], X ). cnd_evaluates_then_expr_test() -> E = [{cnd, 1, [{str, "Z"}], [{var, 3, "x"}], [{str, "B"}]}], @@ -270,7 +269,7 @@ app_non_final_result_preserves_app_with_new_lam_test() -> X = cf_sem:eval( App, ?THETA0 ), [{app, 8, 1, {lam, 7, "f", Sign, {natbody, BodyMap1}}, #{}}] = X, Val = maps:get( "out", BodyMap1 ), - ?assertMatch( [{cnd, 3, [{select, 2, "out", _}], [{var, 4, "x"}], [{var, 5, "x"}]}], Val ). + ?assertMatch( [{cnd, 3, [{select, 2, 1, _}], [{var, 4, "x"}], [{var, 5, "x"}]}], Val ). nested_app_undergoes_reduction_test() -> Sign = {sign, [{param, "out", false}], []}, @@ -281,8 +280,8 @@ nested_app_undergoes_reduction_test() -> App2 = [{app, 4, 1, Lam2, #{}}], X = cf_sem:eval( App2, ?THETA0 ), [{app, 4, 1, {lam, 3, "g", _, {natbody, Fb}}, _}] = X, - [{select, 2, "out", {fut, "f", R, _}}] = maps:get( "out", Fb ), - Omega = #{{"out", R} => [{str, "A"}]}, + [{select, 2, 1, {fut, "f", R, _}}] = maps:get( "out", Fb ), + Omega = #{{1, R} => [{str, "A"}]}, Y = cf_sem:eval( X, {#{}, fun mu/1, #{}, Omega} ), ?assertEqual( [{str, "A"}], Y ). From b7ffda42d3ae775cfd5e2a90fa81e9cdb7ef67b6 Mon Sep 17 00:00:00 2001 From: Jorgen Brandt Date: Thu, 18 Feb 2016 22:32:15 +0100 Subject: [PATCH 13/78] Changes. --- src/cf.erl | 12 ++++++------ src/cf_sem.erl | 11 ++++++----- test/cf_sem_test.erl | 12 ++++++------ 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/cf.erl b/src/cf.erl index 6836a78..29adb18 100644 --- a/src/cf.erl +++ b/src/cf.erl @@ -79,21 +79,21 @@ reduce( X0, {Rho, Mu, Gamma, Omega} ) -> {failed, ActScript, Out} -> error( {failed, ActScript, Out} ); {finished, Summary} -> Ret = maps:get( ret, Summary ), - Prefix = maps:get( prefix, Summary ), + {R, _} = string:to_integer( maps:get( prefix, Summary ) ), Delta = lists:foldl( fun( N, Delta0 ) -> - acc_delta( N, Delta0, Ret, Prefix ) + acc_delta( N, Delta0, Ret, R ) end, #{}, maps:keys( Ret ) ), reduce( X1, {Rho, Mu, Gamma, maps:merge( Omega, Delta )} ) end end. --spec acc_delta( N, Delta0, Ret, Prefix ) -> #{string() => [cf_sem:str()]} +-spec acc_delta( N, Delta0, Ret, R ) -> #{string() => [cf_sem:str()]} when N :: string(), Delta0 :: #{string() => [cf_sem:str()]}, Ret :: #{string() => [string()]}, - Prefix :: string(). + R :: pos_integer(). -acc_delta( N, Delta0, Ret, Prefix ) -> - Delta0#{{N, Prefix} => [{str, S} || S <- maps:get( N, Ret )]}. \ No newline at end of file +acc_delta( N, Delta0, Ret, R ) -> + Delta0#{{N, R} => [{str, S} || S <- maps:get( N, Ret )]}. \ No newline at end of file diff --git a/src/cf_sem.erl b/src/cf_sem.erl index 2225005..e00aa83 100644 --- a/src/cf_sem.erl +++ b/src/cf_sem.erl @@ -34,8 +34,8 @@ -type expr() :: str() | var() | select() | cnd() | app(). % (1) -type str() :: {str, S::string()}. % (2) -type var() :: {var, Line::pos_integer(), N::string()}. % (3) --type select() :: {select, Line::pos_integer(), C::pos_integer(), U::fut()}. % (4) --type fut() :: {fut, Name::string(), R::string(), % (5) +-type select() :: {select, Line::pos_integer(), C::pos_integer(), U::fut()}. % (4) +-type fut() :: {fut, Name::string(), R::pos_integer(), % (5) Fp::#{string() => boolean()}}. -type cnd() :: {cnd, Line::pos_integer(), % (6) Xc::[expr()], Xt::[expr()], Xe::[expr()]}. @@ -68,7 +68,7 @@ -type ctx() :: {Rho :: #{string() => [expr()]}, % (18) Mu :: fun( ( app() ) -> fut() ), Gamma :: #{string() => lam()}, - Omega :: #{{string(), string()} => [expr()]}}. + Omega :: #{{string(), pos_integer()} => [expr()]}}. %% ============================================================================= %% Predicates @@ -164,8 +164,9 @@ step( {var, _, N}, {Rho, _Mu, _Gamma, _Omega} ) -> maps:get( N, Rho ); % Future Channel Selection -step( S={select, _, C, {fut, _, R, _}}, {_Rho, _Mu, _Gamma, Omega} ) -> % (47,48) - maps:get( {C, R}, Omega, [S] ); +step( S={select, _, C, {fut, _, R, Lo}}, {_Rho, _Mu, _Gamma, Omega} ) -> % (47,48) + {param, N, _} = lists:nth( C, Lo ), + maps:get( {N, R}, Omega, [S] ); % Conditional step( {cnd, _, [], _Xt, Xe}, _Theta ) -> Xe; % (49) diff --git a/test/cf_sem_test.erl b/test/cf_sem_test.erl index 32987ff..f4f1560 100644 --- a/test/cf_sem_test.erl +++ b/test/cf_sem_test.erl @@ -24,7 +24,7 @@ -define( THETA0, {#{}, fun mu/1, #{}, #{}} ). mu( {app, _AppLine, _C, {lam, _LamLine, Name, {sign, Lo, _Li}, _B}, _Fa} ) -> - {fut, Name, lists:flatten( io_lib:format( "~B", [random:uniform( 1000000000 )] )), Lo}. + {fut, Name, random:uniform( 1000000000 ), Lo}. nil_should_eval_itself_test() -> ?assertEqual( [], cf_sem:eval( [], ?THETA0 ) ). @@ -54,17 +54,17 @@ def_var_should_cascade_binding_twice_test() -> ?assertEqual( A, cf_sem:eval( [{var, 4, "x"}], {Rho, fun mu/1, #{}, #{}} ) ). unfinished_fut_should_eval_to_itself_test() -> - Fut = {fut, "f", 1234, [false]}, + Fut = {fut, "f", 1234, [{param, "out", false}]}, E = [{select, 2, 1, Fut}], X = cf_sem:eval( E, ?THETA0 ), ?assertEqual( E, X ). finished_fut_should_eval_to_result_test() -> - Fut = {fut, "f", 1234, [false]}, + Fut = {fut, "f", 1234, [{param, "out", false}]}, S = {select, 2, 1, Fut}, F = [{str, "blub"}], - Theta = {#{}, fun mu/1, #{}, #{{1, 1234} => F}}, + Theta = {#{}, fun mu/1, #{}, #{{"out", 1234} => F}}, X = cf_sem:eval( [S], Theta ), ?assertEqual( F, X ). @@ -251,7 +251,7 @@ foreign_app_with_select_param_is_left_untouched_test() -> app_non_final_result_preserves_app_test() -> Sign = {sign, [{param, "out", false}], []}, - Body = {natbody, #{"out" => [{select, 1, 1, {fut, "f", 1234, [false]}}]}}, + Body = {natbody, #{"out" => [{select, 1, 1, {fut, "f", 1234, [{param, "out", false}]}}]}}, Lam = {lam, 3, "g", Sign, Body}, App = [{app, 4, 1, Lam, #{}}], X = cf_sem:eval( App, ?THETA0 ), @@ -281,7 +281,7 @@ nested_app_undergoes_reduction_test() -> X = cf_sem:eval( App2, ?THETA0 ), [{app, 4, 1, {lam, 3, "g", _, {natbody, Fb}}, _}] = X, [{select, 2, 1, {fut, "f", R, _}}] = maps:get( "out", Fb ), - Omega = #{{1, R} => [{str, "A"}]}, + Omega = #{{"out", R} => [{str, "A"}]}, Y = cf_sem:eval( X, {#{}, fun mu/1, #{}, Omega} ), ?assertEqual( [{str, "A"}], Y ). From 70549aa612decd808aefc9f5e657cfff6fcfcd9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Fri, 19 Feb 2016 13:01:38 +0100 Subject: [PATCH 14/78] Makefile made more robust. --- Makefile | 8 +++----- src/cf.erl | 2 +- src/cf_lexer.xrl | 2 +- src/cf_parser.yrl | 2 +- src/cf_sem.erl | 7 ++++--- src/cf_sup.erl | 2 +- test/cf_sem_test.erl | 2 +- 7 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index 6b7a427..0396669 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,9 @@ all: .rebar/cf_18.2.1_plt - rebar co eu dialyze doc + rebar update-deps co eu dialyze doc clean: rebar clean -.rebar/cf_18.2.1_plt: deps/cre/src/cre.erl - rebar build-plt +.rebar/cf_18.2.1_plt: + rebar update-deps build-plt -deps/cre/src/cre.erl: - rebar get-deps \ No newline at end of file diff --git a/src/cf.erl b/src/cf.erl index 29adb18..a12dd20 100644 --- a/src/cf.erl +++ b/src/cf.erl @@ -17,7 +17,7 @@ % limitations under the License. -module( cf ). --author( "Jörgen Brandt " ). +-author( "Jorgen Brandt " ). -behaviour( application ). diff --git a/src/cf_lexer.xrl b/src/cf_lexer.xrl index 8959230..6c7c641 100644 --- a/src/cf_lexer.xrl +++ b/src/cf_lexer.xrl @@ -113,7 +113,7 @@ Rules. Erlang code. --author( "Jörgen Brandt " ). +-author( "Jorgen Brandt " ). -export( [yyrev/2] ). diff --git a/src/cf_parser.yrl b/src/cf_parser.yrl index e6fcfb8..13d9a8b 100644 --- a/src/cf_parser.yrl +++ b/src/cf_parser.yrl @@ -110,7 +110,7 @@ namelist -> name namelist : ['$1'|'$2']. Erlang code. --author( "Jörgen Brandt " ). +-author( "Jorgen Brandt " ). -export( [parse_string/1] ). diff --git a/src/cf_sem.erl b/src/cf_sem.erl index e00aa83..d0df20d 100644 --- a/src/cf_sem.erl +++ b/src/cf_sem.erl @@ -17,7 +17,7 @@ % limitations under the License. -module( cf_sem ). --author( "Jörgen Brandt " ). +-author( "Jorgen Brandt " ). -export( [eval/2, pfinal/1] ). @@ -49,9 +49,10 @@ % Task Signature -type sign() :: {sign, Lo::[param()], Li::[inparam()]}. % (9) --type param() :: {param, N::string(), Pl::boolean()}. % (10) +-type param() :: {param, M::name(), Pl::boolean()}. % (10) +-type name() :: {name, N::string(), Pf::boolean()} -type inparam() :: param() | correl(). % (11) --type correl() :: {correl, Lc::[string()]}. % (12) +-type correl() :: {correl, Lc::[name()]}. % (12) % Body -type body() :: natbody() | forbody(). % (13) diff --git a/src/cf_sup.erl b/src/cf_sup.erl index c01484c..c920087 100644 --- a/src/cf_sup.erl +++ b/src/cf_sup.erl @@ -17,7 +17,7 @@ % limitations under the License. -module(cf_sup). --author( "Jörgen Brandt " ). +-author( "Jorgen Brandt " ). -behaviour(supervisor). diff --git a/test/cf_sem_test.erl b/test/cf_sem_test.erl index f4f1560..cf5a76e 100644 --- a/test/cf_sem_test.erl +++ b/test/cf_sem_test.erl @@ -17,7 +17,7 @@ % limitations under the License. -module( cf_sem_test ). --author( "Jörgen Brandt " ). +-author( "Jorgen Brandt " ). -include_lib( "eunit/include/eunit.hrl" ). From b35fd0795c23a3a95f00d37512894f2e1659352a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Fri, 19 Feb 2016 17:31:03 +0100 Subject: [PATCH 15/78] Semantics updated. --- hello.cf | 7 +++ src/cf.erl | 26 +++------ src/cf_app.erl | 38 ++++++++++++ src/cf_lexer.erl | 2 +- src/cf_parser.erl | 2 +- src/cf_sem.erl | 66 +++++++++++---------- src/cf_sup.erl | 15 ++++- test/cf_sem_test.erl | 136 +++++++++++++++++++++---------------------- 8 files changed, 171 insertions(+), 121 deletions(-) create mode 100644 hello.cf create mode 100644 src/cf_app.erl diff --git a/hello.cf b/hello.cf new file mode 100644 index 0000000..7b276cd --- /dev/null +++ b/hello.cf @@ -0,0 +1,7 @@ +deftask greet( out : inp ) in bash *{ + out="Hello $inp" +}* + +x = greet( inp: "Jorgen" "Marc" ); + +x; diff --git a/src/cf.erl b/src/cf.erl index a12dd20..35cbae1 100644 --- a/src/cf.erl +++ b/src/cf.erl @@ -19,30 +19,15 @@ -module( cf ). -author( "Jorgen Brandt " ). --behaviour( application ). - -% Application --export( [start/2, stop/1] ). - % API --export( [start/0, string/1] ). - -%% ============================================================================= -%% Application callbacks -%% ============================================================================= - -start( normal, [] ) -> - cf_sup:start_link(). - -stop( _State ) -> - ok. +-export( [start/0, string/1, file/1] ). %% ============================================================================= %% API functions %% ============================================================================= start() -> - start( normal, [] ). + application:start( cf ). -spec string( S::string() ) -> [cf_sem:str()]. @@ -50,6 +35,13 @@ string( S ) -> {Query, Rho, Gamma} = cf_parser:parse_string( S ), reduce( Query, Rho, Gamma ). +-spec file( F::string() ) -> [cf_sem:str()]. + +file( Filename ) -> + {ok, B} = file:read_file( Filename ), + S = binary_to_list( B ), + string( S ). + %% ============================================================================= diff --git a/src/cf_app.erl b/src/cf_app.erl new file mode 100644 index 0000000..fac337e --- /dev/null +++ b/src/cf_app.erl @@ -0,0 +1,38 @@ +%% -*- erlang -*- +% +% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis +% +% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser +% +% Licensed under the Apache License, Version 2.0 (the "License"); +% you may not use this file except in compliance with the License. +% You may obtain a copy of the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, +% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +% See the License for the specific language governing permissions and +% limitations under the License. + +-module( cf_app ). +-author( "Jorgen Brandt " ). + +-behaviour( application ). + +% Application +-export( [start/2, stop/1] ). + +%% ============================================================================= +%% Application callbacks +%% ============================================================================= + +start( normal, [] ) -> + + % TODO: load and hand down configuration + + cf_sup:start_link(). + +stop( _State ) -> + ok. diff --git a/src/cf_lexer.erl b/src/cf_lexer.erl index f7eb4e3..9d213ea 100644 --- a/src/cf_lexer.erl +++ b/src/cf_lexer.erl @@ -14,7 +14,7 @@ %% User code. This is placed here to allow extra attributes. -file("src/cf_lexer.xrl", 114). --author( "Jörgen Brandt " ). +-author( "Jorgen Brandt " ). -export( [yyrev/2] ). diff --git a/src/cf_parser.erl b/src/cf_parser.erl index efe4661..5bd88c0 100644 --- a/src/cf_parser.erl +++ b/src/cf_parser.erl @@ -2,7 +2,7 @@ -export([parse/1, parse_and_scan/1, format_error/1]). -file("src/cf_parser.yrl", 111). --author( "Jörgen Brandt " ). +-author( "Jorgen Brandt " ). -export( [parse_string/1] ). diff --git a/src/cf_sem.erl b/src/cf_sem.erl index d0df20d..5edd625 100644 --- a/src/cf_sem.erl +++ b/src/cf_sem.erl @@ -32,7 +32,7 @@ %% Expression %% =============================================================== -type expr() :: str() | var() | select() | cnd() | app(). % (1) --type str() :: {str, S::string()}. % (2) +-type str() :: {str, Line::pos_integer(), S::string()}. % (2) -type var() :: {var, Line::pos_integer(), N::string()}. % (3) -type select() :: {select, Line::pos_integer(), C::pos_integer(), U::fut()}. % (4) -type fut() :: {fut, Name::string(), R::pos_integer(), % (5) @@ -50,7 +50,7 @@ % Task Signature -type sign() :: {sign, Lo::[param()], Li::[inparam()]}. % (9) -type param() :: {param, M::name(), Pl::boolean()}. % (10) --type name() :: {name, N::string(), Pf::boolean()} +-type name() :: {name, N::string(), Pf::boolean()}. -type inparam() :: param() | correl(). % (11) -type correl() :: {correl, Lc::[name()]}. % (12) @@ -82,7 +82,7 @@ when X :: #{string() => [expr()]} | [expr()] | expr(). pfinal( F ) when is_map( F ) -> pfinal( maps:values( F ) ); % (20) pfinal( L ) when is_list( L ) -> lists:all( fun pfinal/1, L ); % (21,22) -pfinal( {str, _S} ) -> true; % (23) +pfinal( {str, _, _S} ) -> true; % (23) pfinal( _T ) -> false. %% Singularity %% ============================================================== @@ -94,9 +94,11 @@ psing( {app, _, _C, {lam, _, _, {sign, _Lo, Li}, _B}, Fa} ) -> -spec psing_argpair( Z::argpair() ) -> boolean(). % (26) -psing_argpair( {[], _F} ) -> true; % (27) -psing_argpair( {[{param, _N, Pl}|T], F} ) when Pl -> psing_argpair( {T, F} ); % (28) -psing_argpair( {[{param, N, _Pl}|T], F} ) -> % (29) +psing_argpair( {[], _F} ) -> true; % (27) +psing_argpair( {[{param, _, Pl}|T], F} ) % (28) +when Pl -> + psing_argpair( {T, F} ); +psing_argpair( {[{param, {name, N, _}, _Pl}|T], F} ) -> % (29) case length( maps:get( N, F ) ) of 1 -> psing_argpair( {T, F} ); _ -> false @@ -108,18 +110,18 @@ psing_argpair( _Z ) -> false. -spec pen( X::expr()|[expr()] ) -> boolean(). % (30) pen( X )when is_list( X ) -> lists:all( fun pen/1, X ); % (31,32) -pen( {str, _S} ) -> true; % (33) +pen( {str, _, _S} ) -> true; % (33) pen( {cnd, _, _Xc, Xt, Xe} )when length( Xt ) =:= 1, length( Xe ) =:= 1 -> % (34) pen( Xt ) andalso pen( Xe ); pen( X={app, _, C, {lam, _, _, {sign, Lo, _Li}, _B}, _Fb} ) -> % (35) case psing( X ) of false -> false; true -> - {param, _N, Pl} = lists:nth( C, Lo ), + {param, _, Pl} = lists:nth( C, Lo ), not Pl end; pen( {select, _, C, {fut, _, _R, Lo}} ) -> % (36) - {param, _N, Pl} = lists:nth( C, Lo ), + {param, _, Pl} = lists:nth( C, Lo ), not Pl; pen( _T ) -> false. @@ -158,7 +160,7 @@ step( X, Theta ) when is_list( X ) -> lists:flatmap( fun( Y ) -> step( Y, Theta ) end, X ); % String Literal -step( X={str, _S}, _Theta ) -> [X]; % (45) +step( X={str, _Line, _S}, _Theta ) -> [X]; % (45) % Variable step( {var, _, N}, {Rho, _Mu, _Gamma, _Omega} ) -> % (46) @@ -166,7 +168,7 @@ step( {var, _, N}, {Rho, _Mu, _Gamma, _Omega} ) -> % Future Channel Selection step( S={select, _, C, {fut, _, R, Lo}}, {_Rho, _Mu, _Gamma, Omega} ) -> % (47,48) - {param, N, _} = lists:nth( C, Lo ), + {param, {name, N, _}, _} = lists:nth( C, Lo ), maps:get( {N, R}, Omega, [S] ); % Conditional @@ -194,7 +196,7 @@ step( X={app, AppLine, C, true -> [{select, AppLine, C, apply( Mu, [X] )}] % (55) end; {natbody, Fb} -> - {param, N, Pl} = lists:nth( C, Lo ), + {param, {name, N, _}, Pl} = lists:nth( C, Lo ), V0 = maps:get( N, Fb ), V1 = step( V0, {maps:merge( Fb, Fa ), Mu, Gamma, Omega} ), case pfinal( V1 ) of @@ -243,8 +245,8 @@ estep( Z ) -> -spec estep( Li::[inparam()], F::#{string() => [expr()]} ) -> [argpair()]. % (66) estep( [], F ) -> [{[], F}]; % (67) -estep( [H={param, _N, Pl}|T], F ) when Pl -> aug( estep( T, F ), H ); % (68) -estep( L=[H={param, N, _Pl}|T], F ) -> +estep( [H={param, _, Pl}|T], F ) when Pl -> aug( estep( T, F ), H ); % (68) +estep( L=[H={param, {name, N, _}, _Pl}|T], F ) -> V = maps:get( N, F ), case pen( V ) of false -> [{L, F}]; % (69) @@ -255,7 +257,7 @@ estep( L=[H={param, N, _Pl}|T], F ) -> end end; estep( L=[H={correl, Lc}|T], F ) when length( Lc ) > 1 -> - Pen = pen( [maps:get( N, F ) || N <- Lc] ), + Pen = pen( [maps:get( N, F ) || {name, N, _} <- Lc] ), case Pen of false -> [{L, F}]; % (72) true -> @@ -273,9 +275,9 @@ aug( Z, A ) -> [aug_argpair( Y, A ) || Y <- Z]. -spec aug_argpair( Y::argpair(), A::inparam() ) -> argpair(). % (76) -aug_argpair( {L0, F}, A={param, _N, _Pl} ) -> {[A|L0], F}; % (77) +aug_argpair( {L0, F}, A={param, _, _Pl} ) -> {[A|L0], F}; % (77) aug_argpair( {L0, F}, {correl, Lc} ) -> % (78) - L1 = [{param, N, false} || N <- Lc], + L1 = [{param, M, false} || M <- Lc], {L1++L0, F}. %% Correlation %% @@ -286,7 +288,7 @@ when Lc :: [string()], F0 :: #{string() => [expr()]}. corrstep( [], Facc, F0 ) -> [Facc, F0]; % (80) -corrstep( [H|T], Facc, F0 ) -> +corrstep( [{name, H, _}|T], Facc, F0 ) -> case maps:get( H, F0 ) of [] -> []; % (81) [A|B] -> corrstep( T, Facc#{H => [A]}, F0#{H => B}) % (82) @@ -304,7 +306,7 @@ corrstep( [H|T], Facc, F0 ) -> %% The enum Function %% enum_app_without_app_does_nothing_test() -> - S = {sign, [{param, "out", false}], []}, + S = {sign, [{param, {param, "out", false}, false}], []}, B = {forbody, bash, "shalala"}, Lam = {lam, 1, "f", S, B}, App = {app, 2, 1, Lam, #{}}, @@ -315,43 +317,43 @@ enum_app_without_app_does_nothing_test() -> %% Augmentation %% can_aug_argpair_with_param_test() -> - L0 = [{param, "b", false}, {param, "c", false}], + L0 = [{param, {name, "b", false}, false}, {param, {name, "c", false}, false}], F = #{"a" => [{str, "1"}], "b" => [{str, "2"}], "c" => [{str, "3"}]}, Pair = {L0, F}, - I = {param, "a", false}, + I = {param, {name, "a", false}, false}, L1 = [I|L0], ?assertEqual( {L1, F}, aug_argpair( Pair, I ) ). can_aug_argpair_with_correl_test() -> - L0 = [{param, "b", false}, {param, "c", false}], + L0 = [{param, {name, "b", false}, false}, {param, {name, "c", false}, false}], F = #{"a1" => [{str, "11"}], "a2" => [{str, "12"}], "b" => [{str, "2"}], "c" => [{str, "3"}]}, Pair = {L0, F}, - I = {correl, ["a1", "a2"]}, - L1 = [{param, "a1", false}, {param, "a2", false}|L0], + I = {correl, [{name, "a1", false}, {name, "a2", false}]}, + L1 = [{param, {name, "a1", false}, false}, {param, {name, "a2", false}, false}|L0], ?assertEqual( {L1, F}, aug_argpair( Pair, I ) ). can_augment_empty_argpairlist_with_param_test() -> F1 = #{"a" => [{str, "x1"}]}, F2 = #{"a" => [{str, "y1"}]}, PairList = [{[], F1}, {[], F2}], - I = {param, "a", false}, - L1 = [{param, "a", false}], + I = {param, {name, "a", false}, false}, + L1 = [{param, {name, "a", false}, false}], ?assertEqual( [{L1, F1}, {L1, F2}], aug( PairList, I ) ). can_augment_argpairlist_with_param_test() -> - L0 = [{param, "b", false}, {param, "c", false}], + L0 = [{param, {name, "b", false}, false}, {param, {name, "c", false}, false}], F1 = #{"a" => [{str, "x1"}], "b" => [{str, "x2"}], "c" => [{str, "x3"}]}, F2 = #{"a" => [{str, "y1"}], "b" => [{str, "y2"}], "c" => [{str, "y3"}]}, PairList = [{L0, F1}, {L0, F2}], - I = {param, "a", false}, - L1 = [{param, "a", false}|L0], + I = {param, {name, "a", false}, false}, + L1 = [{param, {name, "a", false}, false}|L0], ?assertEqual( [{L1, F1}, {L1, F2}], aug( PairList, I ) ). can_augment_argpairlist_with_correl_test() -> - L0 = [{param, "b", false}, {param, "c", false}], + L0 = [{param, {name, "b", false}, false}, {param, {name, "c", false}, false}], F1 = #{"a1" => [{str, "x11"}], "a2" => [{str, "x12"}], "b" => [{str, "x2"}], @@ -361,8 +363,8 @@ can_augment_argpairlist_with_correl_test() -> "b" => [{str, "y2"}], "c" => [{str, "y3"}]}, PairList = [{L0, F1}, {L0, F2}], - I = {correl, ["a1", "a2"]}, - L1 = [{param, "a1", false}, {param, "a2", false}|L0], + I = {correl, [{name, "a1", false}, {name, "a2", false}]}, + L1 = [{param, {name, "a1", false}, false}, {param, {name, "a2", false}, false}|L0], ?assertEqual( [{L1, F1}, {L1, F2}], aug( PairList, I ) ). %% Correlation %% diff --git a/src/cf_sup.erl b/src/cf_sup.erl index c920087..95c9a9a 100644 --- a/src/cf_sup.erl +++ b/src/cf_sup.erl @@ -19,7 +19,7 @@ -module(cf_sup). -author( "Jorgen Brandt " ). --behaviour(supervisor). +-behaviour( supervisor ). %% API -export( [start_link/0] ). @@ -40,5 +40,16 @@ start_link() -> %% ============================================================================= init( [] ) -> - {ok, { {one_for_one, 5, 10}, []} }. + + RestartStrategy = one_for_one, + MaxRestarts = 5, + MaxSecondsBetweenRestarts = 10, + SupFlags = {RestartStrategy, MaxRestarts, MaxSecondsBetweenRestarts}, + + Restart = permanent, + Shutdown = 2000, + Type = worker, + Cre = {cre, {cre, start_link, []}, Restart, Shutdown, Type, [cre]}, + + {ok, {SupFlags, [Cre]}}. diff --git a/test/cf_sem_test.erl b/test/cf_sem_test.erl index cf5a76e..8ae22ac 100644 --- a/test/cf_sem_test.erl +++ b/test/cf_sem_test.erl @@ -30,7 +30,7 @@ nil_should_eval_itself_test() -> ?assertEqual( [], cf_sem:eval( [], ?THETA0 ) ). str_should_eval_itself_test() -> - E = [{str, "bla"}], + E = [{str, 1, "bla"}], ?assertEqual( E, cf_sem:eval( E, ?THETA0 ) ). undef_var_should_fail_test() -> @@ -38,55 +38,55 @@ undef_var_should_fail_test() -> ?assertError( {badkey, "x"}, cf_sem:eval( E, ?THETA0 ) ). def_var_should_eval_to_bound_value_test() -> - E = [{str, "blub"}], + E = [{str, 1, "blub"}], X = cf_sem:eval( [{var, 2, "x"}], {#{"x" => E}, fun mu/1, #{}, #{}} ), ?assertEqual( E, X ). def_var_should_cascade_binding_test() -> - E = [{str, "blub"}], + E = [{str, 1, "blub"}], Theta = {#{"x" => [{var, 2, "y"}], "y" => E}, fun mu/1, #{}, #{}}, X = cf_sem:eval( [{var, 3, "x"}], Theta ), ?assertEqual( E, X ). def_var_should_cascade_binding_twice_test() -> - A = [{str, "A"}], + A = [{str, 1, "A"}], Rho = #{"x" => [{var, 2, "y"}], "y" => [{var, 3, "z"}], "z" => A}, ?assertEqual( A, cf_sem:eval( [{var, 4, "x"}], {Rho, fun mu/1, #{}, #{}} ) ). unfinished_fut_should_eval_to_itself_test() -> - Fut = {fut, "f", 1234, [{param, "out", false}]}, + Fut = {fut, "f", 1234, [{param, {name, "out", false}, false}]}, E = [{select, 2, 1, Fut}], X = cf_sem:eval( E, ?THETA0 ), ?assertEqual( E, X ). finished_fut_should_eval_to_result_test() -> - Fut = {fut, "f", 1234, [{param, "out", false}]}, + Fut = {fut, "f", 1234, [{param, {name, "out", false}, false}]}, S = {select, 2, 1, Fut}, - F = [{str, "blub"}], + F = [{str, 3, "blub"}], Theta = {#{}, fun mu/1, #{}, #{{"out", 1234} => F}}, X = cf_sem:eval( [S], Theta ), ?assertEqual( F, X ). noarg_fn_should_eval_plain_test() -> - E = [{str, "bla"}], - Sign = {sign, [{param, "out", false}], []}, + E = [{str, 1, "bla"}], + Sign = {sign, [{param, {name, "out", false}, false}], []}, Body = {natbody, #{"out" => E}}, Lam = {lam, 2, "f", Sign, Body}, F = [{app, 3, 1, Lam, #{}}], ?assertEqual( E, cf_sem:eval( F, ?THETA0 ) ). noarg_fn_should_eval_body_test() -> - E = [{str, "bla"}], - Sign = {sign, [{param, "out", false}], []}, + E = [{str, 1, "bla"}], + Sign = {sign, [{param, {name, "out", false}, false}], []}, Body = {natbody, #{"out" => [{var, 2, "x"}], "x" => E}}, Lam = {lam, 3, "f", Sign, Body}, F = [{app, 4, 1, Lam, #{}}], ?assertEqual( E, cf_sem:eval( F, ?THETA0 ) ). fn_call_should_insert_lam_test() -> - E = [{str, "bla"}], - Sign = {sign, [{param, "out", false}], []}, + E = [{str, 1, "bla"}], + Sign = {sign, [{param, {name, "out", false}, false}], []}, Body = {natbody, #{"out" => E}}, Lam = {lam, 2, "f", Sign, Body}, F = [{app, 3, 1, {var, 4, "f"}, #{}}], @@ -98,17 +98,17 @@ app_with_unbound_lam_should_fail_test() -> ?assertError( {badkey, "f"}, cf_sem:eval( F, ?THETA0 ) ). identity_fn_should_eval_arg_test() -> - E = [{str, "bla"}], - Sign = {sign, [{param, "out", false}], [{param, "inp", false}]}, + E = [{str, 1, "bla"}], + Sign = {sign, [{param, {name, "out", false}, false}], [{param, {name, "inp", false}, false}]}, Body = {natbody, #{"out" => [{var, 2, "inp"}]}}, Lam = {lam, 3, "f", Sign, Body}, F = [{app, 4, 1, Lam, #{"inp" => E}}], ?assertEqual( E, cf_sem:eval( F, ?THETA0 ) ). multiple_output_should_be_bindable_test() -> - Sign = {sign, [{param, "out1", false}, {param, "out2", false}], []}, - E1 = [{str, "bla"}], - E2 = [{str, "blub"}], + Sign = {sign, [{param, {name, "out1", false}, false}, {param, {name, "out2", false}, false}], []}, + E1 = [{str, 1, "bla"}], + E2 = [{str, 2, "blub"}], Body = {natbody, #{"out1" => E1, "out2" => E2}}, Lam = {lam, 3, "f", Sign, Body}, F1 = [{app, 4, 1, Lam, #{}}], @@ -117,58 +117,58 @@ multiple_output_should_be_bindable_test() -> ?assertEqual( E2, cf_sem:eval( F2, ?THETA0 ) )]. app_should_ignore_calling_context_test() -> - Sign = {sign, [{param, "out", false}], []}, + Sign = {sign, [{param, {name, "out", false}, false}], []}, Body = {natbody, #{"out" => [{var, 1, "x"}]}}, Lam = {lam, 2, "f", Sign, Body}, X = [{app, 3, 1, Lam, #{}}], - Rho = #{"x" => [{str, "blub"}]}, + Rho = #{"x" => [{str, 4, "blub"}]}, ?assertError( {badkey, "x"}, cf_sem:eval( X, {Rho, fun mu/1, #{}, #{}} ) ). app_should_hand_down_gamma_test() -> - Sign = {sign, [{param, "out", false}], []}, + Sign = {sign, [{param, {name, "out", false}, false}], []}, Body = {natbody, #{"out" => [{app, 1, 1, {var, 2, "f"}, #{}}]}}, Lam = {lam, 3, "g", Sign, Body}, X = [{app, 4, 1, Lam, #{}}], - E = [{str, "blub"}], + E = [{str, 5, "blub"}], Gamma = #{"f" => {lam, 6, "f", Sign, {natbody, #{"out" => E}}}}, Theta = {#{}, fun mu/1, Gamma, #{}}, ?assertEqual( E, cf_sem:eval( X, Theta ) ). binding_should_override_body_test() -> - F = [{str, "blub"}], - Sign = {sign, [{param, "out", false}], [{param, "x", false}]}, + F = [{str, 1, "blub"}], + Sign = {sign, [{param, {name, "out", false}, false}], [{param, {name, "x", false}, false}]}, Body = {natbody, #{"x" => [{str, "bla"}], "out" => [{var, 3, "x"}]}}, Lam = {lam, 4, "f", Sign, Body}, X = [{app, 5, 1, Lam, #{"x" => F}}], ?assertEqual( F, cf_sem:eval( X, ?THETA0 ) ). returning_empty_list_on_nonlist_output_channel_should_fail_test() -> - S = {sign, [{param, "out", false}], []}, + S = {sign, [{param, {name, "out", false}, false}], []}, B = {natbody, #{"out" => []}}, Lam = {lam, 1, "f", S, B}, X = [{app, 2, 1, Lam, #{}}], ?assertError( output_sign_mismatch, cf_sem:eval( X, ?THETA0 ) ). cross_product_should_be_derivable_test() -> - Sign = {sign, [{param, "out1", false}, {param, "out2", false}], - [{param, "p1", false}, {param, "p2", false}]}, - E1 = [{str, "A"}, {str, "B"}], - E2 = [{str, "1"}, {str, "2"}], + Sign = {sign, [{param, {name, "out1", false}, false}, {param, {name, "out2", false}, false}], + [{param, {name, "p1", false}, false}, {param, {name, "p2", false}, false}]}, + E1 = [{str, 1, "A"}, {str, 2, "B"}], + E2 = [{str, 3, "1"}, {str, 4, "2"}], Body = {natbody, #{"out1" => [{var, 5, "p1"}], "out2" => [{var, 6, "p2"}]}}, Lam = {lam, 7, "f", Sign, Body}, Binding = #{"p1" => E1, "p2" => E2}, App1 = [{app, 8, 1, Lam, Binding}], App2 = [{app, 9, 2, Lam, Binding}], - F1 = [{str, "A"}, {str, "A"}, {str, "B"}, {str, "B"}], - F2 = [{str, "1"}, {str, "2"}, {str, "1"}, {str, "2"}], + F1 = [{str, 1, "A"}, {str, 1, "A"}, {str, 2, "B"}, {str, 2, "B"}], + F2 = [{str, 3, "1"}, {str, 4, "2"}, {str, 3, "1"}, {str, 4, "2"}], [?assertEqual( F1, cf_sem:eval( App1, ?THETA0 ) ), ?assertEqual( F2, cf_sem:eval( App2, ?THETA0 ) )]. dot_product_should_be_derivable_test() -> - Sign = {sign, [{param, "out1", false}, {param, "out2", false}], - [{correl, ["p1", "p2"]}]}, - E1 = [{str, "A"}, {str, "B"}], - E2 = [{str, "1"}, {str, "2"}], + Sign = {sign, [{param, {name, "out1", false}, false}, {param, {name, "out2", false}, false}], + [{correl, [{name, "p1", false}, {name, "p2", false}]}]}, + E1 = [{str, 1, "A"}, {str, 2, "B"}], + E2 = [{str, 3, "1"}, {str, 4, "2"}], Body = {natbody, #{"out1" => [{var, 5, "p1"}], "out2" => [{var, 6, "p2"}]}}, Lam = {lam, 7, "f", Sign, Body}, Binding = #{"p1" => E1, "p2" => E2}, @@ -178,10 +178,10 @@ dot_product_should_be_derivable_test() -> ?assertEqual( E2, cf_sem:eval( App2, ?THETA0 ) )]. aggregate_should_consume_whole_list_test() -> - Sign = {sign, [{param, "out", true}], - [{param, "inp", true}]}, - E1 = [{str, "A"}], - E2 = [{str, "B"}, {str, "C"}], + Sign = {sign, [{param, {name, "out", false}, true}], + [{param, {name, "inp", false}, true}]}, + E1 = [{str, 1, "A"}], + E2 = [{str, 2, "B"}, {str, 3, "C"}], Body = {natbody, #{"out" => E1++[{var, 4, "inp"}]}}, Lam = {lam, 5, "f", Sign, Body}, Binding = #{"inp" => E2}, @@ -189,79 +189,79 @@ aggregate_should_consume_whole_list_test() -> ?assertEqual( E1++E2, cf_sem:eval( App, ?THETA0 ) ). cnd_false_should_eval_else_expr_test() -> - E = [{cnd, 1, [], [{str, "A"}], [{str, "B"}]}], - ?assertEqual( [{str, "B"}], cf_sem:eval( E, ?THETA0 ) ). + E = [{cnd, 1, [], [{str, 2, "A"}], [{str, 3, "B"}]}], + ?assertEqual( [{str, 3, "B"}], cf_sem:eval( E, ?THETA0 ) ). cnd_evaluates_condition_before_decision1_test() -> - Sign = {sign, [{param, "out", true}], []}, + Sign = {sign, [{param, {name, "out", false}, true}], []}, Body = {natbody, #{"out" => []}}, Lam = {lam, 1, "f", Sign, Body}, App = [{app, 2, 1, Lam, #{}}], - E = [{cnd, 3, App, [{str, "A"}], [{str, "B"}]}], - ?assertEqual( [{str, "B"}], cf_sem:eval( E, ?THETA0 ) ). + E = [{cnd, 3, App, [{str, 4, "A"}], [{str, 5, "B"}]}], + ?assertEqual( [{str, 5, "B"}], cf_sem:eval( E, ?THETA0 ) ). cnd_evaluates_condition_before_decision2_test() -> - Sign = {sign, [{param, "out", true}], []}, - Body = {natbody, #{"out" => [{str, "X"}]}}, + Sign = {sign, [{param, {name, "out", false}, true}], []}, + Body = {natbody, #{"out" => [{str, 1, "X"}]}}, Lam = {lam, 2, "f", Sign, Body}, App = [{app, 3, 1, Lam, #{}}], - E = [{cnd, 4, App, [{str, "A"}], [{str, "B"}]}], - ?assertEqual( [{str, "A"}], cf_sem:eval( E, ?THETA0 ) ). + E = [{cnd, 4, App, [{str, 5, "A"}], [{str, 6, "B"}]}], + ?assertEqual( [{str, 5, "A"}], cf_sem:eval( E, ?THETA0 ) ). cnd_evaluates_only_on_final_condition_test() -> - Sign = {sign, [{param, "out", true}], []}, + Sign = {sign, [{param, {name, "out", false}, true}], []}, Lam = {lam, 1, "f", Sign, {forbody, bash, "shalala"}}, App = [{app, 2, 1, Lam, #{}}], A = [{var, 3, "a"}], B = [{var, 4, "b"}], E = [{cnd, 5, App, A, B}], - Rho = #{"a" => [{str, "A"}], "b" => [{str, "B"}]}, + Rho = #{"a" => [{str, 6, "A"}], "b" => [{str, 7, "B"}]}, X = cf_sem:eval( E, {Rho, fun mu/1, #{}, #{}} ), ?assertMatch( [{cnd, 5, [{select, 2, 1, _}], A, B}], X ). cnd_evaluates_then_expr_test() -> - E = [{cnd, 1, [{str, "Z"}], [{var, 3, "x"}], [{str, "B"}]}], - F = [{str, "A"}], + E = [{cnd, 1, [{str, 2, "Z"}], [{var, 3, "x"}], [{str, 4, "B"}]}], + F = [{str, 5, "A"}], Theta = {#{"x" => F}, fun mu/1, #{}, #{}}, ?assertEqual( F, cf_sem:eval( E, Theta ) ). cnd_evaluates_else_expr_test() -> E = [{cnd, 1, [], [{str, "B"}], [{var, 3, "x"}]}], - F = [{str, "A"}], + F = [{str, 2, "A"}], Theta = {#{"x" => F}, fun mu/1, #{}, #{}}, ?assertEqual( F, cf_sem:eval( E, Theta ) ). foreign_app_with_cnd_param_is_left_untouched_test() -> - Sign = {sign, [{param, "out", false}], [{param, "p", false}]}, + Sign = {sign, [{param, {name, "out", false}, false}], [{param, {name, "p", false}, false}]}, Lam = {lam, 1, "f", Sign, {forbody, bash, "shalala"}}, - App1 = [{app, 2, 1, Lam, #{"p" => [{str, "A"}]}}], + App1 = [{app, 2, 1, Lam, #{"p" => [{str, 3, "A"}]}}], E = [{cnd, 4, App1, [], []}], App2 = [{app, 5, 1, Lam, #{"p" => E}}], X = cf_sem:eval( App2, ?THETA0 ), ?assertMatch( [{app, 5, 1, Lam, _}], X ). foreign_app_with_select_param_is_left_untouched_test() -> - Sign = {sign, [{param, "out", false}], - [{param, "p", false}]}, + Sign = {sign, [{param, {name, "out", false}, false}], + [{param, {name, "p", false}, false}]}, Lam = {lam, 1, "f", Sign, {forbody, bash, "shalala"}}, - App1 = [{app, 2, 1, Lam, #{"p" => [{str, "A"}]}}], + App1 = [{app, 2, 1, Lam, #{"p" => [{str, 3, "A"}]}}], App2 = [{app, 4, 1, Lam, #{"p" => App1}}], X = cf_sem:eval( App2, ?THETA0 ), ?assertMatch( [{app, 4, 1, Lam, _}], X ). app_non_final_result_preserves_app_test() -> - Sign = {sign, [{param, "out", false}], []}, - Body = {natbody, #{"out" => [{select, 1, 1, {fut, "f", 1234, [{param, "out", false}]}}]}}, + Sign = {sign, [{param, {name, "out", false}, false}], []}, + Body = {natbody, #{"out" => [{select, 1, 1, {fut, "f", 1234, [{param, {name, "out", false}, false}]}}]}}, Lam = {lam, 3, "g", Sign, Body}, App = [{app, 4, 1, Lam, #{}}], X = cf_sem:eval( App, ?THETA0 ), ?assertMatch( App, X ). app_non_final_result_preserves_app_with_new_lam_test() -> - CSign = {sign, [{param, "out", true}], []}, + CSign = {sign, [{param, {name, "out", false}, true}], []}, CLam = {lam, 1, "f", CSign, {forbody, bash, "shalala"}}, CApp = [{app, 2, 1, CLam, #{}}], - Sign = {sign, [{param, "out", false}], []}, + Sign = {sign, [{param, {name, "out", false}, false}], []}, Body = {natbody, #{"out" => [{cnd, 3, CApp, [{var, 4, "x"}], [{var, 5, "x"}]}], "x" => [{str, "A"}]}}, Lam = {lam, 7, "f", Sign, Body}, @@ -272,7 +272,7 @@ app_non_final_result_preserves_app_with_new_lam_test() -> ?assertMatch( [{cnd, 3, [{select, 2, 1, _}], [{var, 4, "x"}], [{var, 5, "x"}]}], Val ). nested_app_undergoes_reduction_test() -> - Sign = {sign, [{param, "out", false}], []}, + Sign = {sign, [{param, {name, "out", false}, false}], []}, Lam1 = {lam, 1, "f", Sign, {forbody, bash, "shalala"}}, App1 = [{app, 2, 1, Lam1, #{}}], Body2 = {natbody, #{"out" => App1}}, @@ -281,15 +281,15 @@ nested_app_undergoes_reduction_test() -> X = cf_sem:eval( App2, ?THETA0 ), [{app, 4, 1, {lam, 3, "g", _, {natbody, Fb}}, _}] = X, [{select, 2, 1, {fut, "f", R, _}}] = maps:get( "out", Fb ), - Omega = #{{"out", R} => [{str, "A"}]}, + Omega = #{{"out", R} => [{str, 5, "A"}]}, Y = cf_sem:eval( X, {#{}, fun mu/1, #{}, Omega} ), - ?assertEqual( [{str, "A"}], Y ). + ?assertEqual( [{str, 5, "A"}], Y ). app_select_param_is_enumerated_test() -> - Sign1 = {sign, [{param, "out", false}], []}, + Sign1 = {sign, [{param, {name, "out", false}, false}], []}, Lam1 = {lam, 1, "f", Sign1, {forbody, bash, "shalala"}}, - Sign2 = {sign, [{param, "out", false}], - [{param, "inp", false}]}, + Sign2 = {sign, [{param, {name, "out", false}, false}], + [{param, {name, "inp", false}, false}]}, Body2 = {natbody, #{"out" => [{var, 2, "inp"}]}}, Lam2 = {lam, 3, "g", Sign2, Body2}, A0 = {app, 4, 1, Lam1, #{}}, From 944d656a18345fde1222084b825d79a32440b279 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Tue, 23 Feb 2016 16:26:14 +0100 Subject: [PATCH 16/78] Message passing implemented. --- Makefile | 2 +- src/cf.erl | 42 +++++++++++++++++++++++++++++++++++------- src/cf_parser.erl | 32 ++++++++++++++++---------------- src/cf_parser.yrl | 36 ++++++++++++++++++------------------ src/cf_sem.erl | 25 +++++++++++++------------ 5 files changed, 83 insertions(+), 54 deletions(-) diff --git a/Makefile b/Makefile index 0396669..dc4d9fb 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ all: .rebar/cf_18.2.1_plt - rebar update-deps co eu dialyze doc + rebar co eu dialyze doc clean: rebar clean diff --git a/src/cf.erl b/src/cf.erl index 35cbae1..d0f665b 100644 --- a/src/cf.erl +++ b/src/cf.erl @@ -21,7 +21,7 @@ % API -export( [start/0, string/1, file/1] ). - + %% ============================================================================= %% API functions %% ============================================================================= @@ -63,21 +63,49 @@ when X0 :: [cf_sem:expr()], Theta :: cf_sem:ctx(). reduce( X0, {Rho, Mu, Gamma, Omega} ) -> - X1 = cf_sem:eval( X0, {Rho, fun cre:submit/1, Gamma, #{}} ), + X1 = cf_sem:eval( X0, {Rho, fun cre:submit/1, Gamma, Omega} ), case cf_sem:pfinal( X1 ) of - true -> X1; + true -> + io:format( "Finished: ~p~nReturning ...~n", [X1] ), + X1; false -> + io:format( "Not finished: ~p~nOmega: ~p~nWaiting for futures to terminate ...~n", [X1, Omega] ), receive - {failed, ActScript, Out} -> error( {failed, ActScript, Out} ); + + {failed, script_error, {ActScript, Out}} -> + + % print tool output + ok = lists:foreach( fun( Line ) -> + io:format( "~s~n", [Line] ) + end, + Out ), + + % print actual script + ok = io:format( "[script]~n" ), + _ = lists:foldl( fun( Line, N ) -> + ok = io:format( "~4.B ~s~n", [N, Line] ), + N+1 + end, + 1, string:tokens( ActScript, "\n" ) ), + + error( script_error ); + + {failed, Reason, Data} -> + error( {Reason, Data} ); + {finished, Summary} -> Ret = maps:get( ret, Summary ), - {R, _} = string:to_integer( maps:get( prefix, Summary ) ), + R = maps:get( prefix, Summary ), Delta = lists:foldl( fun( N, Delta0 ) -> acc_delta( N, Delta0, Ret, R ) end, #{}, maps:keys( Ret ) ), - reduce( X1, {Rho, Mu, Gamma, maps:merge( Omega, Delta )} ) + io:format( "Reducing with Omega = ~p~n", [maps:merge( Omega, Delta )] ), + reduce( X1, {Rho, Mu, Gamma, maps:merge( Omega, Delta )} ); + + Msg -> error( {bad_msg, Msg} ) + end end. @@ -88,4 +116,4 @@ when N :: string(), R :: pos_integer(). acc_delta( N, Delta0, Ret, R ) -> - Delta0#{{N, R} => [{str, S} || S <- maps:get( N, Ret )]}. \ No newline at end of file + Delta0#{{N, R} => maps:get( N, Ret )}. \ No newline at end of file diff --git a/src/cf_parser.erl b/src/cf_parser.erl index 5bd88c0..ae769d4 100644 --- a/src/cf_parser.erl +++ b/src/cf_parser.erl @@ -33,14 +33,14 @@ get_name( {id, _Line, Name} ) -> Name. mk_binding( {id, _, Name}, ExprList ) -> #{Name => ExprList}. - + mk_assign( [], _ExprList, _Channel ) -> #{}; mk_assign( [{var, _Line, Name}|Rest], ExprList, Channel ) -> Rho = mk_assign( Rest, ExprList, Channel+1 ), Value = lists:flatmap( fun( E ) -> set_channel( E, Channel ) end, ExprList ), Rho#{Name => Value}; - + mk_assign( [E|_Rest], _ExprList, _Channel ) -> error( {parser, nonvar_expr_left_of_eq, element( 1, E ), element( 2, E )} ). @@ -48,13 +48,13 @@ mk_assign( [E|_Rest], _ExprList, _Channel ) -> set_channel( {app, Line, _Channel, LamList, Binding}, N ) -> [{app, Line, N, LamList, Binding}]; set_channel( E, 1 ) -> [E]; set_channel( E, _ ) -> error( {parser, cannot_set_channel_on_nonapp_expr, element( 1, E ), element( 2, E )} ). - + mk_natlam( {deftask, Line, _}, {id, _, Name}, Sign, Block ) -> #{Name => {lam, Line, Name, Sign, {natbody, Block}}}. - + mk_forlam( {deftask, Line, _}, {id, _, Name}, Sign, Lang, {body, _, Code} ) -> #{Name => {lam, Line, Name, Sign, {forbody, Lang, Code}}}. - + %% ============================================================================= %% Unit Tests @@ -64,24 +64,24 @@ mk_forlam( {deftask, Line, _}, {id, _, Name}, Sign, Lang, {body, _, Code} ) -> nil_should_be_recognized_test() -> ?assertEqual( {[], #{}, #{}}, parse_string( "nil;" ) ). - + var_should_be_recognized_test() -> ?assertEqual( {[{var, 1, "blub"}], #{}, #{}}, parse_string( "blub;" ) ). - + multi_element_compoundexpr_should_be_recognized_test() -> ?assertEqual( {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}, parse_string( "bla blub;" ) ). - + multiple_targets_should_be_joined_test() -> ?assertEqual( {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}, parse_string( "bla; blub;" ) ). - + strlit_should_be_recognized_test() -> ?assertEqual( {[{str, 1, "bla"}], #{}, #{}}, parse_string( "\"bla\";" ) ). - + intlit_should_be_recognized_test() -> ?assertEqual( {[{str, 1, "-5"}], #{}, #{}}, parse_string( "-5;" ) ). - + cnd_should_be_recognized_test() -> ?assertEqual( {[{cnd, 1, [], [{str, 1, "bla"}], [{str, 1, "blub"}]}], #{}, #{}}, @@ -99,18 +99,18 @@ app_should_be_recognized_test() -> assign_should_be_recognized_test() -> - [?assertEqual( {[], #{"x" => [{str, 1, "x"}]}, #{}}, parse_string( "x = \"x\";" ) ), + [?assertEqual( {[], #{"x" => [{str, 1, "x"}]}, #{}}, parse_string( "x = \"x\";" ) ), ?assertEqual( {[], #{"x" => [{app, 1, 1, {var, 1, "f"}, #{}}], "y" => [{app, 1, 2, {var, 1, "f"}, #{}}]}, #{}}, parse_string( "x y = f();" ) ), ?assertError( {parser, cannot_set_channel_on_nonapp_expr, str, 1}, parse_string( "x y = \"A\";" ) ), ?assertError( {parser, nonvar_expr_left_of_eq, str, 1}, parse_string( "\"a\" = \"A\";" ) )]. - + native_deftask_should_be_recognized_test() -> ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, {natbody, #{"out" => [{str, 1, "A"}]}}}}}, parse_string( "deftask f( out : ) { out = \"A\"; }" ) ). - + foreign_deftask_should_be_recognized_test() -> [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], @@ -140,7 +140,7 @@ sign_with_inparam_should_be_recognized_test() -> {param, {name, "b", false}, false}]}, {forbody, python, "(defparameter out \"A\")"}}}}, parse_string( "deftask f( out : a b )in python *{(defparameter out \"A\")}*" ) )]. - + %% ============================================================================= %% Failing Tests %% ============================================================================= @@ -171,7 +171,7 @@ param_should_be_recognized_test() -> [{param, {name, "inp", true}, true}]}, {forbody, bash, "blub"}}}}, parse_string( "deftask f( : )in bash *{blub}*" ) )]. - + correl_inparam_should_be_recognized_test() -> [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], diff --git a/src/cf_parser.yrl b/src/cf_parser.yrl index 13d9a8b..f491b52 100644 --- a/src/cf_parser.yrl +++ b/src/cf_parser.yrl @@ -20,7 +20,7 @@ %% Symbol Declaration %% ============================================================================= -Nonterminals +Nonterminals script stat assign exprlist expr binding assignlist sign query app cnd paramlist param inparamlist inparam namelist name defun lang bindinglist compoundexpr. @@ -30,7 +30,7 @@ Terminals python r lbrace lparen lsquarebr ltag nil rbrace rparen rsquarebr rtag semicolon string then id. - + %% ============================================================================= %% Syntax Definition %% ============================================================================= @@ -141,14 +141,14 @@ get_name( {id, _Line, Name} ) -> Name. mk_binding( {id, _, Name}, ExprList ) -> #{Name => ExprList}. - + mk_assign( [], _ExprList, _Channel ) -> #{}; mk_assign( [{var, _Line, Name}|Rest], ExprList, Channel ) -> Rho = mk_assign( Rest, ExprList, Channel+1 ), Value = lists:flatmap( fun( E ) -> set_channel( E, Channel ) end, ExprList ), Rho#{Name => Value}; - + mk_assign( [E|_Rest], _ExprList, _Channel ) -> error( {parser, nonvar_expr_left_of_eq, element( 1, E ), element( 2, E )} ). @@ -156,13 +156,13 @@ mk_assign( [E|_Rest], _ExprList, _Channel ) -> set_channel( {app, Line, _Channel, LamList, Binding}, N ) -> [{app, Line, N, LamList, Binding}]; set_channel( E, 1 ) -> [E]; set_channel( E, _ ) -> error( {parser, cannot_set_channel_on_nonapp_expr, element( 1, E ), element( 2, E )} ). - + mk_natlam( {deftask, Line, _}, {id, _, Name}, Sign, Block ) -> #{Name => {lam, Line, Name, Sign, {natbody, Block}}}. - + mk_forlam( {deftask, Line, _}, {id, _, Name}, Sign, Lang, {body, _, Code} ) -> #{Name => {lam, Line, Name, Sign, {forbody, Lang, Code}}}. - + %% ============================================================================= %% Unit Tests @@ -172,24 +172,24 @@ mk_forlam( {deftask, Line, _}, {id, _, Name}, Sign, Lang, {body, _, Code} ) -> nil_should_be_recognized_test() -> ?assertEqual( {[], #{}, #{}}, parse_string( "nil;" ) ). - + var_should_be_recognized_test() -> ?assertEqual( {[{var, 1, "blub"}], #{}, #{}}, parse_string( "blub;" ) ). - + multi_element_compoundexpr_should_be_recognized_test() -> ?assertEqual( {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}, parse_string( "bla blub;" ) ). - + multiple_targets_should_be_joined_test() -> ?assertEqual( {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}, parse_string( "bla; blub;" ) ). - + strlit_should_be_recognized_test() -> ?assertEqual( {[{str, 1, "bla"}], #{}, #{}}, parse_string( "\"bla\";" ) ). - + intlit_should_be_recognized_test() -> ?assertEqual( {[{str, 1, "-5"}], #{}, #{}}, parse_string( "-5;" ) ). - + cnd_should_be_recognized_test() -> ?assertEqual( {[{cnd, 1, [], [{str, 1, "bla"}], [{str, 1, "blub"}]}], #{}, #{}}, @@ -207,18 +207,18 @@ app_should_be_recognized_test() -> assign_should_be_recognized_test() -> - [?assertEqual( {[], #{"x" => [{str, 1, "x"}]}, #{}}, parse_string( "x = \"x\";" ) ), + [?assertEqual( {[], #{"x" => [{str, 1, "x"}]}, #{}}, parse_string( "x = \"x\";" ) ), ?assertEqual( {[], #{"x" => [{app, 1, 1, {var, 1, "f"}, #{}}], "y" => [{app, 1, 2, {var, 1, "f"}, #{}}]}, #{}}, parse_string( "x y = f();" ) ), ?assertError( {parser, cannot_set_channel_on_nonapp_expr, str, 1}, parse_string( "x y = \"A\";" ) ), ?assertError( {parser, nonvar_expr_left_of_eq, str, 1}, parse_string( "\"a\" = \"A\";" ) )]. - + native_deftask_should_be_recognized_test() -> ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, {natbody, #{"out" => [{str, 1, "A"}]}}}}}, parse_string( "deftask f( out : ) { out = \"A\"; }" ) ). - + foreign_deftask_should_be_recognized_test() -> [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], @@ -248,7 +248,7 @@ sign_with_inparam_should_be_recognized_test() -> {param, {name, "b", false}, false}]}, {forbody, python, "(defparameter out \"A\")"}}}}, parse_string( "deftask f( out : a b )in python *{(defparameter out \"A\")}*" ) )]. - + %% ============================================================================= %% Failing Tests %% ============================================================================= @@ -279,7 +279,7 @@ param_should_be_recognized_test() -> [{param, {name, "inp", true}, true}]}, {forbody, bash, "blub"}}}}, parse_string( "deftask f( : )in bash *{blub}*" ) )]. - + correl_inparam_should_be_recognized_test() -> [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], diff --git a/src/cf_sem.erl b/src/cf_sem.erl index 5edd625..36b5a8d 100644 --- a/src/cf_sem.erl +++ b/src/cf_sem.erl @@ -70,7 +70,7 @@ Mu :: fun( ( app() ) -> fut() ), Gamma :: #{string() => lam()}, Omega :: #{{string(), pos_integer()} => [expr()]}}. - + %% ============================================================================= %% Predicates %% ============================================================================= @@ -132,14 +132,14 @@ pen( _T ) -> false. %% The eval Function %% ======================================================== -spec eval( X::[expr()], Theta::ctx() ) -> [expr()]. % (37) - + eval( X, Theta ) -> X1 = step( X, Theta ), case X1 of X -> X; % (38) _ -> eval( X1, Theta ) % (39) end. - + %% Reduction Rules %% ========================================================== -spec step_assoc( F, Theta ) -> #{string() => [expr()]} % (40) @@ -153,22 +153,23 @@ step_assoc( F, Theta ) when is_map( F ) -> -spec step( X, Theta ) -> [expr()] % (42) when X :: #{string() => [expr()]} | [expr()] | expr(), Theta :: ctx(). - -% Expression List + +% Expression List step( X, Theta ) when is_list( X ) -> % (43,44) lists:flatmap( fun( Y ) -> step( Y, Theta ) end, X ); - + % String Literal step( X={str, _Line, _S}, _Theta ) -> [X]; % (45) % Variable step( {var, _, N}, {Rho, _Mu, _Gamma, _Omega} ) -> % (46) maps:get( N, Rho ); - + % Future Channel Selection step( S={select, _, C, {fut, _, R, Lo}}, {_Rho, _Mu, _Gamma, Omega} ) -> % (47,48) {param, {name, N, _}, _} = lists:nth( C, Lo ), + io:format( "Looking up {~p, ~p} in ~p~n", [N, R, Omega] ), maps:get( {N, R}, Omega, [S] ); % Conditional @@ -178,11 +179,11 @@ step( {cnd, Line, Xc=[_|_], Xt, Xe}, Theta ) -> false -> [{cnd, Line, step( Xc, Theta ), Xt, Xe}]; % (50) true -> Xt % (51) end; - + % Application step( {app, Line, C, {var, _, N}, Fa}, {_Rho, _Mu, Gamma, _Omega} ) -> [{app, Line, C, maps:get( N, Gamma ), Fa}]; - + step( X={app, AppLine, C, Lambda={lam, LamLine, LamName, S={sign, Lo, _Li}, B}, Fa}, Theta={_Rho, Mu, Gamma, Omega} ) -> @@ -210,7 +211,7 @@ step( X={app, AppLine, C, end end end. - + %% ============================================================================= @@ -264,8 +265,8 @@ estep( L=[H={correl, Lc}|T], F ) when length( Lc ) > 1 -> Z = corrstep( Lc, F, F ), aug( [{T, G} || G <- Z], H ) % (73) end. - - + + %% Augmentation %% From 88459056bb2b84eee63ad532d7314a2b12d462ca Mon Sep 17 00:00:00 2001 From: Jorgen Brandt Date: Wed, 24 Feb 2016 00:45:46 +0100 Subject: [PATCH 17/78] Improvement. --- src/cf.erl | 42 +++++++++++++------------ src/cf_parser.erl | 22 ++++++------- src/cf_parser.yrl | 22 ++++++------- src/cf_sem.erl | 10 +++--- test/cf_sem_test.erl | 74 ++++++++++++++++++++++---------------------- 5 files changed, 87 insertions(+), 83 deletions(-) diff --git a/src/cf.erl b/src/cf.erl index d0f665b..96d59f3 100644 --- a/src/cf.erl +++ b/src/cf.erl @@ -20,7 +20,7 @@ -author( "Jorgen Brandt " ). % API --export( [start/0, string/1, file/1] ). +-export( [start/0, string/2, file/2] ). %% ============================================================================= %% API functions @@ -29,18 +29,18 @@ start() -> application:start( cf ). --spec string( S::string() ) -> [cf_sem:str()]. +-spec string( S::string(), DataDir::string() ) -> [cf_sem:str()]. -string( S ) -> +string( S, DataDir ) -> {Query, Rho, Gamma} = cf_parser:parse_string( S ), - reduce( Query, Rho, Gamma ). + reduce( Query, Rho, Gamma, DataDir ). --spec file( F::string() ) -> [cf_sem:str()]. +-spec file( Filename::string(), DataDir::string() ) -> [cf_sem:str()]. -file( Filename ) -> +file( Filename, DataDir ) -> {ok, B} = file:read_file( Filename ), S = binary_to_list( B ), - string( S ). + string( S, DataDir ). @@ -50,20 +50,24 @@ file( Filename ) -> %% Reduction %% --spec reduce( X0, Rho, Gamma ) -> [cf_sem:str()] -when X0 :: [cf_sem:expr()], - Rho :: #{string() => [cf_sem:expr()]}, - Gamma :: #{string() => cf_sem:lam()}. +-spec reduce( X0, Rho, Gamma, DataDir ) -> [cf_sem:str()] +when X0 :: [cf_sem:expr()], + Rho :: #{string() => [cf_sem:expr()]}, + Gamma :: #{string() => cf_sem:lam()}, + DataDir :: string(). -reduce( X0, Rho, Gamma ) -> - reduce( X0, {Rho, fun cre:submit/1, Gamma, #{}} ). +reduce( X0, Rho, Gamma, DataDir ) -> + Mu = fun( A ) -> cre:submit( A, DataDir ) end, + reduce( X0, {Rho, Mu, Gamma, #{}}, DataDir ). --spec reduce( X0, Theta ) -> [cf_sem:str()] -when X0 :: [cf_sem:expr()], - Theta :: cf_sem:ctx(). +-spec reduce( X0, Theta, DataDir ) -> [cf_sem:str()] +when X0 :: [cf_sem:expr()], + Theta :: cf_sem:ctx(), + DataDir :: string(). -reduce( X0, {Rho, Mu, Gamma, Omega} ) -> - X1 = cf_sem:eval( X0, {Rho, fun cre:submit/1, Gamma, Omega} ), +reduce( X0, {Rho, Mu, Gamma, Omega}, DataDir ) -> + + X1 = cf_sem:eval( X0, {Rho, Mu, Gamma, Omega} ), case cf_sem:pfinal( X1 ) of true -> io:format( "Finished: ~p~nReturning ...~n", [X1] ), @@ -102,7 +106,7 @@ reduce( X0, {Rho, Mu, Gamma, Omega} ) -> end, #{}, maps:keys( Ret ) ), io:format( "Reducing with Omega = ~p~n", [maps:merge( Omega, Delta )] ), - reduce( X1, {Rho, Mu, Gamma, maps:merge( Omega, Delta )} ); + reduce( X1, {Rho, Mu, Gamma, maps:merge( Omega, Delta )}, DataDir ); Msg -> error( {bad_msg, Msg} ) diff --git a/src/cf_parser.erl b/src/cf_parser.erl index ae769d4..2b337fc 100644 --- a/src/cf_parser.erl +++ b/src/cf_parser.erl @@ -24,8 +24,8 @@ combine( {Target1, Rho1, Global1}, {Target2, Rho2, Global2} ) -> mk_var( {id, Line, Name} ) -> {var, Line, Name}. -mk_str( {intlit, Line, N} ) -> {str, Line, N}; -mk_str( {strlit, Line, S} ) -> {str, Line, S}. +mk_str( {intlit, _Line, N} ) -> {str, N}; +mk_str( {strlit, _Line, S} ) -> {str, S}. get_line( {_, Line, _} ) -> Line. @@ -47,7 +47,7 @@ mk_assign( [E|_Rest], _ExprList, _Channel ) -> set_channel( {app, Line, _Channel, LamList, Binding}, N ) -> [{app, Line, N, LamList, Binding}]; set_channel( E, 1 ) -> [E]; -set_channel( E, _ ) -> error( {parser, cannot_set_channel_on_nonapp_expr, element( 1, E ), element( 2, E )} ). +set_channel( E, _ ) -> error( {parser, nonapp_expr, element( 1, E ), element( 2, E )} ). mk_natlam( {deftask, Line, _}, {id, _, Name}, Sign, Block ) -> #{Name => {lam, Line, Name, Sign, {natbody, Block}}}. @@ -77,13 +77,13 @@ multiple_targets_should_be_joined_test() -> parse_string( "bla; blub;" ) ). strlit_should_be_recognized_test() -> - ?assertEqual( {[{str, 1, "bla"}], #{}, #{}}, parse_string( "\"bla\";" ) ). + ?assertEqual( {[{str, "bla"}], #{}, #{}}, parse_string( "\"bla\";" ) ). intlit_should_be_recognized_test() -> - ?assertEqual( {[{str, 1, "-5"}], #{}, #{}}, parse_string( "-5;" ) ). + ?assertEqual( {[{str, "-5"}], #{}, #{}}, parse_string( "-5;" ) ). cnd_should_be_recognized_test() -> - ?assertEqual( {[{cnd, 1, [], [{str, 1, "bla"}], [{str, 1, "blub"}]}], + ?assertEqual( {[{cnd, 1, [], [{str, "bla"}], [{str, "blub"}]}], #{}, #{}}, parse_string( "if nil then \"bla\" else \"blub\" end;" ) ). @@ -94,21 +94,21 @@ app_should_be_recognized_test() -> #{}, #{}}, parse_string( "f( x: x );" ) ), ?assertEqual( {[{app, 1, 1, {var, 1, "f"}, #{"x" => [{var, 1, "x"}], - "y" => [{str, 1, "y"}]}}], #{}, #{}}, + "y" => [{str, "y"}]}}], #{}, #{}}, parse_string( "f( x: x, y: \"y\" );" ) )]. assign_should_be_recognized_test() -> - [?assertEqual( {[], #{"x" => [{str, 1, "x"}]}, #{}}, parse_string( "x = \"x\";" ) ), + [?assertEqual( {[], #{"x" => [{str, "x"}]}, #{}}, parse_string( "x = \"x\";" ) ), ?assertEqual( {[], #{"x" => [{app, 1, 1, {var, 1, "f"}, #{}}], "y" => [{app, 1, 2, {var, 1, "f"}, #{}}]}, #{}}, parse_string( "x y = f();" ) ), - ?assertError( {parser, cannot_set_channel_on_nonapp_expr, str, 1}, parse_string( "x y = \"A\";" ) ), - ?assertError( {parser, nonvar_expr_left_of_eq, str, 1}, parse_string( "\"a\" = \"A\";" ) )]. + ?assertError( {parser, nonapp_expr, str, "A"}, parse_string( "x y = \"A\";" ) ), + ?assertError( {parser, nonvar_expr_left_of_eq, str, "a"}, parse_string( "\"a\" = \"A\";" ) )]. native_deftask_should_be_recognized_test() -> ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, - {natbody, #{"out" => [{str, 1, "A"}]}}}}}, + {natbody, #{"out" => [{str, "A"}]}}}}}, parse_string( "deftask f( out : ) { out = \"A\"; }" ) ). foreign_deftask_should_be_recognized_test() -> diff --git a/src/cf_parser.yrl b/src/cf_parser.yrl index f491b52..0820425 100644 --- a/src/cf_parser.yrl +++ b/src/cf_parser.yrl @@ -132,8 +132,8 @@ combine( {Target1, Rho1, Global1}, {Target2, Rho2, Global2} ) -> mk_var( {id, Line, Name} ) -> {var, Line, Name}. -mk_str( {intlit, Line, N} ) -> {str, Line, N}; -mk_str( {strlit, Line, S} ) -> {str, Line, S}. +mk_str( {intlit, _Line, N} ) -> {str, N}; +mk_str( {strlit, _Line, S} ) -> {str, S}. get_line( {_, Line, _} ) -> Line. @@ -155,7 +155,7 @@ mk_assign( [E|_Rest], _ExprList, _Channel ) -> set_channel( {app, Line, _Channel, LamList, Binding}, N ) -> [{app, Line, N, LamList, Binding}]; set_channel( E, 1 ) -> [E]; -set_channel( E, _ ) -> error( {parser, cannot_set_channel_on_nonapp_expr, element( 1, E ), element( 2, E )} ). +set_channel( E, _ ) -> error( {parser, nonapp_expr, element( 1, E ), element( 2, E )} ). mk_natlam( {deftask, Line, _}, {id, _, Name}, Sign, Block ) -> #{Name => {lam, Line, Name, Sign, {natbody, Block}}}. @@ -185,13 +185,13 @@ multiple_targets_should_be_joined_test() -> parse_string( "bla; blub;" ) ). strlit_should_be_recognized_test() -> - ?assertEqual( {[{str, 1, "bla"}], #{}, #{}}, parse_string( "\"bla\";" ) ). + ?assertEqual( {[{str, "bla"}], #{}, #{}}, parse_string( "\"bla\";" ) ). intlit_should_be_recognized_test() -> - ?assertEqual( {[{str, 1, "-5"}], #{}, #{}}, parse_string( "-5;" ) ). + ?assertEqual( {[{str, "-5"}], #{}, #{}}, parse_string( "-5;" ) ). cnd_should_be_recognized_test() -> - ?assertEqual( {[{cnd, 1, [], [{str, 1, "bla"}], [{str, 1, "blub"}]}], + ?assertEqual( {[{cnd, 1, [], [{str, "bla"}], [{str, "blub"}]}], #{}, #{}}, parse_string( "if nil then \"bla\" else \"blub\" end;" ) ). @@ -202,21 +202,21 @@ app_should_be_recognized_test() -> #{}, #{}}, parse_string( "f( x: x );" ) ), ?assertEqual( {[{app, 1, 1, {var, 1, "f"}, #{"x" => [{var, 1, "x"}], - "y" => [{str, 1, "y"}]}}], #{}, #{}}, + "y" => [{str, "y"}]}}], #{}, #{}}, parse_string( "f( x: x, y: \"y\" );" ) )]. assign_should_be_recognized_test() -> - [?assertEqual( {[], #{"x" => [{str, 1, "x"}]}, #{}}, parse_string( "x = \"x\";" ) ), + [?assertEqual( {[], #{"x" => [{str, "x"}]}, #{}}, parse_string( "x = \"x\";" ) ), ?assertEqual( {[], #{"x" => [{app, 1, 1, {var, 1, "f"}, #{}}], "y" => [{app, 1, 2, {var, 1, "f"}, #{}}]}, #{}}, parse_string( "x y = f();" ) ), - ?assertError( {parser, cannot_set_channel_on_nonapp_expr, str, 1}, parse_string( "x y = \"A\";" ) ), - ?assertError( {parser, nonvar_expr_left_of_eq, str, 1}, parse_string( "\"a\" = \"A\";" ) )]. + ?assertError( {parser, nonapp_expr, str, "A"}, parse_string( "x y = \"A\";" ) ), + ?assertError( {parser, nonvar_expr_left_of_eq, str, "a"}, parse_string( "\"a\" = \"A\";" ) )]. native_deftask_should_be_recognized_test() -> ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, - {natbody, #{"out" => [{str, 1, "A"}]}}}}}, + {natbody, #{"out" => [{str, "A"}]}}}}}, parse_string( "deftask f( out : ) { out = \"A\"; }" ) ). foreign_deftask_should_be_recognized_test() -> diff --git a/src/cf_sem.erl b/src/cf_sem.erl index 36b5a8d..3785db3 100644 --- a/src/cf_sem.erl +++ b/src/cf_sem.erl @@ -32,7 +32,7 @@ %% Expression %% =============================================================== -type expr() :: str() | var() | select() | cnd() | app(). % (1) --type str() :: {str, Line::pos_integer(), S::string()}. % (2) +-type str() :: {str, S::string()}. % (2) -type var() :: {var, Line::pos_integer(), N::string()}. % (3) -type select() :: {select, Line::pos_integer(), C::pos_integer(), U::fut()}. % (4) -type fut() :: {fut, Name::string(), R::pos_integer(), % (5) @@ -82,7 +82,7 @@ when X :: #{string() => [expr()]} | [expr()] | expr(). pfinal( F ) when is_map( F ) -> pfinal( maps:values( F ) ); % (20) pfinal( L ) when is_list( L ) -> lists:all( fun pfinal/1, L ); % (21,22) -pfinal( {str, _, _S} ) -> true; % (23) +pfinal( {str, _S} ) -> true; % (23) pfinal( _T ) -> false. %% Singularity %% ============================================================== @@ -110,8 +110,8 @@ psing_argpair( _Z ) -> false. -spec pen( X::expr()|[expr()] ) -> boolean(). % (30) pen( X )when is_list( X ) -> lists:all( fun pen/1, X ); % (31,32) -pen( {str, _, _S} ) -> true; % (33) -pen( {cnd, _, _Xc, Xt, Xe} )when length( Xt ) =:= 1, length( Xe ) =:= 1 -> % (34) +pen( {str, _S} ) -> true; % (33) +pen( {cnd, _, _Xc, Xt, Xe} ) when length( Xt ) =:= 1, length( Xe ) =:= 1 -> % (34) pen( Xt ) andalso pen( Xe ); pen( X={app, _, C, {lam, _, _, {sign, Lo, _Li}, _B}, _Fb} ) -> % (35) case psing( X ) of @@ -160,7 +160,7 @@ step( X, Theta ) when is_list( X ) -> lists:flatmap( fun( Y ) -> step( Y, Theta ) end, X ); % String Literal -step( X={str, _Line, _S}, _Theta ) -> [X]; % (45) +step( X={str, _S}, _Theta ) -> [X]; % (45) % Variable step( {var, _, N}, {Rho, _Mu, _Gamma, _Omega} ) -> % (46) diff --git a/test/cf_sem_test.erl b/test/cf_sem_test.erl index 8ae22ac..748ffcf 100644 --- a/test/cf_sem_test.erl +++ b/test/cf_sem_test.erl @@ -30,7 +30,7 @@ nil_should_eval_itself_test() -> ?assertEqual( [], cf_sem:eval( [], ?THETA0 ) ). str_should_eval_itself_test() -> - E = [{str, 1, "bla"}], + E = [{str, "bla"}], ?assertEqual( E, cf_sem:eval( E, ?THETA0 ) ). undef_var_should_fail_test() -> @@ -38,18 +38,18 @@ undef_var_should_fail_test() -> ?assertError( {badkey, "x"}, cf_sem:eval( E, ?THETA0 ) ). def_var_should_eval_to_bound_value_test() -> - E = [{str, 1, "blub"}], + E = [{str, "blub"}], X = cf_sem:eval( [{var, 2, "x"}], {#{"x" => E}, fun mu/1, #{}, #{}} ), ?assertEqual( E, X ). def_var_should_cascade_binding_test() -> - E = [{str, 1, "blub"}], + E = [{str, "blub"}], Theta = {#{"x" => [{var, 2, "y"}], "y" => E}, fun mu/1, #{}, #{}}, X = cf_sem:eval( [{var, 3, "x"}], Theta ), ?assertEqual( E, X ). def_var_should_cascade_binding_twice_test() -> - A = [{str, 1, "A"}], + A = [{str, "A"}], Rho = #{"x" => [{var, 2, "y"}], "y" => [{var, 3, "z"}], "z" => A}, ?assertEqual( A, cf_sem:eval( [{var, 4, "x"}], {Rho, fun mu/1, #{}, #{}} ) ). @@ -63,13 +63,13 @@ unfinished_fut_should_eval_to_itself_test() -> finished_fut_should_eval_to_result_test() -> Fut = {fut, "f", 1234, [{param, {name, "out", false}, false}]}, S = {select, 2, 1, Fut}, - F = [{str, 3, "blub"}], + F = [{str, "blub"}], Theta = {#{}, fun mu/1, #{}, #{{"out", 1234} => F}}, X = cf_sem:eval( [S], Theta ), ?assertEqual( F, X ). noarg_fn_should_eval_plain_test() -> - E = [{str, 1, "bla"}], + E = [{str, "bla"}], Sign = {sign, [{param, {name, "out", false}, false}], []}, Body = {natbody, #{"out" => E}}, Lam = {lam, 2, "f", Sign, Body}, @@ -77,7 +77,7 @@ noarg_fn_should_eval_plain_test() -> ?assertEqual( E, cf_sem:eval( F, ?THETA0 ) ). noarg_fn_should_eval_body_test() -> - E = [{str, 1, "bla"}], + E = [{str, "bla"}], Sign = {sign, [{param, {name, "out", false}, false}], []}, Body = {natbody, #{"out" => [{var, 2, "x"}], "x" => E}}, Lam = {lam, 3, "f", Sign, Body}, @@ -85,7 +85,7 @@ noarg_fn_should_eval_body_test() -> ?assertEqual( E, cf_sem:eval( F, ?THETA0 ) ). fn_call_should_insert_lam_test() -> - E = [{str, 1, "bla"}], + E = [{str, "bla"}], Sign = {sign, [{param, {name, "out", false}, false}], []}, Body = {natbody, #{"out" => E}}, Lam = {lam, 2, "f", Sign, Body}, @@ -98,7 +98,7 @@ app_with_unbound_lam_should_fail_test() -> ?assertError( {badkey, "f"}, cf_sem:eval( F, ?THETA0 ) ). identity_fn_should_eval_arg_test() -> - E = [{str, 1, "bla"}], + E = [{str, "bla"}], Sign = {sign, [{param, {name, "out", false}, false}], [{param, {name, "inp", false}, false}]}, Body = {natbody, #{"out" => [{var, 2, "inp"}]}}, Lam = {lam, 3, "f", Sign, Body}, @@ -107,8 +107,8 @@ identity_fn_should_eval_arg_test() -> multiple_output_should_be_bindable_test() -> Sign = {sign, [{param, {name, "out1", false}, false}, {param, {name, "out2", false}, false}], []}, - E1 = [{str, 1, "bla"}], - E2 = [{str, 2, "blub"}], + E1 = [{str, "bla"}], + E2 = [{str, "blub"}], Body = {natbody, #{"out1" => E1, "out2" => E2}}, Lam = {lam, 3, "f", Sign, Body}, F1 = [{app, 4, 1, Lam, #{}}], @@ -121,7 +121,7 @@ app_should_ignore_calling_context_test() -> Body = {natbody, #{"out" => [{var, 1, "x"}]}}, Lam = {lam, 2, "f", Sign, Body}, X = [{app, 3, 1, Lam, #{}}], - Rho = #{"x" => [{str, 4, "blub"}]}, + Rho = #{"x" => [{str, "blub"}]}, ?assertError( {badkey, "x"}, cf_sem:eval( X, {Rho, fun mu/1, #{}, #{}} ) ). app_should_hand_down_gamma_test() -> @@ -129,13 +129,13 @@ app_should_hand_down_gamma_test() -> Body = {natbody, #{"out" => [{app, 1, 1, {var, 2, "f"}, #{}}]}}, Lam = {lam, 3, "g", Sign, Body}, X = [{app, 4, 1, Lam, #{}}], - E = [{str, 5, "blub"}], + E = [{str, "blub"}], Gamma = #{"f" => {lam, 6, "f", Sign, {natbody, #{"out" => E}}}}, Theta = {#{}, fun mu/1, Gamma, #{}}, ?assertEqual( E, cf_sem:eval( X, Theta ) ). binding_should_override_body_test() -> - F = [{str, 1, "blub"}], + F = [{str, "blub"}], Sign = {sign, [{param, {name, "out", false}, false}], [{param, {name, "x", false}, false}]}, Body = {natbody, #{"x" => [{str, "bla"}], "out" => [{var, 3, "x"}]}}, Lam = {lam, 4, "f", Sign, Body}, @@ -152,23 +152,23 @@ returning_empty_list_on_nonlist_output_channel_should_fail_test() -> cross_product_should_be_derivable_test() -> Sign = {sign, [{param, {name, "out1", false}, false}, {param, {name, "out2", false}, false}], [{param, {name, "p1", false}, false}, {param, {name, "p2", false}, false}]}, - E1 = [{str, 1, "A"}, {str, 2, "B"}], - E2 = [{str, 3, "1"}, {str, 4, "2"}], + E1 = [{str, "A"}, {str, "B"}], + E2 = [{str, "1"}, {str, "2"}], Body = {natbody, #{"out1" => [{var, 5, "p1"}], "out2" => [{var, 6, "p2"}]}}, Lam = {lam, 7, "f", Sign, Body}, Binding = #{"p1" => E1, "p2" => E2}, App1 = [{app, 8, 1, Lam, Binding}], App2 = [{app, 9, 2, Lam, Binding}], - F1 = [{str, 1, "A"}, {str, 1, "A"}, {str, 2, "B"}, {str, 2, "B"}], - F2 = [{str, 3, "1"}, {str, 4, "2"}, {str, 3, "1"}, {str, 4, "2"}], + F1 = [{str, "A"}, {str, "A"}, {str, "B"}, {str, "B"}], + F2 = [{str, "1"}, {str, "2"}, {str, "1"}, {str, "2"}], [?assertEqual( F1, cf_sem:eval( App1, ?THETA0 ) ), ?assertEqual( F2, cf_sem:eval( App2, ?THETA0 ) )]. dot_product_should_be_derivable_test() -> Sign = {sign, [{param, {name, "out1", false}, false}, {param, {name, "out2", false}, false}], [{correl, [{name, "p1", false}, {name, "p2", false}]}]}, - E1 = [{str, 1, "A"}, {str, 2, "B"}], - E2 = [{str, 3, "1"}, {str, 4, "2"}], + E1 = [{str, "A"}, {str, "B"}], + E2 = [{str, "1"}, {str, "2"}], Body = {natbody, #{"out1" => [{var, 5, "p1"}], "out2" => [{var, 6, "p2"}]}}, Lam = {lam, 7, "f", Sign, Body}, Binding = #{"p1" => E1, "p2" => E2}, @@ -180,8 +180,8 @@ dot_product_should_be_derivable_test() -> aggregate_should_consume_whole_list_test() -> Sign = {sign, [{param, {name, "out", false}, true}], [{param, {name, "inp", false}, true}]}, - E1 = [{str, 1, "A"}], - E2 = [{str, 2, "B"}, {str, 3, "C"}], + E1 = [{str, "A"}], + E2 = [{str, "B"}, {str, "C"}], Body = {natbody, #{"out" => E1++[{var, 4, "inp"}]}}, Lam = {lam, 5, "f", Sign, Body}, Binding = #{"inp" => E2}, @@ -189,24 +189,24 @@ aggregate_should_consume_whole_list_test() -> ?assertEqual( E1++E2, cf_sem:eval( App, ?THETA0 ) ). cnd_false_should_eval_else_expr_test() -> - E = [{cnd, 1, [], [{str, 2, "A"}], [{str, 3, "B"}]}], - ?assertEqual( [{str, 3, "B"}], cf_sem:eval( E, ?THETA0 ) ). + E = [{cnd, 1, [], [{str, "A"}], [{str, "B"}]}], + ?assertEqual( [{str, "B"}], cf_sem:eval( E, ?THETA0 ) ). cnd_evaluates_condition_before_decision1_test() -> Sign = {sign, [{param, {name, "out", false}, true}], []}, Body = {natbody, #{"out" => []}}, Lam = {lam, 1, "f", Sign, Body}, App = [{app, 2, 1, Lam, #{}}], - E = [{cnd, 3, App, [{str, 4, "A"}], [{str, 5, "B"}]}], - ?assertEqual( [{str, 5, "B"}], cf_sem:eval( E, ?THETA0 ) ). + E = [{cnd, 3, App, [{str, "A"}], [{str, "B"}]}], + ?assertEqual( [{str, "B"}], cf_sem:eval( E, ?THETA0 ) ). cnd_evaluates_condition_before_decision2_test() -> Sign = {sign, [{param, {name, "out", false}, true}], []}, - Body = {natbody, #{"out" => [{str, 1, "X"}]}}, + Body = {natbody, #{"out" => [{str, "X"}]}}, Lam = {lam, 2, "f", Sign, Body}, App = [{app, 3, 1, Lam, #{}}], - E = [{cnd, 4, App, [{str, 5, "A"}], [{str, 6, "B"}]}], - ?assertEqual( [{str, 5, "A"}], cf_sem:eval( E, ?THETA0 ) ). + E = [{cnd, 4, App, [{str, "A"}], [{str, "B"}]}], + ?assertEqual( [{str, "A"}], cf_sem:eval( E, ?THETA0 ) ). cnd_evaluates_only_on_final_condition_test() -> Sign = {sign, [{param, {name, "out", false}, true}], []}, @@ -215,26 +215,26 @@ cnd_evaluates_only_on_final_condition_test() -> A = [{var, 3, "a"}], B = [{var, 4, "b"}], E = [{cnd, 5, App, A, B}], - Rho = #{"a" => [{str, 6, "A"}], "b" => [{str, 7, "B"}]}, + Rho = #{"a" => [{str, "A"}], "b" => [{str, "B"}]}, X = cf_sem:eval( E, {Rho, fun mu/1, #{}, #{}} ), ?assertMatch( [{cnd, 5, [{select, 2, 1, _}], A, B}], X ). cnd_evaluates_then_expr_test() -> - E = [{cnd, 1, [{str, 2, "Z"}], [{var, 3, "x"}], [{str, 4, "B"}]}], - F = [{str, 5, "A"}], + E = [{cnd, 1, [{str, "Z"}], [{var, 3, "x"}], [{str, "B"}]}], + F = [{str, "A"}], Theta = {#{"x" => F}, fun mu/1, #{}, #{}}, ?assertEqual( F, cf_sem:eval( E, Theta ) ). cnd_evaluates_else_expr_test() -> E = [{cnd, 1, [], [{str, "B"}], [{var, 3, "x"}]}], - F = [{str, 2, "A"}], + F = [{str, "A"}], Theta = {#{"x" => F}, fun mu/1, #{}, #{}}, ?assertEqual( F, cf_sem:eval( E, Theta ) ). foreign_app_with_cnd_param_is_left_untouched_test() -> Sign = {sign, [{param, {name, "out", false}, false}], [{param, {name, "p", false}, false}]}, Lam = {lam, 1, "f", Sign, {forbody, bash, "shalala"}}, - App1 = [{app, 2, 1, Lam, #{"p" => [{str, 3, "A"}]}}], + App1 = [{app, 2, 1, Lam, #{"p" => [{str, "A"}]}}], E = [{cnd, 4, App1, [], []}], App2 = [{app, 5, 1, Lam, #{"p" => E}}], X = cf_sem:eval( App2, ?THETA0 ), @@ -244,7 +244,7 @@ foreign_app_with_select_param_is_left_untouched_test() -> Sign = {sign, [{param, {name, "out", false}, false}], [{param, {name, "p", false}, false}]}, Lam = {lam, 1, "f", Sign, {forbody, bash, "shalala"}}, - App1 = [{app, 2, 1, Lam, #{"p" => [{str, 3, "A"}]}}], + App1 = [{app, 2, 1, Lam, #{"p" => [{str, "A"}]}}], App2 = [{app, 4, 1, Lam, #{"p" => App1}}], X = cf_sem:eval( App2, ?THETA0 ), ?assertMatch( [{app, 4, 1, Lam, _}], X ). @@ -281,9 +281,9 @@ nested_app_undergoes_reduction_test() -> X = cf_sem:eval( App2, ?THETA0 ), [{app, 4, 1, {lam, 3, "g", _, {natbody, Fb}}, _}] = X, [{select, 2, 1, {fut, "f", R, _}}] = maps:get( "out", Fb ), - Omega = #{{"out", R} => [{str, 5, "A"}]}, + Omega = #{{"out", R} => [{str, "A"}]}, Y = cf_sem:eval( X, {#{}, fun mu/1, #{}, Omega} ), - ?assertEqual( [{str, 5, "A"}], Y ). + ?assertEqual( [{str, "A"}], Y ). app_select_param_is_enumerated_test() -> Sign1 = {sign, [{param, {name, "out", false}, false}], []}, From f7368a740fe3eba85111f6c47732355a9d1202cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Wed, 24 Feb 2016 11:55:37 +0100 Subject: [PATCH 18/78] reduce function now responsible for converting effi summary to Cuneiform expression. --- src/cf.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cf.erl b/src/cf.erl index 96d59f3..a7ad939 100644 --- a/src/cf.erl +++ b/src/cf.erl @@ -120,4 +120,4 @@ when N :: string(), R :: pos_integer(). acc_delta( N, Delta0, Ret, R ) -> - Delta0#{{N, R} => maps:get( N, Ret )}. \ No newline at end of file + Delta0#{{N, R} => [{str, S} || S <- maps:get( N, Ret )]}. \ No newline at end of file From 200e9a59a74f480ad1879fb606de04a5b9c60801 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Wed, 24 Feb 2016 18:30:08 +0100 Subject: [PATCH 19/78] CRE made temporary. Convenience function added. --- src/cf.erl | 6 +++++- src/cf_app.erl | 2 +- src/cf_sup.erl | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/cf.erl b/src/cf.erl index a7ad939..636b7c4 100644 --- a/src/cf.erl +++ b/src/cf.erl @@ -20,7 +20,7 @@ -author( "Jorgen Brandt " ). % API --export( [start/0, string/2, file/2] ). +-export( [start/0, string/2, file/1, file/2] ). %% ============================================================================= %% API functions @@ -35,6 +35,10 @@ string( S, DataDir ) -> {Query, Rho, Gamma} = cf_parser:parse_string( S ), reduce( Query, Rho, Gamma, DataDir ). +-spec file( Filename::string() ) -> [cf_sem:str()]. + +file( Filename ) -> file( Filename, "." ). + -spec file( Filename::string(), DataDir::string() ) -> [cf_sem:str()]. file( Filename, DataDir ) -> diff --git a/src/cf_app.erl b/src/cf_app.erl index fac337e..cc4d1f9 100644 --- a/src/cf_app.erl +++ b/src/cf_app.erl @@ -31,7 +31,7 @@ start( normal, [] ) -> % TODO: load and hand down configuration - + cf_sup:start_link(). stop( _State ) -> diff --git a/src/cf_sup.erl b/src/cf_sup.erl index 95c9a9a..153965b 100644 --- a/src/cf_sup.erl +++ b/src/cf_sup.erl @@ -46,7 +46,7 @@ init( [] ) -> MaxSecondsBetweenRestarts = 10, SupFlags = {RestartStrategy, MaxRestarts, MaxSecondsBetweenRestarts}, - Restart = permanent, + Restart = temporary, Shutdown = 2000, Type = worker, Cre = {cre, {cre, start_link, []}, Restart, Shutdown, Type, [cre]}, From 10153d4b92e508d85dc4c7fe0e18c36b510fb02c Mon Sep 17 00:00:00 2001 From: Jorgen Brandt Date: Wed, 24 Feb 2016 23:02:42 +0100 Subject: [PATCH 20/78] Parser and lexer renamed to parse and scan. --- Makefile | 2 +- src/cf.erl | 2 +- src/{cf_parser.erl => cf_parse.erl} | 144 ++++++++++++++-------------- src/{cf_parser.yrl => cf_parse.yrl} | 62 ++++++------ src/{cf_lexer.erl => cf_scan.erl} | 68 ++++++------- src/{cf_lexer.xrl => cf_scan.xrl} | 0 6 files changed, 139 insertions(+), 139 deletions(-) rename src/{cf_parser.erl => cf_parse.erl} (93%) rename src/{cf_parser.yrl => cf_parse.yrl} (83%) rename src/{cf_lexer.erl => cf_scan.erl} (98%) rename src/{cf_lexer.xrl => cf_scan.xrl} (100%) diff --git a/Makefile b/Makefile index dc4d9fb..34b1baf 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ all: .rebar/cf_18.2.1_plt - rebar co eu dialyze doc + rebar co eu dialyze clean: rebar clean diff --git a/src/cf.erl b/src/cf.erl index 636b7c4..7c7e220 100644 --- a/src/cf.erl +++ b/src/cf.erl @@ -32,7 +32,7 @@ start() -> -spec string( S::string(), DataDir::string() ) -> [cf_sem:str()]. string( S, DataDir ) -> - {Query, Rho, Gamma} = cf_parser:parse_string( S ), + {Query, Rho, Gamma} = cf_parse:string( S ), reduce( Query, Rho, Gamma, DataDir ). -spec file( Filename::string() ) -> [cf_sem:str()]. diff --git a/src/cf_parser.erl b/src/cf_parse.erl similarity index 93% rename from src/cf_parser.erl rename to src/cf_parse.erl index 2b337fc..16b69c1 100644 --- a/src/cf_parser.erl +++ b/src/cf_parse.erl @@ -1,18 +1,18 @@ --module(cf_parser). +-module(cf_parse). -export([parse/1, parse_and_scan/1, format_error/1]). --file("src/cf_parser.yrl", 111). +-file("src/cf_parse.yrl", 111). -author( "Jorgen Brandt " ). --export( [parse_string/1] ). +-export( [string/1] ). -ifdef( TEST ). -include_lib( "eunit/include/eunit.hrl" ). -endif. -parse_string( S ) -> - {ok, TokenList, _} = cf_lexer:string( S ), - {ok, ParseTree} = cf_parser:parse( TokenList ), +string( S ) -> + {ok, TokenList, _} = cf_scan:string( S ), + {ok, ParseTree} = cf_parse:parse( TokenList ), ParseTree. @@ -63,83 +63,83 @@ mk_forlam( {deftask, Line, _}, {id, _, Name}, Sign, Lang, {body, _, Code} ) -> -ifdef( TEST ). nil_should_be_recognized_test() -> - ?assertEqual( {[], #{}, #{}}, parse_string( "nil;" ) ). + ?assertEqual( {[], #{}, #{}}, string( "nil;" ) ). var_should_be_recognized_test() -> - ?assertEqual( {[{var, 1, "blub"}], #{}, #{}}, parse_string( "blub;" ) ). + ?assertEqual( {[{var, 1, "blub"}], #{}, #{}}, string( "blub;" ) ). multi_element_compoundexpr_should_be_recognized_test() -> ?assertEqual( {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}, - parse_string( "bla blub;" ) ). + string( "bla blub;" ) ). multiple_targets_should_be_joined_test() -> ?assertEqual( {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}, - parse_string( "bla; blub;" ) ). + string( "bla; blub;" ) ). strlit_should_be_recognized_test() -> - ?assertEqual( {[{str, "bla"}], #{}, #{}}, parse_string( "\"bla\";" ) ). + ?assertEqual( {[{str, "bla"}], #{}, #{}}, string( "\"bla\";" ) ). intlit_should_be_recognized_test() -> - ?assertEqual( {[{str, "-5"}], #{}, #{}}, parse_string( "-5;" ) ). + ?assertEqual( {[{str, "-5"}], #{}, #{}}, string( "-5;" ) ). cnd_should_be_recognized_test() -> ?assertEqual( {[{cnd, 1, [], [{str, "bla"}], [{str, "blub"}]}], #{}, #{}}, - parse_string( "if nil then \"bla\" else \"blub\" end;" ) ). + string( "if nil then \"bla\" else \"blub\" end;" ) ). app_should_be_recognized_test() -> [?assertEqual( {[{app, 1, 1, {var, 1, "f"}, #{}}], #{}, #{}}, - parse_string( "f();" ) ), + string( "f();" ) ), ?assertEqual( {[{app, 1, 1, {var, 1, "f"}, #{"x" => [{var, 1, "x"}]}}], - #{}, #{}}, parse_string( "f( x: x );" ) ), + #{}, #{}}, string( "f( x: x );" ) ), ?assertEqual( {[{app, 1, 1, {var, 1, "f"}, #{"x" => [{var, 1, "x"}], "y" => [{str, "y"}]}}], #{}, #{}}, - parse_string( "f( x: x, y: \"y\" );" ) )]. + string( "f( x: x, y: \"y\" );" ) )]. assign_should_be_recognized_test() -> - [?assertEqual( {[], #{"x" => [{str, "x"}]}, #{}}, parse_string( "x = \"x\";" ) ), - ?assertEqual( {[], #{"x" => [{app, 1, 1, {var, 1, "f"}, #{}}], "y" => [{app, 1, 2, {var, 1, "f"}, #{}}]}, #{}}, parse_string( "x y = f();" ) ), - ?assertError( {parser, nonapp_expr, str, "A"}, parse_string( "x y = \"A\";" ) ), - ?assertError( {parser, nonvar_expr_left_of_eq, str, "a"}, parse_string( "\"a\" = \"A\";" ) )]. + [?assertEqual( {[], #{"x" => [{str, "x"}]}, #{}}, string( "x = \"x\";" ) ), + ?assertEqual( {[], #{"x" => [{app, 1, 1, {var, 1, "f"}, #{}}], "y" => [{app, 1, 2, {var, 1, "f"}, #{}}]}, #{}}, string( "x y = f();" ) ), + ?assertError( {parser, nonapp_expr, str, "A"}, string( "x y = \"A\";" ) ), + ?assertError( {parser, nonvar_expr_left_of_eq, str, "a"}, string( "\"a\" = \"A\";" ) )]. native_deftask_should_be_recognized_test() -> ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, {natbody, #{"out" => [{str, "A"}]}}}}}, - parse_string( "deftask f( out : ) { out = \"A\"; }" ) ). + string( "deftask f( out : ) { out = \"A\"; }" ) ). foreign_deftask_should_be_recognized_test() -> [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, {forbody, bash, "out=A"}}}}, - parse_string( "deftask f( out : )in bash *{out=A}*" ) ), + string( "deftask f( out : )in bash *{out=A}*" ) ), ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, {forbody, r, "out=\"A\""}}}}, - parse_string( "deftask f( out : )in R *{out=\"A\"}*" ) ), + string( "deftask f( out : )in R *{out=\"A\"}*" ) ), ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, {forbody, python, ""}}}}, - parse_string( "deftask f( out : )in python *{}*" ) )]. + string( "deftask f( out : )in python *{}*" ) )]. sign_with_inparam_should_be_recognized_test() -> [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], [{param, {name, "inp", false}, false}]}, {forbody, python, "(defparameter out \"A\")"}}}}, - parse_string( "deftask f( out : inp )in python *{(defparameter out \"A\")}*" ) ), + string( "deftask f( out : inp )in python *{(defparameter out \"A\")}*" ) ), ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], [{param, {name, "a", false}, false}, {param, {name, "b", false}, false}]}, {forbody, python, "(defparameter out \"A\")"}}}}, - parse_string( "deftask f( out : a b )in python *{(defparameter out \"A\")}*" ) )]. + string( "deftask f( out : a b )in python *{(defparameter out \"A\")}*" ) )]. %% ============================================================================= %% Failing Tests @@ -150,27 +150,27 @@ param_should_be_recognized_test() -> {sign, [{param, {name, "out", false}, false}], [{param, {name, "inp", false}, false}]}, {forbody, bash, "blub"}}}}, - parse_string( "deftask f( out( String ) : inp( String ) )in bash *{blub}*" ) ), + string( "deftask f( out( String ) : inp( String ) )in bash *{blub}*" ) ), ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", true}, false}], [{param, {name, "inp", true}, false}]}, {forbody, bash, "blub"}}}}, - parse_string( "deftask f( out( File ) : inp( File ) )in bash *{blub}*" ) ), + string( "deftask f( out( File ) : inp( File ) )in bash *{blub}*" ) ), ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, true}], [{param, {name, "inp", false}, true}]}, {forbody, bash, "blub"}}}}, - parse_string( "deftask f( : )in bash *{blub}*" ) ), + string( "deftask f( : )in bash *{blub}*" ) ), ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, true}], [{param, {name, "inp", false}, true}]}, {forbody, bash, "blub"}}}}, - parse_string( "deftask f( : )in bash *{blub}*" ) ), + string( "deftask f( : )in bash *{blub}*" ) ), ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", true}, true}], [{param, {name, "inp", true}, true}]}, {forbody, bash, "blub"}}}}, - parse_string( "deftask f( : )in bash *{blub}*" ) )]. + string( "deftask f( : )in bash *{blub}*" ) )]. correl_inparam_should_be_recognized_test() -> [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", @@ -178,14 +178,14 @@ correl_inparam_should_be_recognized_test() -> [{correl, [{name, "a", true}, {name, "b", true}]}]}, {forbody, bash, "blub"}}}}, - parse_string( "deftask f( out : [a( File ) b( File )] )in bash *{blub}*" ) ), + string( "deftask f( out : [a( File ) b( File )] )in bash *{blub}*" ) ), ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], [{correl, [{name, "a", true}, {name, "b", true}]}, {param, {name, "c", false}, false}]}, {forbody, bash, "blub"}}}}, - parse_string( "deftask f( out : [a( File ) b( File )] c )in bash *{blub}*" ) )]. + string( "deftask f( out : [a( File ) b( File )] c )in bash *{blub}*" ) )]. -endif. @@ -365,7 +365,7 @@ yecctoken2string(Other) -> --file("src/cf_parser.erl", 368). +-file("src/cf_parse.erl", 368). -dialyzer({nowarn_function, yeccpars2/7}). yeccpars2(0=S, Cat, Ss, Stack, T, Ts, Tzr) -> @@ -1180,7 +1180,7 @@ yeccgoto_stat(1, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_1(1, Cat, Ss, Stack, T, Ts, Tzr). -compile({inline,yeccpars2_3_/1}). --file("src/cf_parser.yrl", 40). +-file("src/cf_parse.yrl", 40). yeccpars2_3_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1188,7 +1188,7 @@ yeccpars2_3_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_5_/1}). --file("src/cf_parser.yrl", 67). +-file("src/cf_parse.yrl", 67). yeccpars2_5_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1196,7 +1196,7 @@ yeccpars2_5_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_6_/1}). --file("src/cf_parser.yrl", 42). +-file("src/cf_parse.yrl", 42). yeccpars2_6_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1204,7 +1204,7 @@ yeccpars2_6_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_9_/1}). --file("src/cf_parser.yrl", 41). +-file("src/cf_parse.yrl", 41). yeccpars2_9_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1212,7 +1212,7 @@ yeccpars2_9_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_13_/1}). --file("src/cf_parser.yrl", 63). +-file("src/cf_parse.yrl", 63). yeccpars2_13_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1220,7 +1220,7 @@ yeccpars2_13_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_14_/1}). --file("src/cf_parser.yrl", 61). +-file("src/cf_parse.yrl", 61). yeccpars2_14_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1228,7 +1228,7 @@ yeccpars2_14_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_15_/1}). --file("src/cf_parser.yrl", 58). +-file("src/cf_parse.yrl", 58). yeccpars2_15_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1236,7 +1236,7 @@ yeccpars2_15_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_16_/1}). --file("src/cf_parser.yrl", 62). +-file("src/cf_parse.yrl", 62). yeccpars2_16_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1244,7 +1244,7 @@ yeccpars2_16_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_21_/1}). --file("src/cf_parser.yrl", 73). +-file("src/cf_parse.yrl", 73). yeccpars2_21_(__Stack0) -> [__3,__2,__1 | __Stack] = __Stack0, [begin @@ -1252,7 +1252,7 @@ yeccpars2_21_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_24_/1}). --file("src/cf_parser.yrl", 76). +-file("src/cf_parse.yrl", 76). yeccpars2_24_(__Stack0) -> [__3,__2,__1 | __Stack] = __Stack0, [begin @@ -1260,7 +1260,7 @@ yeccpars2_24_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_26_/1}). --file("src/cf_parser.yrl", 79). +-file("src/cf_parse.yrl", 79). yeccpars2_26_(__Stack0) -> [__3,__2,__1 | __Stack] = __Stack0, [begin @@ -1268,7 +1268,7 @@ yeccpars2_26_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_27_/1}). --file("src/cf_parser.yrl", 74). +-file("src/cf_parse.yrl", 74). yeccpars2_27_(__Stack0) -> [__4,__3,__2,__1 | __Stack] = __Stack0, [begin @@ -1276,7 +1276,7 @@ yeccpars2_27_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_32_/1}). --file("src/cf_parser.yrl", 93). +-file("src/cf_parse.yrl", 93). yeccpars2_32_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1284,7 +1284,7 @@ yeccpars2_32_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_33_/1}). --file("src/cf_parser.yrl", 90). +-file("src/cf_parse.yrl", 90). yeccpars2_33_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1292,7 +1292,7 @@ yeccpars2_33_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_34_/1}). --file("src/cf_parser.yrl", 96). +-file("src/cf_parse.yrl", 96). yeccpars2_34_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1300,7 +1300,7 @@ yeccpars2_34_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_37_/1}). --file("src/cf_parser.yrl", 91). +-file("src/cf_parse.yrl", 91). yeccpars2_37_(__Stack0) -> [__3,__2,__1 | __Stack] = __Stack0, [begin @@ -1308,7 +1308,7 @@ yeccpars2_37_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_41_/1}). --file("src/cf_parser.yrl", 97). +-file("src/cf_parse.yrl", 97). yeccpars2_41_(__Stack0) -> [__4,__3,__2,__1 | __Stack] = __Stack0, [begin @@ -1316,7 +1316,7 @@ yeccpars2_41_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_42_/1}). --file("src/cf_parser.yrl", 98). +-file("src/cf_parse.yrl", 98). yeccpars2_42_(__Stack0) -> [__4,__3,__2,__1 | __Stack] = __Stack0, [begin @@ -1324,7 +1324,7 @@ yeccpars2_42_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_43_/1}). --file("src/cf_parser.yrl", 94). +-file("src/cf_parse.yrl", 94). yeccpars2_43_(__Stack0) -> [__2,__1 | __Stack] = __Stack0, [begin @@ -1332,7 +1332,7 @@ yeccpars2_43_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_47_/1}). --file("src/cf_parser.yrl", 87). +-file("src/cf_parse.yrl", 87). yeccpars2_47_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1340,7 +1340,7 @@ yeccpars2_47_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_49_/1}). --file("src/cf_parser.yrl", 81). +-file("src/cf_parse.yrl", 81). yeccpars2_49_(__Stack0) -> [__4,__3,__2,__1 | __Stack] = __Stack0, [begin @@ -1348,7 +1348,7 @@ yeccpars2_49_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_51_/1}). --file("src/cf_parser.yrl", 100). +-file("src/cf_parse.yrl", 100). yeccpars2_51_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1356,7 +1356,7 @@ yeccpars2_51_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_52_/1}). --file("src/cf_parser.yrl", 101). +-file("src/cf_parse.yrl", 101). yeccpars2_52_(__Stack0) -> [__2,__1 | __Stack] = __Stack0, [begin @@ -1364,7 +1364,7 @@ yeccpars2_52_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_53_/1}). --file("src/cf_parser.yrl", 85). +-file("src/cf_parse.yrl", 85). yeccpars2_53_(__Stack0) -> [__3,__2,__1 | __Stack] = __Stack0, [begin @@ -1372,7 +1372,7 @@ yeccpars2_53_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_54_/1}). --file("src/cf_parser.yrl", 88). +-file("src/cf_parse.yrl", 88). yeccpars2_54_(__Stack0) -> [__2,__1 | __Stack] = __Stack0, [begin @@ -1380,7 +1380,7 @@ yeccpars2_54_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_55_/1}). --file("src/cf_parser.yrl", 82). +-file("src/cf_parse.yrl", 82). yeccpars2_55_(__Stack0) -> [__5,__4,__3,__2,__1 | __Stack] = __Stack0, [begin @@ -1388,7 +1388,7 @@ yeccpars2_55_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_61_/1}). --file("src/cf_parser.yrl", 49). +-file("src/cf_parse.yrl", 49). yeccpars2_61_(__Stack0) -> [__2,__1 | __Stack] = __Stack0, [begin @@ -1396,7 +1396,7 @@ yeccpars2_61_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_62_/1}). --file("src/cf_parser.yrl", 51). +-file("src/cf_parse.yrl", 51). yeccpars2_62_(__Stack0) -> [__6,__5,__4,__3,__2,__1 | __Stack] = __Stack0, [begin @@ -1404,7 +1404,7 @@ yeccpars2_62_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_65_/1}). --file("src/cf_parser.yrl", 46). +-file("src/cf_parse.yrl", 46). yeccpars2_65_(__Stack0) -> [__4,__3,__2,__1 | __Stack] = __Stack0, [begin @@ -1412,7 +1412,7 @@ yeccpars2_65_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_67_/1}). --file("src/cf_parser.yrl", 54). +-file("src/cf_parse.yrl", 54). yeccpars2_67_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1420,7 +1420,7 @@ yeccpars2_67_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_68_/1}). --file("src/cf_parser.yrl", 55). +-file("src/cf_parse.yrl", 55). yeccpars2_68_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1428,7 +1428,7 @@ yeccpars2_68_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_69_/1}). --file("src/cf_parser.yrl", 56). +-file("src/cf_parse.yrl", 56). yeccpars2_69_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin @@ -1436,7 +1436,7 @@ yeccpars2_69_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_70_/1}). --file("src/cf_parser.yrl", 52). +-file("src/cf_parse.yrl", 52). yeccpars2_70_(__Stack0) -> [__6,__5,__4,__3,__2,__1 | __Stack] = __Stack0, [begin @@ -1444,7 +1444,7 @@ yeccpars2_70_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_76_/1}). --file("src/cf_parser.yrl", 71). +-file("src/cf_parse.yrl", 71). yeccpars2_76_(__Stack0) -> [__7,__6,__5,__4,__3,__2,__1 | __Stack] = __Stack0, [begin @@ -1452,7 +1452,7 @@ yeccpars2_76_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_77_/1}). --file("src/cf_parser.yrl", 44). +-file("src/cf_parse.yrl", 44). yeccpars2_77_(__Stack0) -> [__2,__1 | __Stack] = __Stack0, [begin @@ -1460,7 +1460,7 @@ yeccpars2_77_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_78_/1}). --file("src/cf_parser.yrl", 68). +-file("src/cf_parse.yrl", 68). yeccpars2_78_(__Stack0) -> [__2,__1 | __Stack] = __Stack0, [begin @@ -1468,7 +1468,7 @@ yeccpars2_78_(__Stack0) -> end | __Stack]. -compile({inline,yeccpars2_79_/1}). --file("src/cf_parser.yrl", 38). +-file("src/cf_parse.yrl", 38). yeccpars2_79_(__Stack0) -> [__2,__1 | __Stack] = __Stack0, [begin @@ -1476,4 +1476,4 @@ yeccpars2_79_(__Stack0) -> end | __Stack]. --file("src/cf_parser.yrl", 301). +-file("src/cf_parse.yrl", 301). diff --git a/src/cf_parser.yrl b/src/cf_parse.yrl similarity index 83% rename from src/cf_parser.yrl rename to src/cf_parse.yrl index 0820425..2aced3e 100644 --- a/src/cf_parser.yrl +++ b/src/cf_parse.yrl @@ -112,15 +112,15 @@ Erlang code. -author( "Jorgen Brandt " ). --export( [parse_string/1] ). +-export( [string/1] ). -ifdef( TEST ). -include_lib( "eunit/include/eunit.hrl" ). -endif. -parse_string( S ) -> - {ok, TokenList, _} = cf_lexer:string( S ), - {ok, ParseTree} = cf_parser:parse( TokenList ), +string( S ) -> + {ok, TokenList, _} = cf_scan:string( S ), + {ok, ParseTree} = cf_parse:parse( TokenList ), ParseTree. @@ -171,83 +171,83 @@ mk_forlam( {deftask, Line, _}, {id, _, Name}, Sign, Lang, {body, _, Code} ) -> -ifdef( TEST ). nil_should_be_recognized_test() -> - ?assertEqual( {[], #{}, #{}}, parse_string( "nil;" ) ). + ?assertEqual( {[], #{}, #{}}, string( "nil;" ) ). var_should_be_recognized_test() -> - ?assertEqual( {[{var, 1, "blub"}], #{}, #{}}, parse_string( "blub;" ) ). + ?assertEqual( {[{var, 1, "blub"}], #{}, #{}}, string( "blub;" ) ). multi_element_compoundexpr_should_be_recognized_test() -> ?assertEqual( {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}, - parse_string( "bla blub;" ) ). + string( "bla blub;" ) ). multiple_targets_should_be_joined_test() -> ?assertEqual( {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}, - parse_string( "bla; blub;" ) ). + string( "bla; blub;" ) ). strlit_should_be_recognized_test() -> - ?assertEqual( {[{str, "bla"}], #{}, #{}}, parse_string( "\"bla\";" ) ). + ?assertEqual( {[{str, "bla"}], #{}, #{}}, string( "\"bla\";" ) ). intlit_should_be_recognized_test() -> - ?assertEqual( {[{str, "-5"}], #{}, #{}}, parse_string( "-5;" ) ). + ?assertEqual( {[{str, "-5"}], #{}, #{}}, string( "-5;" ) ). cnd_should_be_recognized_test() -> ?assertEqual( {[{cnd, 1, [], [{str, "bla"}], [{str, "blub"}]}], #{}, #{}}, - parse_string( "if nil then \"bla\" else \"blub\" end;" ) ). + string( "if nil then \"bla\" else \"blub\" end;" ) ). app_should_be_recognized_test() -> [?assertEqual( {[{app, 1, 1, {var, 1, "f"}, #{}}], #{}, #{}}, - parse_string( "f();" ) ), + string( "f();" ) ), ?assertEqual( {[{app, 1, 1, {var, 1, "f"}, #{"x" => [{var, 1, "x"}]}}], - #{}, #{}}, parse_string( "f( x: x );" ) ), + #{}, #{}}, string( "f( x: x );" ) ), ?assertEqual( {[{app, 1, 1, {var, 1, "f"}, #{"x" => [{var, 1, "x"}], "y" => [{str, "y"}]}}], #{}, #{}}, - parse_string( "f( x: x, y: \"y\" );" ) )]. + string( "f( x: x, y: \"y\" );" ) )]. assign_should_be_recognized_test() -> - [?assertEqual( {[], #{"x" => [{str, "x"}]}, #{}}, parse_string( "x = \"x\";" ) ), - ?assertEqual( {[], #{"x" => [{app, 1, 1, {var, 1, "f"}, #{}}], "y" => [{app, 1, 2, {var, 1, "f"}, #{}}]}, #{}}, parse_string( "x y = f();" ) ), - ?assertError( {parser, nonapp_expr, str, "A"}, parse_string( "x y = \"A\";" ) ), - ?assertError( {parser, nonvar_expr_left_of_eq, str, "a"}, parse_string( "\"a\" = \"A\";" ) )]. + [?assertEqual( {[], #{"x" => [{str, "x"}]}, #{}}, string( "x = \"x\";" ) ), + ?assertEqual( {[], #{"x" => [{app, 1, 1, {var, 1, "f"}, #{}}], "y" => [{app, 1, 2, {var, 1, "f"}, #{}}]}, #{}}, string( "x y = f();" ) ), + ?assertError( {parser, nonapp_expr, str, "A"}, string( "x y = \"A\";" ) ), + ?assertError( {parser, nonvar_expr_left_of_eq, str, "a"}, string( "\"a\" = \"A\";" ) )]. native_deftask_should_be_recognized_test() -> ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, {natbody, #{"out" => [{str, "A"}]}}}}}, - parse_string( "deftask f( out : ) { out = \"A\"; }" ) ). + string( "deftask f( out : ) { out = \"A\"; }" ) ). foreign_deftask_should_be_recognized_test() -> [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, {forbody, bash, "out=A"}}}}, - parse_string( "deftask f( out : )in bash *{out=A}*" ) ), + string( "deftask f( out : )in bash *{out=A}*" ) ), ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, {forbody, r, "out=\"A\""}}}}, - parse_string( "deftask f( out : )in R *{out=\"A\"}*" ) ), + string( "deftask f( out : )in R *{out=\"A\"}*" ) ), ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, {forbody, python, ""}}}}, - parse_string( "deftask f( out : )in python *{}*" ) )]. + string( "deftask f( out : )in python *{}*" ) )]. sign_with_inparam_should_be_recognized_test() -> [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], [{param, {name, "inp", false}, false}]}, {forbody, python, "(defparameter out \"A\")"}}}}, - parse_string( "deftask f( out : inp )in python *{(defparameter out \"A\")}*" ) ), + string( "deftask f( out : inp )in python *{(defparameter out \"A\")}*" ) ), ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], [{param, {name, "a", false}, false}, {param, {name, "b", false}, false}]}, {forbody, python, "(defparameter out \"A\")"}}}}, - parse_string( "deftask f( out : a b )in python *{(defparameter out \"A\")}*" ) )]. + string( "deftask f( out : a b )in python *{(defparameter out \"A\")}*" ) )]. %% ============================================================================= %% Failing Tests @@ -258,27 +258,27 @@ param_should_be_recognized_test() -> {sign, [{param, {name, "out", false}, false}], [{param, {name, "inp", false}, false}]}, {forbody, bash, "blub"}}}}, - parse_string( "deftask f( out( String ) : inp( String ) )in bash *{blub}*" ) ), + string( "deftask f( out( String ) : inp( String ) )in bash *{blub}*" ) ), ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", true}, false}], [{param, {name, "inp", true}, false}]}, {forbody, bash, "blub"}}}}, - parse_string( "deftask f( out( File ) : inp( File ) )in bash *{blub}*" ) ), + string( "deftask f( out( File ) : inp( File ) )in bash *{blub}*" ) ), ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, true}], [{param, {name, "inp", false}, true}]}, {forbody, bash, "blub"}}}}, - parse_string( "deftask f( : )in bash *{blub}*" ) ), + string( "deftask f( : )in bash *{blub}*" ) ), ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, true}], [{param, {name, "inp", false}, true}]}, {forbody, bash, "blub"}}}}, - parse_string( "deftask f( : )in bash *{blub}*" ) ), + string( "deftask f( : )in bash *{blub}*" ) ), ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", true}, true}], [{param, {name, "inp", true}, true}]}, {forbody, bash, "blub"}}}}, - parse_string( "deftask f( : )in bash *{blub}*" ) )]. + string( "deftask f( : )in bash *{blub}*" ) )]. correl_inparam_should_be_recognized_test() -> [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", @@ -286,14 +286,14 @@ correl_inparam_should_be_recognized_test() -> [{correl, [{name, "a", true}, {name, "b", true}]}]}, {forbody, bash, "blub"}}}}, - parse_string( "deftask f( out : [a( File ) b( File )] )in bash *{blub}*" ) ), + string( "deftask f( out : [a( File ) b( File )] )in bash *{blub}*" ) ), ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], [{correl, [{name, "a", true}, {name, "b", true}]}, {param, {name, "c", false}, false}]}, {forbody, bash, "blub"}}}}, - parse_string( "deftask f( out : [a( File ) b( File )] c )in bash *{blub}*" ) )]. + string( "deftask f( out : [a( File ) b( File )] c )in bash *{blub}*" ) )]. -endif. diff --git a/src/cf_lexer.erl b/src/cf_scan.erl similarity index 98% rename from src/cf_lexer.erl rename to src/cf_scan.erl index 9d213ea..9eb1182 100644 --- a/src/cf_lexer.erl +++ b/src/cf_scan.erl @@ -6,13 +6,13 @@ %% property of the creator of the scanner and is not covered by that %% Copyright. --module(cf_lexer). +-module(cf_scan). -export([string/1,string/2,token/2,token/3,tokens/2,tokens/3]). -export([format_error/1]). %% User code. This is placed here to allow extra attributes. --file("src/cf_lexer.xrl", 114). +-file("src/cf_scan.xrl", 114). -author( "Jorgen Brandt " ). @@ -426,7 +426,7 @@ yysuf(List, N) -> lists:nthtail(N, List). %% return signal either an unrecognised character or end of current %% input. --file("src/cf_lexer.erl", 428). +-file("src/cf_scan.erl", 428). yystate() -> 69. yystate(72, [122|Ics], Line, Tlen, _, _) -> @@ -1519,157 +1519,157 @@ yyaction(30, _, _, _) -> yyaction(_, _, _, _) -> error. -compile({inline,yyaction_0/2}). --file("src/cf_lexer.xrl", 69). +-file("src/cf_scan.xrl", 69). yyaction_0(TokenChars, TokenLine) -> { token, { bash, TokenLine, TokenChars } } . -compile({inline,yyaction_1/2}). --file("src/cf_lexer.xrl", 70). +-file("src/cf_scan.xrl", 70). yyaction_1(TokenChars, TokenLine) -> { token, { python, TokenLine, TokenChars } } . -compile({inline,yyaction_2/2}). --file("src/cf_lexer.xrl", 71). +-file("src/cf_scan.xrl", 71). yyaction_2(TokenChars, TokenLine) -> { token, { r, TokenLine, TokenChars } } . -compile({inline,yyaction_3/2}). --file("src/cf_lexer.xrl", 73). +-file("src/cf_scan.xrl", 73). yyaction_3(TokenChars, TokenLine) -> { token, { intlit, TokenLine, TokenChars } } . -compile({inline,yyaction_4/2}). --file("src/cf_lexer.xrl", 74). +-file("src/cf_scan.xrl", 74). yyaction_4(TokenChars, TokenLine) -> { token, { strlit, TokenLine, trim_strlit (TokenChars) } } . -compile({inline,yyaction_5/2}). --file("src/cf_lexer.xrl", 75). +-file("src/cf_scan.xrl", 75). yyaction_5(TokenChars, TokenLine) -> { token, { body, TokenLine, trim_body (TokenChars) } } . -compile({inline,yyaction_6/2}). --file("src/cf_lexer.xrl", 76). +-file("src/cf_scan.xrl", 76). yyaction_6(TokenChars, TokenLine) -> { token, { beginif, TokenLine, TokenChars } } . -compile({inline,yyaction_7/2}). --file("src/cf_lexer.xrl", 77). +-file("src/cf_scan.xrl", 77). yyaction_7(TokenChars, TokenLine) -> { token, { colon, TokenLine, TokenChars } } . -compile({inline,yyaction_8/2}). --file("src/cf_lexer.xrl", 78). +-file("src/cf_scan.xrl", 78). yyaction_8(TokenChars, TokenLine) -> { token, { comma, TokenLine, TokenChars } } . -compile({inline,yyaction_9/2}). --file("src/cf_lexer.xrl", 79). +-file("src/cf_scan.xrl", 79). yyaction_9(TokenChars, TokenLine) -> { token, { deftask, TokenLine, TokenChars } } . -compile({inline,yyaction_10/2}). --file("src/cf_lexer.xrl", 80). +-file("src/cf_scan.xrl", 80). yyaction_10(TokenChars, TokenLine) -> { token, { else, TokenLine, TokenChars } } . -compile({inline,yyaction_11/2}). --file("src/cf_lexer.xrl", 81). +-file("src/cf_scan.xrl", 81). yyaction_11(TokenChars, TokenLine) -> { token, { endif, TokenLine, TokenChars } } . -compile({inline,yyaction_12/2}). --file("src/cf_lexer.xrl", 82). +-file("src/cf_scan.xrl", 82). yyaction_12(TokenChars, TokenLine) -> { token, { eq, TokenLine, TokenChars } } . -compile({inline,yyaction_13/2}). --file("src/cf_lexer.xrl", 83). +-file("src/cf_scan.xrl", 83). yyaction_13(TokenChars, TokenLine) -> { token, { file, TokenLine, TokenChars } } . -compile({inline,yyaction_14/2}). --file("src/cf_lexer.xrl", 84). +-file("src/cf_scan.xrl", 84). yyaction_14(TokenChars, TokenLine) -> { token, { in, TokenLine, TokenChars } } . -compile({inline,yyaction_15/2}). --file("src/cf_lexer.xrl", 85). +-file("src/cf_scan.xrl", 85). yyaction_15(TokenChars, TokenLine) -> { token, { lbrace, TokenLine, TokenChars } } . -compile({inline,yyaction_16/2}). --file("src/cf_lexer.xrl", 86). +-file("src/cf_scan.xrl", 86). yyaction_16(TokenChars, TokenLine) -> { token, { lparen, TokenLine, TokenChars } } . -compile({inline,yyaction_17/2}). --file("src/cf_lexer.xrl", 87). +-file("src/cf_scan.xrl", 87). yyaction_17(TokenChars, TokenLine) -> { token, { lsquarebr, TokenLine, TokenChars } } . -compile({inline,yyaction_18/2}). --file("src/cf_lexer.xrl", 88). +-file("src/cf_scan.xrl", 88). yyaction_18(TokenChars, TokenLine) -> { token, { ltag, TokenLine, TokenChars } } . -compile({inline,yyaction_19/2}). --file("src/cf_lexer.xrl", 89). +-file("src/cf_scan.xrl", 89). yyaction_19(TokenChars, TokenLine) -> { token, { nil, TokenLine, TokenChars } } . -compile({inline,yyaction_20/2}). --file("src/cf_lexer.xrl", 90). +-file("src/cf_scan.xrl", 90). yyaction_20(TokenChars, TokenLine) -> { token, { rbrace, TokenLine, TokenChars } } . -compile({inline,yyaction_21/2}). --file("src/cf_lexer.xrl", 91). +-file("src/cf_scan.xrl", 91). yyaction_21(TokenChars, TokenLine) -> { token, { rparen, TokenLine, TokenChars } } . -compile({inline,yyaction_22/2}). --file("src/cf_lexer.xrl", 92). +-file("src/cf_scan.xrl", 92). yyaction_22(TokenChars, TokenLine) -> { token, { rsquarebr, TokenLine, TokenChars } } . -compile({inline,yyaction_23/2}). --file("src/cf_lexer.xrl", 93). +-file("src/cf_scan.xrl", 93). yyaction_23(TokenChars, TokenLine) -> { token, { rtag, TokenLine, TokenChars } } . -compile({inline,yyaction_24/2}). --file("src/cf_lexer.xrl", 94). +-file("src/cf_scan.xrl", 94). yyaction_24(TokenChars, TokenLine) -> { token, { semicolon, TokenLine, TokenChars } } . -compile({inline,yyaction_25/2}). --file("src/cf_lexer.xrl", 95). +-file("src/cf_scan.xrl", 95). yyaction_25(TokenChars, TokenLine) -> { token, { string, TokenLine, TokenChars } } . -compile({inline,yyaction_26/2}). --file("src/cf_lexer.xrl", 96). +-file("src/cf_scan.xrl", 96). yyaction_26(TokenChars, TokenLine) -> { token, { then, TokenLine, TokenChars } } . -compile({inline,yyaction_27/2}). --file("src/cf_lexer.xrl", 98). +-file("src/cf_scan.xrl", 98). yyaction_27(TokenChars, TokenLine) -> { token, { id, TokenLine, TokenChars } } . -compile({inline,yyaction_28/0}). --file("src/cf_lexer.xrl", 100). +-file("src/cf_scan.xrl", 100). yyaction_28() -> skip_token . -compile({inline,yyaction_29/0}). --file("src/cf_lexer.xrl", 101). +-file("src/cf_scan.xrl", 101). yyaction_29() -> skip_token . -compile({inline,yyaction_30/0}). --file("src/cf_lexer.xrl", 102). +-file("src/cf_scan.xrl", 102). yyaction_30() -> skip_token . diff --git a/src/cf_lexer.xrl b/src/cf_scan.xrl similarity index 100% rename from src/cf_lexer.xrl rename to src/cf_scan.xrl From 1838ee4eb4d8aeb8aba9c2f292addaa617261b02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Thu, 25 Feb 2016 13:39:45 +0100 Subject: [PATCH 21/78] Debug output removed. --- src/cf.erl | 9 +++------ src/cf_parse.erl | 12 ++++++++---- src/cf_parse.yrl | 8 ++++++-- src/cf_sem.erl | 1 - 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/cf.erl b/src/cf.erl index 7c7e220..f5bd171 100644 --- a/src/cf.erl +++ b/src/cf.erl @@ -73,11 +73,8 @@ reduce( X0, {Rho, Mu, Gamma, Omega}, DataDir ) -> X1 = cf_sem:eval( X0, {Rho, Mu, Gamma, Omega} ), case cf_sem:pfinal( X1 ) of - true -> - io:format( "Finished: ~p~nReturning ...~n", [X1] ), - X1; + true -> X1; false -> - io:format( "Not finished: ~p~nOmega: ~p~nWaiting for futures to terminate ...~n", [X1, Omega] ), receive {failed, script_error, {ActScript, Out}} -> @@ -94,7 +91,7 @@ reduce( X0, {Rho, Mu, Gamma, Omega}, DataDir ) -> ok = io:format( "~4.B ~s~n", [N, Line] ), N+1 end, - 1, string:tokens( ActScript, "\n" ) ), + 1, re:split( ActScript, "\n" ) ), error( script_error ); @@ -109,7 +106,7 @@ reduce( X0, {Rho, Mu, Gamma, Omega}, DataDir ) -> acc_delta( N, Delta0, Ret, R ) end, #{}, maps:keys( Ret ) ), - io:format( "Reducing with Omega = ~p~n", [maps:merge( Omega, Delta )] ), + reduce( X1, {Rho, Mu, Gamma, maps:merge( Omega, Delta )}, DataDir ); Msg -> error( {bad_msg, Msg} ) diff --git a/src/cf_parse.erl b/src/cf_parse.erl index 16b69c1..e0bdb4e 100644 --- a/src/cf_parse.erl +++ b/src/cf_parse.erl @@ -12,8 +12,12 @@ string( S ) -> {ok, TokenList, _} = cf_scan:string( S ), - {ok, ParseTree} = cf_parse:parse( TokenList ), - ParseTree. + + % parse + case parse( TokenList ) of + {error, R2} -> error( R2 ); + {ok, ParseTree} -> ParseTree + end. @@ -365,7 +369,7 @@ yecctoken2string(Other) -> --file("src/cf_parse.erl", 368). +-file("src/cf_parse.erl", 372). -dialyzer({nowarn_function, yeccpars2/7}). yeccpars2(0=S, Cat, Ss, Stack, T, Ts, Tzr) -> @@ -1476,4 +1480,4 @@ yeccpars2_79_(__Stack0) -> end | __Stack]. --file("src/cf_parse.yrl", 301). +-file("src/cf_parse.yrl", 305). diff --git a/src/cf_parse.yrl b/src/cf_parse.yrl index 2aced3e..e21899c 100644 --- a/src/cf_parse.yrl +++ b/src/cf_parse.yrl @@ -120,8 +120,12 @@ Erlang code. string( S ) -> {ok, TokenList, _} = cf_scan:string( S ), - {ok, ParseTree} = cf_parse:parse( TokenList ), - ParseTree. + + % parse + case parse( TokenList ) of + {error, R2} -> error( R2 ); + {ok, ParseTree} -> ParseTree + end. diff --git a/src/cf_sem.erl b/src/cf_sem.erl index 3785db3..91d7f49 100644 --- a/src/cf_sem.erl +++ b/src/cf_sem.erl @@ -169,7 +169,6 @@ step( {var, _, N}, {Rho, _Mu, _Gamma, _Omega} ) -> % Future Channel Selection step( S={select, _, C, {fut, _, R, Lo}}, {_Rho, _Mu, _Gamma, Omega} ) -> % (47,48) {param, {name, N, _}, _} = lists:nth( C, Lo ), - io:format( "Looking up {~p, ~p} in ~p~n", [N, R, Omega] ), maps:get( {N, R}, Omega, [S] ); % Conditional From b5fc49d1824384bdc32030774cb763c4194aa13a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Thu, 25 Feb 2016 15:42:45 +0100 Subject: [PATCH 22/78] Semantic bug fixed. --- src/cf_sem.erl | 38 ++++++++++++++++++++------------------ test/cf_sem_test.erl | 18 ++++++++++++++++++ 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/src/cf_sem.erl b/src/cf_sem.erl index 91d7f49..31db42e 100644 --- a/src/cf_sem.erl +++ b/src/cf_sem.erl @@ -180,7 +180,7 @@ step( {cnd, Line, Xc=[_|_], Xt, Xe}, Theta ) -> end; % Application -step( {app, Line, C, {var, _, N}, Fa}, {_Rho, _Mu, Gamma, _Omega} ) -> +step( {app, Line, C, {var, _, N}, Fa}, {_Rho, _Mu, Gamma, _Omega} ) -> % (52) [{app, Line, C, maps:get( N, Gamma ), Fa}]; step( X={app, AppLine, C, @@ -189,23 +189,25 @@ step( X={app, AppLine, C, case psing( X ) of false -> enum_app( {app, AppLine, C, Lambda, step_assoc( Fa, Theta )} ); % (53) true -> - case B of - {forbody, _L, _Z} -> - case pfinal( Fa ) of - false -> [{app, AppLine, C, Lambda, step_assoc( Fa, Theta )}]; % (54) - true -> [{select, AppLine, C, apply( Mu, [X] )}] % (55) - end; - {natbody, Fb} -> - {param, {name, N, _}, Pl} = lists:nth( C, Lo ), - V0 = maps:get( N, Fb ), - V1 = step( V0, {maps:merge( Fb, Fa ), Mu, Gamma, Omega} ), - case pfinal( V1 ) of - false -> [{app, AppLine, C, {lam, LamLine, LamName, S, % (56) - {natbody, Fb#{ N => V1}}}, Fa}]; - true -> - case Pl orelse length( V1 ) =:= 1 of - true -> V1; % (57) - false -> error( output_sign_mismatch ) + case pfinal( Fa ) of + false -> [{app, AppLine, C, Lambda, step_assoc( Fa, Theta )}]; % (54) + true -> + case B of + {forbody, _L, _Z} -> [{select, AppLine, C, apply( Mu, [X] )}]; % (55) + {natbody, Fb} -> + {param, {name, N, _}, Pl} = lists:nth( C, Lo ), + V0 = maps:get( N, Fb ), + V1 = step( V0, {maps:merge( Fb, Fa ), Mu, Gamma, Omega} ), + case pfinal( V1 ) of + false -> [{app, AppLine, C, % (56) + {lam, LamLine, LamName, S, + {natbody, Fb#{ N => V1}}}, + Fa}]; + true -> + case Pl orelse length( V1 ) =:= 1 of + true -> V1; % (57) + false -> error( output_sign_mismatch ) + end end end end diff --git a/test/cf_sem_test.erl b/test/cf_sem_test.erl index 748ffcf..09410fb 100644 --- a/test/cf_sem_test.erl +++ b/test/cf_sem_test.erl @@ -297,3 +297,21 @@ app_select_param_is_enumerated_test() -> B = [{app, 5, 1, Lam2, #{"inp" => A}}], X = cf_sem:eval( B, ?THETA0 ), ?assertMatch( [{app, 5, 1, _, _}, {app, 5, 1, _, _}], X ). + +% deftask find_clusters( cls( File ) : state( File ) ) { +% cls = state; +% } +% mu0 = 1; +% cls = find_clusters( state: mu0 ); +% cls; +identity_fn_should_resolve_var_test() -> + Lo = [{param, {name, "cls", false}, false}], + Li = [{param, {name, "state", false}, false}], + Sign = {sign, Lo, Li}, + Body = {natbody, #{"cls" => [{var, 1, "state"}]}}, + Lam = {lam, 2, "find_clusters", Sign, Body}, + Fa = #{"state" => [{var, 3, "mu0"}]}, + App = {app, 4, 1, Lam, Fa}, + Rho = #{"cls" => [App], "mu0" => [{str, "1"}]}, + X = [{var, 6, "cls"}], + ?assertEqual( [{str, "1"}], cf_sem:eval( X, {Rho, fun sem:mu/1, #{}, #{}} ) ). \ No newline at end of file From 642c71ea0ca507916b25fd683842a24d24196687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Mon, 29 Feb 2016 22:17:13 +0100 Subject: [PATCH 23/78] update-deps to get-deps to avoid warning. Test file deleted. --- Makefile | 2 +- hello.cf | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) delete mode 100644 hello.cf diff --git a/Makefile b/Makefile index 34b1baf..9a3022b 100644 --- a/Makefile +++ b/Makefile @@ -5,5 +5,5 @@ clean: rebar clean .rebar/cf_18.2.1_plt: - rebar update-deps build-plt + rebar get-deps build-plt diff --git a/hello.cf b/hello.cf deleted file mode 100644 index 7b276cd..0000000 --- a/hello.cf +++ /dev/null @@ -1,7 +0,0 @@ -deftask greet( out : inp ) in bash *{ - out="Hello $inp" -}* - -x = greet( inp: "Jorgen" "Marc" ); - -x; From 65c2cd1bc78a9b1a2356854222df87ee14ccc266 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Thu, 3 Mar 2016 17:52:26 +0100 Subject: [PATCH 24/78] Indentation improved. --- src/cf_sem.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cf_sem.erl b/src/cf_sem.erl index 31db42e..baab916 100644 --- a/src/cf_sem.erl +++ b/src/cf_sem.erl @@ -82,7 +82,7 @@ when X :: #{string() => [expr()]} | [expr()] | expr(). pfinal( F ) when is_map( F ) -> pfinal( maps:values( F ) ); % (20) pfinal( L ) when is_list( L ) -> lists:all( fun pfinal/1, L ); % (21,22) -pfinal( {str, _S} ) -> true; % (23) +pfinal( {str, _S} ) -> true; % (23) pfinal( _T ) -> false. %% Singularity %% ============================================================== From baffc81b84a1cdf1acb522795a406dcb719df0c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Mon, 7 Mar 2016 18:18:47 +0100 Subject: [PATCH 25/78] Tests added. --- src/cf_sem.erl | 125 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 122 insertions(+), 3 deletions(-) diff --git a/src/cf_sem.erl b/src/cf_sem.erl index baab916..4db9e74 100644 --- a/src/cf_sem.erl +++ b/src/cf_sem.erl @@ -35,8 +35,7 @@ -type str() :: {str, S::string()}. % (2) -type var() :: {var, Line::pos_integer(), N::string()}. % (3) -type select() :: {select, Line::pos_integer(), C::pos_integer(), U::fut()}. % (4) --type fut() :: {fut, Name::string(), R::pos_integer(), % (5) - Fp::#{string() => boolean()}}. +-type fut() :: {fut, Name::string(), R::pos_integer(), Lo::[param()]}. % (5) -type cnd() :: {cnd, Line::pos_integer(), % (6) Xc::[expr()], Xt::[expr()], Xe::[expr()]}. -type app() :: {app, Line::pos_integer(), C::pos_integer(), % (7) @@ -95,7 +94,7 @@ psing( {app, _, _C, {lam, _, _, {sign, _Lo, Li}, _B}, Fa} ) -> -spec psing_argpair( Z::argpair() ) -> boolean(). % (26) psing_argpair( {[], _F} ) -> true; % (27) -psing_argpair( {[{param, _, Pl}|T], F} ) % (28) +psing_argpair( {[{param, _, Pl}|T], F} ) % (28) when Pl -> psing_argpair( {T, F} ); psing_argpair( {[{param, {name, N, _}, _Pl}|T], F} ) -> % (29) @@ -305,6 +304,126 @@ corrstep( [{name, H, _}|T], Facc, F0 ) -> -ifdef( TEST ). + +%% ============================================================================= +%% Predicates +%% ============================================================================= + +%% Finality %% + +str_should_be_final_test() -> + S = {str, "blub"}, + ?assert( pfinal( S ) ). + +app_should_not_be_final_test() -> + A = {app, 12, 1, {var, "f"}, #{}}, + ?assertNot( pfinal( A ) ). + +cnd_should_not_be_final_test() -> + C = {cnd, 12, [{str, "a"}], [{str, "b"}], [{str, "c"}]}, + ?assertNot( pfinal( C ) ). + +select_should_not_be_final_test() -> + Fut = {fut, "f", 1234, [{param, "out", false}]}, + S = {select, 12, 1, Fut}, + ?assertNot( pfinal( S ) ). + +var_should_not_be_final_test() -> + V = {var, 12, "x"}, + ?assertNot( pfinal( V ) ). + +all_str_should_be_final_test() -> + X = [{str, "bla"}, {str, "blub"}], + ?assert( pfinal( X ) ). + +empty_lst_should_be_final_test() -> + ?assert( pfinal( [] ) ). + +one_var_lst_should_not_be_final_test() -> + X = [{str, "bla"}, {str, "blub"}, {var, 12, "x"}], + ?assertNot( pfinal( X ) ). + +all_var_lst_should_not_be_final_test() -> + X = [{var, 10, "bla"}, {var, 11, "blub"}, {var, 12, "x"}], + ?assertNot( pfinal( X ) ). + +empty_map_should_be_final_test() -> + ?assert( pfinal( #{} ) ). + +only_str_map_should_be_final_test() -> + M = #{"x" => [{str, "bla"}, {str, "blub"}], "y" => [{str, "shalala"}]}, + ?assert( pfinal( M ) ). + +one_var_map_should_not_be_final_test() -> + M = #{"x" => [{str, "bla"}, {str, "blub"}], + "y" => [{str, "shalala"}, {var, 12, "x"}]}, + ?assertNot( pfinal( M ) ). + +all_var_map_should_not_be_final_test() -> + M = #{"x" => [{var, 10, "bla"}, {var, 11, "blub"}], + "y" => [{var, 12, "shalala"}, {var, 13, "x"}]}, + ?assertNot( pfinal( M ) ). + +%% Singularity %% + +app_without_arg_should_be_singular_test() -> + S = {sign, [{param, {name, "out", false}, false}], []}, + B = {forbody, bash, "shalala"}, + Lam = {lam, 12, "f", S, B}, + App = {app, 13, 1, Lam, #{}}, + ?assert( psing( App ) ). + +app_binding_single_str_should_be_singular_test() -> + S = {sign, [{param, {name, "out", false}, false}], [{param, {name, "x", false}, false}]}, + B = {forbody, bash, "shalala"}, + Lam = {lam, 12, "f", S, B}, + App = {app, 13, 1, Lam, #{"x" => [{str, "bla"}]}}, + ?assert( psing( App ) ). + +app_binding_str_lst_should_not_be_singular_test() -> + S = {sign, [{param, {name, "out", false}, false}], [{param, {name, "x", false}, false}]}, + B = {forbody, bash, "shalala"}, + Lam = {lam, 12, "f", S, B}, + App = {app, 13, 1, Lam, #{"x" => [{str, "bla"}, {str, "blub"}]}}, + ?assertNot( psing( App ) ). + +app_with_only_aggregate_args_should_be_singular_test() -> + S = {sign, [{param, {name, "out", false}, false}], [{param, {name, "x", false}, true}]}, + B = {forbody, bash, "shalala"}, + Lam = {lam, 12, "f", S, B}, + App = {app, 13, 1, Lam, #{"x" => [{str, "bla"}, {str, "blub"}]}}, + ?assert( psing( App ) ). + +%% Enumerability %% + +empty_lst_should_be_enumerable_test() -> + ?assert( pen( [] ) ). + +str_lst_should_be_enumerable_test() -> + ?assert( pen( [{str, "a"}, {str, "b"}] ) ). + +one_var_lst_should_not_be_enumerable_test() -> + ?assertNot( pen( [{str, "a"}, {var, 12, "x"}] ) ). + +all_var_lst_should_not_be_enumerable_test() -> + ?assertNot( pen( [{var, 12, "x"}, {var, 13, "y"}] ) ). + +str_should_be_enumerable_test() -> + ?assert( pen( {str, "blub"} ) ). + +single_str_branch_cnd_should_be_enumerable_test() -> + ?assert( pen( {cnd, 12, [], [{str, "a"}], [{str, "b"}]} ) ). + +empty_then_branch_cnd_should_not_be_enumerable_test() -> + ?assertNot( pen( {cnd, 12, [], [], [{str, "b"}]} ) ). + +empty_else_branch_cnd_should_not_be_enumerable_test() -> + ?assertNot( pen( {cnd, 12, [], [{str, "a"}]} ) ). + +%% ============================================================================= +%% Enumeration +%% ============================================================================= + %% The enum Function %% enum_app_without_app_does_nothing_test() -> From f1f48e97816adfbb7257153da655487e7040a6bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Tue, 8 Mar 2016 11:42:46 +0100 Subject: [PATCH 26/78] More unit tests. --- src/cf_sem.erl | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/cf_sem.erl b/src/cf_sem.erl index 4db9e74..ab9ff5a 100644 --- a/src/cf_sem.erl +++ b/src/cf_sem.erl @@ -420,6 +420,40 @@ empty_then_branch_cnd_should_not_be_enumerable_test() -> empty_else_branch_cnd_should_not_be_enumerable_test() -> ?assertNot( pen( {cnd, 12, [], [{str, "a"}]} ) ). +select_non_lst_app_should_be_enumerable_test() -> + Sign = {sign, [{param, {name, "out", false}, false}], []}, + Body = {forbody, bash, "shalala"}, + Lam = {lam, 12, "f", Sign, Body}, + App = {app, 13, 1, Lam, #{}}, + ?assert( pen( App ) ). + +select_lst_app_should_not_be_enumerable_test() -> + Sign = {sign, [{param, {name, "out", false}, true}], []}, + Body = {forbody, bash, "shalala"}, + Lam = {lam, 12, "f", Sign, Body}, + App = {app, 13, 1, Lam, #{}}, + ?assertNot( pen( App ) ). + +non_singular_app_should_not_be_enumerable_test() -> + Sign = {sign, [{param, {name, "out", false}, false}], [{param, {name, "x", false}, false}]}, + Body = {forbody, bash, "shalala"}, + Lam = {lam, 12, "f", Sign, Body}, + Fa = #{"x" => [{str, "bla"}, {str, "blub"}]}, + App = {app, 13, 1, Lam, Fa}, + ?assertNot( pen( App ) ). + +non_lst_select_should_be_enumerable_test() -> + Lo = [{param, {name, "out", false}, false}], + Fut = {fut, "f", 1234, Lo}, + Select = {select, 12, 1, Fut}, + ?assert( pen( Select ) ). + +lst_select_should_not_be_enumerable_test() -> + Lo = [{param, {name, "out", false}, true}], + Fut = {fut, "f", 1234, Lo}, + Select = {select, 12, 1, Fut}, + ?assertNot( pen( Select ) ). + %% ============================================================================= %% Enumeration %% ============================================================================= From 8edb60a054f071d061bbca81e3239518cd35ba27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Tue, 8 Mar 2016 17:59:23 +0100 Subject: [PATCH 27/78] Test refactored. --- src/cf_parse.yrl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cf_parse.yrl b/src/cf_parse.yrl index e21899c..12d2702 100644 --- a/src/cf_parse.yrl +++ b/src/cf_parse.yrl @@ -184,7 +184,7 @@ multi_element_compoundexpr_should_be_recognized_test() -> ?assertEqual( {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}, string( "bla blub;" ) ). -multiple_targets_should_be_joined_test() -> +multiple_queries_should_be_joined_test() -> ?assertEqual( {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}, string( "bla; blub;" ) ). From d7a2de898dd0ace9be2a9f2991d9b7e7db62aa3e Mon Sep 17 00:00:00 2001 From: Jorgen Brandt Date: Tue, 8 Mar 2016 22:03:05 +0100 Subject: [PATCH 28/78] Formatting changed. --- src/cf_parse.erl | 1483 ---------------------------------------- src/cf_parse.yrl | 16 +- src/cf_scan.erl | 1676 ---------------------------------------------- 3 files changed, 6 insertions(+), 3169 deletions(-) delete mode 100644 src/cf_parse.erl delete mode 100644 src/cf_scan.erl diff --git a/src/cf_parse.erl b/src/cf_parse.erl deleted file mode 100644 index e0bdb4e..0000000 --- a/src/cf_parse.erl +++ /dev/null @@ -1,1483 +0,0 @@ --module(cf_parse). --export([parse/1, parse_and_scan/1, format_error/1]). --file("src/cf_parse.yrl", 111). - --author( "Jorgen Brandt " ). - --export( [string/1] ). - --ifdef( TEST ). --include_lib( "eunit/include/eunit.hrl" ). --endif. - -string( S ) -> - {ok, TokenList, _} = cf_scan:string( S ), - - % parse - case parse( TokenList ) of - {error, R2} -> error( R2 ); - {ok, ParseTree} -> ParseTree - end. - - - - - -combine( {Target1, Rho1, Global1}, {Target2, Rho2, Global2} ) -> - {Target1++Target2, maps:merge( Rho1, Rho2 ), maps:merge( Global1, Global2 )}. - -mk_var( {id, Line, Name} ) -> {var, Line, Name}. - -mk_str( {intlit, _Line, N} ) -> {str, N}; -mk_str( {strlit, _Line, S} ) -> {str, S}. - -get_line( {_, Line, _} ) -> Line. - -get_name( {id, _Line, Name} ) -> Name. - -mk_binding( {id, _, Name}, ExprList ) -> - #{Name => ExprList}. - -mk_assign( [], _ExprList, _Channel ) -> #{}; - -mk_assign( [{var, _Line, Name}|Rest], ExprList, Channel ) -> - Rho = mk_assign( Rest, ExprList, Channel+1 ), - Value = lists:flatmap( fun( E ) -> set_channel( E, Channel ) end, ExprList ), - Rho#{Name => Value}; - -mk_assign( [E|_Rest], _ExprList, _Channel ) -> - error( {parser, nonvar_expr_left_of_eq, element( 1, E ), element( 2, E )} ). - - -set_channel( {app, Line, _Channel, LamList, Binding}, N ) -> [{app, Line, N, LamList, Binding}]; -set_channel( E, 1 ) -> [E]; -set_channel( E, _ ) -> error( {parser, nonapp_expr, element( 1, E ), element( 2, E )} ). - -mk_natlam( {deftask, Line, _}, {id, _, Name}, Sign, Block ) -> - #{Name => {lam, Line, Name, Sign, {natbody, Block}}}. - -mk_forlam( {deftask, Line, _}, {id, _, Name}, Sign, Lang, {body, _, Code} ) -> - #{Name => {lam, Line, Name, Sign, {forbody, Lang, Code}}}. - - -%% ============================================================================= -%% Unit Tests -%% ============================================================================= - --ifdef( TEST ). - -nil_should_be_recognized_test() -> - ?assertEqual( {[], #{}, #{}}, string( "nil;" ) ). - -var_should_be_recognized_test() -> - ?assertEqual( {[{var, 1, "blub"}], #{}, #{}}, string( "blub;" ) ). - -multi_element_compoundexpr_should_be_recognized_test() -> - ?assertEqual( {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}, - string( "bla blub;" ) ). - -multiple_targets_should_be_joined_test() -> - ?assertEqual( {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}, - string( "bla; blub;" ) ). - -strlit_should_be_recognized_test() -> - ?assertEqual( {[{str, "bla"}], #{}, #{}}, string( "\"bla\";" ) ). - -intlit_should_be_recognized_test() -> - ?assertEqual( {[{str, "-5"}], #{}, #{}}, string( "-5;" ) ). - -cnd_should_be_recognized_test() -> - ?assertEqual( {[{cnd, 1, [], [{str, "bla"}], [{str, "blub"}]}], - #{}, #{}}, - string( "if nil then \"bla\" else \"blub\" end;" ) ). - -app_should_be_recognized_test() -> - [?assertEqual( {[{app, 1, 1, {var, 1, "f"}, #{}}], #{}, #{}}, - string( "f();" ) ), - ?assertEqual( {[{app, 1, 1, {var, 1, "f"}, #{"x" => [{var, 1, "x"}]}}], - #{}, #{}}, string( "f( x: x );" ) ), - ?assertEqual( {[{app, 1, 1, {var, 1, "f"}, - #{"x" => [{var, 1, "x"}], - "y" => [{str, "y"}]}}], #{}, #{}}, - string( "f( x: x, y: \"y\" );" ) )]. - - -assign_should_be_recognized_test() -> - [?assertEqual( {[], #{"x" => [{str, "x"}]}, #{}}, string( "x = \"x\";" ) ), - ?assertEqual( {[], #{"x" => [{app, 1, 1, {var, 1, "f"}, #{}}], "y" => [{app, 1, 2, {var, 1, "f"}, #{}}]}, #{}}, string( "x y = f();" ) ), - ?assertError( {parser, nonapp_expr, str, "A"}, string( "x y = \"A\";" ) ), - ?assertError( {parser, nonvar_expr_left_of_eq, str, "a"}, string( "\"a\" = \"A\";" ) )]. - -native_deftask_should_be_recognized_test() -> - ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - []}, - {natbody, #{"out" => [{str, "A"}]}}}}}, - string( "deftask f( out : ) { out = \"A\"; }" ) ). - -foreign_deftask_should_be_recognized_test() -> - [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - []}, - {forbody, bash, "out=A"}}}}, - string( "deftask f( out : )in bash *{out=A}*" ) ), - ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - []}, - {forbody, r, "out=\"A\""}}}}, - string( "deftask f( out : )in R *{out=\"A\"}*" ) ), - ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - []}, - {forbody, python, ""}}}}, - string( "deftask f( out : )in python *{}*" ) )]. - -sign_with_inparam_should_be_recognized_test() -> - [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [{param, {name, "inp", false}, false}]}, - {forbody, python, "(defparameter out \"A\")"}}}}, - string( "deftask f( out : inp )in python *{(defparameter out \"A\")}*" ) ), - ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [{param, {name, "a", false}, false}, - {param, {name, "b", false}, false}]}, - {forbody, python, "(defparameter out \"A\")"}}}}, - string( "deftask f( out : a b )in python *{(defparameter out \"A\")}*" ) )]. - -%% ============================================================================= -%% Failing Tests -%% ============================================================================= - -param_should_be_recognized_test() -> - [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [{param, {name, "inp", false}, false}]}, - {forbody, bash, "blub"}}}}, - string( "deftask f( out( String ) : inp( String ) )in bash *{blub}*" ) ), - ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", - {sign, [{param, {name, "out", true}, false}], - [{param, {name, "inp", true}, false}]}, - {forbody, bash, "blub"}}}}, - string( "deftask f( out( File ) : inp( File ) )in bash *{blub}*" ) ), - ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", - {sign, [{param, {name, "out", false}, true}], - [{param, {name, "inp", false}, true}]}, - {forbody, bash, "blub"}}}}, - string( "deftask f( : )in bash *{blub}*" ) ), - ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", - {sign, [{param, {name, "out", false}, true}], - [{param, {name, "inp", false}, true}]}, - {forbody, bash, "blub"}}}}, - string( "deftask f( : )in bash *{blub}*" ) ), - ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", - {sign, [{param, {name, "out", true}, true}], - [{param, {name, "inp", true}, true}]}, - {forbody, bash, "blub"}}}}, - string( "deftask f( : )in bash *{blub}*" ) )]. - -correl_inparam_should_be_recognized_test() -> - [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [{correl, [{name, "a", true}, - {name, "b", true}]}]}, - {forbody, bash, "blub"}}}}, - string( "deftask f( out : [a( File ) b( File )] )in bash *{blub}*" ) ), - ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [{correl, [{name, "a", true}, - {name, "b", true}]}, - {param, {name, "c", false}, false}]}, - {forbody, bash, "blub"}}}}, - string( "deftask f( out : [a( File ) b( File )] c )in bash *{blub}*" ) )]. - --endif. - - - --file("/usr/local/lib/erlang/lib/parsetools-2.1.1/include/yeccpre.hrl", 0). -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2015. All Rights Reserved. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -%% -%% %CopyrightEnd% -%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% The parser generator will insert appropriate declarations before this line.% - --type yecc_ret() :: {'error', _} | {'ok', _}. - --spec parse(Tokens :: list()) -> yecc_ret(). -parse(Tokens) -> - yeccpars0(Tokens, {no_func, no_line}, 0, [], []). - --spec parse_and_scan({function() | {atom(), atom()}, [_]} - | {atom(), atom(), [_]}) -> yecc_ret(). -parse_and_scan({F, A}) -> - yeccpars0([], {{F, A}, no_line}, 0, [], []); -parse_and_scan({M, F, A}) -> - Arity = length(A), - yeccpars0([], {{fun M:F/Arity, A}, no_line}, 0, [], []). - --spec format_error(any()) -> [char() | list()]. -format_error(Message) -> - case io_lib:deep_char_list(Message) of - true -> - Message; - _ -> - io_lib:write(Message) - end. - -%% To be used in grammar files to throw an error message to the parser -%% toplevel. Doesn't have to be exported! --compile({nowarn_unused_function, return_error/2}). --spec return_error(integer(), any()) -> no_return(). -return_error(Line, Message) -> - throw({error, {Line, ?MODULE, Message}}). - --define(CODE_VERSION, "1.4"). - -yeccpars0(Tokens, Tzr, State, States, Vstack) -> - try yeccpars1(Tokens, Tzr, State, States, Vstack) - catch - error: Error -> - Stacktrace = erlang:get_stacktrace(), - try yecc_error_type(Error, Stacktrace) of - Desc -> - erlang:raise(error, {yecc_bug, ?CODE_VERSION, Desc}, - Stacktrace) - catch _:_ -> erlang:raise(error, Error, Stacktrace) - end; - %% Probably thrown from return_error/2: - throw: {error, {_Line, ?MODULE, _M}} = Error -> - Error - end. - -yecc_error_type(function_clause, [{?MODULE,F,ArityOrArgs,_} | _]) -> - case atom_to_list(F) of - "yeccgoto_" ++ SymbolL -> - {ok,[{atom,_,Symbol}],_} = erl_scan:string(SymbolL), - State = case ArityOrArgs of - [S,_,_,_,_,_,_] -> S; - _ -> state_is_unknown - end, - {Symbol, State, missing_in_goto_table} - end. - -yeccpars1([Token | Tokens], Tzr, State, States, Vstack) -> - yeccpars2(State, element(1, Token), States, Vstack, Token, Tokens, Tzr); -yeccpars1([], {{F, A},_Line}, State, States, Vstack) -> - case apply(F, A) of - {ok, Tokens, Endline} -> - yeccpars1(Tokens, {{F, A}, Endline}, State, States, Vstack); - {eof, Endline} -> - yeccpars1([], {no_func, Endline}, State, States, Vstack); - {error, Descriptor, _Endline} -> - {error, Descriptor} - end; -yeccpars1([], {no_func, no_line}, State, States, Vstack) -> - Line = 999999, - yeccpars2(State, '$end', States, Vstack, yecc_end(Line), [], - {no_func, Line}); -yeccpars1([], {no_func, Endline}, State, States, Vstack) -> - yeccpars2(State, '$end', States, Vstack, yecc_end(Endline), [], - {no_func, Endline}). - -%% yeccpars1/7 is called from generated code. -%% -%% When using the {includefile, Includefile} option, make sure that -%% yeccpars1/7 can be found by parsing the file without following -%% include directives. yecc will otherwise assume that an old -%% yeccpre.hrl is included (one which defines yeccpars1/5). -yeccpars1(State1, State, States, Vstack, Token0, [Token | Tokens], Tzr) -> - yeccpars2(State, element(1, Token), [State1 | States], - [Token0 | Vstack], Token, Tokens, Tzr); -yeccpars1(State1, State, States, Vstack, Token0, [], {{_F,_A}, _Line}=Tzr) -> - yeccpars1([], Tzr, State, [State1 | States], [Token0 | Vstack]); -yeccpars1(State1, State, States, Vstack, Token0, [], {no_func, no_line}) -> - Line = yecctoken_end_location(Token0), - yeccpars2(State, '$end', [State1 | States], [Token0 | Vstack], - yecc_end(Line), [], {no_func, Line}); -yeccpars1(State1, State, States, Vstack, Token0, [], {no_func, Line}) -> - yeccpars2(State, '$end', [State1 | States], [Token0 | Vstack], - yecc_end(Line), [], {no_func, Line}). - -%% For internal use only. -yecc_end({Line,_Column}) -> - {'$end', Line}; -yecc_end(Line) -> - {'$end', Line}. - -yecctoken_end_location(Token) -> - try erl_anno:end_location(element(2, Token)) of - undefined -> yecctoken_location(Token); - Loc -> Loc - catch _:_ -> yecctoken_location(Token) - end. - --compile({nowarn_unused_function, yeccerror/1}). -yeccerror(Token) -> - Text = yecctoken_to_string(Token), - Location = yecctoken_location(Token), - {error, {Location, ?MODULE, ["syntax error before: ", Text]}}. - --compile({nowarn_unused_function, yecctoken_to_string/1}). -yecctoken_to_string(Token) -> - try erl_scan:text(Token) of - undefined -> yecctoken2string(Token); - Txt -> Txt - catch _:_ -> yecctoken2string(Token) - end. - -yecctoken_location(Token) -> - try erl_scan:location(Token) - catch _:_ -> element(2, Token) - end. - --compile({nowarn_unused_function, yecctoken2string/1}). -yecctoken2string({atom, _, A}) -> io_lib:write(A); -yecctoken2string({integer,_,N}) -> io_lib:write(N); -yecctoken2string({float,_,F}) -> io_lib:write(F); -yecctoken2string({char,_,C}) -> io_lib:write_char(C); -yecctoken2string({var,_,V}) -> io_lib:format("~s", [V]); -yecctoken2string({string,_,S}) -> io_lib:write_string(S); -yecctoken2string({reserved_symbol, _, A}) -> io_lib:write(A); -yecctoken2string({_Cat, _, Val}) -> io_lib:format("~p",[Val]); -yecctoken2string({dot, _}) -> "'.'"; -yecctoken2string({'$end', _}) -> - []; -yecctoken2string({Other, _}) when is_atom(Other) -> - io_lib:write(Other); -yecctoken2string(Other) -> - io_lib:write(Other). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - - --file("src/cf_parse.erl", 372). - --dialyzer({nowarn_function, yeccpars2/7}). -yeccpars2(0=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_0(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(1=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_1(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(2=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_2(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(3=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_3(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(4=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_4(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(5=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_5(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(6=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_6(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(7=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_7(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(8=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_8(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(9=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_9(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(10=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_10(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(11=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_11(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(12=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_12(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(13=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_13(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(14=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_14(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(15=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_15(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(16=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_16(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(17=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_17(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(18=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_18(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(19=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_19(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(20=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_20(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(21=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_21(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(22=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_11(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(23=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_23(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(24=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_24(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(25=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_25(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(26=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_26(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(27=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_27(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(28=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_28(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(29=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_29(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(30=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_30(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(31=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_31(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(32=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_32(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(33=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_33(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(34=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_34(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(35=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_35(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(36=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_36(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(37=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_37(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(38=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_38(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(39=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_39(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(40=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_40(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(41=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_41(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(42=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_42(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(43=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_43(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(44=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_44(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(45=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(46=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_46(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(47=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_47(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(48=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_35(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(49=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_49(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(50=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_50(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(51=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_51(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(52=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_52(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(53=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_53(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(54=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_54(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(55=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_55(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(56=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_56(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(57=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_57(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(58=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_58(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(59=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_59(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(60=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_60(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(61=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_61(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(62=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_62(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(63=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_11(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(64=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_64(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(65=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_65(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(66=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_66(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(67=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_67(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(68=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_68(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(69=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_69(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(70=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_70(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(71=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_71(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(72=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_11(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(73=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_73(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(74=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_11(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(75=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_75(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(76=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_76(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(77=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_77(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(78=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_78(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(79=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_79(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(Other, _, _, _, _, _, _) -> - erlang:error({yecc_bug,"1.4",{missing_state_in_action_table, Other}}). - -yeccpars2_0(S, deftask, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr); -yeccpars2_0(S, nil, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 15, Ss, Stack, T, Ts, Tzr); -yeccpars2_0(S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_57(S, Cat, Ss, Stack, T, Ts, Tzr). - -yeccpars2_1(S, beginif, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr); -yeccpars2_1(S, deftask, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr); -yeccpars2_1(S, id, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 13, Ss, Stack, T, Ts, Tzr); -yeccpars2_1(S, intlit, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 14, Ss, Stack, T, Ts, Tzr); -yeccpars2_1(S, nil, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 15, Ss, Stack, T, Ts, Tzr); -yeccpars2_1(S, strlit, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 16, Ss, Stack, T, Ts, Tzr); -yeccpars2_1(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccgoto_script(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). - --dialyzer({nowarn_function, yeccpars2_2/7}). -yeccpars2_2(_S, '$end', _Ss, Stack, _T, _Ts, _Tzr) -> - {ok, hd(Stack)}; -yeccpars2_2(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_3(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_3_(Stack), - yeccgoto_stat(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - -yeccpars2_4(S, eq, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 63, Ss, Stack, T, Ts, Tzr); -yeccpars2_4(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccgoto_compoundexpr(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). - -yeccpars2_5(S, beginif, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr); -yeccpars2_5(S, id, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 13, Ss, Stack, T, Ts, Tzr); -yeccpars2_5(S, intlit, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 14, Ss, Stack, T, Ts, Tzr); -yeccpars2_5(S, strlit, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 16, Ss, Stack, T, Ts, Tzr); -yeccpars2_5(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_5_(Stack), - yeccgoto_exprlist(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - -yeccpars2_6(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_6_(Stack), - yeccgoto_stat(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - --dialyzer({nowarn_function, yeccpars2_7/7}). -yeccpars2_7(S, semicolon, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 77, Ss, Stack, T, Ts, Tzr); -yeccpars2_7(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccgoto_expr(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). - -yeccpars2_9(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_9_(Stack), - yeccgoto_stat(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - -yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccgoto_expr(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). - -yeccpars2_11(S, nil, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 15, Ss, Stack, T, Ts, Tzr); -yeccpars2_11(S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_57(S, Cat, Ss, Stack, T, Ts, Tzr). - --dialyzer({nowarn_function, yeccpars2_12/7}). -yeccpars2_12(S, id, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 28, Ss, Stack, T, Ts, Tzr); -yeccpars2_12(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_13(S, lparen, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 17, Ss, Stack, T, Ts, Tzr); -yeccpars2_13(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_13_(Stack), - yeccgoto_expr(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - -yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_14_(Stack), - yeccgoto_expr(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - -yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_15_(Stack), - yeccgoto_compoundexpr(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - -yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_16_(Stack), - yeccgoto_expr(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - --dialyzer({nowarn_function, yeccpars2_17/7}). -yeccpars2_17(S, id, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 20, Ss, Stack, T, Ts, Tzr); -yeccpars2_17(S, rparen, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 21, Ss, Stack, T, Ts, Tzr); -yeccpars2_17(_, _, _, _, T, _, _) -> - yeccerror(T). - --dialyzer({nowarn_function, yeccpars2_18/7}). -yeccpars2_18(S, rparen, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 27, Ss, Stack, T, Ts, Tzr); -yeccpars2_18(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_19(S, comma, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 25, Ss, Stack, T, Ts, Tzr); -yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccgoto_bindinglist(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). - --dialyzer({nowarn_function, yeccpars2_20/7}). -yeccpars2_20(S, colon, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 22, Ss, Stack, T, Ts, Tzr); -yeccpars2_20(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_,_|Nss] = Ss, - NewStack = yeccpars2_21_(Stack), - yeccgoto_app(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - -%% yeccpars2_22: see yeccpars2_11 - -yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccgoto_compoundexpr(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). - -yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_,_|Nss] = Ss, - NewStack = yeccpars2_24_(Stack), - yeccgoto_binding(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - --dialyzer({nowarn_function, yeccpars2_25/7}). -yeccpars2_25(S, id, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 20, Ss, Stack, T, Ts, Tzr); -yeccpars2_25(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_26(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_,_|Nss] = Ss, - NewStack = yeccpars2_26_(Stack), - yeccgoto_bindinglist(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - -yeccpars2_27(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_,_,_|Nss] = Ss, - NewStack = yeccpars2_27_(Stack), - yeccgoto_app(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - --dialyzer({nowarn_function, yeccpars2_28/7}). -yeccpars2_28(S, lparen, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 30, Ss, Stack, T, Ts, Tzr); -yeccpars2_28(_, _, _, _, T, _, _) -> - yeccerror(T). - --dialyzer({nowarn_function, yeccpars2_29/7}). -yeccpars2_29(S, in, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 56, Ss, Stack, T, Ts, Tzr); -yeccpars2_29(S, lbrace, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 57, Ss, Stack, T, Ts, Tzr); -yeccpars2_29(_, _, _, _, T, _, _) -> - yeccerror(T). - --dialyzer({nowarn_function, yeccpars2_30/7}). -yeccpars2_30(S, id, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr); -yeccpars2_30(S, ltag, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 35, Ss, Stack, T, Ts, Tzr); -yeccpars2_30(_, _, _, _, T, _, _) -> - yeccerror(T). - --dialyzer({nowarn_function, yeccpars2_31/7}). -yeccpars2_31(S, colon, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 44, Ss, Stack, T, Ts, Tzr); -yeccpars2_31(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_32(S, id, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr); -yeccpars2_32(S, ltag, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 35, Ss, Stack, T, Ts, Tzr); -yeccpars2_32(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_32_(Stack), - yeccgoto_paramlist(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - -yeccpars2_33(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_33_(Stack), - yeccgoto_param(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - -yeccpars2_34(S, lparen, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 38, Ss, Stack, T, Ts, Tzr); -yeccpars2_34(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_34_(Stack), - yeccgoto_name(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - --dialyzer({nowarn_function, yeccpars2_35/7}). -yeccpars2_35(S, id, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr); -yeccpars2_35(_, _, _, _, T, _, _) -> - yeccerror(T). - --dialyzer({nowarn_function, yeccpars2_36/7}). -yeccpars2_36(S, rtag, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 37, Ss, Stack, T, Ts, Tzr); -yeccpars2_36(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_37(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_,_|Nss] = Ss, - NewStack = yeccpars2_37_(Stack), - yeccgoto_param(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - --dialyzer({nowarn_function, yeccpars2_38/7}). -yeccpars2_38(S, file, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 39, Ss, Stack, T, Ts, Tzr); -yeccpars2_38(S, string, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 40, Ss, Stack, T, Ts, Tzr); -yeccpars2_38(_, _, _, _, T, _, _) -> - yeccerror(T). - --dialyzer({nowarn_function, yeccpars2_39/7}). -yeccpars2_39(S, rparen, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 42, Ss, Stack, T, Ts, Tzr); -yeccpars2_39(_, _, _, _, T, _, _) -> - yeccerror(T). - --dialyzer({nowarn_function, yeccpars2_40/7}). -yeccpars2_40(S, rparen, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 41, Ss, Stack, T, Ts, Tzr); -yeccpars2_40(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_,_,_|Nss] = Ss, - NewStack = yeccpars2_41_(Stack), - yeccgoto_name(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - -yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_,_,_|Nss] = Ss, - NewStack = yeccpars2_42_(Stack), - yeccgoto_name(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - -yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_|Nss] = Ss, - NewStack = yeccpars2_43_(Stack), - yeccgoto_paramlist(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - --dialyzer({nowarn_function, yeccpars2_44/7}). -yeccpars2_44(S, id, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr); -yeccpars2_44(S, lsquarebr, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 48, Ss, Stack, T, Ts, Tzr); -yeccpars2_44(S, ltag, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 35, Ss, Stack, T, Ts, Tzr); -yeccpars2_44(S, rparen, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 49, Ss, Stack, T, Ts, Tzr); -yeccpars2_44(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_45(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccgoto_inparam(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). - --dialyzer({nowarn_function, yeccpars2_46/7}). -yeccpars2_46(S, rparen, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 55, Ss, Stack, T, Ts, Tzr); -yeccpars2_46(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_47(S, id, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr); -yeccpars2_47(S, lsquarebr, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 48, Ss, Stack, T, Ts, Tzr); -yeccpars2_47(S, ltag, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 35, Ss, Stack, T, Ts, Tzr); -yeccpars2_47(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_47_(Stack), - yeccgoto_inparamlist(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - -%% yeccpars2_48: see yeccpars2_35 - -yeccpars2_49(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_,_,_|Nss] = Ss, - NewStack = yeccpars2_49_(Stack), - yeccgoto_sign(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - --dialyzer({nowarn_function, yeccpars2_50/7}). -yeccpars2_50(S, rsquarebr, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 53, Ss, Stack, T, Ts, Tzr); -yeccpars2_50(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_51(S, id, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr); -yeccpars2_51(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_51_(Stack), - yeccgoto_namelist(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - -yeccpars2_52(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_|Nss] = Ss, - NewStack = yeccpars2_52_(Stack), - yeccgoto_namelist(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - -yeccpars2_53(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_,_|Nss] = Ss, - NewStack = yeccpars2_53_(Stack), - yeccgoto_inparam(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - -yeccpars2_54(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_|Nss] = Ss, - NewStack = yeccpars2_54_(Stack), - yeccgoto_inparamlist(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - -yeccpars2_55(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_,_,_,_|Nss] = Ss, - NewStack = yeccpars2_55_(Stack), - yeccgoto_sign(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - --dialyzer({nowarn_function, yeccpars2_56/7}). -yeccpars2_56(S, bash, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 67, Ss, Stack, T, Ts, Tzr); -yeccpars2_56(S, python, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 68, Ss, Stack, T, Ts, Tzr); -yeccpars2_56(S, r, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 69, Ss, Stack, T, Ts, Tzr); -yeccpars2_56(_, _, _, _, T, _, _) -> - yeccerror(T). - --dialyzer({nowarn_function, yeccpars2_57/7}). -yeccpars2_57(S, beginif, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr); -yeccpars2_57(S, id, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 13, Ss, Stack, T, Ts, Tzr); -yeccpars2_57(S, intlit, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 14, Ss, Stack, T, Ts, Tzr); -yeccpars2_57(S, strlit, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 16, Ss, Stack, T, Ts, Tzr); -yeccpars2_57(_, _, _, _, T, _, _) -> - yeccerror(T). - --dialyzer({nowarn_function, yeccpars2_58/7}). -yeccpars2_58(S, eq, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 63, Ss, Stack, T, Ts, Tzr); -yeccpars2_58(_, _, _, _, T, _, _) -> - yeccerror(T). - --dialyzer({nowarn_function, yeccpars2_59/7}). -yeccpars2_59(S, rbrace, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 62, Ss, Stack, T, Ts, Tzr); -yeccpars2_59(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_60(S, beginif, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr); -yeccpars2_60(S, id, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 13, Ss, Stack, T, Ts, Tzr); -yeccpars2_60(S, intlit, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 14, Ss, Stack, T, Ts, Tzr); -yeccpars2_60(S, strlit, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 16, Ss, Stack, T, Ts, Tzr); -yeccpars2_60(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccgoto_assignlist(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). - -yeccpars2_61(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_|Nss] = Ss, - NewStack = yeccpars2_61_(Stack), - yeccgoto_assignlist(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - -yeccpars2_62(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_,_,_,_,_|Nss] = Ss, - NewStack = yeccpars2_62_(Stack), - yeccgoto_defun(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - -%% yeccpars2_63: see yeccpars2_11 - --dialyzer({nowarn_function, yeccpars2_64/7}). -yeccpars2_64(S, semicolon, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 65, Ss, Stack, T, Ts, Tzr); -yeccpars2_64(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_65(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_,_,_|Nss] = Ss, - NewStack = yeccpars2_65_(Stack), - yeccgoto_assign(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - --dialyzer({nowarn_function, yeccpars2_66/7}). -yeccpars2_66(S, body, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 70, Ss, Stack, T, Ts, Tzr); -yeccpars2_66(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_67(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_67_(Stack), - yeccgoto_lang(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - -yeccpars2_68(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_68_(Stack), - yeccgoto_lang(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - -yeccpars2_69(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_69_(Stack), - yeccgoto_lang(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - -yeccpars2_70(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_,_,_,_,_|Nss] = Ss, - NewStack = yeccpars2_70_(Stack), - yeccgoto_defun(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - --dialyzer({nowarn_function, yeccpars2_71/7}). -yeccpars2_71(S, then, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 72, Ss, Stack, T, Ts, Tzr); -yeccpars2_71(_, _, _, _, T, _, _) -> - yeccerror(T). - -%% yeccpars2_72: see yeccpars2_11 - --dialyzer({nowarn_function, yeccpars2_73/7}). -yeccpars2_73(S, else, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 74, Ss, Stack, T, Ts, Tzr); -yeccpars2_73(_, _, _, _, T, _, _) -> - yeccerror(T). - -%% yeccpars2_74: see yeccpars2_11 - --dialyzer({nowarn_function, yeccpars2_75/7}). -yeccpars2_75(S, endif, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 76, Ss, Stack, T, Ts, Tzr); -yeccpars2_75(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_76(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_,_,_,_,_,_|Nss] = Ss, - NewStack = yeccpars2_76_(Stack), - yeccgoto_cnd(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - -yeccpars2_77(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_|Nss] = Ss, - NewStack = yeccpars2_77_(Stack), - yeccgoto_query(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - -yeccpars2_78(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_|Nss] = Ss, - NewStack = yeccpars2_78_(Stack), - yeccgoto_exprlist(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - -yeccpars2_79(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_|Nss] = Ss, - NewStack = yeccpars2_79_(Stack), - yeccgoto_script(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - -yeccgoto_app(0=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_app(1=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_app(5=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_app(11=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_app(22=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_app(57=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_app(60=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_app(63=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_app(72=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_app(74=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_assign(0=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_9(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_assign(1=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_9(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_assign(57, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_60(60, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_assign(60, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_60(60, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_assignlist(57, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_59(59, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_assignlist(60=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_61(_S, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_binding(17, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_19(19, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_binding(25, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_19(19, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_bindinglist(17, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_18(18, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_bindinglist(25=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_26(_S, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_cnd(0=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_cnd(1=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_cnd(5=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_cnd(11=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_cnd(22=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_cnd(57=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_cnd(60=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_cnd(63=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_cnd(72=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_cnd(74=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_compoundexpr(0, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_7(7, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_compoundexpr(1, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_7(7, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_compoundexpr(11, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_71(71, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_compoundexpr(22=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_compoundexpr(63, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_64(64, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_compoundexpr(72, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_73(73, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_compoundexpr(74, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_75(75, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_defun(0=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_6(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_defun(1=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_6(_S, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_expr(0, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_expr(1, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_expr(5, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_expr(11, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_expr(22, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_expr(57, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_expr(60, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_expr(63, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_expr(72, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_expr(74, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_exprlist(0, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_4(4, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_exprlist(1, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_4(4, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_exprlist(5=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_78(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_exprlist(11=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_exprlist(22=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_exprlist(57, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_58(58, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_exprlist(60, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_58(58, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_exprlist(63=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_exprlist(72=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_exprlist(74=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_inparam(44, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_47(47, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_inparam(47, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_47(47, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_inparamlist(44, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_46(46, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_inparamlist(47=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_54(_S, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_lang(56, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_66(66, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_name(30=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_33(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_name(32=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_33(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_name(35, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_name(44=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_33(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_name(47=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_33(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_name(48, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_51(51, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_name(51, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_51(51, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_namelist(48, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_50(50, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_namelist(51=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_52(_S, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_param(30, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_param(32, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_param(44=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_45(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_param(47=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_45(_S, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_paramlist(30, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_31(31, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_paramlist(32=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_query(0=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_3(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_query(1=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_3(_S, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_script(0, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_2(2, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_script(1=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_79(_S, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_sign(28, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_stat(0, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_1(1, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_stat(1, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_1(1, Cat, Ss, Stack, T, Ts, Tzr). - --compile({inline,yeccpars2_3_/1}). --file("src/cf_parse.yrl", 40). -yeccpars2_3_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - { __1 , # { } , # { } } - end | __Stack]. - --compile({inline,yeccpars2_5_/1}). --file("src/cf_parse.yrl", 67). -yeccpars2_5_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - [ __1 ] - end | __Stack]. - --compile({inline,yeccpars2_6_/1}). --file("src/cf_parse.yrl", 42). -yeccpars2_6_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - { [ ] , # { } , __1 } - end | __Stack]. - --compile({inline,yeccpars2_9_/1}). --file("src/cf_parse.yrl", 41). -yeccpars2_9_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - { [ ] , __1 , # { } } - end | __Stack]. - --compile({inline,yeccpars2_13_/1}). --file("src/cf_parse.yrl", 63). -yeccpars2_13_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - mk_var ( __1 ) - end | __Stack]. - --compile({inline,yeccpars2_14_/1}). --file("src/cf_parse.yrl", 61). -yeccpars2_14_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - mk_str ( __1 ) - end | __Stack]. - --compile({inline,yeccpars2_15_/1}). --file("src/cf_parse.yrl", 58). -yeccpars2_15_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - [ ] - end | __Stack]. - --compile({inline,yeccpars2_16_/1}). --file("src/cf_parse.yrl", 62). -yeccpars2_16_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - mk_str ( __1 ) - end | __Stack]. - --compile({inline,yeccpars2_21_/1}). --file("src/cf_parse.yrl", 73). -yeccpars2_21_(__Stack0) -> - [__3,__2,__1 | __Stack] = __Stack0, - [begin - { app , get_line ( __1 ) , 1 , mk_var ( __1 ) , # { } } - end | __Stack]. - --compile({inline,yeccpars2_24_/1}). --file("src/cf_parse.yrl", 76). -yeccpars2_24_(__Stack0) -> - [__3,__2,__1 | __Stack] = __Stack0, - [begin - mk_binding ( __1 , __3 ) - end | __Stack]. - --compile({inline,yeccpars2_26_/1}). --file("src/cf_parse.yrl", 79). -yeccpars2_26_(__Stack0) -> - [__3,__2,__1 | __Stack] = __Stack0, - [begin - maps : merge ( __1 , __3 ) - end | __Stack]. - --compile({inline,yeccpars2_27_/1}). --file("src/cf_parse.yrl", 74). -yeccpars2_27_(__Stack0) -> - [__4,__3,__2,__1 | __Stack] = __Stack0, - [begin - { app , get_line ( __1 ) , 1 , mk_var ( __1 ) , __3 } - end | __Stack]. - --compile({inline,yeccpars2_32_/1}). --file("src/cf_parse.yrl", 93). -yeccpars2_32_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - [ __1 ] - end | __Stack]. - --compile({inline,yeccpars2_33_/1}). --file("src/cf_parse.yrl", 90). -yeccpars2_33_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - { param , __1 , false } - end | __Stack]. - --compile({inline,yeccpars2_34_/1}). --file("src/cf_parse.yrl", 96). -yeccpars2_34_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - { name , get_name ( __1 ) , false } - end | __Stack]. - --compile({inline,yeccpars2_37_/1}). --file("src/cf_parse.yrl", 91). -yeccpars2_37_(__Stack0) -> - [__3,__2,__1 | __Stack] = __Stack0, - [begin - { param , __2 , true } - end | __Stack]. - --compile({inline,yeccpars2_41_/1}). --file("src/cf_parse.yrl", 97). -yeccpars2_41_(__Stack0) -> - [__4,__3,__2,__1 | __Stack] = __Stack0, - [begin - { name , get_name ( __1 ) , false } - end | __Stack]. - --compile({inline,yeccpars2_42_/1}). --file("src/cf_parse.yrl", 98). -yeccpars2_42_(__Stack0) -> - [__4,__3,__2,__1 | __Stack] = __Stack0, - [begin - { name , get_name ( __1 ) , true } - end | __Stack]. - --compile({inline,yeccpars2_43_/1}). --file("src/cf_parse.yrl", 94). -yeccpars2_43_(__Stack0) -> - [__2,__1 | __Stack] = __Stack0, - [begin - [ __1 | __2 ] - end | __Stack]. - --compile({inline,yeccpars2_47_/1}). --file("src/cf_parse.yrl", 87). -yeccpars2_47_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - [ __1 ] - end | __Stack]. - --compile({inline,yeccpars2_49_/1}). --file("src/cf_parse.yrl", 81). -yeccpars2_49_(__Stack0) -> - [__4,__3,__2,__1 | __Stack] = __Stack0, - [begin - { sign , __2 , [ ] } - end | __Stack]. - --compile({inline,yeccpars2_51_/1}). --file("src/cf_parse.yrl", 100). -yeccpars2_51_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - [ __1 ] - end | __Stack]. - --compile({inline,yeccpars2_52_/1}). --file("src/cf_parse.yrl", 101). -yeccpars2_52_(__Stack0) -> - [__2,__1 | __Stack] = __Stack0, - [begin - [ __1 | __2 ] - end | __Stack]. - --compile({inline,yeccpars2_53_/1}). --file("src/cf_parse.yrl", 85). -yeccpars2_53_(__Stack0) -> - [__3,__2,__1 | __Stack] = __Stack0, - [begin - { correl , __2 } - end | __Stack]. - --compile({inline,yeccpars2_54_/1}). --file("src/cf_parse.yrl", 88). -yeccpars2_54_(__Stack0) -> - [__2,__1 | __Stack] = __Stack0, - [begin - [ __1 | __2 ] - end | __Stack]. - --compile({inline,yeccpars2_55_/1}). --file("src/cf_parse.yrl", 82). -yeccpars2_55_(__Stack0) -> - [__5,__4,__3,__2,__1 | __Stack] = __Stack0, - [begin - { sign , __2 , __4 } - end | __Stack]. - --compile({inline,yeccpars2_61_/1}). --file("src/cf_parse.yrl", 49). -yeccpars2_61_(__Stack0) -> - [__2,__1 | __Stack] = __Stack0, - [begin - maps : merge ( __1 , __2 ) - end | __Stack]. - --compile({inline,yeccpars2_62_/1}). --file("src/cf_parse.yrl", 51). -yeccpars2_62_(__Stack0) -> - [__6,__5,__4,__3,__2,__1 | __Stack] = __Stack0, - [begin - mk_natlam ( __1 , __2 , __3 , __5 ) - end | __Stack]. - --compile({inline,yeccpars2_65_/1}). --file("src/cf_parse.yrl", 46). -yeccpars2_65_(__Stack0) -> - [__4,__3,__2,__1 | __Stack] = __Stack0, - [begin - mk_assign ( __1 , __3 , 1 ) - end | __Stack]. - --compile({inline,yeccpars2_67_/1}). --file("src/cf_parse.yrl", 54). -yeccpars2_67_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - bash - end | __Stack]. - --compile({inline,yeccpars2_68_/1}). --file("src/cf_parse.yrl", 55). -yeccpars2_68_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - python - end | __Stack]. - --compile({inline,yeccpars2_69_/1}). --file("src/cf_parse.yrl", 56). -yeccpars2_69_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - r - end | __Stack]. - --compile({inline,yeccpars2_70_/1}). --file("src/cf_parse.yrl", 52). -yeccpars2_70_(__Stack0) -> - [__6,__5,__4,__3,__2,__1 | __Stack] = __Stack0, - [begin - mk_forlam ( __1 , __2 , __3 , __5 , __6 ) - end | __Stack]. - --compile({inline,yeccpars2_76_/1}). --file("src/cf_parse.yrl", 71). -yeccpars2_76_(__Stack0) -> - [__7,__6,__5,__4,__3,__2,__1 | __Stack] = __Stack0, - [begin - { cnd , get_line ( __1 ) , __2 , __4 , __6 } - end | __Stack]. - --compile({inline,yeccpars2_77_/1}). --file("src/cf_parse.yrl", 44). -yeccpars2_77_(__Stack0) -> - [__2,__1 | __Stack] = __Stack0, - [begin - __1 - end | __Stack]. - --compile({inline,yeccpars2_78_/1}). --file("src/cf_parse.yrl", 68). -yeccpars2_78_(__Stack0) -> - [__2,__1 | __Stack] = __Stack0, - [begin - [ __1 | __2 ] - end | __Stack]. - --compile({inline,yeccpars2_79_/1}). --file("src/cf_parse.yrl", 38). -yeccpars2_79_(__Stack0) -> - [__2,__1 | __Stack] = __Stack0, - [begin - combine ( __1 , __2 ) - end | __Stack]. - - --file("src/cf_parse.yrl", 305). diff --git a/src/cf_parse.yrl b/src/cf_parse.yrl index 12d2702..3bf02db 100644 --- a/src/cf_parse.yrl +++ b/src/cf_parse.yrl @@ -71,11 +71,11 @@ expr -> app : '$1'. exprlist -> expr : ['$1']. exprlist -> expr exprlist : ['$1'|'$2']. -cnd -> beginif compoundexpr then compoundexpr else - compoundexpr endif : {cnd, get_line( '$1' ), '$2', '$4', '$6'}. +cnd -> beginif compoundexpr then compoundexpr + else compoundexpr endif : {cnd, get_line( '$1' ), '$2', '$4', '$6'}. -app -> id lparen rparen : {app, get_line( '$1' ), 1, mk_var( '$1' ), #{}}. -app -> id lparen bindinglist rparen : {app, get_line( '$1' ), 1, mk_var( '$1' ), '$3'}. +app -> id lparen rparen : {app, get_line( '$1' ), 1, mk_var( '$1' ), #{}}. +app -> id lparen bindinglist rparen : {app, get_line( '$1' ), 1, mk_var( '$1' ), '$3'}. binding -> id colon compoundexpr : mk_binding( '$1', '$3' ). @@ -85,8 +85,8 @@ bindinglist -> binding comma bindinglist : maps:merge( '$1', '$3' ). sign -> lparen paramlist colon rparen : {sign, '$2', []}. sign -> lparen paramlist colon inparamlist rparen : {sign, '$2', '$4'}. -inparam -> param : '$1'. -inparam -> lsquarebr namelist rsquarebr : {correl, '$2'}. +inparam -> param : '$1'. +inparam -> lsquarebr namelist rsquarebr : {correl, '$2'}. inparamlist -> inparam : ['$1']. inparamlist -> inparam inparamlist : ['$1'|'$2']. @@ -253,10 +253,6 @@ sign_with_inparam_should_be_recognized_test() -> {forbody, python, "(defparameter out \"A\")"}}}}, string( "deftask f( out : a b )in python *{(defparameter out \"A\")}*" ) )]. -%% ============================================================================= -%% Failing Tests -%% ============================================================================= - param_should_be_recognized_test() -> [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], diff --git a/src/cf_scan.erl b/src/cf_scan.erl deleted file mode 100644 index 9eb1182..0000000 --- a/src/cf_scan.erl +++ /dev/null @@ -1,1676 +0,0 @@ --file("/usr/local/lib/erlang/lib/parsetools-2.1.1/include/leexinc.hrl", 0). -%% The source of this file is part of leex distribution, as such it -%% has the same Copyright as the other files in the leex -%% distribution. The Copyright is defined in the accompanying file -%% COPYRIGHT. However, the resultant scanner generated by leex is the -%% property of the creator of the scanner and is not covered by that -%% Copyright. - --module(cf_scan). - --export([string/1,string/2,token/2,token/3,tokens/2,tokens/3]). --export([format_error/1]). - -%% User code. This is placed here to allow extra attributes. --file("src/cf_scan.xrl", 114). - --author( "Jorgen Brandt " ). - --export( [yyrev/2] ). - --ifdef( TEST ). --include_lib( "eunit/include/eunit.hrl" ). --endif. - -trim_body( S ) -> - string:substr( S, 3, length( S )-4 ). - -trim_strlit( S ) -> - string:substr( S, 2, length( S )-2 ). - - - -%% ============================================================================= -%% Unit Tests -%% ============================================================================= - - --ifdef( TEST ). - - - -bash_style_comment_should_be_recognized_test() -> - ?assertEqual( {ok, [], 1}, string( "#this is a comment" ) ). - -c_style_comment_should_be_recognized_test() -> - ?assertEqual( {ok, [], 1}, string( "//this is a comment" ) ). - -erlang_style_comment_should_be_recognized_test() -> - ?assertEqual( {ok, [], 1}, string( "%this is a comment" ) ). - - -multiline_comment_should_be_recognized_test() -> - [?assertEqual( {ok, [], 1}, string( "/**/" ) ), - ?assertEqual( {ok, [], 1}, string( "/*x*/" ) ), - ?assertEqual( {ok, [], 1}, string( "/*xy*/" ) ), - ?assertEqual( {ok, [], 2}, string( "/*x\ny*/" ) )]. - -bash_should_be_recognized_test() -> - ?assertEqual( {ok, [{bash, 1, "bash"}], 1}, string( "bash" ) ). - -beginif_should_be_recognized_test() -> - ?assertEqual( {ok, [{beginif, 1, "if"}], 1}, string( "if" ) ). - -colon_should_be_recognized_test() -> - ?assertEqual( {ok, [{colon, 1, ":"}], 1}, string( ":" ) ). - -deftask_should_be_recognized_test() -> - ?assertEqual( {ok, [{deftask, 1, "deftask"}], 1}, string( "deftask" ) ). - -else_should_be_recognized_test() -> - ?assertEqual( {ok, [{else, 1, "else"}], 1}, string( "else" ) ). - -endif_should_be_recognized_test() -> - ?assertEqual( {ok, [{endif, 1, "end"}], 1}, string( "end" ) ). - -eq_should_be_recognized_test() -> - ?assertEqual( {ok, [{eq, 1, "="}], 1}, string( "=" ) ). - -file_should_be_recognized_test() -> - ?assertEqual( {ok, [{file, 1, "File"}], 1}, string( "File" ) ). - -in_should_be_recognized_test() -> - ?assertEqual( {ok, [{in, 1, "in"}], 1}, string( "in" ) ). - -id_should_be_recognized_test() -> - [?assertEqual( {ok, [{id, 1, "inp"}], 1}, string( "inp" ) ), - ?assertEqual( {ok, [{id, 1, "a0"}], 1}, string( "a0" ) ), - ?assertEqual( {ok, [{id, 1, "a9"}], 1}, string( "a9" ) ), - ?assertEqual( {ok, [{id, 1, "a."}], 1}, string( "a." ) ), - ?assertEqual( {ok, [{id, 1, "a-"}], 1}, string( "a-" ) ), - ?assertEqual( {ok, [{id, 1, "a_"}], 1}, string( "a_" ) )]. - -python_should_be_recognized_test() -> - ?assertEqual( {ok, [{python, 1, "python"}], 1}, string( "python" ) ). - -r_should_be_recognized_test() -> - [?assertEqual( {ok, [{r, 1, "r"}], 1}, string( "r" ) ), - ?assertEqual( {ok, [{r, 1, "R"}], 1}, string( "R" ) )]. - -lbrace_should_be_recognized_test() -> - ?assertEqual( {ok, [{lbrace, 1, "{"}], 1}, string( "{" ) ). - -lparen_should_be_recognized_test() -> - ?assertEqual( {ok, [{lparen, 1, "("}], 1}, string( "(" ) ). - -lsquarebr_should_be_recognized_test() -> - ?assertEqual( {ok, [{lsquarebr, 1, "["}], 1}, string( "[" ) ). - -ltag_should_be_recognized_test() -> - ?assertEqual( {ok, [{ltag, 1, "<"}], 1}, string( "<" ) ). - -nil_should_be_recognized_test() -> - ?assertEqual( {ok, [{nil, 1, "nil"}], 1}, string( "nil" ) ). - -rbrace_should_be_recognized_test() -> - ?assertEqual( {ok, [{rbrace, 1, "}"}], 1}, string( "}" ) ). - -rparen_should_be_recognized_test() -> - ?assertEqual( {ok, [{rparen, 1, ")"}], 1}, string( ")" ) ). - -rsquarebr_should_be_recognized_test() -> - ?assertEqual( {ok, [{rsquarebr, 1, "]"}], 1}, string( "]" ) ). - -rtag_should_be_recognized_test() -> - ?assertEqual( {ok, [{rtag, 1, ">"}], 1}, string( ">" ) ). - -semicolon_should_be_recognized_test() -> - ?assertEqual( {ok, [{semicolon, 1, ";"}], 1}, string( ";" ) ). - -string_should_be_recognized_test() -> - ?assertEqual( {ok, [{string, 1, "String"}], 1}, string( "String" ) ). - -then_should_be_recognized_test() -> - ?assertEqual( {ok, [{then, 1, "then"}], 1}, string( "then" ) ). - -intlit_should_be_recognized_test() -> - [?assertEqual( {ok, [{intlit, 1, "10"}], 1}, string( "10" ) ), - ?assertEqual( {ok, [{intlit, 1, "-10"}], 1}, string( "-10" ) ), - ?assertEqual( {ok, [{intlit, 1, "9"}], 1}, string( "9" ) ), - ?assertEqual( {ok, [{intlit, 1, "0"}], 1}, string( "0" ) )]. - -body_should_be_recognized_test() -> - [?assertEqual( {ok, [{body, 1, ""}], 1}, string( "*{}*" ) ), - ?assertEqual( {ok, [{body, 1, "x"}], 1}, string( "*{x}*" ) ), - ?assertEqual( {ok, [{body, 1, "xy"}], 1}, string( "*{xy}*" ) ), - ?assertEqual( {ok, [{body, 1, "x\ny"}], 2}, string( "*{x\ny}*" ) )]. - -strlit_should_be_recognized_test() -> - [?assertEqual( {ok, [{strlit, 1, ""}], 1}, string( "\"\"" ) ), - ?assertEqual( {ok, [{strlit, 1, "x"}], 1}, string( "\"x\"" ) ), - ?assertEqual( {ok, [{strlit, 1, "xy"}], 1}, string( "\"xy\"" ) )]. - - - - - --endif. - - - --file("/usr/local/lib/erlang/lib/parsetools-2.1.1/include/leexinc.hrl", 14). - -format_error({illegal,S}) -> ["illegal characters ",io_lib:write_string(S)]; -format_error({user,S}) -> S. - -string(String) -> string(String, 1). - -string(String, Line) -> string(String, Line, String, []). - -%% string(InChars, Line, TokenChars, Tokens) -> -%% {ok,Tokens,Line} | {error,ErrorInfo,Line}. -%% Note the line number going into yystate, L0, is line of token -%% start while line number returned is line of token end. We want line -%% of token start. - -string([], L, [], Ts) -> % No partial tokens! - {ok,yyrev(Ts),L}; -string(Ics0, L0, Tcs, Ts) -> - case yystate(yystate(), Ics0, L0, 0, reject, 0) of - {A,Alen,Ics1,L1} -> % Accepting end state - string_cont(Ics1, L1, yyaction(A, Alen, Tcs, L0), Ts); - {A,Alen,Ics1,L1,_S1} -> % Accepting transistion state - string_cont(Ics1, L1, yyaction(A, Alen, Tcs, L0), Ts); - {reject,_Alen,Tlen,_Ics1,L1,_S1} -> % After a non-accepting state - {error,{L0,?MODULE,{illegal,yypre(Tcs, Tlen+1)}},L1}; - {A,Alen,_Tlen,_Ics1,_L1,_S1} -> - string_cont(yysuf(Tcs, Alen), L0, yyaction(A, Alen, Tcs, L0), Ts) - end. - -%% string_cont(RestChars, Line, Token, Tokens) -%% Test for and remove the end token wrapper. Push back characters -%% are prepended to RestChars. - --dialyzer({nowarn_function, string_cont/4}). - -string_cont(Rest, Line, {token,T}, Ts) -> - string(Rest, Line, Rest, [T|Ts]); -string_cont(Rest, Line, {token,T,Push}, Ts) -> - NewRest = Push ++ Rest, - string(NewRest, Line, NewRest, [T|Ts]); -string_cont(Rest, Line, {end_token,T}, Ts) -> - string(Rest, Line, Rest, [T|Ts]); -string_cont(Rest, Line, {end_token,T,Push}, Ts) -> - NewRest = Push ++ Rest, - string(NewRest, Line, NewRest, [T|Ts]); -string_cont(Rest, Line, skip_token, Ts) -> - string(Rest, Line, Rest, Ts); -string_cont(Rest, Line, {skip_token,Push}, Ts) -> - NewRest = Push ++ Rest, - string(NewRest, Line, NewRest, Ts); -string_cont(_Rest, Line, {error,S}, _Ts) -> - {error,{Line,?MODULE,{user,S}},Line}. - -%% token(Continuation, Chars) -> -%% token(Continuation, Chars, Line) -> -%% {more,Continuation} | {done,ReturnVal,RestChars}. -%% Must be careful when re-entering to append the latest characters to the -%% after characters in an accept. The continuation is: -%% {token,State,CurrLine,TokenChars,TokenLen,TokenLine,AccAction,AccLen} - -token(Cont, Chars) -> token(Cont, Chars, 1). - -token([], Chars, Line) -> - token(yystate(), Chars, Line, Chars, 0, Line, reject, 0); -token({token,State,Line,Tcs,Tlen,Tline,Action,Alen}, Chars, _) -> - token(State, Chars, Line, Tcs ++ Chars, Tlen, Tline, Action, Alen). - -%% token(State, InChars, Line, TokenChars, TokenLen, TokenLine, -%% AcceptAction, AcceptLen) -> -%% {more,Continuation} | {done,ReturnVal,RestChars}. -%% The argument order is chosen to be more efficient. - -token(S0, Ics0, L0, Tcs, Tlen0, Tline, A0, Alen0) -> - case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of - %% Accepting end state, we have a token. - {A1,Alen1,Ics1,L1} -> - token_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline)); - %% Accepting transition state, can take more chars. - {A1,Alen1,[],L1,S1} -> % Need more chars to check - {more,{token,S1,L1,Tcs,Alen1,Tline,A1,Alen1}}; - {A1,Alen1,Ics1,L1,_S1} -> % Take what we got - token_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline)); - %% After a non-accepting state, maybe reach accept state later. - {A1,Alen1,Tlen1,[],L1,S1} -> % Need more chars to check - {more,{token,S1,L1,Tcs,Tlen1,Tline,A1,Alen1}}; - {reject,_Alen1,Tlen1,eof,L1,_S1} -> % No token match - %% Check for partial token which is error. - Ret = if Tlen1 > 0 -> {error,{Tline,?MODULE, - %% Skip eof tail in Tcs. - {illegal,yypre(Tcs, Tlen1)}},L1}; - true -> {eof,L1} - end, - {done,Ret,eof}; - {reject,_Alen1,Tlen1,Ics1,L1,_S1} -> % No token match - Error = {Tline,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}}, - {done,{error,Error,L1},Ics1}; - {A1,Alen1,_Tlen1,_Ics1,_L1,_S1} -> % Use last accept match - token_cont(yysuf(Tcs, Alen1), L0, yyaction(A1, Alen1, Tcs, Tline)) - end. - -%% token_cont(RestChars, Line, Token) -%% If we have a token or error then return done, else if we have a -%% skip_token then continue. - --dialyzer({nowarn_function, token_cont/3}). - -token_cont(Rest, Line, {token,T}) -> - {done,{ok,T,Line},Rest}; -token_cont(Rest, Line, {token,T,Push}) -> - NewRest = Push ++ Rest, - {done,{ok,T,Line},NewRest}; -token_cont(Rest, Line, {end_token,T}) -> - {done,{ok,T,Line},Rest}; -token_cont(Rest, Line, {end_token,T,Push}) -> - NewRest = Push ++ Rest, - {done,{ok,T,Line},NewRest}; -token_cont(Rest, Line, skip_token) -> - token(yystate(), Rest, Line, Rest, 0, Line, reject, 0); -token_cont(Rest, Line, {skip_token,Push}) -> - NewRest = Push ++ Rest, - token(yystate(), NewRest, Line, NewRest, 0, Line, reject, 0); -token_cont(Rest, Line, {error,S}) -> - {done,{error,{Line,?MODULE,{user,S}},Line},Rest}. - -%% tokens(Continuation, Chars, Line) -> -%% {more,Continuation} | {done,ReturnVal,RestChars}. -%% Must be careful when re-entering to append the latest characters to the -%% after characters in an accept. The continuation is: -%% {tokens,State,CurrLine,TokenChars,TokenLen,TokenLine,Tokens,AccAction,AccLen} -%% {skip_tokens,State,CurrLine,TokenChars,TokenLen,TokenLine,Error,AccAction,AccLen} - -tokens(Cont, Chars) -> tokens(Cont, Chars, 1). - -tokens([], Chars, Line) -> - tokens(yystate(), Chars, Line, Chars, 0, Line, [], reject, 0); -tokens({tokens,State,Line,Tcs,Tlen,Tline,Ts,Action,Alen}, Chars, _) -> - tokens(State, Chars, Line, Tcs ++ Chars, Tlen, Tline, Ts, Action, Alen); -tokens({skip_tokens,State,Line,Tcs,Tlen,Tline,Error,Action,Alen}, Chars, _) -> - skip_tokens(State, Chars, Line, Tcs ++ Chars, Tlen, Tline, Error, Action, Alen). - -%% tokens(State, InChars, Line, TokenChars, TokenLen, TokenLine, Tokens, -%% AcceptAction, AcceptLen) -> -%% {more,Continuation} | {done,ReturnVal,RestChars}. - -tokens(S0, Ics0, L0, Tcs, Tlen0, Tline, Ts, A0, Alen0) -> - case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of - %% Accepting end state, we have a token. - {A1,Alen1,Ics1,L1} -> - tokens_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Ts); - %% Accepting transition state, can take more chars. - {A1,Alen1,[],L1,S1} -> % Need more chars to check - {more,{tokens,S1,L1,Tcs,Alen1,Tline,Ts,A1,Alen1}}; - {A1,Alen1,Ics1,L1,_S1} -> % Take what we got - tokens_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Ts); - %% After a non-accepting state, maybe reach accept state later. - {A1,Alen1,Tlen1,[],L1,S1} -> % Need more chars to check - {more,{tokens,S1,L1,Tcs,Tlen1,Tline,Ts,A1,Alen1}}; - {reject,_Alen1,Tlen1,eof,L1,_S1} -> % No token match - %% Check for partial token which is error, no need to skip here. - Ret = if Tlen1 > 0 -> {error,{Tline,?MODULE, - %% Skip eof tail in Tcs. - {illegal,yypre(Tcs, Tlen1)}},L1}; - Ts == [] -> {eof,L1}; - true -> {ok,yyrev(Ts),L1} - end, - {done,Ret,eof}; - {reject,_Alen1,Tlen1,_Ics1,L1,_S1} -> - %% Skip rest of tokens. - Error = {L1,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}}, - skip_tokens(yysuf(Tcs, Tlen1+1), L1, Error); - {A1,Alen1,_Tlen1,_Ics1,_L1,_S1} -> - Token = yyaction(A1, Alen1, Tcs, Tline), - tokens_cont(yysuf(Tcs, Alen1), L0, Token, Ts) - end. - -%% tokens_cont(RestChars, Line, Token, Tokens) -%% If we have an end_token or error then return done, else if we have -%% a token then save it and continue, else if we have a skip_token -%% just continue. - --dialyzer({nowarn_function, tokens_cont/4}). - -tokens_cont(Rest, Line, {token,T}, Ts) -> - tokens(yystate(), Rest, Line, Rest, 0, Line, [T|Ts], reject, 0); -tokens_cont(Rest, Line, {token,T,Push}, Ts) -> - NewRest = Push ++ Rest, - tokens(yystate(), NewRest, Line, NewRest, 0, Line, [T|Ts], reject, 0); -tokens_cont(Rest, Line, {end_token,T}, Ts) -> - {done,{ok,yyrev(Ts, [T]),Line},Rest}; -tokens_cont(Rest, Line, {end_token,T,Push}, Ts) -> - NewRest = Push ++ Rest, - {done,{ok,yyrev(Ts, [T]),Line},NewRest}; -tokens_cont(Rest, Line, skip_token, Ts) -> - tokens(yystate(), Rest, Line, Rest, 0, Line, Ts, reject, 0); -tokens_cont(Rest, Line, {skip_token,Push}, Ts) -> - NewRest = Push ++ Rest, - tokens(yystate(), NewRest, Line, NewRest, 0, Line, Ts, reject, 0); -tokens_cont(Rest, Line, {error,S}, _Ts) -> - skip_tokens(Rest, Line, {Line,?MODULE,{user,S}}). - -%%skip_tokens(InChars, Line, Error) -> {done,{error,Error,Line},Ics}. -%% Skip tokens until an end token, junk everything and return the error. - -skip_tokens(Ics, Line, Error) -> - skip_tokens(yystate(), Ics, Line, Ics, 0, Line, Error, reject, 0). - -%% skip_tokens(State, InChars, Line, TokenChars, TokenLen, TokenLine, Tokens, -%% AcceptAction, AcceptLen) -> -%% {more,Continuation} | {done,ReturnVal,RestChars}. - -skip_tokens(S0, Ics0, L0, Tcs, Tlen0, Tline, Error, A0, Alen0) -> - case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of - {A1,Alen1,Ics1,L1} -> % Accepting end state - skip_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Error); - {A1,Alen1,[],L1,S1} -> % After an accepting state - {more,{skip_tokens,S1,L1,Tcs,Alen1,Tline,Error,A1,Alen1}}; - {A1,Alen1,Ics1,L1,_S1} -> - skip_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Error); - {A1,Alen1,Tlen1,[],L1,S1} -> % After a non-accepting state - {more,{skip_tokens,S1,L1,Tcs,Tlen1,Tline,Error,A1,Alen1}}; - {reject,_Alen1,_Tlen1,eof,L1,_S1} -> - {done,{error,Error,L1},eof}; - {reject,_Alen1,Tlen1,_Ics1,L1,_S1} -> - skip_tokens(yysuf(Tcs, Tlen1+1), L1, Error); - {A1,Alen1,_Tlen1,_Ics1,L1,_S1} -> - Token = yyaction(A1, Alen1, Tcs, Tline), - skip_cont(yysuf(Tcs, Alen1), L1, Token, Error) - end. - -%% skip_cont(RestChars, Line, Token, Error) -%% Skip tokens until we have an end_token or error then return done -%% with the original rror. - --dialyzer({nowarn_function, skip_cont/4}). - -skip_cont(Rest, Line, {token,_T}, Error) -> - skip_tokens(yystate(), Rest, Line, Rest, 0, Line, Error, reject, 0); -skip_cont(Rest, Line, {token,_T,Push}, Error) -> - NewRest = Push ++ Rest, - skip_tokens(yystate(), NewRest, Line, NewRest, 0, Line, Error, reject, 0); -skip_cont(Rest, Line, {end_token,_T}, Error) -> - {done,{error,Error,Line},Rest}; -skip_cont(Rest, Line, {end_token,_T,Push}, Error) -> - NewRest = Push ++ Rest, - {done,{error,Error,Line},NewRest}; -skip_cont(Rest, Line, skip_token, Error) -> - skip_tokens(yystate(), Rest, Line, Rest, 0, Line, Error, reject, 0); -skip_cont(Rest, Line, {skip_token,Push}, Error) -> - NewRest = Push ++ Rest, - skip_tokens(yystate(), NewRest, Line, NewRest, 0, Line, Error, reject, 0); -skip_cont(Rest, Line, {error,_S}, Error) -> - skip_tokens(yystate(), Rest, Line, Rest, 0, Line, Error, reject, 0). - -yyrev(List) -> lists:reverse(List). -yyrev(List, Tail) -> lists:reverse(List, Tail). -yypre(List, N) -> lists:sublist(List, N). -yysuf(List, N) -> lists:nthtail(N, List). - -%% yystate() -> InitialState. -%% yystate(State, InChars, Line, CurrTokLen, AcceptAction, AcceptLen) -> -%% {Action, AcceptLen, RestChars, Line} | -%% {Action, AcceptLen, RestChars, Line, State} | -%% {reject, AcceptLen, CurrTokLen, RestChars, Line, State} | -%% {Action, AcceptLen, CurrTokLen, RestChars, Line, State}. -%% Generated state transition functions. The non-accepting end state -%% return signal either an unrecognised character or end of current -%% input. - --file("src/cf_scan.erl", 428). -yystate() -> 69. - -yystate(72, [122|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(72, [121|Ics], Line, Tlen, _, _) -> - yystate(68, Ics, Line, Tlen+1, 27, Tlen); -yystate(72, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(72, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(72, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(72, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(72, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(72, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 120 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(72, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,72}; -yystate(71, Ics, Line, Tlen, _, _) -> - {30,Tlen,Ics,Line}; -yystate(70, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 2, Tlen); -yystate(70, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 2, Tlen); -yystate(70, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 2, Tlen); -yystate(70, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 2, Tlen); -yystate(70, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 2, Tlen); -yystate(70, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 2, Tlen); -yystate(70, Ics, Line, Tlen, _, _) -> - {2,Tlen,Ics,Line,70}; -yystate(69, [125|Ics], Line, Tlen, Action, Alen) -> - yystate(65, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [123|Ics], Line, Tlen, Action, Alen) -> - yystate(61, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [116|Ics], Line, Tlen, Action, Alen) -> - yystate(57, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [115|Ics], Line, Tlen, Action, Alen) -> - yystate(41, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [114|Ics], Line, Tlen, Action, Alen) -> - yystate(70, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [113|Ics], Line, Tlen, Action, Alen) -> - yystate(41, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [112|Ics], Line, Tlen, Action, Alen) -> - yystate(72, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [111|Ics], Line, Tlen, Action, Alen) -> - yystate(41, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [110|Ics], Line, Tlen, Action, Alen) -> - yystate(37, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [105|Ics], Line, Tlen, Action, Alen) -> - yystate(25, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [101|Ics], Line, Tlen, Action, Alen) -> - yystate(13, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [100|Ics], Line, Tlen, Action, Alen) -> - yystate(10, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [99|Ics], Line, Tlen, Action, Alen) -> - yystate(41, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [98|Ics], Line, Tlen, Action, Alen) -> - yystate(32, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [97|Ics], Line, Tlen, Action, Alen) -> - yystate(41, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [93|Ics], Line, Tlen, Action, Alen) -> - yystate(38, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [91|Ics], Line, Tlen, Action, Alen) -> - yystate(42, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [83|Ics], Line, Tlen, Action, Alen) -> - yystate(46, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [82|Ics], Line, Tlen, Action, Alen) -> - yystate(70, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [81|Ics], Line, Tlen, Action, Alen) -> - yystate(41, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [80|Ics], Line, Tlen, Action, Alen) -> - yystate(72, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [70|Ics], Line, Tlen, Action, Alen) -> - yystate(48, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [66|Ics], Line, Tlen, Action, Alen) -> - yystate(32, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [65|Ics], Line, Tlen, Action, Alen) -> - yystate(41, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [62|Ics], Line, Tlen, Action, Alen) -> - yystate(16, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [61|Ics], Line, Tlen, Action, Alen) -> - yystate(12, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [60|Ics], Line, Tlen, Action, Alen) -> - yystate(8, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [59|Ics], Line, Tlen, Action, Alen) -> - yystate(4, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [58|Ics], Line, Tlen, Action, Alen) -> - yystate(0, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [48|Ics], Line, Tlen, Action, Alen) -> - yystate(7, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [47|Ics], Line, Tlen, Action, Alen) -> - yystate(11, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [45|Ics], Line, Tlen, Action, Alen) -> - yystate(27, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [44|Ics], Line, Tlen, Action, Alen) -> - yystate(31, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [42|Ics], Line, Tlen, Action, Alen) -> - yystate(35, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [41|Ics], Line, Tlen, Action, Alen) -> - yystate(51, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [40|Ics], Line, Tlen, Action, Alen) -> - yystate(55, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [37|Ics], Line, Tlen, Action, Alen) -> - yystate(59, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [35|Ics], Line, Tlen, Action, Alen) -> - yystate(59, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [34|Ics], Line, Tlen, Action, Alen) -> - yystate(67, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [10|Ics], Line, Tlen, Action, Alen) -> - yystate(71, Ics, Line+1, Tlen+1, Action, Alen); -yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 0, C =< 9 -> - yystate(71, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 11, C =< 32 -> - yystate(71, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 49, C =< 57 -> - yystate(3, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 67, C =< 69 -> - yystate(41, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 71, C =< 79 -> - yystate(41, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 84, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 102, C =< 104 -> - yystate(41, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 106, C =< 109 -> - yystate(41, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 117, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, Action, Alen); -yystate(69, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,69}; -yystate(68, [116|Ics], Line, Tlen, _, _) -> - yystate(64, Ics, Line, Tlen+1, 27, Tlen); -yystate(68, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(68, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(68, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(68, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(68, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(68, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 115 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(68, [C|Ics], Line, Tlen, _, _) when C >= 117, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(68, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,68}; -yystate(67, [34|Ics], Line, Tlen, Action, Alen) -> - yystate(63, Ics, Line, Tlen+1, Action, Alen); -yystate(67, [10|Ics], Line, Tlen, Action, Alen) -> - yystate(67, Ics, Line+1, Tlen+1, Action, Alen); -yystate(67, [C|Ics], Line, Tlen, Action, Alen) when C >= 0, C =< 9 -> - yystate(67, Ics, Line, Tlen+1, Action, Alen); -yystate(67, [C|Ics], Line, Tlen, Action, Alen) when C >= 11, C =< 33 -> - yystate(67, Ics, Line, Tlen+1, Action, Alen); -yystate(67, [C|Ics], Line, Tlen, Action, Alen) when C >= 35 -> - yystate(67, Ics, Line, Tlen+1, Action, Alen); -yystate(67, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,67}; -yystate(66, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 25, Tlen); -yystate(66, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 25, Tlen); -yystate(66, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 25, Tlen); -yystate(66, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 25, Tlen); -yystate(66, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 25, Tlen); -yystate(66, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 25, Tlen); -yystate(66, Ics, Line, Tlen, _, _) -> - {25,Tlen,Ics,Line,66}; -yystate(65, Ics, Line, Tlen, _, _) -> - {20,Tlen,Ics,Line}; -yystate(64, [104|Ics], Line, Tlen, _, _) -> - yystate(60, Ics, Line, Tlen+1, 27, Tlen); -yystate(64, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(64, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(64, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(64, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(64, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(64, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 103 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(64, [C|Ics], Line, Tlen, _, _) when C >= 105, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(64, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,64}; -yystate(63, Ics, Line, Tlen, _, _) -> - {4,Tlen,Ics,Line}; -yystate(62, [103|Ics], Line, Tlen, _, _) -> - yystate(66, Ics, Line, Tlen+1, 27, Tlen); -yystate(62, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(62, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(62, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(62, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(62, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(62, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 102 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(62, [C|Ics], Line, Tlen, _, _) when C >= 104, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(62, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,62}; -yystate(61, Ics, Line, Tlen, _, _) -> - {15,Tlen,Ics,Line}; -yystate(60, [111|Ics], Line, Tlen, _, _) -> - yystate(56, Ics, Line, Tlen+1, 27, Tlen); -yystate(60, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(60, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(60, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(60, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(60, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(60, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 110 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(60, [C|Ics], Line, Tlen, _, _) when C >= 112, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(60, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,60}; -yystate(59, [C|Ics], Line, Tlen, _, _) when C >= 0, C =< 9 -> - yystate(59, Ics, Line, Tlen+1, 28, Tlen); -yystate(59, [C|Ics], Line, Tlen, _, _) when C >= 11 -> - yystate(59, Ics, Line, Tlen+1, 28, Tlen); -yystate(59, Ics, Line, Tlen, _, _) -> - {28,Tlen,Ics,Line,59}; -yystate(58, [110|Ics], Line, Tlen, _, _) -> - yystate(62, Ics, Line, Tlen+1, 27, Tlen); -yystate(58, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(58, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(58, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(58, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(58, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(58, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 109 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(58, [C|Ics], Line, Tlen, _, _) when C >= 111, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(58, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,58}; -yystate(57, [104|Ics], Line, Tlen, _, _) -> - yystate(53, Ics, Line, Tlen+1, 27, Tlen); -yystate(57, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(57, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(57, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(57, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(57, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(57, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 103 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(57, [C|Ics], Line, Tlen, _, _) when C >= 105, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(57, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,57}; -yystate(56, [110|Ics], Line, Tlen, _, _) -> - yystate(52, Ics, Line, Tlen+1, 27, Tlen); -yystate(56, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(56, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(56, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(56, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(56, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(56, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 109 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(56, [C|Ics], Line, Tlen, _, _) when C >= 111, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(56, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,56}; -yystate(55, Ics, Line, Tlen, _, _) -> - {16,Tlen,Ics,Line}; -yystate(54, [105|Ics], Line, Tlen, _, _) -> - yystate(58, Ics, Line, Tlen+1, 27, Tlen); -yystate(54, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(54, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(54, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(54, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(54, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(54, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 104 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(54, [C|Ics], Line, Tlen, _, _) when C >= 106, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(54, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,54}; -yystate(53, [101|Ics], Line, Tlen, _, _) -> - yystate(49, Ics, Line, Tlen+1, 27, Tlen); -yystate(53, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(53, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(53, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(53, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(53, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(53, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 100 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(53, [C|Ics], Line, Tlen, _, _) when C >= 102, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(53, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,53}; -yystate(52, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 1, Tlen); -yystate(52, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 1, Tlen); -yystate(52, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 1, Tlen); -yystate(52, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 1, Tlen); -yystate(52, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 1, Tlen); -yystate(52, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 1, Tlen); -yystate(52, Ics, Line, Tlen, _, _) -> - {1,Tlen,Ics,Line,52}; -yystate(51, Ics, Line, Tlen, _, _) -> - {21,Tlen,Ics,Line}; -yystate(50, [114|Ics], Line, Tlen, _, _) -> - yystate(54, Ics, Line, Tlen+1, 27, Tlen); -yystate(50, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(50, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(50, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(50, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(50, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(50, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 113 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(50, [C|Ics], Line, Tlen, _, _) when C >= 115, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(50, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,50}; -yystate(49, [110|Ics], Line, Tlen, _, _) -> - yystate(45, Ics, Line, Tlen+1, 27, Tlen); -yystate(49, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(49, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(49, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(49, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(49, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(49, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 109 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(49, [C|Ics], Line, Tlen, _, _) when C >= 111, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(49, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,49}; -yystate(48, [105|Ics], Line, Tlen, _, _) -> - yystate(44, Ics, Line, Tlen+1, 27, Tlen); -yystate(48, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(48, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(48, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(48, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(48, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(48, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 104 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(48, [C|Ics], Line, Tlen, _, _) when C >= 106, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(48, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,48}; -yystate(47, [125|Ics], Line, Tlen, Action, Alen) -> - yystate(39, Ics, Line, Tlen+1, Action, Alen); -yystate(47, [10|Ics], Line, Tlen, Action, Alen) -> - yystate(47, Ics, Line+1, Tlen+1, Action, Alen); -yystate(47, [C|Ics], Line, Tlen, Action, Alen) when C >= 0, C =< 9 -> - yystate(47, Ics, Line, Tlen+1, Action, Alen); -yystate(47, [C|Ics], Line, Tlen, Action, Alen) when C >= 11, C =< 124 -> - yystate(47, Ics, Line, Tlen+1, Action, Alen); -yystate(47, [C|Ics], Line, Tlen, Action, Alen) when C >= 126 -> - yystate(47, Ics, Line, Tlen+1, Action, Alen); -yystate(47, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,47}; -yystate(46, [116|Ics], Line, Tlen, _, _) -> - yystate(50, Ics, Line, Tlen+1, 27, Tlen); -yystate(46, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(46, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(46, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(46, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(46, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(46, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 115 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(46, [C|Ics], Line, Tlen, _, _) when C >= 117, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(46, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,46}; -yystate(45, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 26, Tlen); -yystate(45, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 26, Tlen); -yystate(45, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 26, Tlen); -yystate(45, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 26, Tlen); -yystate(45, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 26, Tlen); -yystate(45, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 26, Tlen); -yystate(45, Ics, Line, Tlen, _, _) -> - {26,Tlen,Ics,Line,45}; -yystate(44, [108|Ics], Line, Tlen, _, _) -> - yystate(40, Ics, Line, Tlen+1, 27, Tlen); -yystate(44, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(44, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(44, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(44, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(44, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(44, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 107 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(44, [C|Ics], Line, Tlen, _, _) when C >= 109, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(44, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,44}; -yystate(43, Ics, Line, Tlen, _, _) -> - {5,Tlen,Ics,Line}; -yystate(42, Ics, Line, Tlen, _, _) -> - {17,Tlen,Ics,Line}; -yystate(41, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(41, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(41, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(41, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(41, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(41, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(41, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,41}; -yystate(40, [101|Ics], Line, Tlen, _, _) -> - yystate(36, Ics, Line, Tlen+1, 27, Tlen); -yystate(40, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(40, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(40, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(40, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(40, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(40, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 100 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(40, [C|Ics], Line, Tlen, _, _) when C >= 102, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(40, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,40}; -yystate(39, [125|Ics], Line, Tlen, Action, Alen) -> - yystate(39, Ics, Line, Tlen+1, Action, Alen); -yystate(39, [42|Ics], Line, Tlen, Action, Alen) -> - yystate(43, Ics, Line, Tlen+1, Action, Alen); -yystate(39, [10|Ics], Line, Tlen, Action, Alen) -> - yystate(47, Ics, Line+1, Tlen+1, Action, Alen); -yystate(39, [C|Ics], Line, Tlen, Action, Alen) when C >= 0, C =< 9 -> - yystate(47, Ics, Line, Tlen+1, Action, Alen); -yystate(39, [C|Ics], Line, Tlen, Action, Alen) when C >= 11, C =< 41 -> - yystate(47, Ics, Line, Tlen+1, Action, Alen); -yystate(39, [C|Ics], Line, Tlen, Action, Alen) when C >= 43, C =< 124 -> - yystate(47, Ics, Line, Tlen+1, Action, Alen); -yystate(39, [C|Ics], Line, Tlen, Action, Alen) when C >= 126 -> - yystate(47, Ics, Line, Tlen+1, Action, Alen); -yystate(39, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,39}; -yystate(38, Ics, Line, Tlen, _, _) -> - {22,Tlen,Ics,Line}; -yystate(37, [105|Ics], Line, Tlen, _, _) -> - yystate(33, Ics, Line, Tlen+1, 27, Tlen); -yystate(37, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(37, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(37, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(37, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(37, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(37, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 104 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(37, [C|Ics], Line, Tlen, _, _) when C >= 106, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(37, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,37}; -yystate(36, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 13, Tlen); -yystate(36, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 13, Tlen); -yystate(36, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 13, Tlen); -yystate(36, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 13, Tlen); -yystate(36, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 13, Tlen); -yystate(36, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 13, Tlen); -yystate(36, Ics, Line, Tlen, _, _) -> - {13,Tlen,Ics,Line,36}; -yystate(35, [123|Ics], Line, Tlen, Action, Alen) -> - yystate(47, Ics, Line, Tlen+1, Action, Alen); -yystate(35, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,35}; -yystate(34, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 9, Tlen); -yystate(34, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 9, Tlen); -yystate(34, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 9, Tlen); -yystate(34, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 9, Tlen); -yystate(34, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 9, Tlen); -yystate(34, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 9, Tlen); -yystate(34, Ics, Line, Tlen, _, _) -> - {9,Tlen,Ics,Line,34}; -yystate(33, [108|Ics], Line, Tlen, _, _) -> - yystate(29, Ics, Line, Tlen+1, 27, Tlen); -yystate(33, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(33, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(33, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(33, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(33, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(33, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 107 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(33, [C|Ics], Line, Tlen, _, _) when C >= 109, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(33, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,33}; -yystate(32, [97|Ics], Line, Tlen, _, _) -> - yystate(28, Ics, Line, Tlen+1, 27, Tlen); -yystate(32, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(32, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(32, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(32, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(32, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(32, [C|Ics], Line, Tlen, _, _) when C >= 98, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(32, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,32}; -yystate(31, Ics, Line, Tlen, _, _) -> - {8,Tlen,Ics,Line}; -yystate(30, [107|Ics], Line, Tlen, _, _) -> - yystate(34, Ics, Line, Tlen+1, 27, Tlen); -yystate(30, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(30, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(30, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(30, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(30, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(30, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 106 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(30, [C|Ics], Line, Tlen, _, _) when C >= 108, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(30, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,30}; -yystate(29, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 19, Tlen); -yystate(29, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 19, Tlen); -yystate(29, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 19, Tlen); -yystate(29, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 19, Tlen); -yystate(29, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 19, Tlen); -yystate(29, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 19, Tlen); -yystate(29, Ics, Line, Tlen, _, _) -> - {19,Tlen,Ics,Line,29}; -yystate(28, [115|Ics], Line, Tlen, _, _) -> - yystate(24, Ics, Line, Tlen+1, 27, Tlen); -yystate(28, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(28, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(28, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(28, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(28, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(28, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 114 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(28, [C|Ics], Line, Tlen, _, _) when C >= 116, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(28, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,28}; -yystate(27, [48|Ics], Line, Tlen, Action, Alen) -> - yystate(7, Ics, Line, Tlen+1, Action, Alen); -yystate(27, [C|Ics], Line, Tlen, Action, Alen) when C >= 49, C =< 57 -> - yystate(3, Ics, Line, Tlen+1, Action, Alen); -yystate(27, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,27}; -yystate(26, [115|Ics], Line, Tlen, _, _) -> - yystate(30, Ics, Line, Tlen+1, 27, Tlen); -yystate(26, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(26, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(26, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(26, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(26, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(26, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 114 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(26, [C|Ics], Line, Tlen, _, _) when C >= 116, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(26, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,26}; -yystate(25, [110|Ics], Line, Tlen, _, _) -> - yystate(21, Ics, Line, Tlen+1, 27, Tlen); -yystate(25, [102|Ics], Line, Tlen, _, _) -> - yystate(17, Ics, Line, Tlen+1, 27, Tlen); -yystate(25, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(25, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(25, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(25, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(25, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(25, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 101 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(25, [C|Ics], Line, Tlen, _, _) when C >= 103, C =< 109 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(25, [C|Ics], Line, Tlen, _, _) when C >= 111, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(25, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,25}; -yystate(24, [104|Ics], Line, Tlen, _, _) -> - yystate(20, Ics, Line, Tlen+1, 27, Tlen); -yystate(24, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(24, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(24, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(24, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(24, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(24, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 103 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(24, [C|Ics], Line, Tlen, _, _) when C >= 105, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(24, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,24}; -yystate(23, [42|Ics], Line, Tlen, Action, Alen) -> - yystate(15, Ics, Line, Tlen+1, Action, Alen); -yystate(23, [10|Ics], Line, Tlen, Action, Alen) -> - yystate(23, Ics, Line+1, Tlen+1, Action, Alen); -yystate(23, [C|Ics], Line, Tlen, Action, Alen) when C >= 0, C =< 9 -> - yystate(23, Ics, Line, Tlen+1, Action, Alen); -yystate(23, [C|Ics], Line, Tlen, Action, Alen) when C >= 11, C =< 41 -> - yystate(23, Ics, Line, Tlen+1, Action, Alen); -yystate(23, [C|Ics], Line, Tlen, Action, Alen) when C >= 43 -> - yystate(23, Ics, Line, Tlen+1, Action, Alen); -yystate(23, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,23}; -yystate(22, [97|Ics], Line, Tlen, _, _) -> - yystate(26, Ics, Line, Tlen+1, 27, Tlen); -yystate(22, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(22, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(22, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(22, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(22, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(22, [C|Ics], Line, Tlen, _, _) when C >= 98, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(22, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,22}; -yystate(21, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 14, Tlen); -yystate(21, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 14, Tlen); -yystate(21, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 14, Tlen); -yystate(21, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 14, Tlen); -yystate(21, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 14, Tlen); -yystate(21, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 14, Tlen); -yystate(21, Ics, Line, Tlen, _, _) -> - {14,Tlen,Ics,Line,21}; -yystate(20, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 0, Tlen); -yystate(20, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 0, Tlen); -yystate(20, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 0, Tlen); -yystate(20, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 0, Tlen); -yystate(20, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 0, Tlen); -yystate(20, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 0, Tlen); -yystate(20, Ics, Line, Tlen, _, _) -> - {0,Tlen,Ics,Line,20}; -yystate(19, Ics, Line, Tlen, _, _) -> - {29,Tlen,Ics,Line}; -yystate(18, [116|Ics], Line, Tlen, _, _) -> - yystate(22, Ics, Line, Tlen+1, 27, Tlen); -yystate(18, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(18, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(18, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(18, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(18, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(18, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 115 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(18, [C|Ics], Line, Tlen, _, _) when C >= 117, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(18, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,18}; -yystate(17, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 6, Tlen); -yystate(17, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 6, Tlen); -yystate(17, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 6, Tlen); -yystate(17, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 6, Tlen); -yystate(17, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 6, Tlen); -yystate(17, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 6, Tlen); -yystate(17, Ics, Line, Tlen, _, _) -> - {6,Tlen,Ics,Line,17}; -yystate(16, Ics, Line, Tlen, _, _) -> - {23,Tlen,Ics,Line}; -yystate(15, [47|Ics], Line, Tlen, Action, Alen) -> - yystate(19, Ics, Line, Tlen+1, Action, Alen); -yystate(15, [42|Ics], Line, Tlen, Action, Alen) -> - yystate(15, Ics, Line, Tlen+1, Action, Alen); -yystate(15, [10|Ics], Line, Tlen, Action, Alen) -> - yystate(23, Ics, Line+1, Tlen+1, Action, Alen); -yystate(15, [C|Ics], Line, Tlen, Action, Alen) when C >= 0, C =< 9 -> - yystate(23, Ics, Line, Tlen+1, Action, Alen); -yystate(15, [C|Ics], Line, Tlen, Action, Alen) when C >= 11, C =< 41 -> - yystate(23, Ics, Line, Tlen+1, Action, Alen); -yystate(15, [C|Ics], Line, Tlen, Action, Alen) when C >= 43, C =< 46 -> - yystate(23, Ics, Line, Tlen+1, Action, Alen); -yystate(15, [C|Ics], Line, Tlen, Action, Alen) when C >= 48 -> - yystate(23, Ics, Line, Tlen+1, Action, Alen); -yystate(15, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,15}; -yystate(14, [102|Ics], Line, Tlen, _, _) -> - yystate(18, Ics, Line, Tlen+1, 27, Tlen); -yystate(14, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(14, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(14, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(14, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(14, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(14, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 101 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(14, [C|Ics], Line, Tlen, _, _) when C >= 103, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(14, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,14}; -yystate(13, [110|Ics], Line, Tlen, _, _) -> - yystate(9, Ics, Line, Tlen+1, 27, Tlen); -yystate(13, [109|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(13, [108|Ics], Line, Tlen, _, _) -> - yystate(1, Ics, Line, Tlen+1, 27, Tlen); -yystate(13, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(13, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(13, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(13, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(13, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(13, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 107 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(13, [C|Ics], Line, Tlen, _, _) when C >= 111, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(13, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,13}; -yystate(12, Ics, Line, Tlen, _, _) -> - {12,Tlen,Ics,Line}; -yystate(11, [47|Ics], Line, Tlen, Action, Alen) -> - yystate(59, Ics, Line, Tlen+1, Action, Alen); -yystate(11, [42|Ics], Line, Tlen, Action, Alen) -> - yystate(23, Ics, Line, Tlen+1, Action, Alen); -yystate(11, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,11}; -yystate(10, [101|Ics], Line, Tlen, _, _) -> - yystate(14, Ics, Line, Tlen+1, 27, Tlen); -yystate(10, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(10, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(10, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(10, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(10, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(10, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 100 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(10, [C|Ics], Line, Tlen, _, _) when C >= 102, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(10, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,10}; -yystate(9, [100|Ics], Line, Tlen, _, _) -> - yystate(5, Ics, Line, Tlen+1, 27, Tlen); -yystate(9, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(9, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(9, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(9, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(9, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(9, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 99 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(9, [C|Ics], Line, Tlen, _, _) when C >= 101, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(9, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,9}; -yystate(8, Ics, Line, Tlen, _, _) -> - {18,Tlen,Ics,Line}; -yystate(7, Ics, Line, Tlen, _, _) -> - {3,Tlen,Ics,Line}; -yystate(6, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 10, Tlen); -yystate(6, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 10, Tlen); -yystate(6, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 10, Tlen); -yystate(6, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 10, Tlen); -yystate(6, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 10, Tlen); -yystate(6, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 10, Tlen); -yystate(6, Ics, Line, Tlen, _, _) -> - {10,Tlen,Ics,Line,6}; -yystate(5, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 11, Tlen); -yystate(5, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 11, Tlen); -yystate(5, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 11, Tlen); -yystate(5, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 11, Tlen); -yystate(5, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 11, Tlen); -yystate(5, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 11, Tlen); -yystate(5, Ics, Line, Tlen, _, _) -> - {11,Tlen,Ics,Line,5}; -yystate(4, Ics, Line, Tlen, _, _) -> - {24,Tlen,Ics,Line}; -yystate(3, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(3, Ics, Line, Tlen+1, 3, Tlen); -yystate(3, Ics, Line, Tlen, _, _) -> - {3,Tlen,Ics,Line,3}; -yystate(2, [101|Ics], Line, Tlen, _, _) -> - yystate(6, Ics, Line, Tlen+1, 27, Tlen); -yystate(2, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(2, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(2, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(2, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(2, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(2, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 100 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(2, [C|Ics], Line, Tlen, _, _) when C >= 102, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(2, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,2}; -yystate(1, [115|Ics], Line, Tlen, _, _) -> - yystate(2, Ics, Line, Tlen+1, 27, Tlen); -yystate(1, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(1, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(1, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(1, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(1, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(1, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 114 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(1, [C|Ics], Line, Tlen, _, _) when C >= 116, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(1, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,1}; -yystate(0, Ics, Line, Tlen, _, _) -> - {7,Tlen,Ics,Line}; -yystate(S, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,S}. - -%% yyaction(Action, TokenLength, TokenChars, TokenLine) -> -%% {token,Token} | {end_token, Token} | skip_token | {error,String}. -%% Generated action function. - -yyaction(0, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_0(TokenChars, TokenLine); -yyaction(1, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_1(TokenChars, TokenLine); -yyaction(2, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_2(TokenChars, TokenLine); -yyaction(3, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_3(TokenChars, TokenLine); -yyaction(4, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_4(TokenChars, TokenLine); -yyaction(5, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_5(TokenChars, TokenLine); -yyaction(6, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_6(TokenChars, TokenLine); -yyaction(7, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_7(TokenChars, TokenLine); -yyaction(8, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_8(TokenChars, TokenLine); -yyaction(9, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_9(TokenChars, TokenLine); -yyaction(10, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_10(TokenChars, TokenLine); -yyaction(11, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_11(TokenChars, TokenLine); -yyaction(12, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_12(TokenChars, TokenLine); -yyaction(13, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_13(TokenChars, TokenLine); -yyaction(14, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_14(TokenChars, TokenLine); -yyaction(15, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_15(TokenChars, TokenLine); -yyaction(16, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_16(TokenChars, TokenLine); -yyaction(17, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_17(TokenChars, TokenLine); -yyaction(18, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_18(TokenChars, TokenLine); -yyaction(19, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_19(TokenChars, TokenLine); -yyaction(20, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_20(TokenChars, TokenLine); -yyaction(21, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_21(TokenChars, TokenLine); -yyaction(22, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_22(TokenChars, TokenLine); -yyaction(23, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_23(TokenChars, TokenLine); -yyaction(24, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_24(TokenChars, TokenLine); -yyaction(25, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_25(TokenChars, TokenLine); -yyaction(26, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_26(TokenChars, TokenLine); -yyaction(27, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_27(TokenChars, TokenLine); -yyaction(28, _, _, _) -> - yyaction_28(); -yyaction(29, _, _, _) -> - yyaction_29(); -yyaction(30, _, _, _) -> - yyaction_30(); -yyaction(_, _, _, _) -> error. - --compile({inline,yyaction_0/2}). --file("src/cf_scan.xrl", 69). -yyaction_0(TokenChars, TokenLine) -> - { token, { bash, TokenLine, TokenChars } } . - --compile({inline,yyaction_1/2}). --file("src/cf_scan.xrl", 70). -yyaction_1(TokenChars, TokenLine) -> - { token, { python, TokenLine, TokenChars } } . - --compile({inline,yyaction_2/2}). --file("src/cf_scan.xrl", 71). -yyaction_2(TokenChars, TokenLine) -> - { token, { r, TokenLine, TokenChars } } . - --compile({inline,yyaction_3/2}). --file("src/cf_scan.xrl", 73). -yyaction_3(TokenChars, TokenLine) -> - { token, { intlit, TokenLine, TokenChars } } . - --compile({inline,yyaction_4/2}). --file("src/cf_scan.xrl", 74). -yyaction_4(TokenChars, TokenLine) -> - { token, { strlit, TokenLine, trim_strlit (TokenChars) } } . - --compile({inline,yyaction_5/2}). --file("src/cf_scan.xrl", 75). -yyaction_5(TokenChars, TokenLine) -> - { token, { body, TokenLine, trim_body (TokenChars) } } . - --compile({inline,yyaction_6/2}). --file("src/cf_scan.xrl", 76). -yyaction_6(TokenChars, TokenLine) -> - { token, { beginif, TokenLine, TokenChars } } . - --compile({inline,yyaction_7/2}). --file("src/cf_scan.xrl", 77). -yyaction_7(TokenChars, TokenLine) -> - { token, { colon, TokenLine, TokenChars } } . - --compile({inline,yyaction_8/2}). --file("src/cf_scan.xrl", 78). -yyaction_8(TokenChars, TokenLine) -> - { token, { comma, TokenLine, TokenChars } } . - --compile({inline,yyaction_9/2}). --file("src/cf_scan.xrl", 79). -yyaction_9(TokenChars, TokenLine) -> - { token, { deftask, TokenLine, TokenChars } } . - --compile({inline,yyaction_10/2}). --file("src/cf_scan.xrl", 80). -yyaction_10(TokenChars, TokenLine) -> - { token, { else, TokenLine, TokenChars } } . - --compile({inline,yyaction_11/2}). --file("src/cf_scan.xrl", 81). -yyaction_11(TokenChars, TokenLine) -> - { token, { endif, TokenLine, TokenChars } } . - --compile({inline,yyaction_12/2}). --file("src/cf_scan.xrl", 82). -yyaction_12(TokenChars, TokenLine) -> - { token, { eq, TokenLine, TokenChars } } . - --compile({inline,yyaction_13/2}). --file("src/cf_scan.xrl", 83). -yyaction_13(TokenChars, TokenLine) -> - { token, { file, TokenLine, TokenChars } } . - --compile({inline,yyaction_14/2}). --file("src/cf_scan.xrl", 84). -yyaction_14(TokenChars, TokenLine) -> - { token, { in, TokenLine, TokenChars } } . - --compile({inline,yyaction_15/2}). --file("src/cf_scan.xrl", 85). -yyaction_15(TokenChars, TokenLine) -> - { token, { lbrace, TokenLine, TokenChars } } . - --compile({inline,yyaction_16/2}). --file("src/cf_scan.xrl", 86). -yyaction_16(TokenChars, TokenLine) -> - { token, { lparen, TokenLine, TokenChars } } . - --compile({inline,yyaction_17/2}). --file("src/cf_scan.xrl", 87). -yyaction_17(TokenChars, TokenLine) -> - { token, { lsquarebr, TokenLine, TokenChars } } . - --compile({inline,yyaction_18/2}). --file("src/cf_scan.xrl", 88). -yyaction_18(TokenChars, TokenLine) -> - { token, { ltag, TokenLine, TokenChars } } . - --compile({inline,yyaction_19/2}). --file("src/cf_scan.xrl", 89). -yyaction_19(TokenChars, TokenLine) -> - { token, { nil, TokenLine, TokenChars } } . - --compile({inline,yyaction_20/2}). --file("src/cf_scan.xrl", 90). -yyaction_20(TokenChars, TokenLine) -> - { token, { rbrace, TokenLine, TokenChars } } . - --compile({inline,yyaction_21/2}). --file("src/cf_scan.xrl", 91). -yyaction_21(TokenChars, TokenLine) -> - { token, { rparen, TokenLine, TokenChars } } . - --compile({inline,yyaction_22/2}). --file("src/cf_scan.xrl", 92). -yyaction_22(TokenChars, TokenLine) -> - { token, { rsquarebr, TokenLine, TokenChars } } . - --compile({inline,yyaction_23/2}). --file("src/cf_scan.xrl", 93). -yyaction_23(TokenChars, TokenLine) -> - { token, { rtag, TokenLine, TokenChars } } . - --compile({inline,yyaction_24/2}). --file("src/cf_scan.xrl", 94). -yyaction_24(TokenChars, TokenLine) -> - { token, { semicolon, TokenLine, TokenChars } } . - --compile({inline,yyaction_25/2}). --file("src/cf_scan.xrl", 95). -yyaction_25(TokenChars, TokenLine) -> - { token, { string, TokenLine, TokenChars } } . - --compile({inline,yyaction_26/2}). --file("src/cf_scan.xrl", 96). -yyaction_26(TokenChars, TokenLine) -> - { token, { then, TokenLine, TokenChars } } . - --compile({inline,yyaction_27/2}). --file("src/cf_scan.xrl", 98). -yyaction_27(TokenChars, TokenLine) -> - { token, { id, TokenLine, TokenChars } } . - --compile({inline,yyaction_28/0}). --file("src/cf_scan.xrl", 100). -yyaction_28() -> - skip_token . - --compile({inline,yyaction_29/0}). --file("src/cf_scan.xrl", 101). -yyaction_29() -> - skip_token . - --compile({inline,yyaction_30/0}). --file("src/cf_scan.xrl", 102). -yyaction_30() -> - skip_token . - --file("/usr/local/lib/erlang/lib/parsetools-2.1.1/include/leexinc.hrl", 290). From 20601e2ed63f8a9d39152fa1f2edf6a94593c4c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Fri, 11 Mar 2016 10:39:48 +0100 Subject: [PATCH 29/78] Switch to rebar3 --- .gitignore | 2 + Makefile | 11 +- rebar.config | 4 +- src/cf_parse.erl | 1479 ++++++++++++++++++++++ src/cf_scan.erl | 1676 +++++++++++++++++++++++++ src/{cf.app.src => cuneiform.app.src} | 4 +- src/{cf.erl => cuneiform.erl} | 4 +- src/{cf_app.erl => cuneiform_app.erl} | 2 +- 8 files changed, 3170 insertions(+), 12 deletions(-) create mode 100644 src/cf_parse.erl create mode 100644 src/cf_scan.erl rename src/{cf.app.src => cuneiform.app.src} (81%) rename src/{cf.erl => cuneiform.erl} (98%) rename src/{cf_app.erl => cuneiform_app.erl} (97%) diff --git a/.gitignore b/.gitignore index 29553ed..2397123 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,5 @@ rel/example_project src/cf_lexer.erl src/cf_parser.erl doc +_build +rebar.lock diff --git a/Makefile b/Makefile index 9a3022b..071b355 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,8 @@ -all: .rebar/cf_18.2.1_plt - rebar co eu dialyze +all: + rebar3 compile + rebar3 eunit + rebar3 dialyzer clean: - rebar clean - -.rebar/cf_18.2.1_plt: - rebar get-deps build-plt + rebar3 clean diff --git a/rebar.config b/rebar.config index dc20cf4..30c0fff 100644 --- a/rebar.config +++ b/rebar.config @@ -1,4 +1,6 @@ {cover_enabled, true}. {deps, [ - {cre, "0.1.0", {git, "https://github.com/joergen7/cre.git"}} + {cre, "0.1.0", + {git, "https://github.com/joergen7/cre.git", + {branch, "master"}}} ]}. diff --git a/src/cf_parse.erl b/src/cf_parse.erl new file mode 100644 index 0000000..0c17f53 --- /dev/null +++ b/src/cf_parse.erl @@ -0,0 +1,1479 @@ +-module(cf_parse). +-export([parse/1, parse_and_scan/1, format_error/1]). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 111). + +-author( "Jorgen Brandt " ). + +-export( [string/1] ). + +-ifdef( TEST ). +-include_lib( "eunit/include/eunit.hrl" ). +-endif. + +string( S ) -> + {ok, TokenList, _} = cf_scan:string( S ), + + % parse + case parse( TokenList ) of + {error, R2} -> error( R2 ); + {ok, ParseTree} -> ParseTree + end. + + + + + +combine( {Target1, Rho1, Global1}, {Target2, Rho2, Global2} ) -> + {Target1++Target2, maps:merge( Rho1, Rho2 ), maps:merge( Global1, Global2 )}. + +mk_var( {id, Line, Name} ) -> {var, Line, Name}. + +mk_str( {intlit, _Line, N} ) -> {str, N}; +mk_str( {strlit, _Line, S} ) -> {str, S}. + +get_line( {_, Line, _} ) -> Line. + +get_name( {id, _Line, Name} ) -> Name. + +mk_binding( {id, _, Name}, ExprList ) -> + #{Name => ExprList}. + +mk_assign( [], _ExprList, _Channel ) -> #{}; + +mk_assign( [{var, _Line, Name}|Rest], ExprList, Channel ) -> + Rho = mk_assign( Rest, ExprList, Channel+1 ), + Value = lists:flatmap( fun( E ) -> set_channel( E, Channel ) end, ExprList ), + Rho#{Name => Value}; + +mk_assign( [E|_Rest], _ExprList, _Channel ) -> + error( {parser, nonvar_expr_left_of_eq, element( 1, E ), element( 2, E )} ). + + +set_channel( {app, Line, _Channel, LamList, Binding}, N ) -> [{app, Line, N, LamList, Binding}]; +set_channel( E, 1 ) -> [E]; +set_channel( E, _ ) -> error( {parser, nonapp_expr, element( 1, E ), element( 2, E )} ). + +mk_natlam( {deftask, Line, _}, {id, _, Name}, Sign, Block ) -> + #{Name => {lam, Line, Name, Sign, {natbody, Block}}}. + +mk_forlam( {deftask, Line, _}, {id, _, Name}, Sign, Lang, {body, _, Code} ) -> + #{Name => {lam, Line, Name, Sign, {forbody, Lang, Code}}}. + + +%% ============================================================================= +%% Unit Tests +%% ============================================================================= + +-ifdef( TEST ). + +nil_should_be_recognized_test() -> + ?assertEqual( {[], #{}, #{}}, string( "nil;" ) ). + +var_should_be_recognized_test() -> + ?assertEqual( {[{var, 1, "blub"}], #{}, #{}}, string( "blub;" ) ). + +multi_element_compoundexpr_should_be_recognized_test() -> + ?assertEqual( {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}, + string( "bla blub;" ) ). + +multiple_queries_should_be_joined_test() -> + ?assertEqual( {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}, + string( "bla; blub;" ) ). + +strlit_should_be_recognized_test() -> + ?assertEqual( {[{str, "bla"}], #{}, #{}}, string( "\"bla\";" ) ). + +intlit_should_be_recognized_test() -> + ?assertEqual( {[{str, "-5"}], #{}, #{}}, string( "-5;" ) ). + +cnd_should_be_recognized_test() -> + ?assertEqual( {[{cnd, 1, [], [{str, "bla"}], [{str, "blub"}]}], + #{}, #{}}, + string( "if nil then \"bla\" else \"blub\" end;" ) ). + +app_should_be_recognized_test() -> + [?assertEqual( {[{app, 1, 1, {var, 1, "f"}, #{}}], #{}, #{}}, + string( "f();" ) ), + ?assertEqual( {[{app, 1, 1, {var, 1, "f"}, #{"x" => [{var, 1, "x"}]}}], + #{}, #{}}, string( "f( x: x );" ) ), + ?assertEqual( {[{app, 1, 1, {var, 1, "f"}, + #{"x" => [{var, 1, "x"}], + "y" => [{str, "y"}]}}], #{}, #{}}, + string( "f( x: x, y: \"y\" );" ) )]. + + +assign_should_be_recognized_test() -> + [?assertEqual( {[], #{"x" => [{str, "x"}]}, #{}}, string( "x = \"x\";" ) ), + ?assertEqual( {[], #{"x" => [{app, 1, 1, {var, 1, "f"}, #{}}], "y" => [{app, 1, 2, {var, 1, "f"}, #{}}]}, #{}}, string( "x y = f();" ) ), + ?assertError( {parser, nonapp_expr, str, "A"}, string( "x y = \"A\";" ) ), + ?assertError( {parser, nonvar_expr_left_of_eq, str, "a"}, string( "\"a\" = \"A\";" ) )]. + +native_deftask_should_be_recognized_test() -> + ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + []}, + {natbody, #{"out" => [{str, "A"}]}}}}}, + string( "deftask f( out : ) { out = \"A\"; }" ) ). + +foreign_deftask_should_be_recognized_test() -> + [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + []}, + {forbody, bash, "out=A"}}}}, + string( "deftask f( out : )in bash *{out=A}*" ) ), + ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + []}, + {forbody, r, "out=\"A\""}}}}, + string( "deftask f( out : )in R *{out=\"A\"}*" ) ), + ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + []}, + {forbody, python, ""}}}}, + string( "deftask f( out : )in python *{}*" ) )]. + +sign_with_inparam_should_be_recognized_test() -> + [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [{param, {name, "inp", false}, false}]}, + {forbody, python, "(defparameter out \"A\")"}}}}, + string( "deftask f( out : inp )in python *{(defparameter out \"A\")}*" ) ), + ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [{param, {name, "a", false}, false}, + {param, {name, "b", false}, false}]}, + {forbody, python, "(defparameter out \"A\")"}}}}, + string( "deftask f( out : a b )in python *{(defparameter out \"A\")}*" ) )]. + +param_should_be_recognized_test() -> + [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [{param, {name, "inp", false}, false}]}, + {forbody, bash, "blub"}}}}, + string( "deftask f( out( String ) : inp( String ) )in bash *{blub}*" ) ), + ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + {sign, [{param, {name, "out", true}, false}], + [{param, {name, "inp", true}, false}]}, + {forbody, bash, "blub"}}}}, + string( "deftask f( out( File ) : inp( File ) )in bash *{blub}*" ) ), + ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + {sign, [{param, {name, "out", false}, true}], + [{param, {name, "inp", false}, true}]}, + {forbody, bash, "blub"}}}}, + string( "deftask f( : )in bash *{blub}*" ) ), + ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + {sign, [{param, {name, "out", false}, true}], + [{param, {name, "inp", false}, true}]}, + {forbody, bash, "blub"}}}}, + string( "deftask f( : )in bash *{blub}*" ) ), + ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + {sign, [{param, {name, "out", true}, true}], + [{param, {name, "inp", true}, true}]}, + {forbody, bash, "blub"}}}}, + string( "deftask f( : )in bash *{blub}*" ) )]. + +correl_inparam_should_be_recognized_test() -> + [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [{correl, [{name, "a", true}, + {name, "b", true}]}]}, + {forbody, bash, "blub"}}}}, + string( "deftask f( out : [a( File ) b( File )] )in bash *{blub}*" ) ), + ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + {sign, [{param, {name, "out", false}, false}], + [{correl, [{name, "a", true}, + {name, "b", true}]}, + {param, {name, "c", false}, false}]}, + {forbody, bash, "blub"}}}}, + string( "deftask f( out : [a( File ) b( File )] c )in bash *{blub}*" ) )]. + +-endif. + + + +-file("/usr/local/lib/erlang/lib/parsetools-2.1.1/include/yeccpre.hrl", 0). +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1996-2015. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%% +%% %CopyrightEnd% +%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% The parser generator will insert appropriate declarations before this line.% + +-type yecc_ret() :: {'error', _} | {'ok', _}. + +-spec parse(Tokens :: list()) -> yecc_ret(). +parse(Tokens) -> + yeccpars0(Tokens, {no_func, no_line}, 0, [], []). + +-spec parse_and_scan({function() | {atom(), atom()}, [_]} + | {atom(), atom(), [_]}) -> yecc_ret(). +parse_and_scan({F, A}) -> + yeccpars0([], {{F, A}, no_line}, 0, [], []); +parse_and_scan({M, F, A}) -> + Arity = length(A), + yeccpars0([], {{fun M:F/Arity, A}, no_line}, 0, [], []). + +-spec format_error(any()) -> [char() | list()]. +format_error(Message) -> + case io_lib:deep_char_list(Message) of + true -> + Message; + _ -> + io_lib:write(Message) + end. + +%% To be used in grammar files to throw an error message to the parser +%% toplevel. Doesn't have to be exported! +-compile({nowarn_unused_function, return_error/2}). +-spec return_error(integer(), any()) -> no_return(). +return_error(Line, Message) -> + throw({error, {Line, ?MODULE, Message}}). + +-define(CODE_VERSION, "1.4"). + +yeccpars0(Tokens, Tzr, State, States, Vstack) -> + try yeccpars1(Tokens, Tzr, State, States, Vstack) + catch + error: Error -> + Stacktrace = erlang:get_stacktrace(), + try yecc_error_type(Error, Stacktrace) of + Desc -> + erlang:raise(error, {yecc_bug, ?CODE_VERSION, Desc}, + Stacktrace) + catch _:_ -> erlang:raise(error, Error, Stacktrace) + end; + %% Probably thrown from return_error/2: + throw: {error, {_Line, ?MODULE, _M}} = Error -> + Error + end. + +yecc_error_type(function_clause, [{?MODULE,F,ArityOrArgs,_} | _]) -> + case atom_to_list(F) of + "yeccgoto_" ++ SymbolL -> + {ok,[{atom,_,Symbol}],_} = erl_scan:string(SymbolL), + State = case ArityOrArgs of + [S,_,_,_,_,_,_] -> S; + _ -> state_is_unknown + end, + {Symbol, State, missing_in_goto_table} + end. + +yeccpars1([Token | Tokens], Tzr, State, States, Vstack) -> + yeccpars2(State, element(1, Token), States, Vstack, Token, Tokens, Tzr); +yeccpars1([], {{F, A},_Line}, State, States, Vstack) -> + case apply(F, A) of + {ok, Tokens, Endline} -> + yeccpars1(Tokens, {{F, A}, Endline}, State, States, Vstack); + {eof, Endline} -> + yeccpars1([], {no_func, Endline}, State, States, Vstack); + {error, Descriptor, _Endline} -> + {error, Descriptor} + end; +yeccpars1([], {no_func, no_line}, State, States, Vstack) -> + Line = 999999, + yeccpars2(State, '$end', States, Vstack, yecc_end(Line), [], + {no_func, Line}); +yeccpars1([], {no_func, Endline}, State, States, Vstack) -> + yeccpars2(State, '$end', States, Vstack, yecc_end(Endline), [], + {no_func, Endline}). + +%% yeccpars1/7 is called from generated code. +%% +%% When using the {includefile, Includefile} option, make sure that +%% yeccpars1/7 can be found by parsing the file without following +%% include directives. yecc will otherwise assume that an old +%% yeccpre.hrl is included (one which defines yeccpars1/5). +yeccpars1(State1, State, States, Vstack, Token0, [Token | Tokens], Tzr) -> + yeccpars2(State, element(1, Token), [State1 | States], + [Token0 | Vstack], Token, Tokens, Tzr); +yeccpars1(State1, State, States, Vstack, Token0, [], {{_F,_A}, _Line}=Tzr) -> + yeccpars1([], Tzr, State, [State1 | States], [Token0 | Vstack]); +yeccpars1(State1, State, States, Vstack, Token0, [], {no_func, no_line}) -> + Line = yecctoken_end_location(Token0), + yeccpars2(State, '$end', [State1 | States], [Token0 | Vstack], + yecc_end(Line), [], {no_func, Line}); +yeccpars1(State1, State, States, Vstack, Token0, [], {no_func, Line}) -> + yeccpars2(State, '$end', [State1 | States], [Token0 | Vstack], + yecc_end(Line), [], {no_func, Line}). + +%% For internal use only. +yecc_end({Line,_Column}) -> + {'$end', Line}; +yecc_end(Line) -> + {'$end', Line}. + +yecctoken_end_location(Token) -> + try erl_anno:end_location(element(2, Token)) of + undefined -> yecctoken_location(Token); + Loc -> Loc + catch _:_ -> yecctoken_location(Token) + end. + +-compile({nowarn_unused_function, yeccerror/1}). +yeccerror(Token) -> + Text = yecctoken_to_string(Token), + Location = yecctoken_location(Token), + {error, {Location, ?MODULE, ["syntax error before: ", Text]}}. + +-compile({nowarn_unused_function, yecctoken_to_string/1}). +yecctoken_to_string(Token) -> + try erl_scan:text(Token) of + undefined -> yecctoken2string(Token); + Txt -> Txt + catch _:_ -> yecctoken2string(Token) + end. + +yecctoken_location(Token) -> + try erl_scan:location(Token) + catch _:_ -> element(2, Token) + end. + +-compile({nowarn_unused_function, yecctoken2string/1}). +yecctoken2string({atom, _, A}) -> io_lib:write(A); +yecctoken2string({integer,_,N}) -> io_lib:write(N); +yecctoken2string({float,_,F}) -> io_lib:write(F); +yecctoken2string({char,_,C}) -> io_lib:write_char(C); +yecctoken2string({var,_,V}) -> io_lib:format("~s", [V]); +yecctoken2string({string,_,S}) -> io_lib:write_string(S); +yecctoken2string({reserved_symbol, _, A}) -> io_lib:write(A); +yecctoken2string({_Cat, _, Val}) -> io_lib:format("~p",[Val]); +yecctoken2string({dot, _}) -> "'.'"; +yecctoken2string({'$end', _}) -> + []; +yecctoken2string({Other, _}) when is_atom(Other) -> + io_lib:write(Other); +yecctoken2string(Other) -> + io_lib:write(Other). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.erl", 368). + +-dialyzer({nowarn_function, yeccpars2/7}). +yeccpars2(0=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_0(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(1=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_1(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(2=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_2(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(3=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_3(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(4=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_4(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(5=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_5(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(6=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_6(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(7=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_7(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(8=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_8(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(9=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_9(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(10=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_10(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(11=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_11(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(12=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_12(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(13=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_13(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(14=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_14(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(15=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_15(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(16=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_16(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(17=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_17(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(18=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_18(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(19=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_19(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(20=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_20(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(21=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_21(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(22=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_11(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(23=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_23(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(24=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_24(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(25=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_25(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(26=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_26(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(27=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_27(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(28=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_28(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(29=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_29(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(30=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_30(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(31=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_31(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(32=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_32(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(33=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_33(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(34=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_34(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(35=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_35(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(36=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_36(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(37=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_37(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(38=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_38(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(39=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_39(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(40=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_40(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(41=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_41(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(42=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_42(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(43=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_43(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(44=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_44(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(45=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(46=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_46(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(47=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_47(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(48=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_35(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(49=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_49(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(50=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_50(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(51=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_51(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(52=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_52(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(53=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_53(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(54=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_54(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(55=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_55(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(56=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_56(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(57=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_57(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(58=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_58(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(59=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_59(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(60=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_60(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(61=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_61(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(62=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_62(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(63=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_11(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(64=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_64(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(65=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_65(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(66=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_66(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(67=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_67(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(68=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_68(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(69=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_69(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(70=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_70(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(71=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_71(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(72=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_11(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(73=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_73(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(74=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_11(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(75=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_75(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(76=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_76(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(77=S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_77(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(78=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_78(S, Cat, Ss, Stack, T, Ts, Tzr); +%% yeccpars2(79=S, Cat, Ss, Stack, T, Ts, Tzr) -> +%% yeccpars2_79(S, Cat, Ss, Stack, T, Ts, Tzr); +yeccpars2(Other, _, _, _, _, _, _) -> + erlang:error({yecc_bug,"1.4",{missing_state_in_action_table, Other}}). + +yeccpars2_0(S, deftask, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr); +yeccpars2_0(S, nil, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 15, Ss, Stack, T, Ts, Tzr); +yeccpars2_0(S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_57(S, Cat, Ss, Stack, T, Ts, Tzr). + +yeccpars2_1(S, beginif, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr); +yeccpars2_1(S, deftask, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr); +yeccpars2_1(S, id, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 13, Ss, Stack, T, Ts, Tzr); +yeccpars2_1(S, intlit, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 14, Ss, Stack, T, Ts, Tzr); +yeccpars2_1(S, nil, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 15, Ss, Stack, T, Ts, Tzr); +yeccpars2_1(S, strlit, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 16, Ss, Stack, T, Ts, Tzr); +yeccpars2_1(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccgoto_script(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). + +-dialyzer({nowarn_function, yeccpars2_2/7}). +yeccpars2_2(_S, '$end', _Ss, Stack, _T, _Ts, _Tzr) -> + {ok, hd(Stack)}; +yeccpars2_2(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_3(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_3_(Stack), + yeccgoto_stat(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +yeccpars2_4(S, eq, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 63, Ss, Stack, T, Ts, Tzr); +yeccpars2_4(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccgoto_compoundexpr(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). + +yeccpars2_5(S, beginif, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr); +yeccpars2_5(S, id, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 13, Ss, Stack, T, Ts, Tzr); +yeccpars2_5(S, intlit, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 14, Ss, Stack, T, Ts, Tzr); +yeccpars2_5(S, strlit, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 16, Ss, Stack, T, Ts, Tzr); +yeccpars2_5(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_5_(Stack), + yeccgoto_exprlist(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +yeccpars2_6(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_6_(Stack), + yeccgoto_stat(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +-dialyzer({nowarn_function, yeccpars2_7/7}). +yeccpars2_7(S, semicolon, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 77, Ss, Stack, T, Ts, Tzr); +yeccpars2_7(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccgoto_expr(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). + +yeccpars2_9(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_9_(Stack), + yeccgoto_stat(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccgoto_expr(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). + +yeccpars2_11(S, nil, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 15, Ss, Stack, T, Ts, Tzr); +yeccpars2_11(S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_57(S, Cat, Ss, Stack, T, Ts, Tzr). + +-dialyzer({nowarn_function, yeccpars2_12/7}). +yeccpars2_12(S, id, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 28, Ss, Stack, T, Ts, Tzr); +yeccpars2_12(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_13(S, lparen, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 17, Ss, Stack, T, Ts, Tzr); +yeccpars2_13(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_13_(Stack), + yeccgoto_expr(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_14_(Stack), + yeccgoto_expr(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_15_(Stack), + yeccgoto_compoundexpr(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_16_(Stack), + yeccgoto_expr(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +-dialyzer({nowarn_function, yeccpars2_17/7}). +yeccpars2_17(S, id, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 20, Ss, Stack, T, Ts, Tzr); +yeccpars2_17(S, rparen, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 21, Ss, Stack, T, Ts, Tzr); +yeccpars2_17(_, _, _, _, T, _, _) -> + yeccerror(T). + +-dialyzer({nowarn_function, yeccpars2_18/7}). +yeccpars2_18(S, rparen, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 27, Ss, Stack, T, Ts, Tzr); +yeccpars2_18(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_19(S, comma, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 25, Ss, Stack, T, Ts, Tzr); +yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccgoto_bindinglist(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). + +-dialyzer({nowarn_function, yeccpars2_20/7}). +yeccpars2_20(S, colon, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 22, Ss, Stack, T, Ts, Tzr); +yeccpars2_20(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_,_|Nss] = Ss, + NewStack = yeccpars2_21_(Stack), + yeccgoto_app(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +%% yeccpars2_22: see yeccpars2_11 + +yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccgoto_compoundexpr(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). + +yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_,_|Nss] = Ss, + NewStack = yeccpars2_24_(Stack), + yeccgoto_binding(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +-dialyzer({nowarn_function, yeccpars2_25/7}). +yeccpars2_25(S, id, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 20, Ss, Stack, T, Ts, Tzr); +yeccpars2_25(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_26(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_,_|Nss] = Ss, + NewStack = yeccpars2_26_(Stack), + yeccgoto_bindinglist(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +yeccpars2_27(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_,_,_|Nss] = Ss, + NewStack = yeccpars2_27_(Stack), + yeccgoto_app(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +-dialyzer({nowarn_function, yeccpars2_28/7}). +yeccpars2_28(S, lparen, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 30, Ss, Stack, T, Ts, Tzr); +yeccpars2_28(_, _, _, _, T, _, _) -> + yeccerror(T). + +-dialyzer({nowarn_function, yeccpars2_29/7}). +yeccpars2_29(S, in, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 56, Ss, Stack, T, Ts, Tzr); +yeccpars2_29(S, lbrace, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 57, Ss, Stack, T, Ts, Tzr); +yeccpars2_29(_, _, _, _, T, _, _) -> + yeccerror(T). + +-dialyzer({nowarn_function, yeccpars2_30/7}). +yeccpars2_30(S, id, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr); +yeccpars2_30(S, ltag, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 35, Ss, Stack, T, Ts, Tzr); +yeccpars2_30(_, _, _, _, T, _, _) -> + yeccerror(T). + +-dialyzer({nowarn_function, yeccpars2_31/7}). +yeccpars2_31(S, colon, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 44, Ss, Stack, T, Ts, Tzr); +yeccpars2_31(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_32(S, id, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr); +yeccpars2_32(S, ltag, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 35, Ss, Stack, T, Ts, Tzr); +yeccpars2_32(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_32_(Stack), + yeccgoto_paramlist(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +yeccpars2_33(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_33_(Stack), + yeccgoto_param(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +yeccpars2_34(S, lparen, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 38, Ss, Stack, T, Ts, Tzr); +yeccpars2_34(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_34_(Stack), + yeccgoto_name(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +-dialyzer({nowarn_function, yeccpars2_35/7}). +yeccpars2_35(S, id, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr); +yeccpars2_35(_, _, _, _, T, _, _) -> + yeccerror(T). + +-dialyzer({nowarn_function, yeccpars2_36/7}). +yeccpars2_36(S, rtag, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 37, Ss, Stack, T, Ts, Tzr); +yeccpars2_36(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_37(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_,_|Nss] = Ss, + NewStack = yeccpars2_37_(Stack), + yeccgoto_param(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +-dialyzer({nowarn_function, yeccpars2_38/7}). +yeccpars2_38(S, file, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 39, Ss, Stack, T, Ts, Tzr); +yeccpars2_38(S, string, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 40, Ss, Stack, T, Ts, Tzr); +yeccpars2_38(_, _, _, _, T, _, _) -> + yeccerror(T). + +-dialyzer({nowarn_function, yeccpars2_39/7}). +yeccpars2_39(S, rparen, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 42, Ss, Stack, T, Ts, Tzr); +yeccpars2_39(_, _, _, _, T, _, _) -> + yeccerror(T). + +-dialyzer({nowarn_function, yeccpars2_40/7}). +yeccpars2_40(S, rparen, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 41, Ss, Stack, T, Ts, Tzr); +yeccpars2_40(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_,_,_|Nss] = Ss, + NewStack = yeccpars2_41_(Stack), + yeccgoto_name(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_,_,_|Nss] = Ss, + NewStack = yeccpars2_42_(Stack), + yeccgoto_name(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_|Nss] = Ss, + NewStack = yeccpars2_43_(Stack), + yeccgoto_paramlist(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +-dialyzer({nowarn_function, yeccpars2_44/7}). +yeccpars2_44(S, id, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr); +yeccpars2_44(S, lsquarebr, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 48, Ss, Stack, T, Ts, Tzr); +yeccpars2_44(S, ltag, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 35, Ss, Stack, T, Ts, Tzr); +yeccpars2_44(S, rparen, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 49, Ss, Stack, T, Ts, Tzr); +yeccpars2_44(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_45(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccgoto_inparam(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). + +-dialyzer({nowarn_function, yeccpars2_46/7}). +yeccpars2_46(S, rparen, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 55, Ss, Stack, T, Ts, Tzr); +yeccpars2_46(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_47(S, id, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr); +yeccpars2_47(S, lsquarebr, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 48, Ss, Stack, T, Ts, Tzr); +yeccpars2_47(S, ltag, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 35, Ss, Stack, T, Ts, Tzr); +yeccpars2_47(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_47_(Stack), + yeccgoto_inparamlist(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +%% yeccpars2_48: see yeccpars2_35 + +yeccpars2_49(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_,_,_|Nss] = Ss, + NewStack = yeccpars2_49_(Stack), + yeccgoto_sign(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +-dialyzer({nowarn_function, yeccpars2_50/7}). +yeccpars2_50(S, rsquarebr, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 53, Ss, Stack, T, Ts, Tzr); +yeccpars2_50(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_51(S, id, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr); +yeccpars2_51(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_51_(Stack), + yeccgoto_namelist(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +yeccpars2_52(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_|Nss] = Ss, + NewStack = yeccpars2_52_(Stack), + yeccgoto_namelist(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +yeccpars2_53(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_,_|Nss] = Ss, + NewStack = yeccpars2_53_(Stack), + yeccgoto_inparam(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +yeccpars2_54(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_|Nss] = Ss, + NewStack = yeccpars2_54_(Stack), + yeccgoto_inparamlist(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +yeccpars2_55(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_,_,_,_|Nss] = Ss, + NewStack = yeccpars2_55_(Stack), + yeccgoto_sign(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +-dialyzer({nowarn_function, yeccpars2_56/7}). +yeccpars2_56(S, bash, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 67, Ss, Stack, T, Ts, Tzr); +yeccpars2_56(S, python, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 68, Ss, Stack, T, Ts, Tzr); +yeccpars2_56(S, r, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 69, Ss, Stack, T, Ts, Tzr); +yeccpars2_56(_, _, _, _, T, _, _) -> + yeccerror(T). + +-dialyzer({nowarn_function, yeccpars2_57/7}). +yeccpars2_57(S, beginif, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr); +yeccpars2_57(S, id, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 13, Ss, Stack, T, Ts, Tzr); +yeccpars2_57(S, intlit, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 14, Ss, Stack, T, Ts, Tzr); +yeccpars2_57(S, strlit, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 16, Ss, Stack, T, Ts, Tzr); +yeccpars2_57(_, _, _, _, T, _, _) -> + yeccerror(T). + +-dialyzer({nowarn_function, yeccpars2_58/7}). +yeccpars2_58(S, eq, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 63, Ss, Stack, T, Ts, Tzr); +yeccpars2_58(_, _, _, _, T, _, _) -> + yeccerror(T). + +-dialyzer({nowarn_function, yeccpars2_59/7}). +yeccpars2_59(S, rbrace, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 62, Ss, Stack, T, Ts, Tzr); +yeccpars2_59(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_60(S, beginif, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr); +yeccpars2_60(S, id, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 13, Ss, Stack, T, Ts, Tzr); +yeccpars2_60(S, intlit, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 14, Ss, Stack, T, Ts, Tzr); +yeccpars2_60(S, strlit, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 16, Ss, Stack, T, Ts, Tzr); +yeccpars2_60(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccgoto_assignlist(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). + +yeccpars2_61(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_|Nss] = Ss, + NewStack = yeccpars2_61_(Stack), + yeccgoto_assignlist(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +yeccpars2_62(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_,_,_,_,_|Nss] = Ss, + NewStack = yeccpars2_62_(Stack), + yeccgoto_defun(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +%% yeccpars2_63: see yeccpars2_11 + +-dialyzer({nowarn_function, yeccpars2_64/7}). +yeccpars2_64(S, semicolon, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 65, Ss, Stack, T, Ts, Tzr); +yeccpars2_64(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_65(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_,_,_|Nss] = Ss, + NewStack = yeccpars2_65_(Stack), + yeccgoto_assign(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +-dialyzer({nowarn_function, yeccpars2_66/7}). +yeccpars2_66(S, body, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 70, Ss, Stack, T, Ts, Tzr); +yeccpars2_66(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_67(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_67_(Stack), + yeccgoto_lang(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +yeccpars2_68(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_68_(Stack), + yeccgoto_lang(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +yeccpars2_69(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + NewStack = yeccpars2_69_(Stack), + yeccgoto_lang(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). + +yeccpars2_70(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_,_,_,_,_|Nss] = Ss, + NewStack = yeccpars2_70_(Stack), + yeccgoto_defun(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +-dialyzer({nowarn_function, yeccpars2_71/7}). +yeccpars2_71(S, then, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 72, Ss, Stack, T, Ts, Tzr); +yeccpars2_71(_, _, _, _, T, _, _) -> + yeccerror(T). + +%% yeccpars2_72: see yeccpars2_11 + +-dialyzer({nowarn_function, yeccpars2_73/7}). +yeccpars2_73(S, else, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 74, Ss, Stack, T, Ts, Tzr); +yeccpars2_73(_, _, _, _, T, _, _) -> + yeccerror(T). + +%% yeccpars2_74: see yeccpars2_11 + +-dialyzer({nowarn_function, yeccpars2_75/7}). +yeccpars2_75(S, endif, Ss, Stack, T, Ts, Tzr) -> + yeccpars1(S, 76, Ss, Stack, T, Ts, Tzr); +yeccpars2_75(_, _, _, _, T, _, _) -> + yeccerror(T). + +yeccpars2_76(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_,_,_,_,_,_|Nss] = Ss, + NewStack = yeccpars2_76_(Stack), + yeccgoto_cnd(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +yeccpars2_77(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_|Nss] = Ss, + NewStack = yeccpars2_77_(Stack), + yeccgoto_query(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +yeccpars2_78(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_|Nss] = Ss, + NewStack = yeccpars2_78_(Stack), + yeccgoto_exprlist(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +yeccpars2_79(_S, Cat, Ss, Stack, T, Ts, Tzr) -> + [_|Nss] = Ss, + NewStack = yeccpars2_79_(Stack), + yeccgoto_script(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). + +yeccgoto_app(0=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_app(1=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_app(5=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_app(11=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_app(22=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_app(57=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_app(60=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_app(63=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_app(72=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_app(74=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_assign(0=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_9(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_assign(1=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_9(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_assign(57, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_60(60, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_assign(60, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_60(60, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_assignlist(57, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_59(59, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_assignlist(60=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_61(_S, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_binding(17, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_19(19, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_binding(25, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_19(19, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_bindinglist(17, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_18(18, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_bindinglist(25=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_26(_S, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_cnd(0=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_cnd(1=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_cnd(5=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_cnd(11=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_cnd(22=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_cnd(57=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_cnd(60=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_cnd(63=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_cnd(72=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_cnd(74=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_compoundexpr(0, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_7(7, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_compoundexpr(1, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_7(7, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_compoundexpr(11, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_71(71, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_compoundexpr(22=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_compoundexpr(63, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_64(64, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_compoundexpr(72, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_73(73, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_compoundexpr(74, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_75(75, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_defun(0=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_6(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_defun(1=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_6(_S, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_expr(0, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_expr(1, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_expr(5, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_expr(11, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_expr(22, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_expr(57, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_expr(60, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_expr(63, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_expr(72, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_expr(74, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_exprlist(0, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_4(4, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_exprlist(1, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_4(4, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_exprlist(5=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_78(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_exprlist(11=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_exprlist(22=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_exprlist(57, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_58(58, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_exprlist(60, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_58(58, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_exprlist(63=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_exprlist(72=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_exprlist(74=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_inparam(44, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_47(47, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_inparam(47, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_47(47, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_inparamlist(44, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_46(46, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_inparamlist(47=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_54(_S, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_lang(56, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_66(66, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_name(30=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_33(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_name(32=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_33(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_name(35, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_name(44=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_33(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_name(47=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_33(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_name(48, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_51(51, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_name(51, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_51(51, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_namelist(48, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_50(50, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_namelist(51=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_52(_S, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_param(30, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_param(32, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_param(44=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_45(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_param(47=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_45(_S, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_paramlist(30, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_31(31, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_paramlist(32=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_query(0=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_3(_S, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_query(1=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_3(_S, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_script(0, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_2(2, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_script(1=_S, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_79(_S, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_sign(28, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr). + +yeccgoto_stat(0, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_1(1, Cat, Ss, Stack, T, Ts, Tzr); +yeccgoto_stat(1, Cat, Ss, Stack, T, Ts, Tzr) -> + yeccpars2_1(1, Cat, Ss, Stack, T, Ts, Tzr). + +-compile({inline,yeccpars2_3_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 40). +yeccpars2_3_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + { __1 , # { } , # { } } + end | __Stack]. + +-compile({inline,yeccpars2_5_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 67). +yeccpars2_5_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + [ __1 ] + end | __Stack]. + +-compile({inline,yeccpars2_6_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 42). +yeccpars2_6_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + { [ ] , # { } , __1 } + end | __Stack]. + +-compile({inline,yeccpars2_9_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 41). +yeccpars2_9_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + { [ ] , __1 , # { } } + end | __Stack]. + +-compile({inline,yeccpars2_13_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 63). +yeccpars2_13_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + mk_var ( __1 ) + end | __Stack]. + +-compile({inline,yeccpars2_14_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 61). +yeccpars2_14_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + mk_str ( __1 ) + end | __Stack]. + +-compile({inline,yeccpars2_15_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 58). +yeccpars2_15_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + [ ] + end | __Stack]. + +-compile({inline,yeccpars2_16_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 62). +yeccpars2_16_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + mk_str ( __1 ) + end | __Stack]. + +-compile({inline,yeccpars2_21_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 73). +yeccpars2_21_(__Stack0) -> + [__3,__2,__1 | __Stack] = __Stack0, + [begin + { app , get_line ( __1 ) , 1 , mk_var ( __1 ) , # { } } + end | __Stack]. + +-compile({inline,yeccpars2_24_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 76). +yeccpars2_24_(__Stack0) -> + [__3,__2,__1 | __Stack] = __Stack0, + [begin + mk_binding ( __1 , __3 ) + end | __Stack]. + +-compile({inline,yeccpars2_26_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 79). +yeccpars2_26_(__Stack0) -> + [__3,__2,__1 | __Stack] = __Stack0, + [begin + maps : merge ( __1 , __3 ) + end | __Stack]. + +-compile({inline,yeccpars2_27_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 74). +yeccpars2_27_(__Stack0) -> + [__4,__3,__2,__1 | __Stack] = __Stack0, + [begin + { app , get_line ( __1 ) , 1 , mk_var ( __1 ) , __3 } + end | __Stack]. + +-compile({inline,yeccpars2_32_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 93). +yeccpars2_32_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + [ __1 ] + end | __Stack]. + +-compile({inline,yeccpars2_33_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 90). +yeccpars2_33_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + { param , __1 , false } + end | __Stack]. + +-compile({inline,yeccpars2_34_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 96). +yeccpars2_34_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + { name , get_name ( __1 ) , false } + end | __Stack]. + +-compile({inline,yeccpars2_37_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 91). +yeccpars2_37_(__Stack0) -> + [__3,__2,__1 | __Stack] = __Stack0, + [begin + { param , __2 , true } + end | __Stack]. + +-compile({inline,yeccpars2_41_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 97). +yeccpars2_41_(__Stack0) -> + [__4,__3,__2,__1 | __Stack] = __Stack0, + [begin + { name , get_name ( __1 ) , false } + end | __Stack]. + +-compile({inline,yeccpars2_42_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 98). +yeccpars2_42_(__Stack0) -> + [__4,__3,__2,__1 | __Stack] = __Stack0, + [begin + { name , get_name ( __1 ) , true } + end | __Stack]. + +-compile({inline,yeccpars2_43_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 94). +yeccpars2_43_(__Stack0) -> + [__2,__1 | __Stack] = __Stack0, + [begin + [ __1 | __2 ] + end | __Stack]. + +-compile({inline,yeccpars2_47_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 87). +yeccpars2_47_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + [ __1 ] + end | __Stack]. + +-compile({inline,yeccpars2_49_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 81). +yeccpars2_49_(__Stack0) -> + [__4,__3,__2,__1 | __Stack] = __Stack0, + [begin + { sign , __2 , [ ] } + end | __Stack]. + +-compile({inline,yeccpars2_51_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 100). +yeccpars2_51_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + [ __1 ] + end | __Stack]. + +-compile({inline,yeccpars2_52_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 101). +yeccpars2_52_(__Stack0) -> + [__2,__1 | __Stack] = __Stack0, + [begin + [ __1 | __2 ] + end | __Stack]. + +-compile({inline,yeccpars2_53_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 85). +yeccpars2_53_(__Stack0) -> + [__3,__2,__1 | __Stack] = __Stack0, + [begin + { correl , __2 } + end | __Stack]. + +-compile({inline,yeccpars2_54_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 88). +yeccpars2_54_(__Stack0) -> + [__2,__1 | __Stack] = __Stack0, + [begin + [ __1 | __2 ] + end | __Stack]. + +-compile({inline,yeccpars2_55_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 82). +yeccpars2_55_(__Stack0) -> + [__5,__4,__3,__2,__1 | __Stack] = __Stack0, + [begin + { sign , __2 , __4 } + end | __Stack]. + +-compile({inline,yeccpars2_61_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 49). +yeccpars2_61_(__Stack0) -> + [__2,__1 | __Stack] = __Stack0, + [begin + maps : merge ( __1 , __2 ) + end | __Stack]. + +-compile({inline,yeccpars2_62_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 51). +yeccpars2_62_(__Stack0) -> + [__6,__5,__4,__3,__2,__1 | __Stack] = __Stack0, + [begin + mk_natlam ( __1 , __2 , __3 , __5 ) + end | __Stack]. + +-compile({inline,yeccpars2_65_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 46). +yeccpars2_65_(__Stack0) -> + [__4,__3,__2,__1 | __Stack] = __Stack0, + [begin + mk_assign ( __1 , __3 , 1 ) + end | __Stack]. + +-compile({inline,yeccpars2_67_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 54). +yeccpars2_67_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + bash + end | __Stack]. + +-compile({inline,yeccpars2_68_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 55). +yeccpars2_68_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + python + end | __Stack]. + +-compile({inline,yeccpars2_69_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 56). +yeccpars2_69_(__Stack0) -> + [__1 | __Stack] = __Stack0, + [begin + r + end | __Stack]. + +-compile({inline,yeccpars2_70_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 52). +yeccpars2_70_(__Stack0) -> + [__6,__5,__4,__3,__2,__1 | __Stack] = __Stack0, + [begin + mk_forlam ( __1 , __2 , __3 , __5 , __6 ) + end | __Stack]. + +-compile({inline,yeccpars2_76_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 71). +yeccpars2_76_(__Stack0) -> + [__7,__6,__5,__4,__3,__2,__1 | __Stack] = __Stack0, + [begin + { cnd , get_line ( __1 ) , __2 , __4 , __6 } + end | __Stack]. + +-compile({inline,yeccpars2_77_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 44). +yeccpars2_77_(__Stack0) -> + [__2,__1 | __Stack] = __Stack0, + [begin + __1 + end | __Stack]. + +-compile({inline,yeccpars2_78_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 68). +yeccpars2_78_(__Stack0) -> + [__2,__1 | __Stack] = __Stack0, + [begin + [ __1 | __2 ] + end | __Stack]. + +-compile({inline,yeccpars2_79_/1}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 38). +yeccpars2_79_(__Stack0) -> + [__2,__1 | __Stack] = __Stack0, + [begin + combine ( __1 , __2 ) + end | __Stack]. + + +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 301). diff --git a/src/cf_scan.erl b/src/cf_scan.erl new file mode 100644 index 0000000..34ec090 --- /dev/null +++ b/src/cf_scan.erl @@ -0,0 +1,1676 @@ +-file("/usr/local/lib/erlang/lib/parsetools-2.1.1/include/leexinc.hrl", 0). +%% The source of this file is part of leex distribution, as such it +%% has the same Copyright as the other files in the leex +%% distribution. The Copyright is defined in the accompanying file +%% COPYRIGHT. However, the resultant scanner generated by leex is the +%% property of the creator of the scanner and is not covered by that +%% Copyright. + +-module(cf_scan). + +-export([string/1,string/2,token/2,token/3,tokens/2,tokens/3]). +-export([format_error/1]). + +%% User code. This is placed here to allow extra attributes. +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 114). + +-author( "Jorgen Brandt " ). + +-export( [yyrev/2] ). + +-ifdef( TEST ). +-include_lib( "eunit/include/eunit.hrl" ). +-endif. + +trim_body( S ) -> + string:substr( S, 3, length( S )-4 ). + +trim_strlit( S ) -> + string:substr( S, 2, length( S )-2 ). + + + +%% ============================================================================= +%% Unit Tests +%% ============================================================================= + + +-ifdef( TEST ). + + + +bash_style_comment_should_be_recognized_test() -> + ?assertEqual( {ok, [], 1}, string( "#this is a comment" ) ). + +c_style_comment_should_be_recognized_test() -> + ?assertEqual( {ok, [], 1}, string( "//this is a comment" ) ). + +erlang_style_comment_should_be_recognized_test() -> + ?assertEqual( {ok, [], 1}, string( "%this is a comment" ) ). + + +multiline_comment_should_be_recognized_test() -> + [?assertEqual( {ok, [], 1}, string( "/**/" ) ), + ?assertEqual( {ok, [], 1}, string( "/*x*/" ) ), + ?assertEqual( {ok, [], 1}, string( "/*xy*/" ) ), + ?assertEqual( {ok, [], 2}, string( "/*x\ny*/" ) )]. + +bash_should_be_recognized_test() -> + ?assertEqual( {ok, [{bash, 1, "bash"}], 1}, string( "bash" ) ). + +beginif_should_be_recognized_test() -> + ?assertEqual( {ok, [{beginif, 1, "if"}], 1}, string( "if" ) ). + +colon_should_be_recognized_test() -> + ?assertEqual( {ok, [{colon, 1, ":"}], 1}, string( ":" ) ). + +deftask_should_be_recognized_test() -> + ?assertEqual( {ok, [{deftask, 1, "deftask"}], 1}, string( "deftask" ) ). + +else_should_be_recognized_test() -> + ?assertEqual( {ok, [{else, 1, "else"}], 1}, string( "else" ) ). + +endif_should_be_recognized_test() -> + ?assertEqual( {ok, [{endif, 1, "end"}], 1}, string( "end" ) ). + +eq_should_be_recognized_test() -> + ?assertEqual( {ok, [{eq, 1, "="}], 1}, string( "=" ) ). + +file_should_be_recognized_test() -> + ?assertEqual( {ok, [{file, 1, "File"}], 1}, string( "File" ) ). + +in_should_be_recognized_test() -> + ?assertEqual( {ok, [{in, 1, "in"}], 1}, string( "in" ) ). + +id_should_be_recognized_test() -> + [?assertEqual( {ok, [{id, 1, "inp"}], 1}, string( "inp" ) ), + ?assertEqual( {ok, [{id, 1, "a0"}], 1}, string( "a0" ) ), + ?assertEqual( {ok, [{id, 1, "a9"}], 1}, string( "a9" ) ), + ?assertEqual( {ok, [{id, 1, "a."}], 1}, string( "a." ) ), + ?assertEqual( {ok, [{id, 1, "a-"}], 1}, string( "a-" ) ), + ?assertEqual( {ok, [{id, 1, "a_"}], 1}, string( "a_" ) )]. + +python_should_be_recognized_test() -> + ?assertEqual( {ok, [{python, 1, "python"}], 1}, string( "python" ) ). + +r_should_be_recognized_test() -> + [?assertEqual( {ok, [{r, 1, "r"}], 1}, string( "r" ) ), + ?assertEqual( {ok, [{r, 1, "R"}], 1}, string( "R" ) )]. + +lbrace_should_be_recognized_test() -> + ?assertEqual( {ok, [{lbrace, 1, "{"}], 1}, string( "{" ) ). + +lparen_should_be_recognized_test() -> + ?assertEqual( {ok, [{lparen, 1, "("}], 1}, string( "(" ) ). + +lsquarebr_should_be_recognized_test() -> + ?assertEqual( {ok, [{lsquarebr, 1, "["}], 1}, string( "[" ) ). + +ltag_should_be_recognized_test() -> + ?assertEqual( {ok, [{ltag, 1, "<"}], 1}, string( "<" ) ). + +nil_should_be_recognized_test() -> + ?assertEqual( {ok, [{nil, 1, "nil"}], 1}, string( "nil" ) ). + +rbrace_should_be_recognized_test() -> + ?assertEqual( {ok, [{rbrace, 1, "}"}], 1}, string( "}" ) ). + +rparen_should_be_recognized_test() -> + ?assertEqual( {ok, [{rparen, 1, ")"}], 1}, string( ")" ) ). + +rsquarebr_should_be_recognized_test() -> + ?assertEqual( {ok, [{rsquarebr, 1, "]"}], 1}, string( "]" ) ). + +rtag_should_be_recognized_test() -> + ?assertEqual( {ok, [{rtag, 1, ">"}], 1}, string( ">" ) ). + +semicolon_should_be_recognized_test() -> + ?assertEqual( {ok, [{semicolon, 1, ";"}], 1}, string( ";" ) ). + +string_should_be_recognized_test() -> + ?assertEqual( {ok, [{string, 1, "String"}], 1}, string( "String" ) ). + +then_should_be_recognized_test() -> + ?assertEqual( {ok, [{then, 1, "then"}], 1}, string( "then" ) ). + +intlit_should_be_recognized_test() -> + [?assertEqual( {ok, [{intlit, 1, "10"}], 1}, string( "10" ) ), + ?assertEqual( {ok, [{intlit, 1, "-10"}], 1}, string( "-10" ) ), + ?assertEqual( {ok, [{intlit, 1, "9"}], 1}, string( "9" ) ), + ?assertEqual( {ok, [{intlit, 1, "0"}], 1}, string( "0" ) )]. + +body_should_be_recognized_test() -> + [?assertEqual( {ok, [{body, 1, ""}], 1}, string( "*{}*" ) ), + ?assertEqual( {ok, [{body, 1, "x"}], 1}, string( "*{x}*" ) ), + ?assertEqual( {ok, [{body, 1, "xy"}], 1}, string( "*{xy}*" ) ), + ?assertEqual( {ok, [{body, 1, "x\ny"}], 2}, string( "*{x\ny}*" ) )]. + +strlit_should_be_recognized_test() -> + [?assertEqual( {ok, [{strlit, 1, ""}], 1}, string( "\"\"" ) ), + ?assertEqual( {ok, [{strlit, 1, "x"}], 1}, string( "\"x\"" ) ), + ?assertEqual( {ok, [{strlit, 1, "xy"}], 1}, string( "\"xy\"" ) )]. + + + + + +-endif. + + + +-file("/usr/local/lib/erlang/lib/parsetools-2.1.1/include/leexinc.hrl", 14). + +format_error({illegal,S}) -> ["illegal characters ",io_lib:write_string(S)]; +format_error({user,S}) -> S. + +string(String) -> string(String, 1). + +string(String, Line) -> string(String, Line, String, []). + +%% string(InChars, Line, TokenChars, Tokens) -> +%% {ok,Tokens,Line} | {error,ErrorInfo,Line}. +%% Note the line number going into yystate, L0, is line of token +%% start while line number returned is line of token end. We want line +%% of token start. + +string([], L, [], Ts) -> % No partial tokens! + {ok,yyrev(Ts),L}; +string(Ics0, L0, Tcs, Ts) -> + case yystate(yystate(), Ics0, L0, 0, reject, 0) of + {A,Alen,Ics1,L1} -> % Accepting end state + string_cont(Ics1, L1, yyaction(A, Alen, Tcs, L0), Ts); + {A,Alen,Ics1,L1,_S1} -> % Accepting transistion state + string_cont(Ics1, L1, yyaction(A, Alen, Tcs, L0), Ts); + {reject,_Alen,Tlen,_Ics1,L1,_S1} -> % After a non-accepting state + {error,{L0,?MODULE,{illegal,yypre(Tcs, Tlen+1)}},L1}; + {A,Alen,_Tlen,_Ics1,_L1,_S1} -> + string_cont(yysuf(Tcs, Alen), L0, yyaction(A, Alen, Tcs, L0), Ts) + end. + +%% string_cont(RestChars, Line, Token, Tokens) +%% Test for and remove the end token wrapper. Push back characters +%% are prepended to RestChars. + +-dialyzer({nowarn_function, string_cont/4}). + +string_cont(Rest, Line, {token,T}, Ts) -> + string(Rest, Line, Rest, [T|Ts]); +string_cont(Rest, Line, {token,T,Push}, Ts) -> + NewRest = Push ++ Rest, + string(NewRest, Line, NewRest, [T|Ts]); +string_cont(Rest, Line, {end_token,T}, Ts) -> + string(Rest, Line, Rest, [T|Ts]); +string_cont(Rest, Line, {end_token,T,Push}, Ts) -> + NewRest = Push ++ Rest, + string(NewRest, Line, NewRest, [T|Ts]); +string_cont(Rest, Line, skip_token, Ts) -> + string(Rest, Line, Rest, Ts); +string_cont(Rest, Line, {skip_token,Push}, Ts) -> + NewRest = Push ++ Rest, + string(NewRest, Line, NewRest, Ts); +string_cont(_Rest, Line, {error,S}, _Ts) -> + {error,{Line,?MODULE,{user,S}},Line}. + +%% token(Continuation, Chars) -> +%% token(Continuation, Chars, Line) -> +%% {more,Continuation} | {done,ReturnVal,RestChars}. +%% Must be careful when re-entering to append the latest characters to the +%% after characters in an accept. The continuation is: +%% {token,State,CurrLine,TokenChars,TokenLen,TokenLine,AccAction,AccLen} + +token(Cont, Chars) -> token(Cont, Chars, 1). + +token([], Chars, Line) -> + token(yystate(), Chars, Line, Chars, 0, Line, reject, 0); +token({token,State,Line,Tcs,Tlen,Tline,Action,Alen}, Chars, _) -> + token(State, Chars, Line, Tcs ++ Chars, Tlen, Tline, Action, Alen). + +%% token(State, InChars, Line, TokenChars, TokenLen, TokenLine, +%% AcceptAction, AcceptLen) -> +%% {more,Continuation} | {done,ReturnVal,RestChars}. +%% The argument order is chosen to be more efficient. + +token(S0, Ics0, L0, Tcs, Tlen0, Tline, A0, Alen0) -> + case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of + %% Accepting end state, we have a token. + {A1,Alen1,Ics1,L1} -> + token_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline)); + %% Accepting transition state, can take more chars. + {A1,Alen1,[],L1,S1} -> % Need more chars to check + {more,{token,S1,L1,Tcs,Alen1,Tline,A1,Alen1}}; + {A1,Alen1,Ics1,L1,_S1} -> % Take what we got + token_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline)); + %% After a non-accepting state, maybe reach accept state later. + {A1,Alen1,Tlen1,[],L1,S1} -> % Need more chars to check + {more,{token,S1,L1,Tcs,Tlen1,Tline,A1,Alen1}}; + {reject,_Alen1,Tlen1,eof,L1,_S1} -> % No token match + %% Check for partial token which is error. + Ret = if Tlen1 > 0 -> {error,{Tline,?MODULE, + %% Skip eof tail in Tcs. + {illegal,yypre(Tcs, Tlen1)}},L1}; + true -> {eof,L1} + end, + {done,Ret,eof}; + {reject,_Alen1,Tlen1,Ics1,L1,_S1} -> % No token match + Error = {Tline,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}}, + {done,{error,Error,L1},Ics1}; + {A1,Alen1,_Tlen1,_Ics1,_L1,_S1} -> % Use last accept match + token_cont(yysuf(Tcs, Alen1), L0, yyaction(A1, Alen1, Tcs, Tline)) + end. + +%% token_cont(RestChars, Line, Token) +%% If we have a token or error then return done, else if we have a +%% skip_token then continue. + +-dialyzer({nowarn_function, token_cont/3}). + +token_cont(Rest, Line, {token,T}) -> + {done,{ok,T,Line},Rest}; +token_cont(Rest, Line, {token,T,Push}) -> + NewRest = Push ++ Rest, + {done,{ok,T,Line},NewRest}; +token_cont(Rest, Line, {end_token,T}) -> + {done,{ok,T,Line},Rest}; +token_cont(Rest, Line, {end_token,T,Push}) -> + NewRest = Push ++ Rest, + {done,{ok,T,Line},NewRest}; +token_cont(Rest, Line, skip_token) -> + token(yystate(), Rest, Line, Rest, 0, Line, reject, 0); +token_cont(Rest, Line, {skip_token,Push}) -> + NewRest = Push ++ Rest, + token(yystate(), NewRest, Line, NewRest, 0, Line, reject, 0); +token_cont(Rest, Line, {error,S}) -> + {done,{error,{Line,?MODULE,{user,S}},Line},Rest}. + +%% tokens(Continuation, Chars, Line) -> +%% {more,Continuation} | {done,ReturnVal,RestChars}. +%% Must be careful when re-entering to append the latest characters to the +%% after characters in an accept. The continuation is: +%% {tokens,State,CurrLine,TokenChars,TokenLen,TokenLine,Tokens,AccAction,AccLen} +%% {skip_tokens,State,CurrLine,TokenChars,TokenLen,TokenLine,Error,AccAction,AccLen} + +tokens(Cont, Chars) -> tokens(Cont, Chars, 1). + +tokens([], Chars, Line) -> + tokens(yystate(), Chars, Line, Chars, 0, Line, [], reject, 0); +tokens({tokens,State,Line,Tcs,Tlen,Tline,Ts,Action,Alen}, Chars, _) -> + tokens(State, Chars, Line, Tcs ++ Chars, Tlen, Tline, Ts, Action, Alen); +tokens({skip_tokens,State,Line,Tcs,Tlen,Tline,Error,Action,Alen}, Chars, _) -> + skip_tokens(State, Chars, Line, Tcs ++ Chars, Tlen, Tline, Error, Action, Alen). + +%% tokens(State, InChars, Line, TokenChars, TokenLen, TokenLine, Tokens, +%% AcceptAction, AcceptLen) -> +%% {more,Continuation} | {done,ReturnVal,RestChars}. + +tokens(S0, Ics0, L0, Tcs, Tlen0, Tline, Ts, A0, Alen0) -> + case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of + %% Accepting end state, we have a token. + {A1,Alen1,Ics1,L1} -> + tokens_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Ts); + %% Accepting transition state, can take more chars. + {A1,Alen1,[],L1,S1} -> % Need more chars to check + {more,{tokens,S1,L1,Tcs,Alen1,Tline,Ts,A1,Alen1}}; + {A1,Alen1,Ics1,L1,_S1} -> % Take what we got + tokens_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Ts); + %% After a non-accepting state, maybe reach accept state later. + {A1,Alen1,Tlen1,[],L1,S1} -> % Need more chars to check + {more,{tokens,S1,L1,Tcs,Tlen1,Tline,Ts,A1,Alen1}}; + {reject,_Alen1,Tlen1,eof,L1,_S1} -> % No token match + %% Check for partial token which is error, no need to skip here. + Ret = if Tlen1 > 0 -> {error,{Tline,?MODULE, + %% Skip eof tail in Tcs. + {illegal,yypre(Tcs, Tlen1)}},L1}; + Ts == [] -> {eof,L1}; + true -> {ok,yyrev(Ts),L1} + end, + {done,Ret,eof}; + {reject,_Alen1,Tlen1,_Ics1,L1,_S1} -> + %% Skip rest of tokens. + Error = {L1,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}}, + skip_tokens(yysuf(Tcs, Tlen1+1), L1, Error); + {A1,Alen1,_Tlen1,_Ics1,_L1,_S1} -> + Token = yyaction(A1, Alen1, Tcs, Tline), + tokens_cont(yysuf(Tcs, Alen1), L0, Token, Ts) + end. + +%% tokens_cont(RestChars, Line, Token, Tokens) +%% If we have an end_token or error then return done, else if we have +%% a token then save it and continue, else if we have a skip_token +%% just continue. + +-dialyzer({nowarn_function, tokens_cont/4}). + +tokens_cont(Rest, Line, {token,T}, Ts) -> + tokens(yystate(), Rest, Line, Rest, 0, Line, [T|Ts], reject, 0); +tokens_cont(Rest, Line, {token,T,Push}, Ts) -> + NewRest = Push ++ Rest, + tokens(yystate(), NewRest, Line, NewRest, 0, Line, [T|Ts], reject, 0); +tokens_cont(Rest, Line, {end_token,T}, Ts) -> + {done,{ok,yyrev(Ts, [T]),Line},Rest}; +tokens_cont(Rest, Line, {end_token,T,Push}, Ts) -> + NewRest = Push ++ Rest, + {done,{ok,yyrev(Ts, [T]),Line},NewRest}; +tokens_cont(Rest, Line, skip_token, Ts) -> + tokens(yystate(), Rest, Line, Rest, 0, Line, Ts, reject, 0); +tokens_cont(Rest, Line, {skip_token,Push}, Ts) -> + NewRest = Push ++ Rest, + tokens(yystate(), NewRest, Line, NewRest, 0, Line, Ts, reject, 0); +tokens_cont(Rest, Line, {error,S}, _Ts) -> + skip_tokens(Rest, Line, {Line,?MODULE,{user,S}}). + +%%skip_tokens(InChars, Line, Error) -> {done,{error,Error,Line},Ics}. +%% Skip tokens until an end token, junk everything and return the error. + +skip_tokens(Ics, Line, Error) -> + skip_tokens(yystate(), Ics, Line, Ics, 0, Line, Error, reject, 0). + +%% skip_tokens(State, InChars, Line, TokenChars, TokenLen, TokenLine, Tokens, +%% AcceptAction, AcceptLen) -> +%% {more,Continuation} | {done,ReturnVal,RestChars}. + +skip_tokens(S0, Ics0, L0, Tcs, Tlen0, Tline, Error, A0, Alen0) -> + case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of + {A1,Alen1,Ics1,L1} -> % Accepting end state + skip_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Error); + {A1,Alen1,[],L1,S1} -> % After an accepting state + {more,{skip_tokens,S1,L1,Tcs,Alen1,Tline,Error,A1,Alen1}}; + {A1,Alen1,Ics1,L1,_S1} -> + skip_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Error); + {A1,Alen1,Tlen1,[],L1,S1} -> % After a non-accepting state + {more,{skip_tokens,S1,L1,Tcs,Tlen1,Tline,Error,A1,Alen1}}; + {reject,_Alen1,_Tlen1,eof,L1,_S1} -> + {done,{error,Error,L1},eof}; + {reject,_Alen1,Tlen1,_Ics1,L1,_S1} -> + skip_tokens(yysuf(Tcs, Tlen1+1), L1, Error); + {A1,Alen1,_Tlen1,_Ics1,L1,_S1} -> + Token = yyaction(A1, Alen1, Tcs, Tline), + skip_cont(yysuf(Tcs, Alen1), L1, Token, Error) + end. + +%% skip_cont(RestChars, Line, Token, Error) +%% Skip tokens until we have an end_token or error then return done +%% with the original rror. + +-dialyzer({nowarn_function, skip_cont/4}). + +skip_cont(Rest, Line, {token,_T}, Error) -> + skip_tokens(yystate(), Rest, Line, Rest, 0, Line, Error, reject, 0); +skip_cont(Rest, Line, {token,_T,Push}, Error) -> + NewRest = Push ++ Rest, + skip_tokens(yystate(), NewRest, Line, NewRest, 0, Line, Error, reject, 0); +skip_cont(Rest, Line, {end_token,_T}, Error) -> + {done,{error,Error,Line},Rest}; +skip_cont(Rest, Line, {end_token,_T,Push}, Error) -> + NewRest = Push ++ Rest, + {done,{error,Error,Line},NewRest}; +skip_cont(Rest, Line, skip_token, Error) -> + skip_tokens(yystate(), Rest, Line, Rest, 0, Line, Error, reject, 0); +skip_cont(Rest, Line, {skip_token,Push}, Error) -> + NewRest = Push ++ Rest, + skip_tokens(yystate(), NewRest, Line, NewRest, 0, Line, Error, reject, 0); +skip_cont(Rest, Line, {error,_S}, Error) -> + skip_tokens(yystate(), Rest, Line, Rest, 0, Line, Error, reject, 0). + +yyrev(List) -> lists:reverse(List). +yyrev(List, Tail) -> lists:reverse(List, Tail). +yypre(List, N) -> lists:sublist(List, N). +yysuf(List, N) -> lists:nthtail(N, List). + +%% yystate() -> InitialState. +%% yystate(State, InChars, Line, CurrTokLen, AcceptAction, AcceptLen) -> +%% {Action, AcceptLen, RestChars, Line} | +%% {Action, AcceptLen, RestChars, Line, State} | +%% {reject, AcceptLen, CurrTokLen, RestChars, Line, State} | +%% {Action, AcceptLen, CurrTokLen, RestChars, Line, State}. +%% Generated state transition functions. The non-accepting end state +%% return signal either an unrecognised character or end of current +%% input. + +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.erl", 428). +yystate() -> 69. + +yystate(72, [122|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(72, [121|Ics], Line, Tlen, _, _) -> + yystate(68, Ics, Line, Tlen+1, 27, Tlen); +yystate(72, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(72, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(72, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(72, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(72, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(72, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 120 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(72, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,72}; +yystate(71, Ics, Line, Tlen, _, _) -> + {30,Tlen,Ics,Line}; +yystate(70, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 2, Tlen); +yystate(70, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 2, Tlen); +yystate(70, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 2, Tlen); +yystate(70, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 2, Tlen); +yystate(70, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 2, Tlen); +yystate(70, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 2, Tlen); +yystate(70, Ics, Line, Tlen, _, _) -> + {2,Tlen,Ics,Line,70}; +yystate(69, [125|Ics], Line, Tlen, Action, Alen) -> + yystate(65, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [123|Ics], Line, Tlen, Action, Alen) -> + yystate(61, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [116|Ics], Line, Tlen, Action, Alen) -> + yystate(57, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [115|Ics], Line, Tlen, Action, Alen) -> + yystate(41, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [114|Ics], Line, Tlen, Action, Alen) -> + yystate(70, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [113|Ics], Line, Tlen, Action, Alen) -> + yystate(41, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [112|Ics], Line, Tlen, Action, Alen) -> + yystate(72, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [111|Ics], Line, Tlen, Action, Alen) -> + yystate(41, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [110|Ics], Line, Tlen, Action, Alen) -> + yystate(37, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [105|Ics], Line, Tlen, Action, Alen) -> + yystate(25, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [101|Ics], Line, Tlen, Action, Alen) -> + yystate(13, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [100|Ics], Line, Tlen, Action, Alen) -> + yystate(10, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [99|Ics], Line, Tlen, Action, Alen) -> + yystate(41, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [98|Ics], Line, Tlen, Action, Alen) -> + yystate(32, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [97|Ics], Line, Tlen, Action, Alen) -> + yystate(41, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [93|Ics], Line, Tlen, Action, Alen) -> + yystate(38, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [91|Ics], Line, Tlen, Action, Alen) -> + yystate(42, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [83|Ics], Line, Tlen, Action, Alen) -> + yystate(46, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [82|Ics], Line, Tlen, Action, Alen) -> + yystate(70, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [81|Ics], Line, Tlen, Action, Alen) -> + yystate(41, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [80|Ics], Line, Tlen, Action, Alen) -> + yystate(72, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [70|Ics], Line, Tlen, Action, Alen) -> + yystate(48, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [66|Ics], Line, Tlen, Action, Alen) -> + yystate(32, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [65|Ics], Line, Tlen, Action, Alen) -> + yystate(41, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [62|Ics], Line, Tlen, Action, Alen) -> + yystate(16, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [61|Ics], Line, Tlen, Action, Alen) -> + yystate(12, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [60|Ics], Line, Tlen, Action, Alen) -> + yystate(8, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [59|Ics], Line, Tlen, Action, Alen) -> + yystate(4, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [58|Ics], Line, Tlen, Action, Alen) -> + yystate(0, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [48|Ics], Line, Tlen, Action, Alen) -> + yystate(7, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [47|Ics], Line, Tlen, Action, Alen) -> + yystate(11, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [45|Ics], Line, Tlen, Action, Alen) -> + yystate(27, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [44|Ics], Line, Tlen, Action, Alen) -> + yystate(31, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [42|Ics], Line, Tlen, Action, Alen) -> + yystate(35, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [41|Ics], Line, Tlen, Action, Alen) -> + yystate(51, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [40|Ics], Line, Tlen, Action, Alen) -> + yystate(55, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [37|Ics], Line, Tlen, Action, Alen) -> + yystate(59, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [35|Ics], Line, Tlen, Action, Alen) -> + yystate(59, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [34|Ics], Line, Tlen, Action, Alen) -> + yystate(67, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [10|Ics], Line, Tlen, Action, Alen) -> + yystate(71, Ics, Line+1, Tlen+1, Action, Alen); +yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 0, C =< 9 -> + yystate(71, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 11, C =< 32 -> + yystate(71, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 49, C =< 57 -> + yystate(3, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 67, C =< 69 -> + yystate(41, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 71, C =< 79 -> + yystate(41, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 84, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 102, C =< 104 -> + yystate(41, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 106, C =< 109 -> + yystate(41, Ics, Line, Tlen+1, Action, Alen); +yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 117, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, Action, Alen); +yystate(69, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,69}; +yystate(68, [116|Ics], Line, Tlen, _, _) -> + yystate(64, Ics, Line, Tlen+1, 27, Tlen); +yystate(68, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(68, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(68, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(68, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(68, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(68, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 115 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(68, [C|Ics], Line, Tlen, _, _) when C >= 117, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(68, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,68}; +yystate(67, [34|Ics], Line, Tlen, Action, Alen) -> + yystate(63, Ics, Line, Tlen+1, Action, Alen); +yystate(67, [10|Ics], Line, Tlen, Action, Alen) -> + yystate(67, Ics, Line+1, Tlen+1, Action, Alen); +yystate(67, [C|Ics], Line, Tlen, Action, Alen) when C >= 0, C =< 9 -> + yystate(67, Ics, Line, Tlen+1, Action, Alen); +yystate(67, [C|Ics], Line, Tlen, Action, Alen) when C >= 11, C =< 33 -> + yystate(67, Ics, Line, Tlen+1, Action, Alen); +yystate(67, [C|Ics], Line, Tlen, Action, Alen) when C >= 35 -> + yystate(67, Ics, Line, Tlen+1, Action, Alen); +yystate(67, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,67}; +yystate(66, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 25, Tlen); +yystate(66, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 25, Tlen); +yystate(66, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 25, Tlen); +yystate(66, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 25, Tlen); +yystate(66, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 25, Tlen); +yystate(66, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 25, Tlen); +yystate(66, Ics, Line, Tlen, _, _) -> + {25,Tlen,Ics,Line,66}; +yystate(65, Ics, Line, Tlen, _, _) -> + {20,Tlen,Ics,Line}; +yystate(64, [104|Ics], Line, Tlen, _, _) -> + yystate(60, Ics, Line, Tlen+1, 27, Tlen); +yystate(64, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(64, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(64, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(64, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(64, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(64, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 103 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(64, [C|Ics], Line, Tlen, _, _) when C >= 105, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(64, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,64}; +yystate(63, Ics, Line, Tlen, _, _) -> + {4,Tlen,Ics,Line}; +yystate(62, [103|Ics], Line, Tlen, _, _) -> + yystate(66, Ics, Line, Tlen+1, 27, Tlen); +yystate(62, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(62, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(62, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(62, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(62, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(62, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 102 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(62, [C|Ics], Line, Tlen, _, _) when C >= 104, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(62, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,62}; +yystate(61, Ics, Line, Tlen, _, _) -> + {15,Tlen,Ics,Line}; +yystate(60, [111|Ics], Line, Tlen, _, _) -> + yystate(56, Ics, Line, Tlen+1, 27, Tlen); +yystate(60, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(60, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(60, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(60, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(60, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(60, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 110 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(60, [C|Ics], Line, Tlen, _, _) when C >= 112, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(60, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,60}; +yystate(59, [C|Ics], Line, Tlen, _, _) when C >= 0, C =< 9 -> + yystate(59, Ics, Line, Tlen+1, 28, Tlen); +yystate(59, [C|Ics], Line, Tlen, _, _) when C >= 11 -> + yystate(59, Ics, Line, Tlen+1, 28, Tlen); +yystate(59, Ics, Line, Tlen, _, _) -> + {28,Tlen,Ics,Line,59}; +yystate(58, [110|Ics], Line, Tlen, _, _) -> + yystate(62, Ics, Line, Tlen+1, 27, Tlen); +yystate(58, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(58, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(58, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(58, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(58, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(58, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 109 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(58, [C|Ics], Line, Tlen, _, _) when C >= 111, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(58, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,58}; +yystate(57, [104|Ics], Line, Tlen, _, _) -> + yystate(53, Ics, Line, Tlen+1, 27, Tlen); +yystate(57, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(57, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(57, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(57, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(57, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(57, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 103 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(57, [C|Ics], Line, Tlen, _, _) when C >= 105, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(57, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,57}; +yystate(56, [110|Ics], Line, Tlen, _, _) -> + yystate(52, Ics, Line, Tlen+1, 27, Tlen); +yystate(56, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(56, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(56, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(56, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(56, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(56, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 109 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(56, [C|Ics], Line, Tlen, _, _) when C >= 111, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(56, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,56}; +yystate(55, Ics, Line, Tlen, _, _) -> + {16,Tlen,Ics,Line}; +yystate(54, [105|Ics], Line, Tlen, _, _) -> + yystate(58, Ics, Line, Tlen+1, 27, Tlen); +yystate(54, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(54, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(54, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(54, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(54, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(54, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 104 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(54, [C|Ics], Line, Tlen, _, _) when C >= 106, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(54, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,54}; +yystate(53, [101|Ics], Line, Tlen, _, _) -> + yystate(49, Ics, Line, Tlen+1, 27, Tlen); +yystate(53, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(53, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(53, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(53, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(53, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(53, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 100 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(53, [C|Ics], Line, Tlen, _, _) when C >= 102, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(53, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,53}; +yystate(52, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 1, Tlen); +yystate(52, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 1, Tlen); +yystate(52, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 1, Tlen); +yystate(52, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 1, Tlen); +yystate(52, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 1, Tlen); +yystate(52, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 1, Tlen); +yystate(52, Ics, Line, Tlen, _, _) -> + {1,Tlen,Ics,Line,52}; +yystate(51, Ics, Line, Tlen, _, _) -> + {21,Tlen,Ics,Line}; +yystate(50, [114|Ics], Line, Tlen, _, _) -> + yystate(54, Ics, Line, Tlen+1, 27, Tlen); +yystate(50, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(50, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(50, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(50, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(50, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(50, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 113 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(50, [C|Ics], Line, Tlen, _, _) when C >= 115, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(50, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,50}; +yystate(49, [110|Ics], Line, Tlen, _, _) -> + yystate(45, Ics, Line, Tlen+1, 27, Tlen); +yystate(49, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(49, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(49, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(49, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(49, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(49, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 109 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(49, [C|Ics], Line, Tlen, _, _) when C >= 111, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(49, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,49}; +yystate(48, [105|Ics], Line, Tlen, _, _) -> + yystate(44, Ics, Line, Tlen+1, 27, Tlen); +yystate(48, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(48, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(48, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(48, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(48, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(48, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 104 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(48, [C|Ics], Line, Tlen, _, _) when C >= 106, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(48, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,48}; +yystate(47, [125|Ics], Line, Tlen, Action, Alen) -> + yystate(39, Ics, Line, Tlen+1, Action, Alen); +yystate(47, [10|Ics], Line, Tlen, Action, Alen) -> + yystate(47, Ics, Line+1, Tlen+1, Action, Alen); +yystate(47, [C|Ics], Line, Tlen, Action, Alen) when C >= 0, C =< 9 -> + yystate(47, Ics, Line, Tlen+1, Action, Alen); +yystate(47, [C|Ics], Line, Tlen, Action, Alen) when C >= 11, C =< 124 -> + yystate(47, Ics, Line, Tlen+1, Action, Alen); +yystate(47, [C|Ics], Line, Tlen, Action, Alen) when C >= 126 -> + yystate(47, Ics, Line, Tlen+1, Action, Alen); +yystate(47, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,47}; +yystate(46, [116|Ics], Line, Tlen, _, _) -> + yystate(50, Ics, Line, Tlen+1, 27, Tlen); +yystate(46, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(46, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(46, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(46, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(46, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(46, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 115 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(46, [C|Ics], Line, Tlen, _, _) when C >= 117, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(46, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,46}; +yystate(45, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 26, Tlen); +yystate(45, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 26, Tlen); +yystate(45, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 26, Tlen); +yystate(45, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 26, Tlen); +yystate(45, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 26, Tlen); +yystate(45, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 26, Tlen); +yystate(45, Ics, Line, Tlen, _, _) -> + {26,Tlen,Ics,Line,45}; +yystate(44, [108|Ics], Line, Tlen, _, _) -> + yystate(40, Ics, Line, Tlen+1, 27, Tlen); +yystate(44, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(44, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(44, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(44, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(44, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(44, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 107 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(44, [C|Ics], Line, Tlen, _, _) when C >= 109, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(44, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,44}; +yystate(43, Ics, Line, Tlen, _, _) -> + {5,Tlen,Ics,Line}; +yystate(42, Ics, Line, Tlen, _, _) -> + {17,Tlen,Ics,Line}; +yystate(41, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(41, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(41, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(41, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(41, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(41, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(41, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,41}; +yystate(40, [101|Ics], Line, Tlen, _, _) -> + yystate(36, Ics, Line, Tlen+1, 27, Tlen); +yystate(40, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(40, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(40, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(40, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(40, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(40, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 100 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(40, [C|Ics], Line, Tlen, _, _) when C >= 102, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(40, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,40}; +yystate(39, [125|Ics], Line, Tlen, Action, Alen) -> + yystate(39, Ics, Line, Tlen+1, Action, Alen); +yystate(39, [42|Ics], Line, Tlen, Action, Alen) -> + yystate(43, Ics, Line, Tlen+1, Action, Alen); +yystate(39, [10|Ics], Line, Tlen, Action, Alen) -> + yystate(47, Ics, Line+1, Tlen+1, Action, Alen); +yystate(39, [C|Ics], Line, Tlen, Action, Alen) when C >= 0, C =< 9 -> + yystate(47, Ics, Line, Tlen+1, Action, Alen); +yystate(39, [C|Ics], Line, Tlen, Action, Alen) when C >= 11, C =< 41 -> + yystate(47, Ics, Line, Tlen+1, Action, Alen); +yystate(39, [C|Ics], Line, Tlen, Action, Alen) when C >= 43, C =< 124 -> + yystate(47, Ics, Line, Tlen+1, Action, Alen); +yystate(39, [C|Ics], Line, Tlen, Action, Alen) when C >= 126 -> + yystate(47, Ics, Line, Tlen+1, Action, Alen); +yystate(39, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,39}; +yystate(38, Ics, Line, Tlen, _, _) -> + {22,Tlen,Ics,Line}; +yystate(37, [105|Ics], Line, Tlen, _, _) -> + yystate(33, Ics, Line, Tlen+1, 27, Tlen); +yystate(37, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(37, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(37, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(37, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(37, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(37, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 104 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(37, [C|Ics], Line, Tlen, _, _) when C >= 106, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(37, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,37}; +yystate(36, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 13, Tlen); +yystate(36, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 13, Tlen); +yystate(36, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 13, Tlen); +yystate(36, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 13, Tlen); +yystate(36, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 13, Tlen); +yystate(36, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 13, Tlen); +yystate(36, Ics, Line, Tlen, _, _) -> + {13,Tlen,Ics,Line,36}; +yystate(35, [123|Ics], Line, Tlen, Action, Alen) -> + yystate(47, Ics, Line, Tlen+1, Action, Alen); +yystate(35, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,35}; +yystate(34, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 9, Tlen); +yystate(34, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 9, Tlen); +yystate(34, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 9, Tlen); +yystate(34, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 9, Tlen); +yystate(34, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 9, Tlen); +yystate(34, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 9, Tlen); +yystate(34, Ics, Line, Tlen, _, _) -> + {9,Tlen,Ics,Line,34}; +yystate(33, [108|Ics], Line, Tlen, _, _) -> + yystate(29, Ics, Line, Tlen+1, 27, Tlen); +yystate(33, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(33, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(33, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(33, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(33, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(33, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 107 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(33, [C|Ics], Line, Tlen, _, _) when C >= 109, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(33, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,33}; +yystate(32, [97|Ics], Line, Tlen, _, _) -> + yystate(28, Ics, Line, Tlen+1, 27, Tlen); +yystate(32, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(32, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(32, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(32, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(32, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(32, [C|Ics], Line, Tlen, _, _) when C >= 98, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(32, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,32}; +yystate(31, Ics, Line, Tlen, _, _) -> + {8,Tlen,Ics,Line}; +yystate(30, [107|Ics], Line, Tlen, _, _) -> + yystate(34, Ics, Line, Tlen+1, 27, Tlen); +yystate(30, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(30, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(30, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(30, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(30, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(30, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 106 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(30, [C|Ics], Line, Tlen, _, _) when C >= 108, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(30, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,30}; +yystate(29, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 19, Tlen); +yystate(29, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 19, Tlen); +yystate(29, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 19, Tlen); +yystate(29, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 19, Tlen); +yystate(29, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 19, Tlen); +yystate(29, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 19, Tlen); +yystate(29, Ics, Line, Tlen, _, _) -> + {19,Tlen,Ics,Line,29}; +yystate(28, [115|Ics], Line, Tlen, _, _) -> + yystate(24, Ics, Line, Tlen+1, 27, Tlen); +yystate(28, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(28, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(28, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(28, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(28, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(28, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 114 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(28, [C|Ics], Line, Tlen, _, _) when C >= 116, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(28, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,28}; +yystate(27, [48|Ics], Line, Tlen, Action, Alen) -> + yystate(7, Ics, Line, Tlen+1, Action, Alen); +yystate(27, [C|Ics], Line, Tlen, Action, Alen) when C >= 49, C =< 57 -> + yystate(3, Ics, Line, Tlen+1, Action, Alen); +yystate(27, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,27}; +yystate(26, [115|Ics], Line, Tlen, _, _) -> + yystate(30, Ics, Line, Tlen+1, 27, Tlen); +yystate(26, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(26, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(26, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(26, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(26, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(26, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 114 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(26, [C|Ics], Line, Tlen, _, _) when C >= 116, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(26, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,26}; +yystate(25, [110|Ics], Line, Tlen, _, _) -> + yystate(21, Ics, Line, Tlen+1, 27, Tlen); +yystate(25, [102|Ics], Line, Tlen, _, _) -> + yystate(17, Ics, Line, Tlen+1, 27, Tlen); +yystate(25, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(25, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(25, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(25, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(25, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(25, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 101 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(25, [C|Ics], Line, Tlen, _, _) when C >= 103, C =< 109 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(25, [C|Ics], Line, Tlen, _, _) when C >= 111, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(25, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,25}; +yystate(24, [104|Ics], Line, Tlen, _, _) -> + yystate(20, Ics, Line, Tlen+1, 27, Tlen); +yystate(24, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(24, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(24, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(24, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(24, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(24, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 103 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(24, [C|Ics], Line, Tlen, _, _) when C >= 105, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(24, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,24}; +yystate(23, [42|Ics], Line, Tlen, Action, Alen) -> + yystate(15, Ics, Line, Tlen+1, Action, Alen); +yystate(23, [10|Ics], Line, Tlen, Action, Alen) -> + yystate(23, Ics, Line+1, Tlen+1, Action, Alen); +yystate(23, [C|Ics], Line, Tlen, Action, Alen) when C >= 0, C =< 9 -> + yystate(23, Ics, Line, Tlen+1, Action, Alen); +yystate(23, [C|Ics], Line, Tlen, Action, Alen) when C >= 11, C =< 41 -> + yystate(23, Ics, Line, Tlen+1, Action, Alen); +yystate(23, [C|Ics], Line, Tlen, Action, Alen) when C >= 43 -> + yystate(23, Ics, Line, Tlen+1, Action, Alen); +yystate(23, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,23}; +yystate(22, [97|Ics], Line, Tlen, _, _) -> + yystate(26, Ics, Line, Tlen+1, 27, Tlen); +yystate(22, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(22, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(22, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(22, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(22, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(22, [C|Ics], Line, Tlen, _, _) when C >= 98, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(22, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,22}; +yystate(21, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 14, Tlen); +yystate(21, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 14, Tlen); +yystate(21, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 14, Tlen); +yystate(21, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 14, Tlen); +yystate(21, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 14, Tlen); +yystate(21, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 14, Tlen); +yystate(21, Ics, Line, Tlen, _, _) -> + {14,Tlen,Ics,Line,21}; +yystate(20, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 0, Tlen); +yystate(20, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 0, Tlen); +yystate(20, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 0, Tlen); +yystate(20, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 0, Tlen); +yystate(20, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 0, Tlen); +yystate(20, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 0, Tlen); +yystate(20, Ics, Line, Tlen, _, _) -> + {0,Tlen,Ics,Line,20}; +yystate(19, Ics, Line, Tlen, _, _) -> + {29,Tlen,Ics,Line}; +yystate(18, [116|Ics], Line, Tlen, _, _) -> + yystate(22, Ics, Line, Tlen+1, 27, Tlen); +yystate(18, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(18, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(18, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(18, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(18, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(18, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 115 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(18, [C|Ics], Line, Tlen, _, _) when C >= 117, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(18, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,18}; +yystate(17, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 6, Tlen); +yystate(17, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 6, Tlen); +yystate(17, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 6, Tlen); +yystate(17, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 6, Tlen); +yystate(17, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 6, Tlen); +yystate(17, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 6, Tlen); +yystate(17, Ics, Line, Tlen, _, _) -> + {6,Tlen,Ics,Line,17}; +yystate(16, Ics, Line, Tlen, _, _) -> + {23,Tlen,Ics,Line}; +yystate(15, [47|Ics], Line, Tlen, Action, Alen) -> + yystate(19, Ics, Line, Tlen+1, Action, Alen); +yystate(15, [42|Ics], Line, Tlen, Action, Alen) -> + yystate(15, Ics, Line, Tlen+1, Action, Alen); +yystate(15, [10|Ics], Line, Tlen, Action, Alen) -> + yystate(23, Ics, Line+1, Tlen+1, Action, Alen); +yystate(15, [C|Ics], Line, Tlen, Action, Alen) when C >= 0, C =< 9 -> + yystate(23, Ics, Line, Tlen+1, Action, Alen); +yystate(15, [C|Ics], Line, Tlen, Action, Alen) when C >= 11, C =< 41 -> + yystate(23, Ics, Line, Tlen+1, Action, Alen); +yystate(15, [C|Ics], Line, Tlen, Action, Alen) when C >= 43, C =< 46 -> + yystate(23, Ics, Line, Tlen+1, Action, Alen); +yystate(15, [C|Ics], Line, Tlen, Action, Alen) when C >= 48 -> + yystate(23, Ics, Line, Tlen+1, Action, Alen); +yystate(15, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,15}; +yystate(14, [102|Ics], Line, Tlen, _, _) -> + yystate(18, Ics, Line, Tlen+1, 27, Tlen); +yystate(14, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(14, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(14, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(14, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(14, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(14, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 101 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(14, [C|Ics], Line, Tlen, _, _) when C >= 103, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(14, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,14}; +yystate(13, [110|Ics], Line, Tlen, _, _) -> + yystate(9, Ics, Line, Tlen+1, 27, Tlen); +yystate(13, [109|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(13, [108|Ics], Line, Tlen, _, _) -> + yystate(1, Ics, Line, Tlen+1, 27, Tlen); +yystate(13, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(13, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(13, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(13, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(13, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(13, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 107 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(13, [C|Ics], Line, Tlen, _, _) when C >= 111, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(13, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,13}; +yystate(12, Ics, Line, Tlen, _, _) -> + {12,Tlen,Ics,Line}; +yystate(11, [47|Ics], Line, Tlen, Action, Alen) -> + yystate(59, Ics, Line, Tlen+1, Action, Alen); +yystate(11, [42|Ics], Line, Tlen, Action, Alen) -> + yystate(23, Ics, Line, Tlen+1, Action, Alen); +yystate(11, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,11}; +yystate(10, [101|Ics], Line, Tlen, _, _) -> + yystate(14, Ics, Line, Tlen+1, 27, Tlen); +yystate(10, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(10, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(10, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(10, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(10, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(10, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 100 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(10, [C|Ics], Line, Tlen, _, _) when C >= 102, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(10, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,10}; +yystate(9, [100|Ics], Line, Tlen, _, _) -> + yystate(5, Ics, Line, Tlen+1, 27, Tlen); +yystate(9, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(9, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(9, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(9, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(9, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(9, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 99 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(9, [C|Ics], Line, Tlen, _, _) when C >= 101, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(9, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,9}; +yystate(8, Ics, Line, Tlen, _, _) -> + {18,Tlen,Ics,Line}; +yystate(7, Ics, Line, Tlen, _, _) -> + {3,Tlen,Ics,Line}; +yystate(6, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 10, Tlen); +yystate(6, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 10, Tlen); +yystate(6, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 10, Tlen); +yystate(6, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 10, Tlen); +yystate(6, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 10, Tlen); +yystate(6, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 10, Tlen); +yystate(6, Ics, Line, Tlen, _, _) -> + {10,Tlen,Ics,Line,6}; +yystate(5, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 11, Tlen); +yystate(5, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 11, Tlen); +yystate(5, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 11, Tlen); +yystate(5, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 11, Tlen); +yystate(5, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 11, Tlen); +yystate(5, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 11, Tlen); +yystate(5, Ics, Line, Tlen, _, _) -> + {11,Tlen,Ics,Line,5}; +yystate(4, Ics, Line, Tlen, _, _) -> + {24,Tlen,Ics,Line}; +yystate(3, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(3, Ics, Line, Tlen+1, 3, Tlen); +yystate(3, Ics, Line, Tlen, _, _) -> + {3,Tlen,Ics,Line,3}; +yystate(2, [101|Ics], Line, Tlen, _, _) -> + yystate(6, Ics, Line, Tlen+1, 27, Tlen); +yystate(2, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(2, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(2, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(2, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(2, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(2, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 100 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(2, [C|Ics], Line, Tlen, _, _) when C >= 102, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(2, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,2}; +yystate(1, [115|Ics], Line, Tlen, _, _) -> + yystate(2, Ics, Line, Tlen+1, 27, Tlen); +yystate(1, [95|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(1, [45|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(1, [46|Ics], Line, Tlen, _, _) -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(1, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(1, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(1, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 114 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(1, [C|Ics], Line, Tlen, _, _) when C >= 116, C =< 122 -> + yystate(41, Ics, Line, Tlen+1, 27, Tlen); +yystate(1, Ics, Line, Tlen, _, _) -> + {27,Tlen,Ics,Line,1}; +yystate(0, Ics, Line, Tlen, _, _) -> + {7,Tlen,Ics,Line}; +yystate(S, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,S}. + +%% yyaction(Action, TokenLength, TokenChars, TokenLine) -> +%% {token,Token} | {end_token, Token} | skip_token | {error,String}. +%% Generated action function. + +yyaction(0, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_0(TokenChars, TokenLine); +yyaction(1, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_1(TokenChars, TokenLine); +yyaction(2, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_2(TokenChars, TokenLine); +yyaction(3, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_3(TokenChars, TokenLine); +yyaction(4, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_4(TokenChars, TokenLine); +yyaction(5, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_5(TokenChars, TokenLine); +yyaction(6, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_6(TokenChars, TokenLine); +yyaction(7, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_7(TokenChars, TokenLine); +yyaction(8, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_8(TokenChars, TokenLine); +yyaction(9, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_9(TokenChars, TokenLine); +yyaction(10, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_10(TokenChars, TokenLine); +yyaction(11, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_11(TokenChars, TokenLine); +yyaction(12, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_12(TokenChars, TokenLine); +yyaction(13, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_13(TokenChars, TokenLine); +yyaction(14, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_14(TokenChars, TokenLine); +yyaction(15, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_15(TokenChars, TokenLine); +yyaction(16, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_16(TokenChars, TokenLine); +yyaction(17, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_17(TokenChars, TokenLine); +yyaction(18, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_18(TokenChars, TokenLine); +yyaction(19, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_19(TokenChars, TokenLine); +yyaction(20, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_20(TokenChars, TokenLine); +yyaction(21, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_21(TokenChars, TokenLine); +yyaction(22, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_22(TokenChars, TokenLine); +yyaction(23, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_23(TokenChars, TokenLine); +yyaction(24, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_24(TokenChars, TokenLine); +yyaction(25, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_25(TokenChars, TokenLine); +yyaction(26, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_26(TokenChars, TokenLine); +yyaction(27, TokenLen, YYtcs, TokenLine) -> + TokenChars = yypre(YYtcs, TokenLen), + yyaction_27(TokenChars, TokenLine); +yyaction(28, _, _, _) -> + yyaction_28(); +yyaction(29, _, _, _) -> + yyaction_29(); +yyaction(30, _, _, _) -> + yyaction_30(); +yyaction(_, _, _, _) -> error. + +-compile({inline,yyaction_0/2}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 69). +yyaction_0(TokenChars, TokenLine) -> + { token, { bash, TokenLine, TokenChars } } . + +-compile({inline,yyaction_1/2}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 70). +yyaction_1(TokenChars, TokenLine) -> + { token, { python, TokenLine, TokenChars } } . + +-compile({inline,yyaction_2/2}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 71). +yyaction_2(TokenChars, TokenLine) -> + { token, { r, TokenLine, TokenChars } } . + +-compile({inline,yyaction_3/2}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 73). +yyaction_3(TokenChars, TokenLine) -> + { token, { intlit, TokenLine, TokenChars } } . + +-compile({inline,yyaction_4/2}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 74). +yyaction_4(TokenChars, TokenLine) -> + { token, { strlit, TokenLine, trim_strlit (TokenChars) } } . + +-compile({inline,yyaction_5/2}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 75). +yyaction_5(TokenChars, TokenLine) -> + { token, { body, TokenLine, trim_body (TokenChars) } } . + +-compile({inline,yyaction_6/2}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 76). +yyaction_6(TokenChars, TokenLine) -> + { token, { beginif, TokenLine, TokenChars } } . + +-compile({inline,yyaction_7/2}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 77). +yyaction_7(TokenChars, TokenLine) -> + { token, { colon, TokenLine, TokenChars } } . + +-compile({inline,yyaction_8/2}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 78). +yyaction_8(TokenChars, TokenLine) -> + { token, { comma, TokenLine, TokenChars } } . + +-compile({inline,yyaction_9/2}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 79). +yyaction_9(TokenChars, TokenLine) -> + { token, { deftask, TokenLine, TokenChars } } . + +-compile({inline,yyaction_10/2}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 80). +yyaction_10(TokenChars, TokenLine) -> + { token, { else, TokenLine, TokenChars } } . + +-compile({inline,yyaction_11/2}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 81). +yyaction_11(TokenChars, TokenLine) -> + { token, { endif, TokenLine, TokenChars } } . + +-compile({inline,yyaction_12/2}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 82). +yyaction_12(TokenChars, TokenLine) -> + { token, { eq, TokenLine, TokenChars } } . + +-compile({inline,yyaction_13/2}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 83). +yyaction_13(TokenChars, TokenLine) -> + { token, { file, TokenLine, TokenChars } } . + +-compile({inline,yyaction_14/2}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 84). +yyaction_14(TokenChars, TokenLine) -> + { token, { in, TokenLine, TokenChars } } . + +-compile({inline,yyaction_15/2}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 85). +yyaction_15(TokenChars, TokenLine) -> + { token, { lbrace, TokenLine, TokenChars } } . + +-compile({inline,yyaction_16/2}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 86). +yyaction_16(TokenChars, TokenLine) -> + { token, { lparen, TokenLine, TokenChars } } . + +-compile({inline,yyaction_17/2}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 87). +yyaction_17(TokenChars, TokenLine) -> + { token, { lsquarebr, TokenLine, TokenChars } } . + +-compile({inline,yyaction_18/2}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 88). +yyaction_18(TokenChars, TokenLine) -> + { token, { ltag, TokenLine, TokenChars } } . + +-compile({inline,yyaction_19/2}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 89). +yyaction_19(TokenChars, TokenLine) -> + { token, { nil, TokenLine, TokenChars } } . + +-compile({inline,yyaction_20/2}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 90). +yyaction_20(TokenChars, TokenLine) -> + { token, { rbrace, TokenLine, TokenChars } } . + +-compile({inline,yyaction_21/2}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 91). +yyaction_21(TokenChars, TokenLine) -> + { token, { rparen, TokenLine, TokenChars } } . + +-compile({inline,yyaction_22/2}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 92). +yyaction_22(TokenChars, TokenLine) -> + { token, { rsquarebr, TokenLine, TokenChars } } . + +-compile({inline,yyaction_23/2}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 93). +yyaction_23(TokenChars, TokenLine) -> + { token, { rtag, TokenLine, TokenChars } } . + +-compile({inline,yyaction_24/2}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 94). +yyaction_24(TokenChars, TokenLine) -> + { token, { semicolon, TokenLine, TokenChars } } . + +-compile({inline,yyaction_25/2}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 95). +yyaction_25(TokenChars, TokenLine) -> + { token, { string, TokenLine, TokenChars } } . + +-compile({inline,yyaction_26/2}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 96). +yyaction_26(TokenChars, TokenLine) -> + { token, { then, TokenLine, TokenChars } } . + +-compile({inline,yyaction_27/2}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 98). +yyaction_27(TokenChars, TokenLine) -> + { token, { id, TokenLine, TokenChars } } . + +-compile({inline,yyaction_28/0}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 100). +yyaction_28() -> + skip_token . + +-compile({inline,yyaction_29/0}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 101). +yyaction_29() -> + skip_token . + +-compile({inline,yyaction_30/0}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 102). +yyaction_30() -> + skip_token . + +-file("/usr/local/lib/erlang/lib/parsetools-2.1.1/include/leexinc.hrl", 290). diff --git a/src/cf.app.src b/src/cuneiform.app.src similarity index 81% rename from src/cf.app.src rename to src/cuneiform.app.src index f8c3e2a..c881681 100644 --- a/src/cf.app.src +++ b/src/cuneiform.app.src @@ -1,4 +1,4 @@ -{application, cf, +{application, cuneiform, [ {description, "Cuneiform: A Functional Language for Large Scale Scientific Data Analysis"}, {vsn, "2.2.0"}, @@ -7,6 +7,6 @@ kernel, stdlib ]}, - {mod, { cf_app, []}}, + {mod, { cuneiform_app, []}}, {env, []} ]}. diff --git a/src/cf.erl b/src/cuneiform.erl similarity index 98% rename from src/cf.erl rename to src/cuneiform.erl index f5bd171..bba35a7 100644 --- a/src/cf.erl +++ b/src/cuneiform.erl @@ -16,7 +16,7 @@ % See the License for the specific language governing permissions and % limitations under the License. --module( cf ). +-module( cuneiform ). -author( "Jorgen Brandt " ). % API @@ -27,7 +27,7 @@ %% ============================================================================= start() -> - application:start( cf ). + application:start( cuneiform ). -spec string( S::string(), DataDir::string() ) -> [cf_sem:str()]. diff --git a/src/cf_app.erl b/src/cuneiform_app.erl similarity index 97% rename from src/cf_app.erl rename to src/cuneiform_app.erl index cc4d1f9..4ee9e58 100644 --- a/src/cf_app.erl +++ b/src/cuneiform_app.erl @@ -16,7 +16,7 @@ % See the License for the specific language governing permissions and % limitations under the License. --module( cf_app ). +-module( cuneiform_app ). -author( "Jorgen Brandt " ). -behaviour( application ). From dbb4a426e98ba12c6619db7526059bc7cedf7b69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Fri, 11 Mar 2016 17:02:58 +0100 Subject: [PATCH 30/78] Minor changes. --- src/cuneiform.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cuneiform.erl b/src/cuneiform.erl index bba35a7..7d295da 100644 --- a/src/cuneiform.erl +++ b/src/cuneiform.erl @@ -100,7 +100,7 @@ reduce( X0, {Rho, Mu, Gamma, Omega}, DataDir ) -> {finished, Summary} -> Ret = maps:get( ret, Summary ), - R = maps:get( prefix, Summary ), + % R = maps:get( prefix, Summary ), Delta = lists:foldl( fun( N, Delta0 ) -> acc_delta( N, Delta0, Ret, R ) From a7fa059a4d4fd9ec09846b62bfc0cc36543faeaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Mon, 14 Mar 2016 08:53:36 +0100 Subject: [PATCH 31/78] Message passing fixed. --- src/cuneiform.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cuneiform.erl b/src/cuneiform.erl index 7d295da..329e21d 100644 --- a/src/cuneiform.erl +++ b/src/cuneiform.erl @@ -100,7 +100,7 @@ reduce( X0, {Rho, Mu, Gamma, Omega}, DataDir ) -> {finished, Summary} -> Ret = maps:get( ret, Summary ), - % R = maps:get( prefix, Summary ), + R = maps:get( id, Summary ), Delta = lists:foldl( fun( N, Delta0 ) -> acc_delta( N, Delta0, Ret, R ) @@ -121,4 +121,4 @@ when N :: string(), R :: pos_integer(). acc_delta( N, Delta0, Ret, R ) -> - Delta0#{{N, R} => [{str, S} || S <- maps:get( N, Ret )]}. \ No newline at end of file + Delta0#{{N, R} => maps:get( N, Ret )}. \ No newline at end of file From ecaa3caa74e55e9be8958472a2747724631d0de0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Thu, 17 Mar 2016 17:27:16 +0100 Subject: [PATCH 32/78] Take on Cuneiform shell. --- .travis.yml | 1 + src/cf_shell.erl | 115 ++++++++++++++++++++++++++++++++++++++++++++++ src/cuneiform.erl | 2 +- 3 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 src/cf_shell.erl diff --git a/.travis.yml b/.travis.yml index d00a957..75ddc2a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,6 @@ language: erlang otp_release: + - 18.3 - 18.2.1 - 18.2 - 18.1 diff --git a/src/cf_shell.erl b/src/cf_shell.erl new file mode 100644 index 0000000..8b3180d --- /dev/null +++ b/src/cf_shell.erl @@ -0,0 +1,115 @@ +%% -*- erlang -*- +% +% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis +% +% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser +% +% Licensed under the Apache License, Version 2.0 (the "License"); +% you may not use this file except in compliance with the License. +% You may obtain a copy of the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, +% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +% See the License for the specific language governing permissions and +% limitations under the License. + +-module( cf_shell ). +-author( "Jorgen Brandt " ). + +%% ============================================================================= +%% Function Exports +%% ============================================================================= + +-export( [server/0] ). + +%% ============================================================================= +%% Type Definitions +%% ============================================================================= + + +%% ============================================================================= +%% Macro Definitions +%% ============================================================================= + +-define( VSN, "2.2.0" ). +-define( BUILD, "2016-03-17" ). + +-define( RED( Str ), "\e[31m" ++ Str ++ "\e[0m" ). +-define( GRN( Str ), "\e[1;32m" ++ Str ++ "\e[0m" ). +-define( YLW( Str ), "\e[1;33m" ++ Str ++ "\e[0m" ). +-define( BLU( Str ), "\e[1;34m" ++ Str ++ "\e[0m" ). + +-define( PROMPT, "> " ). + + + + + + + +%% ============================================================================= +%% Internal Functions +%% ============================================================================= + + +server() -> + process_flag( trap_exit, true ), + io:format( "~s", [get_banner()] ), + server_loop( #{}, #{} ). + +server_loop( Rho, Gamma ) -> + + {Query, DRho, DGamma} = read_expression( ?PROMPT ), + + Rho1 = maps:merge( Rho, DRho ), + Gamma1 = maps:merge( Gamma, DGamma ), + case Query of + + undef -> server_loop( Rho1, Gamma1 ); + _ -> + cuneiform:reduce( Query, Rho, Gamma, "." ), + server_loop( Rho, Gamma ) + + end. + + + +read_expression( Prompt ) -> + Read = fun() -> + io:format( Prompt ), + Ret = read(), + exit( Ret ) + end, + Rdr = spawn_link( Read ), + read_expression_1( Rdr ). + +read_expression_1( Rdr ) -> + receive + {'EXIT', Rdr, Ret} -> Ret; + Msg -> error( {bad_msg, Msg} ) + end. + +read() -> + S = io:get_line( "" ), + {ok, TokenLst, _} = cf_scan:string( S ), + {ok, Ret} = cf_parse:parse( TokenLst ), + Ret. + + + +get_banner() -> + string:join( + [" ___", + " @@WB Cuneiform", + " @@E_____ "++?VSN++" "++?BUILD, + " _g@@@@@WWWWWWL", + " g@@#*`3@B Type "++?GRN( "help;" )++" for usage info.", + " @@P 3@B", + " @N____ 3@B Home: "++?BLU( "http://www.cuneiform-lang.org" ), + " \"W@@@WF3@B", + "", "" + ], "\n" ). + diff --git a/src/cuneiform.erl b/src/cuneiform.erl index 329e21d..a49a159 100644 --- a/src/cuneiform.erl +++ b/src/cuneiform.erl @@ -20,7 +20,7 @@ -author( "Jorgen Brandt " ). % API --export( [start/0, string/2, file/1, file/2] ). +-export( [start/0, string/2, file/1, file/2, reduce/4] ). %% ============================================================================= %% API functions From 2d793ae977946df3c71d7e8be232274633b37100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Thu, 17 Mar 2016 17:31:47 +0100 Subject: [PATCH 33/78] Fixed. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 75ddc2a..925969f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: erlang otp_release: - - 18.3 +# - 18.3 - 18.2.1 - 18.2 - 18.1 From 1c69bcd4df921aa417fcc3544523c80d85dd6b88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Fri, 18 Mar 2016 16:06:17 +0100 Subject: [PATCH 34/78] Shell improved. --- src/cf_parse.erl | 47 +++-- src/cf_parse.yrl | 43 ++-- src/cf_sem.erl | 37 +++- src/cf_shell.erl | 145 ++++++++++---- src/cuneiform.erl | 22 +- src/pre_scan.erl | 464 +++++++++++++++++++++++++++++++++++++++++++ src/pre_scan.xrl | 60 ++++++ test/cf_sem_test.erl | 10 +- 8 files changed, 720 insertions(+), 108 deletions(-) create mode 100644 src/pre_scan.erl create mode 100644 src/pre_scan.xrl diff --git a/src/cf_parse.erl b/src/cf_parse.erl index 0c17f53..67068a6 100644 --- a/src/cf_parse.erl +++ b/src/cf_parse.erl @@ -24,7 +24,14 @@ string( S ) -> combine( {Target1, Rho1, Global1}, {Target2, Rho2, Global2} ) -> - {Target1++Target2, maps:merge( Rho1, Rho2 ), maps:merge( Global1, Global2 )}. + case Target1 of + undef -> {Target2, maps:merge( Rho1, Rho2 ), maps:merge( Global1, Global2 )}; + _ -> + case Target2 of + undef -> {undef, maps:merge( Rho1, Rho2 ), maps:merge( Global1, Global2 )}; + _ -> {Target1++Target2, maps:merge( Rho1, Rho2 ), maps:merge( Global1, Global2 )} + end + end. mk_var( {id, Line, Name} ) -> {var, Line, Name}. @@ -103,42 +110,42 @@ app_should_be_recognized_test() -> assign_should_be_recognized_test() -> - [?assertEqual( {[], #{"x" => [{str, "x"}]}, #{}}, string( "x = \"x\";" ) ), - ?assertEqual( {[], #{"x" => [{app, 1, 1, {var, 1, "f"}, #{}}], "y" => [{app, 1, 2, {var, 1, "f"}, #{}}]}, #{}}, string( "x y = f();" ) ), + [?assertEqual( {undef, #{"x" => [{str, "x"}]}, #{}}, string( "x = \"x\";" ) ), + ?assertEqual( {undef, #{"x" => [{app, 1, 1, {var, 1, "f"}, #{}}], "y" => [{app, 1, 2, {var, 1, "f"}, #{}}]}, #{}}, string( "x y = f();" ) ), ?assertError( {parser, nonapp_expr, str, "A"}, string( "x y = \"A\";" ) ), ?assertError( {parser, nonvar_expr_left_of_eq, str, "a"}, string( "\"a\" = \"A\";" ) )]. native_deftask_should_be_recognized_test() -> - ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, {natbody, #{"out" => [{str, "A"}]}}}}}, string( "deftask f( out : ) { out = \"A\"; }" ) ). foreign_deftask_should_be_recognized_test() -> - [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + [?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, {forbody, bash, "out=A"}}}}, string( "deftask f( out : )in bash *{out=A}*" ) ), - ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, {forbody, r, "out=\"A\""}}}}, string( "deftask f( out : )in R *{out=\"A\"}*" ) ), - ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, {forbody, python, ""}}}}, string( "deftask f( out : )in python *{}*" ) )]. sign_with_inparam_should_be_recognized_test() -> - [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + [?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], [{param, {name, "inp", false}, false}]}, {forbody, python, "(defparameter out \"A\")"}}}}, string( "deftask f( out : inp )in python *{(defparameter out \"A\")}*" ) ), - ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], [{param, {name, "a", false}, false}, {param, {name, "b", false}, false}]}, @@ -146,40 +153,40 @@ sign_with_inparam_should_be_recognized_test() -> string( "deftask f( out : a b )in python *{(defparameter out \"A\")}*" ) )]. param_should_be_recognized_test() -> - [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + [?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], [{param, {name, "inp", false}, false}]}, {forbody, bash, "blub"}}}}, string( "deftask f( out( String ) : inp( String ) )in bash *{blub}*" ) ), - ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", true}, false}], [{param, {name, "inp", true}, false}]}, {forbody, bash, "blub"}}}}, string( "deftask f( out( File ) : inp( File ) )in bash *{blub}*" ) ), - ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, true}], [{param, {name, "inp", false}, true}]}, {forbody, bash, "blub"}}}}, string( "deftask f( : )in bash *{blub}*" ) ), - ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, true}], [{param, {name, "inp", false}, true}]}, {forbody, bash, "blub"}}}}, string( "deftask f( : )in bash *{blub}*" ) ), - ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", true}, true}], [{param, {name, "inp", true}, true}]}, {forbody, bash, "blub"}}}}, string( "deftask f( : )in bash *{blub}*" ) )]. correl_inparam_should_be_recognized_test() -> - [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + [?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], [{correl, [{name, "a", true}, {name, "b", true}]}]}, {forbody, bash, "blub"}}}}, string( "deftask f( out : [a( File ) b( File )] )in bash *{blub}*" ) ), - ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], [{correl, [{name, "a", true}, {name, "b", true}]}, @@ -365,7 +372,7 @@ yecctoken2string(Other) -> --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.erl", 368). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.erl", 375). -dialyzer({nowarn_function, yeccpars2/7}). yeccpars2(0=S, Cat, Ss, Stack, T, Ts, Tzr) -> @@ -1200,7 +1207,7 @@ yeccpars2_5_(__Stack0) -> yeccpars2_6_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin - { [ ] , # { } , __1 } + { undef , # { } , __1 } end | __Stack]. -compile({inline,yeccpars2_9_/1}). @@ -1208,7 +1215,7 @@ yeccpars2_6_(__Stack0) -> yeccpars2_9_(__Stack0) -> [__1 | __Stack] = __Stack0, [begin - { [ ] , __1 , # { } } + { undef , __1 , # { } } end | __Stack]. -compile({inline,yeccpars2_13_/1}). @@ -1476,4 +1483,4 @@ yeccpars2_79_(__Stack0) -> end | __Stack]. --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 301). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 308). diff --git a/src/cf_parse.yrl b/src/cf_parse.yrl index 3bf02db..9b8b5dd 100644 --- a/src/cf_parse.yrl +++ b/src/cf_parse.yrl @@ -42,8 +42,8 @@ script -> stat : '$1'. script -> stat script : combine( '$1', '$2' ). stat -> query : {'$1', #{}, #{}}. -stat -> assign : {[], '$1', #{}}. -stat -> defun : {[], #{}, '$1'}. +stat -> assign : {undef, '$1', #{}}. +stat -> defun : {undef, #{}, '$1'}. query -> compoundexpr semicolon : '$1'. @@ -132,7 +132,14 @@ string( S ) -> combine( {Target1, Rho1, Global1}, {Target2, Rho2, Global2} ) -> - {Target1++Target2, maps:merge( Rho1, Rho2 ), maps:merge( Global1, Global2 )}. + case Target1 of + undef -> {Target2, maps:merge( Rho1, Rho2 ), maps:merge( Global1, Global2 )}; + _ -> + case Target2 of + undef -> {undef, maps:merge( Rho1, Rho2 ), maps:merge( Global1, Global2 )}; + _ -> {Target1++Target2, maps:merge( Rho1, Rho2 ), maps:merge( Global1, Global2 )} + end + end. mk_var( {id, Line, Name} ) -> {var, Line, Name}. @@ -211,42 +218,42 @@ app_should_be_recognized_test() -> assign_should_be_recognized_test() -> - [?assertEqual( {[], #{"x" => [{str, "x"}]}, #{}}, string( "x = \"x\";" ) ), - ?assertEqual( {[], #{"x" => [{app, 1, 1, {var, 1, "f"}, #{}}], "y" => [{app, 1, 2, {var, 1, "f"}, #{}}]}, #{}}, string( "x y = f();" ) ), + [?assertEqual( {undef, #{"x" => [{str, "x"}]}, #{}}, string( "x = \"x\";" ) ), + ?assertEqual( {undef, #{"x" => [{app, 1, 1, {var, 1, "f"}, #{}}], "y" => [{app, 1, 2, {var, 1, "f"}, #{}}]}, #{}}, string( "x y = f();" ) ), ?assertError( {parser, nonapp_expr, str, "A"}, string( "x y = \"A\";" ) ), ?assertError( {parser, nonvar_expr_left_of_eq, str, "a"}, string( "\"a\" = \"A\";" ) )]. native_deftask_should_be_recognized_test() -> - ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, {natbody, #{"out" => [{str, "A"}]}}}}}, string( "deftask f( out : ) { out = \"A\"; }" ) ). foreign_deftask_should_be_recognized_test() -> - [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + [?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, {forbody, bash, "out=A"}}}}, string( "deftask f( out : )in bash *{out=A}*" ) ), - ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, {forbody, r, "out=\"A\""}}}}, string( "deftask f( out : )in R *{out=\"A\"}*" ) ), - ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, {forbody, python, ""}}}}, string( "deftask f( out : )in python *{}*" ) )]. sign_with_inparam_should_be_recognized_test() -> - [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + [?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], [{param, {name, "inp", false}, false}]}, {forbody, python, "(defparameter out \"A\")"}}}}, string( "deftask f( out : inp )in python *{(defparameter out \"A\")}*" ) ), - ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], [{param, {name, "a", false}, false}, {param, {name, "b", false}, false}]}, @@ -254,40 +261,40 @@ sign_with_inparam_should_be_recognized_test() -> string( "deftask f( out : a b )in python *{(defparameter out \"A\")}*" ) )]. param_should_be_recognized_test() -> - [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + [?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], [{param, {name, "inp", false}, false}]}, {forbody, bash, "blub"}}}}, string( "deftask f( out( String ) : inp( String ) )in bash *{blub}*" ) ), - ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", true}, false}], [{param, {name, "inp", true}, false}]}, {forbody, bash, "blub"}}}}, string( "deftask f( out( File ) : inp( File ) )in bash *{blub}*" ) ), - ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, true}], [{param, {name, "inp", false}, true}]}, {forbody, bash, "blub"}}}}, string( "deftask f( : )in bash *{blub}*" ) ), - ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, true}], [{param, {name, "inp", false}, true}]}, {forbody, bash, "blub"}}}}, string( "deftask f( : )in bash *{blub}*" ) ), - ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", true}, true}], [{param, {name, "inp", true}, true}]}, {forbody, bash, "blub"}}}}, string( "deftask f( : )in bash *{blub}*" ) )]. correl_inparam_should_be_recognized_test() -> - [?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + [?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], [{correl, [{name, "a", true}, {name, "b", true}]}]}, {forbody, bash, "blub"}}}}, string( "deftask f( out : [a( File ) b( File )] )in bash *{blub}*" ) ), - ?assertEqual( {[], #{}, #{"f" => {lam, 1, "f", + ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], [{correl, [{name, "a", true}, {name, "b", true}]}, diff --git a/src/cf_sem.erl b/src/cf_sem.erl index ab9ff5a..c58b9e3 100644 --- a/src/cf_sem.erl +++ b/src/cf_sem.erl @@ -35,7 +35,7 @@ -type str() :: {str, S::string()}. % (2) -type var() :: {var, Line::pos_integer(), N::string()}. % (3) -type select() :: {select, Line::pos_integer(), C::pos_integer(), U::fut()}. % (4) --type fut() :: {fut, Name::string(), R::pos_integer(), Lo::[param()]}. % (5) +-type fut() :: {fut, LamName::string(), R::pos_integer(), Lo::[param()]}. % (5) -type cnd() :: {cnd, Line::pos_integer(), % (6) Xc::[expr()], Xt::[expr()], Xe::[expr()]}. -type app() :: {app, Line::pos_integer(), C::pos_integer(), % (7) @@ -88,21 +88,30 @@ pfinal( _T ) -> false. -spec psing( A::app() ) -> boolean(). % (24) -psing( {app, _, _C, {lam, _, _, {sign, _Lo, Li}, _B}, Fa} ) -> % (25) - psing_argpair( {Li, Fa} ). +psing( {app, Line, _C, {lam, _, LamName, {sign, _Lo, Li}, _B}, Fa} ) -> % (25) + case psing_argpair( {Li, Fa} ) of + {ok, P} -> P; + {error, N} -> + throw( {Line, cf_sem, + "argument "++N++" is unbound in application of "++LamName} ) + end. --spec psing_argpair( Z::argpair() ) -> boolean(). % (26) +-spec psing_argpair( Z::argpair() ) -> {ok, boolean()} | {error, string()}. % (26) -psing_argpair( {[], _F} ) -> true; % (27) +psing_argpair( {[], _F} ) -> {ok, true}; % (27) psing_argpair( {[{param, _, Pl}|T], F} ) % (28) when Pl -> psing_argpair( {T, F} ); psing_argpair( {[{param, {name, N, _}, _Pl}|T], F} ) -> % (29) - case length( maps:get( N, F ) ) of - 1 -> psing_argpair( {T, F} ); - _ -> false + case maps:is_key( N, F ) of + false -> {error, N}; + true -> + case length( maps:get( N, F ) ) of + 1 -> psing_argpair( {T, F} ); + _ -> {ok, false} + end end; -psing_argpair( _Z ) -> false. +psing_argpair( _Z ) -> {ok, false}. %% Enumerability %% ============================================================ @@ -163,7 +172,10 @@ step( X={str, _S}, _Theta ) -> [X]; % Variable step( {var, _, N}, {Rho, _Mu, _Gamma, _Omega} ) -> % (46) - maps:get( N, Rho ); + case maps:is_key( N, Rho ) of + true -> maps:get( N, Rho ); + false -> throw( {1, cf_sem, "unbound variable "++N} ) + end; % Future Channel Selection step( S={select, _, C, {fut, _, R, Lo}}, {_Rho, _Mu, _Gamma, Omega} ) -> % (47,48) @@ -180,7 +192,10 @@ step( {cnd, Line, Xc=[_|_], Xt, Xe}, Theta ) -> % Application step( {app, Line, C, {var, _, N}, Fa}, {_Rho, _Mu, Gamma, _Omega} ) -> % (52) - [{app, Line, C, maps:get( N, Gamma ), Fa}]; + case maps:is_key( N, Gamma ) of + true -> [{app, Line, C, maps:get( N, Gamma ), Fa}]; + false -> throw( {Line, cf_sem, "undefined task "++N} ) + end; step( X={app, AppLine, C, Lambda={lam, LamLine, LamName, S={sign, Lo, _Li}, B}, Fa}, diff --git a/src/cf_shell.erl b/src/cf_shell.erl index 8b3180d..378ba6d 100644 --- a/src/cf_shell.erl +++ b/src/cf_shell.erl @@ -38,18 +38,14 @@ -define( BUILD, "2016-03-17" ). -define( RED( Str ), "\e[31m" ++ Str ++ "\e[0m" ). --define( GRN( Str ), "\e[1;32m" ++ Str ++ "\e[0m" ). --define( YLW( Str ), "\e[1;33m" ++ Str ++ "\e[0m" ). +-define( BRED( Str ), "\e[1;31m" ++ Str ++ "\e[0m" ). +-define( GRN( Str ), "\e[32m" ++ Str ++ "\e[0m" ). +-define( YLW( Str ), "\e[33m" ++ Str ++ "\e[0m" ). +-define( BYLW( Str ), "\e[1;33m" ++ Str ++ "\e[0m" ). -define( BLU( Str ), "\e[1;34m" ++ Str ++ "\e[0m" ). -define( PROMPT, "> " ). - - - - - - %% ============================================================================= %% Internal Functions %% ============================================================================= @@ -57,22 +53,39 @@ server() -> process_flag( trap_exit, true ), - io:format( "~s", [get_banner()] ), + io:format( "~s~n~n~n", [get_banner()] ), server_loop( #{}, #{} ). server_loop( Rho, Gamma ) -> - - {Query, DRho, DGamma} = read_expression( ?PROMPT ), - - Rho1 = maps:merge( Rho, DRho ), - Gamma1 = maps:merge( Gamma, DGamma ), - case Query of - - undef -> server_loop( Rho1, Gamma1 ); - _ -> - cuneiform:reduce( Query, Rho, Gamma, "." ), - server_loop( Rho, Gamma ) - + case read_expression( ?PROMPT ) of + {ctl, quit} -> + ok; + {ctl, help} -> + io:format( "~n~s~n~n", [get_help()] ), + server_loop( Rho, Gamma ); + {ctl, state} -> + io:format( "~p~n", [Rho] ), + server_loop( Rho, Gamma ); + {ctl, tasks} -> + io:format( "~p~n", [Gamma] ), + server_loop( Rho, Gamma ); + {error, ErrorInfo} -> + S = format_error( ErrorInfo ), + io:format( "~s~n", [S] ), + server_loop( Rho, Gamma ); + {ok, {Query, DRho, DGamma}} -> + Rho1 = maps:merge( Rho, DRho ), + Gamma1 = maps:merge( Gamma, DGamma ), + case Query of + undef -> server_loop( Rho1, Gamma1 ); + _ -> + try cuneiform:reduce( Query, Rho, Gamma, "." ) of + X -> io:format( "~s~n", [format_result( X )] ) + catch + throw:T -> io:format( "~s~n", [format_error( T )] ) + end, + server_loop( Rho, Gamma ) + end end. @@ -80,24 +93,67 @@ server_loop( Rho, Gamma ) -> read_expression( Prompt ) -> Read = fun() -> io:format( Prompt ), - Ret = read(), + Ret = read( [] ), exit( Ret ) end, Rdr = spawn_link( Read ), - read_expression_1( Rdr ). - -read_expression_1( Rdr ) -> receive {'EXIT', Rdr, Ret} -> Ret; Msg -> error( {bad_msg, Msg} ) end. -read() -> +read( Buf ) -> S = io:get_line( "" ), - {ok, TokenLst, _} = cf_scan:string( S ), - {ok, Ret} = cf_parse:parse( TokenLst ), - Ret. + {ok, TokenLst, _} = pre_scan:string( S ), + case TokenLst of + [] -> + case Buf of + [] -> {ok, {undef, #{}, #{}}}; + [_|_] -> read( Buf ) + end; + [_|_] -> + case lists:last( TokenLst ) of + terminal -> parse_string( Buf++S ); + nonws -> read( Buf++S ); + C -> {ctl, C} + end + end. + +parse_string( S ) -> + case cf_scan:string( S ) of + {error, ScanErrorInfo, _} -> {error, ScanErrorInfo}; + {ok, TokenLst, _} -> + case cf_parse:parse( TokenLst ) of + {error, ParseErrorInfo} -> {error, ParseErrorInfo}; + {ok, Triple} -> {ok, Triple} + end + end. + +format_error( {Line, cf_scan, {illegal, Token}} ) -> + io_lib:format( ?RED( "Line ~p: " )++?BRED( "illegal token ~s" ), [Line, Token] ); + +format_error( {Line, cf_parse, S} ) -> + io_lib:format( ?RED( "Line ~p: " )++?BRED( "~s" ), [Line, S] ); + +format_error( {Line, cf_sem, S} ) -> + io_lib:format( ?RED( "Line ~p: " )++?BRED( "~s" ), [Line, S] ); + +format_error( {LamLine, cuneiform, {R, script_error, LamName, _Fa, {ActScript, Out}}} ) -> + io_lib:format( + ?BYLW( "[out]~n" )++?RED( "~s~n" ) + ++?BYLW( "[script]~n" )++?YLW( "~s~n" ) + ++?RED( "Line ~p: " )++?BRED( "script error in call to ~s (~p)" ), + [format_out( Out ), format_script( ActScript ), LamLine, LamName, R] ); + +format_error( ErrorInfo ) -> + io_lib:format( ?RED( "Error: " )++?BRED( "~p" ), [ErrorInfo] ). + +format_result( StrLst ) -> + F = fun( {str, S}, AccIn ) -> + io_lib:format( "~s\"~s\" ", [AccIn, S] ) + end, + io_lib:format( ?GRN( "~s" ), [lists:foldl( F, "", StrLst )] ). get_banner() -> @@ -106,10 +162,31 @@ get_banner() -> " @@WB Cuneiform", " @@E_____ "++?VSN++" "++?BUILD, " _g@@@@@WWWWWWL", - " g@@#*`3@B Type "++?GRN( "help;" )++" for usage info.", - " @@P 3@B", - " @N____ 3@B Home: "++?BLU( "http://www.cuneiform-lang.org" ), - " \"W@@@WF3@B", - "", "" + " g@@#*`3@B Type "++?BYLW( "help" )++" for usage info.", + " @@P 3@B Type "++?BYLW( "quit" )++" to quit.", + " @N____ 3@B Docs: "++?BLU( "http://www.cuneiform-lang.org" ), + " \"W@@@WF3@B Code: "++?BLU( "https://github.com/joergen7/cuneiform" ) + ], "\n" ). + +get_help() -> + string:join( + ["help -- Show this usage info", + "quit -- Quit the shell", + "state -- Show variable bindings", + "tasks -- Show task definitions" ], "\n" ). + + + + + +format_out( Out ) -> + [io_lib:format( "~s~n", [Line] ) || Line <- Out]. + +format_script( ActScript ) -> + {_, S} = lists:foldl( fun( Line, {N, S} ) -> + {N+1, io_lib:format( "~s~4.B ~s~n", [S, N, Line] )} + end, + {1, []}, re:split( ActScript, "\n" ) ), + S. \ No newline at end of file diff --git a/src/cuneiform.erl b/src/cuneiform.erl index a49a159..916d435 100644 --- a/src/cuneiform.erl +++ b/src/cuneiform.erl @@ -77,26 +77,8 @@ reduce( X0, {Rho, Mu, Gamma, Omega}, DataDir ) -> false -> receive - {failed, script_error, {ActScript, Out}} -> - - % print tool output - ok = lists:foreach( fun( Line ) -> - io:format( "~s~n", [Line] ) - end, - Out ), - - % print actual script - ok = io:format( "[script]~n" ), - _ = lists:foldl( fun( Line, N ) -> - ok = io:format( "~4.B ~s~n", [N, Line] ), - N+1 - end, - 1, re:split( ActScript, "\n" ) ), - - error( script_error ); - - {failed, Reason, Data} -> - error( {Reason, Data} ); + {failed, R, R2, {LamLine, LamName, Fa1}, Data} -> + throw( {LamLine, cuneiform, {R, R2, LamName, Fa1, Data}} ); {finished, Summary} -> Ret = maps:get( ret, Summary ), diff --git a/src/pre_scan.erl b/src/pre_scan.erl new file mode 100644 index 0000000..114c89d --- /dev/null +++ b/src/pre_scan.erl @@ -0,0 +1,464 @@ +-file("/usr/local/lib/erlang/lib/parsetools-2.1.1/include/leexinc.hrl", 0). +%% The source of this file is part of leex distribution, as such it +%% has the same Copyright as the other files in the leex +%% distribution. The Copyright is defined in the accompanying file +%% COPYRIGHT. However, the resultant scanner generated by leex is the +%% property of the creator of the scanner and is not covered by that +%% Copyright. + +-module(pre_scan). + +-export([string/1,string/2,token/2,token/3,tokens/2,tokens/3]). +-export([format_error/1]). + +%% User code. This is placed here to allow extra attributes. +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 56). + +-author( "Jorgen Brandt " ). + +-export( [yyrev/2] ). +-file("/usr/local/lib/erlang/lib/parsetools-2.1.1/include/leexinc.hrl", 14). + +format_error({illegal,S}) -> ["illegal characters ",io_lib:write_string(S)]; +format_error({user,S}) -> S. + +string(String) -> string(String, 1). + +string(String, Line) -> string(String, Line, String, []). + +%% string(InChars, Line, TokenChars, Tokens) -> +%% {ok,Tokens,Line} | {error,ErrorInfo,Line}. +%% Note the line number going into yystate, L0, is line of token +%% start while line number returned is line of token end. We want line +%% of token start. + +string([], L, [], Ts) -> % No partial tokens! + {ok,yyrev(Ts),L}; +string(Ics0, L0, Tcs, Ts) -> + case yystate(yystate(), Ics0, L0, 0, reject, 0) of + {A,Alen,Ics1,L1} -> % Accepting end state + string_cont(Ics1, L1, yyaction(A, Alen, Tcs, L0), Ts); + {A,Alen,Ics1,L1,_S1} -> % Accepting transistion state + string_cont(Ics1, L1, yyaction(A, Alen, Tcs, L0), Ts); + {reject,_Alen,Tlen,_Ics1,L1,_S1} -> % After a non-accepting state + {error,{L0,?MODULE,{illegal,yypre(Tcs, Tlen+1)}},L1}; + {A,Alen,_Tlen,_Ics1,_L1,_S1} -> + string_cont(yysuf(Tcs, Alen), L0, yyaction(A, Alen, Tcs, L0), Ts) + end. + +%% string_cont(RestChars, Line, Token, Tokens) +%% Test for and remove the end token wrapper. Push back characters +%% are prepended to RestChars. + +-dialyzer({nowarn_function, string_cont/4}). + +string_cont(Rest, Line, {token,T}, Ts) -> + string(Rest, Line, Rest, [T|Ts]); +string_cont(Rest, Line, {token,T,Push}, Ts) -> + NewRest = Push ++ Rest, + string(NewRest, Line, NewRest, [T|Ts]); +string_cont(Rest, Line, {end_token,T}, Ts) -> + string(Rest, Line, Rest, [T|Ts]); +string_cont(Rest, Line, {end_token,T,Push}, Ts) -> + NewRest = Push ++ Rest, + string(NewRest, Line, NewRest, [T|Ts]); +string_cont(Rest, Line, skip_token, Ts) -> + string(Rest, Line, Rest, Ts); +string_cont(Rest, Line, {skip_token,Push}, Ts) -> + NewRest = Push ++ Rest, + string(NewRest, Line, NewRest, Ts); +string_cont(_Rest, Line, {error,S}, _Ts) -> + {error,{Line,?MODULE,{user,S}},Line}. + +%% token(Continuation, Chars) -> +%% token(Continuation, Chars, Line) -> +%% {more,Continuation} | {done,ReturnVal,RestChars}. +%% Must be careful when re-entering to append the latest characters to the +%% after characters in an accept. The continuation is: +%% {token,State,CurrLine,TokenChars,TokenLen,TokenLine,AccAction,AccLen} + +token(Cont, Chars) -> token(Cont, Chars, 1). + +token([], Chars, Line) -> + token(yystate(), Chars, Line, Chars, 0, Line, reject, 0); +token({token,State,Line,Tcs,Tlen,Tline,Action,Alen}, Chars, _) -> + token(State, Chars, Line, Tcs ++ Chars, Tlen, Tline, Action, Alen). + +%% token(State, InChars, Line, TokenChars, TokenLen, TokenLine, +%% AcceptAction, AcceptLen) -> +%% {more,Continuation} | {done,ReturnVal,RestChars}. +%% The argument order is chosen to be more efficient. + +token(S0, Ics0, L0, Tcs, Tlen0, Tline, A0, Alen0) -> + case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of + %% Accepting end state, we have a token. + {A1,Alen1,Ics1,L1} -> + token_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline)); + %% Accepting transition state, can take more chars. + {A1,Alen1,[],L1,S1} -> % Need more chars to check + {more,{token,S1,L1,Tcs,Alen1,Tline,A1,Alen1}}; + {A1,Alen1,Ics1,L1,_S1} -> % Take what we got + token_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline)); + %% After a non-accepting state, maybe reach accept state later. + {A1,Alen1,Tlen1,[],L1,S1} -> % Need more chars to check + {more,{token,S1,L1,Tcs,Tlen1,Tline,A1,Alen1}}; + {reject,_Alen1,Tlen1,eof,L1,_S1} -> % No token match + %% Check for partial token which is error. + Ret = if Tlen1 > 0 -> {error,{Tline,?MODULE, + %% Skip eof tail in Tcs. + {illegal,yypre(Tcs, Tlen1)}},L1}; + true -> {eof,L1} + end, + {done,Ret,eof}; + {reject,_Alen1,Tlen1,Ics1,L1,_S1} -> % No token match + Error = {Tline,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}}, + {done,{error,Error,L1},Ics1}; + {A1,Alen1,_Tlen1,_Ics1,_L1,_S1} -> % Use last accept match + token_cont(yysuf(Tcs, Alen1), L0, yyaction(A1, Alen1, Tcs, Tline)) + end. + +%% token_cont(RestChars, Line, Token) +%% If we have a token or error then return done, else if we have a +%% skip_token then continue. + +-dialyzer({nowarn_function, token_cont/3}). + +token_cont(Rest, Line, {token,T}) -> + {done,{ok,T,Line},Rest}; +token_cont(Rest, Line, {token,T,Push}) -> + NewRest = Push ++ Rest, + {done,{ok,T,Line},NewRest}; +token_cont(Rest, Line, {end_token,T}) -> + {done,{ok,T,Line},Rest}; +token_cont(Rest, Line, {end_token,T,Push}) -> + NewRest = Push ++ Rest, + {done,{ok,T,Line},NewRest}; +token_cont(Rest, Line, skip_token) -> + token(yystate(), Rest, Line, Rest, 0, Line, reject, 0); +token_cont(Rest, Line, {skip_token,Push}) -> + NewRest = Push ++ Rest, + token(yystate(), NewRest, Line, NewRest, 0, Line, reject, 0); +token_cont(Rest, Line, {error,S}) -> + {done,{error,{Line,?MODULE,{user,S}},Line},Rest}. + +%% tokens(Continuation, Chars, Line) -> +%% {more,Continuation} | {done,ReturnVal,RestChars}. +%% Must be careful when re-entering to append the latest characters to the +%% after characters in an accept. The continuation is: +%% {tokens,State,CurrLine,TokenChars,TokenLen,TokenLine,Tokens,AccAction,AccLen} +%% {skip_tokens,State,CurrLine,TokenChars,TokenLen,TokenLine,Error,AccAction,AccLen} + +tokens(Cont, Chars) -> tokens(Cont, Chars, 1). + +tokens([], Chars, Line) -> + tokens(yystate(), Chars, Line, Chars, 0, Line, [], reject, 0); +tokens({tokens,State,Line,Tcs,Tlen,Tline,Ts,Action,Alen}, Chars, _) -> + tokens(State, Chars, Line, Tcs ++ Chars, Tlen, Tline, Ts, Action, Alen); +tokens({skip_tokens,State,Line,Tcs,Tlen,Tline,Error,Action,Alen}, Chars, _) -> + skip_tokens(State, Chars, Line, Tcs ++ Chars, Tlen, Tline, Error, Action, Alen). + +%% tokens(State, InChars, Line, TokenChars, TokenLen, TokenLine, Tokens, +%% AcceptAction, AcceptLen) -> +%% {more,Continuation} | {done,ReturnVal,RestChars}. + +tokens(S0, Ics0, L0, Tcs, Tlen0, Tline, Ts, A0, Alen0) -> + case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of + %% Accepting end state, we have a token. + {A1,Alen1,Ics1,L1} -> + tokens_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Ts); + %% Accepting transition state, can take more chars. + {A1,Alen1,[],L1,S1} -> % Need more chars to check + {more,{tokens,S1,L1,Tcs,Alen1,Tline,Ts,A1,Alen1}}; + {A1,Alen1,Ics1,L1,_S1} -> % Take what we got + tokens_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Ts); + %% After a non-accepting state, maybe reach accept state later. + {A1,Alen1,Tlen1,[],L1,S1} -> % Need more chars to check + {more,{tokens,S1,L1,Tcs,Tlen1,Tline,Ts,A1,Alen1}}; + {reject,_Alen1,Tlen1,eof,L1,_S1} -> % No token match + %% Check for partial token which is error, no need to skip here. + Ret = if Tlen1 > 0 -> {error,{Tline,?MODULE, + %% Skip eof tail in Tcs. + {illegal,yypre(Tcs, Tlen1)}},L1}; + Ts == [] -> {eof,L1}; + true -> {ok,yyrev(Ts),L1} + end, + {done,Ret,eof}; + {reject,_Alen1,Tlen1,_Ics1,L1,_S1} -> + %% Skip rest of tokens. + Error = {L1,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}}, + skip_tokens(yysuf(Tcs, Tlen1+1), L1, Error); + {A1,Alen1,_Tlen1,_Ics1,_L1,_S1} -> + Token = yyaction(A1, Alen1, Tcs, Tline), + tokens_cont(yysuf(Tcs, Alen1), L0, Token, Ts) + end. + +%% tokens_cont(RestChars, Line, Token, Tokens) +%% If we have an end_token or error then return done, else if we have +%% a token then save it and continue, else if we have a skip_token +%% just continue. + +-dialyzer({nowarn_function, tokens_cont/4}). + +tokens_cont(Rest, Line, {token,T}, Ts) -> + tokens(yystate(), Rest, Line, Rest, 0, Line, [T|Ts], reject, 0); +tokens_cont(Rest, Line, {token,T,Push}, Ts) -> + NewRest = Push ++ Rest, + tokens(yystate(), NewRest, Line, NewRest, 0, Line, [T|Ts], reject, 0); +tokens_cont(Rest, Line, {end_token,T}, Ts) -> + {done,{ok,yyrev(Ts, [T]),Line},Rest}; +tokens_cont(Rest, Line, {end_token,T,Push}, Ts) -> + NewRest = Push ++ Rest, + {done,{ok,yyrev(Ts, [T]),Line},NewRest}; +tokens_cont(Rest, Line, skip_token, Ts) -> + tokens(yystate(), Rest, Line, Rest, 0, Line, Ts, reject, 0); +tokens_cont(Rest, Line, {skip_token,Push}, Ts) -> + NewRest = Push ++ Rest, + tokens(yystate(), NewRest, Line, NewRest, 0, Line, Ts, reject, 0); +tokens_cont(Rest, Line, {error,S}, _Ts) -> + skip_tokens(Rest, Line, {Line,?MODULE,{user,S}}). + +%%skip_tokens(InChars, Line, Error) -> {done,{error,Error,Line},Ics}. +%% Skip tokens until an end token, junk everything and return the error. + +skip_tokens(Ics, Line, Error) -> + skip_tokens(yystate(), Ics, Line, Ics, 0, Line, Error, reject, 0). + +%% skip_tokens(State, InChars, Line, TokenChars, TokenLen, TokenLine, Tokens, +%% AcceptAction, AcceptLen) -> +%% {more,Continuation} | {done,ReturnVal,RestChars}. + +skip_tokens(S0, Ics0, L0, Tcs, Tlen0, Tline, Error, A0, Alen0) -> + case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of + {A1,Alen1,Ics1,L1} -> % Accepting end state + skip_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Error); + {A1,Alen1,[],L1,S1} -> % After an accepting state + {more,{skip_tokens,S1,L1,Tcs,Alen1,Tline,Error,A1,Alen1}}; + {A1,Alen1,Ics1,L1,_S1} -> + skip_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Error); + {A1,Alen1,Tlen1,[],L1,S1} -> % After a non-accepting state + {more,{skip_tokens,S1,L1,Tcs,Tlen1,Tline,Error,A1,Alen1}}; + {reject,_Alen1,_Tlen1,eof,L1,_S1} -> + {done,{error,Error,L1},eof}; + {reject,_Alen1,Tlen1,_Ics1,L1,_S1} -> + skip_tokens(yysuf(Tcs, Tlen1+1), L1, Error); + {A1,Alen1,_Tlen1,_Ics1,L1,_S1} -> + Token = yyaction(A1, Alen1, Tcs, Tline), + skip_cont(yysuf(Tcs, Alen1), L1, Token, Error) + end. + +%% skip_cont(RestChars, Line, Token, Error) +%% Skip tokens until we have an end_token or error then return done +%% with the original rror. + +-dialyzer({nowarn_function, skip_cont/4}). + +skip_cont(Rest, Line, {token,_T}, Error) -> + skip_tokens(yystate(), Rest, Line, Rest, 0, Line, Error, reject, 0); +skip_cont(Rest, Line, {token,_T,Push}, Error) -> + NewRest = Push ++ Rest, + skip_tokens(yystate(), NewRest, Line, NewRest, 0, Line, Error, reject, 0); +skip_cont(Rest, Line, {end_token,_T}, Error) -> + {done,{error,Error,Line},Rest}; +skip_cont(Rest, Line, {end_token,_T,Push}, Error) -> + NewRest = Push ++ Rest, + {done,{error,Error,Line},NewRest}; +skip_cont(Rest, Line, skip_token, Error) -> + skip_tokens(yystate(), Rest, Line, Rest, 0, Line, Error, reject, 0); +skip_cont(Rest, Line, {skip_token,Push}, Error) -> + NewRest = Push ++ Rest, + skip_tokens(yystate(), NewRest, Line, NewRest, 0, Line, Error, reject, 0); +skip_cont(Rest, Line, {error,_S}, Error) -> + skip_tokens(yystate(), Rest, Line, Rest, 0, Line, Error, reject, 0). + +yyrev(List) -> lists:reverse(List). +yyrev(List, Tail) -> lists:reverse(List, Tail). +yypre(List, N) -> lists:sublist(List, N). +yysuf(List, N) -> lists:nthtail(N, List). + +%% yystate() -> InitialState. +%% yystate(State, InChars, Line, CurrTokLen, AcceptAction, AcceptLen) -> +%% {Action, AcceptLen, RestChars, Line} | +%% {Action, AcceptLen, RestChars, Line, State} | +%% {reject, AcceptLen, CurrTokLen, RestChars, Line, State} | +%% {Action, AcceptLen, CurrTokLen, RestChars, Line, State}. +%% Generated state transition functions. The non-accepting end state +%% return signal either an unrecognised character or end of current +%% input. + +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.erl", 288). +yystate() -> 20. + +yystate(23, [101|Ics], Line, Tlen, Action, Alen) -> + yystate(21, Ics, Line, Tlen+1, Action, Alen); +yystate(23, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,23}; +yystate(22, Ics, Line, Tlen, _, _) -> + {6,Tlen,Ics,Line}; +yystate(21, Ics, Line, Tlen, _, _) -> + {1,Tlen,Ics,Line}; +yystate(20, [125|Ics], Line, Tlen, Action, Alen) -> + yystate(16, Ics, Line, Tlen+1, Action, Alen); +yystate(20, [116|Ics], Line, Tlen, Action, Alen) -> + yystate(8, Ics, Line, Tlen+1, Action, Alen); +yystate(20, [115|Ics], Line, Tlen, Action, Alen) -> + yystate(11, Ics, Line, Tlen+1, Action, Alen); +yystate(20, [114|Ics], Line, Tlen, Action, Alen) -> + yystate(18, Ics, Line, Tlen+1, Action, Alen); +yystate(20, [113|Ics], Line, Tlen, Action, Alen) -> + yystate(17, Ics, Line, Tlen+1, Action, Alen); +yystate(20, [104|Ics], Line, Tlen, Action, Alen) -> + yystate(1, Ics, Line, Tlen+1, Action, Alen); +yystate(20, [59|Ics], Line, Tlen, Action, Alen) -> + yystate(14, Ics, Line, Tlen+1, Action, Alen); +yystate(20, [10|Ics], Line, Tlen, Action, Alen) -> + yystate(22, Ics, Line+1, Tlen+1, Action, Alen); +yystate(20, [C|Ics], Line, Tlen, Action, Alen) when C >= 0, C =< 9 -> + yystate(22, Ics, Line, Tlen+1, Action, Alen); +yystate(20, [C|Ics], Line, Tlen, Action, Alen) when C >= 11, C =< 32 -> + yystate(22, Ics, Line, Tlen+1, Action, Alen); +yystate(20, [C|Ics], Line, Tlen, Action, Alen) when C >= 33, C =< 58 -> + yystate(18, Ics, Line, Tlen+1, Action, Alen); +yystate(20, [C|Ics], Line, Tlen, Action, Alen) when C >= 60, C =< 103 -> + yystate(18, Ics, Line, Tlen+1, Action, Alen); +yystate(20, [C|Ics], Line, Tlen, Action, Alen) when C >= 105, C =< 112 -> + yystate(18, Ics, Line, Tlen+1, Action, Alen); +yystate(20, [C|Ics], Line, Tlen, Action, Alen) when C >= 117, C =< 124 -> + yystate(18, Ics, Line, Tlen+1, Action, Alen); +yystate(20, [C|Ics], Line, Tlen, Action, Alen) when C >= 126 -> + yystate(18, Ics, Line, Tlen+1, Action, Alen); +yystate(20, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,20}; +yystate(19, [116|Ics], Line, Tlen, Action, Alen) -> + yystate(23, Ics, Line, Tlen+1, Action, Alen); +yystate(19, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,19}; +yystate(18, Ics, Line, Tlen, _, _) -> + {7,Tlen,Ics,Line}; +yystate(17, [117|Ics], Line, Tlen, _, _) -> + yystate(13, Ics, Line, Tlen+1, 7, Tlen); +yystate(17, Ics, Line, Tlen, _, _) -> + {7,Tlen,Ics,Line,17}; +yystate(16, [42|Ics], Line, Tlen, _, _) -> + yystate(12, Ics, Line, Tlen+1, 7, Tlen); +yystate(16, Ics, Line, Tlen, _, _) -> + {7,Tlen,Ics,Line,16}; +yystate(15, [97|Ics], Line, Tlen, Action, Alen) -> + yystate(19, Ics, Line, Tlen+1, Action, Alen); +yystate(15, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,15}; +yystate(14, Ics, Line, Tlen, _, _) -> + {5,Tlen,Ics,Line}; +yystate(13, [105|Ics], Line, Tlen, Action, Alen) -> + yystate(9, Ics, Line, Tlen+1, Action, Alen); +yystate(13, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,13}; +yystate(12, Ics, Line, Tlen, _, _) -> + {4,Tlen,Ics,Line}; +yystate(11, [116|Ics], Line, Tlen, _, _) -> + yystate(15, Ics, Line, Tlen+1, 7, Tlen); +yystate(11, Ics, Line, Tlen, _, _) -> + {7,Tlen,Ics,Line,11}; +yystate(10, Ics, Line, Tlen, _, _) -> + {3,Tlen,Ics,Line}; +yystate(9, [116|Ics], Line, Tlen, Action, Alen) -> + yystate(5, Ics, Line, Tlen+1, Action, Alen); +yystate(9, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,9}; +yystate(8, [97|Ics], Line, Tlen, _, _) -> + yystate(4, Ics, Line, Tlen+1, 7, Tlen); +yystate(8, Ics, Line, Tlen, _, _) -> + {7,Tlen,Ics,Line,8}; +yystate(7, Ics, Line, Tlen, _, _) -> + {0,Tlen,Ics,Line}; +yystate(6, [112|Ics], Line, Tlen, Action, Alen) -> + yystate(10, Ics, Line, Tlen+1, Action, Alen); +yystate(6, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,6}; +yystate(5, Ics, Line, Tlen, _, _) -> + {2,Tlen,Ics,Line}; +yystate(4, [115|Ics], Line, Tlen, Action, Alen) -> + yystate(0, Ics, Line, Tlen+1, Action, Alen); +yystate(4, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,4}; +yystate(3, [115|Ics], Line, Tlen, Action, Alen) -> + yystate(7, Ics, Line, Tlen+1, Action, Alen); +yystate(3, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,3}; +yystate(2, [108|Ics], Line, Tlen, Action, Alen) -> + yystate(6, Ics, Line, Tlen+1, Action, Alen); +yystate(2, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,2}; +yystate(1, [101|Ics], Line, Tlen, _, _) -> + yystate(2, Ics, Line, Tlen+1, 7, Tlen); +yystate(1, Ics, Line, Tlen, _, _) -> + {7,Tlen,Ics,Line,1}; +yystate(0, [107|Ics], Line, Tlen, Action, Alen) -> + yystate(3, Ics, Line, Tlen+1, Action, Alen); +yystate(0, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,0}; +yystate(S, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,S}. + +%% yyaction(Action, TokenLength, TokenChars, TokenLine) -> +%% {token,Token} | {end_token, Token} | skip_token | {error,String}. +%% Generated action function. + +yyaction(0, _, _, _) -> + yyaction_0(); +yyaction(1, _, _, _) -> + yyaction_1(); +yyaction(2, _, _, _) -> + yyaction_2(); +yyaction(3, _, _, _) -> + yyaction_3(); +yyaction(4, _, _, _) -> + yyaction_4(); +yyaction(5, _, _, _) -> + yyaction_5(); +yyaction(6, _, _, _) -> + yyaction_6(); +yyaction(7, _, _, _) -> + yyaction_7(); +yyaction(_, _, _, _) -> error. + +-compile({inline,yyaction_0/0}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 40). +yyaction_0() -> + { token, tasks } . + +-compile({inline,yyaction_1/0}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 41). +yyaction_1() -> + { token, state } . + +-compile({inline,yyaction_2/0}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 42). +yyaction_2() -> + { token, quit } . + +-compile({inline,yyaction_3/0}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 43). +yyaction_3() -> + { token, help } . + +-compile({inline,yyaction_4/0}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 44). +yyaction_4() -> + { token, terminal } . + +-compile({inline,yyaction_5/0}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 45). +yyaction_5() -> + { token, terminal } . + +-compile({inline,yyaction_6/0}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 46). +yyaction_6() -> + skip_token . + +-compile({inline,yyaction_7/0}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 47). +yyaction_7() -> + { token, nonws } . + +-file("/usr/local/lib/erlang/lib/parsetools-2.1.1/include/leexinc.hrl", 290). diff --git a/src/pre_scan.xrl b/src/pre_scan.xrl new file mode 100644 index 0000000..fb302e5 --- /dev/null +++ b/src/pre_scan.xrl @@ -0,0 +1,60 @@ +%% -*- erlang -*- +% +% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis +% +% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser +% +% Licensed under the Apache License, Version 2.0 (the "License"); +% you may not use this file except in compliance with the License. +% You may obtain a copy of the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, +% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +% See the License for the specific language governing permissions and +% limitations under the License. + + +%% ============================================================================= +%% Definitions +%% ============================================================================= + +Definitions. + +HELP = help +NONWS = . +QUIT = quit +RMMECB = \}\* +SEMICOLON = ; +STATE = state +TASKS = tasks +WS = [\000-\s] + + +%% ============================================================================= +%% Rules +%% ============================================================================= + +Rules. + +{TASKS} : {token, tasks}. +{STATE} : {token, state}. +{QUIT} : {token, quit}. +{HELP} : {token, help}. +{RMMECB} : {token, terminal}. +{SEMICOLON} : {token, terminal}. +{WS} : skip_token. +{NONWS} : {token, nonws}. + +%% ============================================================================= +%% Erlang Code +%% ============================================================================= + + +Erlang code. + +-author( "Jorgen Brandt " ). + +-export( [yyrev/2] ). \ No newline at end of file diff --git a/test/cf_sem_test.erl b/test/cf_sem_test.erl index 09410fb..2d37da2 100644 --- a/test/cf_sem_test.erl +++ b/test/cf_sem_test.erl @@ -23,8 +23,8 @@ -define( THETA0, {#{}, fun mu/1, #{}, #{}} ). -mu( {app, _AppLine, _C, {lam, _LamLine, Name, {sign, Lo, _Li}, _B}, _Fa} ) -> - {fut, Name, random:uniform( 1000000000 ), Lo}. +mu( {app, _AppLine, _C, {lam, _LamLine, LamName, {sign, Lo, _Li}, _B}, _Fa} ) -> + {fut, LamName, random:uniform( 1000000000 ), Lo}. nil_should_eval_itself_test() -> ?assertEqual( [], cf_sem:eval( [], ?THETA0 ) ). @@ -35,7 +35,7 @@ str_should_eval_itself_test() -> undef_var_should_fail_test() -> E = [{var, 1, "x"}], - ?assertError( {badkey, "x"}, cf_sem:eval( E, ?THETA0 ) ). + ?assertThrow( {1, cf_sem, _}, cf_sem:eval( E, ?THETA0 ) ). def_var_should_eval_to_bound_value_test() -> E = [{str, "blub"}], @@ -95,7 +95,7 @@ fn_call_should_insert_lam_test() -> app_with_unbound_lam_should_fail_test() -> F = [{app, 1, 1, {var, 2, "f"}, #{}}], - ?assertError( {badkey, "f"}, cf_sem:eval( F, ?THETA0 ) ). + ?assertThrow( {1, cf_sem, _}, cf_sem:eval( F, ?THETA0 ) ). identity_fn_should_eval_arg_test() -> E = [{str, "bla"}], @@ -122,7 +122,7 @@ app_should_ignore_calling_context_test() -> Lam = {lam, 2, "f", Sign, Body}, X = [{app, 3, 1, Lam, #{}}], Rho = #{"x" => [{str, "blub"}]}, - ?assertError( {badkey, "x"}, cf_sem:eval( X, {Rho, fun mu/1, #{}, #{}} ) ). + ?assertThrow( {1, cf_sem, _}, cf_sem:eval( X, {Rho, fun mu/1, #{}, #{}} ) ). app_should_hand_down_gamma_test() -> Sign = {sign, [{param, {name, "out", false}, false}], []}, From 240601aa363691bb27d693c823a2c3436e5ae3e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Fri, 18 Mar 2016 16:37:01 +0100 Subject: [PATCH 35/78] Shell error output improved. --- src/cf_shell.erl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cf_shell.erl b/src/cf_shell.erl index 378ba6d..bd1da6d 100644 --- a/src/cf_shell.erl +++ b/src/cf_shell.erl @@ -141,11 +141,14 @@ format_error( {Line, cf_sem, S} ) -> format_error( {LamLine, cuneiform, {R, script_error, LamName, _Fa, {ActScript, Out}}} ) -> io_lib:format( - ?BYLW( "[out]~n" )++?RED( "~s~n" ) + ?BYLW( "[out]~n" )++?YLW( "~s~n" ) ++?BYLW( "[script]~n" )++?YLW( "~s~n" ) ++?RED( "Line ~p: " )++?BRED( "script error in call to ~s (~p)" ), [format_out( Out ), format_script( ActScript ), LamLine, LamName, R] ); +format_error( {LamLine, cuneiform, {R, not_found, LamName, _Fa, MissingLst}} ) -> + io_lib:format( ?RED( "Line ~p: " )++?BRED( "precondition not met in call to ~s (~p)~n" )++?RED( "Missing files: ~p" ), [LamLine, LamName, R, MissingLst] ); + format_error( ErrorInfo ) -> io_lib:format( ?RED( "Error: " )++?BRED( "~p" ), [ErrorInfo] ). From b9b7a8b2851b33b6a183c7d165cd5f74eba8d3a5 Mon Sep 17 00:00:00 2001 From: Jorgen Brandt Date: Fri, 18 Mar 2016 22:42:54 +0100 Subject: [PATCH 36/78] Generated code removed. --- .gitignore | 5 +- src/cf_parse.erl | 1486 ---------------------------------------- src/cf_scan.erl | 1676 ---------------------------------------------- src/pre_scan.erl | 464 ------------- 4 files changed, 3 insertions(+), 3628 deletions(-) delete mode 100644 src/cf_parse.erl delete mode 100644 src/cf_scan.erl delete mode 100644 src/pre_scan.erl diff --git a/.gitignore b/.gitignore index 2397123..40974c9 100644 --- a/.gitignore +++ b/.gitignore @@ -9,8 +9,9 @@ rel/example_project .concrete/DEV_MODE .rebar *~ -src/cf_lexer.erl -src/cf_parser.erl +src/cf_scan.erl +src/cf_parse.erl +src/cf_prescan.erl doc _build rebar.lock diff --git a/src/cf_parse.erl b/src/cf_parse.erl deleted file mode 100644 index 67068a6..0000000 --- a/src/cf_parse.erl +++ /dev/null @@ -1,1486 +0,0 @@ --module(cf_parse). --export([parse/1, parse_and_scan/1, format_error/1]). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 111). - --author( "Jorgen Brandt " ). - --export( [string/1] ). - --ifdef( TEST ). --include_lib( "eunit/include/eunit.hrl" ). --endif. - -string( S ) -> - {ok, TokenList, _} = cf_scan:string( S ), - - % parse - case parse( TokenList ) of - {error, R2} -> error( R2 ); - {ok, ParseTree} -> ParseTree - end. - - - - - -combine( {Target1, Rho1, Global1}, {Target2, Rho2, Global2} ) -> - case Target1 of - undef -> {Target2, maps:merge( Rho1, Rho2 ), maps:merge( Global1, Global2 )}; - _ -> - case Target2 of - undef -> {undef, maps:merge( Rho1, Rho2 ), maps:merge( Global1, Global2 )}; - _ -> {Target1++Target2, maps:merge( Rho1, Rho2 ), maps:merge( Global1, Global2 )} - end - end. - -mk_var( {id, Line, Name} ) -> {var, Line, Name}. - -mk_str( {intlit, _Line, N} ) -> {str, N}; -mk_str( {strlit, _Line, S} ) -> {str, S}. - -get_line( {_, Line, _} ) -> Line. - -get_name( {id, _Line, Name} ) -> Name. - -mk_binding( {id, _, Name}, ExprList ) -> - #{Name => ExprList}. - -mk_assign( [], _ExprList, _Channel ) -> #{}; - -mk_assign( [{var, _Line, Name}|Rest], ExprList, Channel ) -> - Rho = mk_assign( Rest, ExprList, Channel+1 ), - Value = lists:flatmap( fun( E ) -> set_channel( E, Channel ) end, ExprList ), - Rho#{Name => Value}; - -mk_assign( [E|_Rest], _ExprList, _Channel ) -> - error( {parser, nonvar_expr_left_of_eq, element( 1, E ), element( 2, E )} ). - - -set_channel( {app, Line, _Channel, LamList, Binding}, N ) -> [{app, Line, N, LamList, Binding}]; -set_channel( E, 1 ) -> [E]; -set_channel( E, _ ) -> error( {parser, nonapp_expr, element( 1, E ), element( 2, E )} ). - -mk_natlam( {deftask, Line, _}, {id, _, Name}, Sign, Block ) -> - #{Name => {lam, Line, Name, Sign, {natbody, Block}}}. - -mk_forlam( {deftask, Line, _}, {id, _, Name}, Sign, Lang, {body, _, Code} ) -> - #{Name => {lam, Line, Name, Sign, {forbody, Lang, Code}}}. - - -%% ============================================================================= -%% Unit Tests -%% ============================================================================= - --ifdef( TEST ). - -nil_should_be_recognized_test() -> - ?assertEqual( {[], #{}, #{}}, string( "nil;" ) ). - -var_should_be_recognized_test() -> - ?assertEqual( {[{var, 1, "blub"}], #{}, #{}}, string( "blub;" ) ). - -multi_element_compoundexpr_should_be_recognized_test() -> - ?assertEqual( {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}, - string( "bla blub;" ) ). - -multiple_queries_should_be_joined_test() -> - ?assertEqual( {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}, - string( "bla; blub;" ) ). - -strlit_should_be_recognized_test() -> - ?assertEqual( {[{str, "bla"}], #{}, #{}}, string( "\"bla\";" ) ). - -intlit_should_be_recognized_test() -> - ?assertEqual( {[{str, "-5"}], #{}, #{}}, string( "-5;" ) ). - -cnd_should_be_recognized_test() -> - ?assertEqual( {[{cnd, 1, [], [{str, "bla"}], [{str, "blub"}]}], - #{}, #{}}, - string( "if nil then \"bla\" else \"blub\" end;" ) ). - -app_should_be_recognized_test() -> - [?assertEqual( {[{app, 1, 1, {var, 1, "f"}, #{}}], #{}, #{}}, - string( "f();" ) ), - ?assertEqual( {[{app, 1, 1, {var, 1, "f"}, #{"x" => [{var, 1, "x"}]}}], - #{}, #{}}, string( "f( x: x );" ) ), - ?assertEqual( {[{app, 1, 1, {var, 1, "f"}, - #{"x" => [{var, 1, "x"}], - "y" => [{str, "y"}]}}], #{}, #{}}, - string( "f( x: x, y: \"y\" );" ) )]. - - -assign_should_be_recognized_test() -> - [?assertEqual( {undef, #{"x" => [{str, "x"}]}, #{}}, string( "x = \"x\";" ) ), - ?assertEqual( {undef, #{"x" => [{app, 1, 1, {var, 1, "f"}, #{}}], "y" => [{app, 1, 2, {var, 1, "f"}, #{}}]}, #{}}, string( "x y = f();" ) ), - ?assertError( {parser, nonapp_expr, str, "A"}, string( "x y = \"A\";" ) ), - ?assertError( {parser, nonvar_expr_left_of_eq, str, "a"}, string( "\"a\" = \"A\";" ) )]. - -native_deftask_should_be_recognized_test() -> - ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - []}, - {natbody, #{"out" => [{str, "A"}]}}}}}, - string( "deftask f( out : ) { out = \"A\"; }" ) ). - -foreign_deftask_should_be_recognized_test() -> - [?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - []}, - {forbody, bash, "out=A"}}}}, - string( "deftask f( out : )in bash *{out=A}*" ) ), - ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - []}, - {forbody, r, "out=\"A\""}}}}, - string( "deftask f( out : )in R *{out=\"A\"}*" ) ), - ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - []}, - {forbody, python, ""}}}}, - string( "deftask f( out : )in python *{}*" ) )]. - -sign_with_inparam_should_be_recognized_test() -> - [?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [{param, {name, "inp", false}, false}]}, - {forbody, python, "(defparameter out \"A\")"}}}}, - string( "deftask f( out : inp )in python *{(defparameter out \"A\")}*" ) ), - ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [{param, {name, "a", false}, false}, - {param, {name, "b", false}, false}]}, - {forbody, python, "(defparameter out \"A\")"}}}}, - string( "deftask f( out : a b )in python *{(defparameter out \"A\")}*" ) )]. - -param_should_be_recognized_test() -> - [?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [{param, {name, "inp", false}, false}]}, - {forbody, bash, "blub"}}}}, - string( "deftask f( out( String ) : inp( String ) )in bash *{blub}*" ) ), - ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", - {sign, [{param, {name, "out", true}, false}], - [{param, {name, "inp", true}, false}]}, - {forbody, bash, "blub"}}}}, - string( "deftask f( out( File ) : inp( File ) )in bash *{blub}*" ) ), - ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", - {sign, [{param, {name, "out", false}, true}], - [{param, {name, "inp", false}, true}]}, - {forbody, bash, "blub"}}}}, - string( "deftask f( : )in bash *{blub}*" ) ), - ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", - {sign, [{param, {name, "out", false}, true}], - [{param, {name, "inp", false}, true}]}, - {forbody, bash, "blub"}}}}, - string( "deftask f( : )in bash *{blub}*" ) ), - ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", - {sign, [{param, {name, "out", true}, true}], - [{param, {name, "inp", true}, true}]}, - {forbody, bash, "blub"}}}}, - string( "deftask f( : )in bash *{blub}*" ) )]. - -correl_inparam_should_be_recognized_test() -> - [?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [{correl, [{name, "a", true}, - {name, "b", true}]}]}, - {forbody, bash, "blub"}}}}, - string( "deftask f( out : [a( File ) b( File )] )in bash *{blub}*" ) ), - ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", - {sign, [{param, {name, "out", false}, false}], - [{correl, [{name, "a", true}, - {name, "b", true}]}, - {param, {name, "c", false}, false}]}, - {forbody, bash, "blub"}}}}, - string( "deftask f( out : [a( File ) b( File )] c )in bash *{blub}*" ) )]. - --endif. - - - --file("/usr/local/lib/erlang/lib/parsetools-2.1.1/include/yeccpre.hrl", 0). -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2015. All Rights Reserved. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -%% -%% %CopyrightEnd% -%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% The parser generator will insert appropriate declarations before this line.% - --type yecc_ret() :: {'error', _} | {'ok', _}. - --spec parse(Tokens :: list()) -> yecc_ret(). -parse(Tokens) -> - yeccpars0(Tokens, {no_func, no_line}, 0, [], []). - --spec parse_and_scan({function() | {atom(), atom()}, [_]} - | {atom(), atom(), [_]}) -> yecc_ret(). -parse_and_scan({F, A}) -> - yeccpars0([], {{F, A}, no_line}, 0, [], []); -parse_and_scan({M, F, A}) -> - Arity = length(A), - yeccpars0([], {{fun M:F/Arity, A}, no_line}, 0, [], []). - --spec format_error(any()) -> [char() | list()]. -format_error(Message) -> - case io_lib:deep_char_list(Message) of - true -> - Message; - _ -> - io_lib:write(Message) - end. - -%% To be used in grammar files to throw an error message to the parser -%% toplevel. Doesn't have to be exported! --compile({nowarn_unused_function, return_error/2}). --spec return_error(integer(), any()) -> no_return(). -return_error(Line, Message) -> - throw({error, {Line, ?MODULE, Message}}). - --define(CODE_VERSION, "1.4"). - -yeccpars0(Tokens, Tzr, State, States, Vstack) -> - try yeccpars1(Tokens, Tzr, State, States, Vstack) - catch - error: Error -> - Stacktrace = erlang:get_stacktrace(), - try yecc_error_type(Error, Stacktrace) of - Desc -> - erlang:raise(error, {yecc_bug, ?CODE_VERSION, Desc}, - Stacktrace) - catch _:_ -> erlang:raise(error, Error, Stacktrace) - end; - %% Probably thrown from return_error/2: - throw: {error, {_Line, ?MODULE, _M}} = Error -> - Error - end. - -yecc_error_type(function_clause, [{?MODULE,F,ArityOrArgs,_} | _]) -> - case atom_to_list(F) of - "yeccgoto_" ++ SymbolL -> - {ok,[{atom,_,Symbol}],_} = erl_scan:string(SymbolL), - State = case ArityOrArgs of - [S,_,_,_,_,_,_] -> S; - _ -> state_is_unknown - end, - {Symbol, State, missing_in_goto_table} - end. - -yeccpars1([Token | Tokens], Tzr, State, States, Vstack) -> - yeccpars2(State, element(1, Token), States, Vstack, Token, Tokens, Tzr); -yeccpars1([], {{F, A},_Line}, State, States, Vstack) -> - case apply(F, A) of - {ok, Tokens, Endline} -> - yeccpars1(Tokens, {{F, A}, Endline}, State, States, Vstack); - {eof, Endline} -> - yeccpars1([], {no_func, Endline}, State, States, Vstack); - {error, Descriptor, _Endline} -> - {error, Descriptor} - end; -yeccpars1([], {no_func, no_line}, State, States, Vstack) -> - Line = 999999, - yeccpars2(State, '$end', States, Vstack, yecc_end(Line), [], - {no_func, Line}); -yeccpars1([], {no_func, Endline}, State, States, Vstack) -> - yeccpars2(State, '$end', States, Vstack, yecc_end(Endline), [], - {no_func, Endline}). - -%% yeccpars1/7 is called from generated code. -%% -%% When using the {includefile, Includefile} option, make sure that -%% yeccpars1/7 can be found by parsing the file without following -%% include directives. yecc will otherwise assume that an old -%% yeccpre.hrl is included (one which defines yeccpars1/5). -yeccpars1(State1, State, States, Vstack, Token0, [Token | Tokens], Tzr) -> - yeccpars2(State, element(1, Token), [State1 | States], - [Token0 | Vstack], Token, Tokens, Tzr); -yeccpars1(State1, State, States, Vstack, Token0, [], {{_F,_A}, _Line}=Tzr) -> - yeccpars1([], Tzr, State, [State1 | States], [Token0 | Vstack]); -yeccpars1(State1, State, States, Vstack, Token0, [], {no_func, no_line}) -> - Line = yecctoken_end_location(Token0), - yeccpars2(State, '$end', [State1 | States], [Token0 | Vstack], - yecc_end(Line), [], {no_func, Line}); -yeccpars1(State1, State, States, Vstack, Token0, [], {no_func, Line}) -> - yeccpars2(State, '$end', [State1 | States], [Token0 | Vstack], - yecc_end(Line), [], {no_func, Line}). - -%% For internal use only. -yecc_end({Line,_Column}) -> - {'$end', Line}; -yecc_end(Line) -> - {'$end', Line}. - -yecctoken_end_location(Token) -> - try erl_anno:end_location(element(2, Token)) of - undefined -> yecctoken_location(Token); - Loc -> Loc - catch _:_ -> yecctoken_location(Token) - end. - --compile({nowarn_unused_function, yeccerror/1}). -yeccerror(Token) -> - Text = yecctoken_to_string(Token), - Location = yecctoken_location(Token), - {error, {Location, ?MODULE, ["syntax error before: ", Text]}}. - --compile({nowarn_unused_function, yecctoken_to_string/1}). -yecctoken_to_string(Token) -> - try erl_scan:text(Token) of - undefined -> yecctoken2string(Token); - Txt -> Txt - catch _:_ -> yecctoken2string(Token) - end. - -yecctoken_location(Token) -> - try erl_scan:location(Token) - catch _:_ -> element(2, Token) - end. - --compile({nowarn_unused_function, yecctoken2string/1}). -yecctoken2string({atom, _, A}) -> io_lib:write(A); -yecctoken2string({integer,_,N}) -> io_lib:write(N); -yecctoken2string({float,_,F}) -> io_lib:write(F); -yecctoken2string({char,_,C}) -> io_lib:write_char(C); -yecctoken2string({var,_,V}) -> io_lib:format("~s", [V]); -yecctoken2string({string,_,S}) -> io_lib:write_string(S); -yecctoken2string({reserved_symbol, _, A}) -> io_lib:write(A); -yecctoken2string({_Cat, _, Val}) -> io_lib:format("~p",[Val]); -yecctoken2string({dot, _}) -> "'.'"; -yecctoken2string({'$end', _}) -> - []; -yecctoken2string({Other, _}) when is_atom(Other) -> - io_lib:write(Other); -yecctoken2string(Other) -> - io_lib:write(Other). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - - --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.erl", 375). - --dialyzer({nowarn_function, yeccpars2/7}). -yeccpars2(0=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_0(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(1=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_1(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(2=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_2(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(3=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_3(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(4=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_4(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(5=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_5(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(6=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_6(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(7=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_7(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(8=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_8(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(9=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_9(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(10=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_10(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(11=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_11(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(12=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_12(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(13=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_13(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(14=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_14(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(15=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_15(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(16=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_16(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(17=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_17(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(18=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_18(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(19=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_19(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(20=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_20(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(21=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_21(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(22=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_11(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(23=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_23(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(24=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_24(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(25=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_25(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(26=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_26(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(27=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_27(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(28=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_28(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(29=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_29(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(30=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_30(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(31=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_31(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(32=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_32(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(33=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_33(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(34=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_34(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(35=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_35(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(36=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_36(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(37=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_37(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(38=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_38(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(39=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_39(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(40=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_40(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(41=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_41(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(42=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_42(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(43=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_43(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(44=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_44(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(45=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(46=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_46(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(47=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_47(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(48=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_35(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(49=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_49(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(50=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_50(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(51=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_51(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(52=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_52(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(53=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_53(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(54=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_54(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(55=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_55(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(56=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_56(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(57=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_57(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(58=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_58(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(59=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_59(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(60=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_60(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(61=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_61(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(62=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_62(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(63=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_11(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(64=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_64(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(65=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_65(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(66=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_66(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(67=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_67(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(68=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_68(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(69=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_69(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(70=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_70(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(71=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_71(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(72=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_11(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(73=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_73(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(74=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_11(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(75=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_75(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(76=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_76(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(77=S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_77(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(78=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_78(S, Cat, Ss, Stack, T, Ts, Tzr); -%% yeccpars2(79=S, Cat, Ss, Stack, T, Ts, Tzr) -> -%% yeccpars2_79(S, Cat, Ss, Stack, T, Ts, Tzr); -yeccpars2(Other, _, _, _, _, _, _) -> - erlang:error({yecc_bug,"1.4",{missing_state_in_action_table, Other}}). - -yeccpars2_0(S, deftask, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr); -yeccpars2_0(S, nil, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 15, Ss, Stack, T, Ts, Tzr); -yeccpars2_0(S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_57(S, Cat, Ss, Stack, T, Ts, Tzr). - -yeccpars2_1(S, beginif, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr); -yeccpars2_1(S, deftask, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr); -yeccpars2_1(S, id, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 13, Ss, Stack, T, Ts, Tzr); -yeccpars2_1(S, intlit, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 14, Ss, Stack, T, Ts, Tzr); -yeccpars2_1(S, nil, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 15, Ss, Stack, T, Ts, Tzr); -yeccpars2_1(S, strlit, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 16, Ss, Stack, T, Ts, Tzr); -yeccpars2_1(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccgoto_script(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). - --dialyzer({nowarn_function, yeccpars2_2/7}). -yeccpars2_2(_S, '$end', _Ss, Stack, _T, _Ts, _Tzr) -> - {ok, hd(Stack)}; -yeccpars2_2(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_3(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_3_(Stack), - yeccgoto_stat(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - -yeccpars2_4(S, eq, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 63, Ss, Stack, T, Ts, Tzr); -yeccpars2_4(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccgoto_compoundexpr(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). - -yeccpars2_5(S, beginif, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr); -yeccpars2_5(S, id, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 13, Ss, Stack, T, Ts, Tzr); -yeccpars2_5(S, intlit, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 14, Ss, Stack, T, Ts, Tzr); -yeccpars2_5(S, strlit, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 16, Ss, Stack, T, Ts, Tzr); -yeccpars2_5(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_5_(Stack), - yeccgoto_exprlist(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - -yeccpars2_6(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_6_(Stack), - yeccgoto_stat(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - --dialyzer({nowarn_function, yeccpars2_7/7}). -yeccpars2_7(S, semicolon, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 77, Ss, Stack, T, Ts, Tzr); -yeccpars2_7(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccgoto_expr(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). - -yeccpars2_9(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_9_(Stack), - yeccgoto_stat(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - -yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccgoto_expr(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). - -yeccpars2_11(S, nil, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 15, Ss, Stack, T, Ts, Tzr); -yeccpars2_11(S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_57(S, Cat, Ss, Stack, T, Ts, Tzr). - --dialyzer({nowarn_function, yeccpars2_12/7}). -yeccpars2_12(S, id, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 28, Ss, Stack, T, Ts, Tzr); -yeccpars2_12(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_13(S, lparen, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 17, Ss, Stack, T, Ts, Tzr); -yeccpars2_13(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_13_(Stack), - yeccgoto_expr(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - -yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_14_(Stack), - yeccgoto_expr(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - -yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_15_(Stack), - yeccgoto_compoundexpr(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - -yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_16_(Stack), - yeccgoto_expr(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - --dialyzer({nowarn_function, yeccpars2_17/7}). -yeccpars2_17(S, id, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 20, Ss, Stack, T, Ts, Tzr); -yeccpars2_17(S, rparen, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 21, Ss, Stack, T, Ts, Tzr); -yeccpars2_17(_, _, _, _, T, _, _) -> - yeccerror(T). - --dialyzer({nowarn_function, yeccpars2_18/7}). -yeccpars2_18(S, rparen, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 27, Ss, Stack, T, Ts, Tzr); -yeccpars2_18(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_19(S, comma, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 25, Ss, Stack, T, Ts, Tzr); -yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccgoto_bindinglist(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). - --dialyzer({nowarn_function, yeccpars2_20/7}). -yeccpars2_20(S, colon, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 22, Ss, Stack, T, Ts, Tzr); -yeccpars2_20(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_,_|Nss] = Ss, - NewStack = yeccpars2_21_(Stack), - yeccgoto_app(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - -%% yeccpars2_22: see yeccpars2_11 - -yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccgoto_compoundexpr(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). - -yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_,_|Nss] = Ss, - NewStack = yeccpars2_24_(Stack), - yeccgoto_binding(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - --dialyzer({nowarn_function, yeccpars2_25/7}). -yeccpars2_25(S, id, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 20, Ss, Stack, T, Ts, Tzr); -yeccpars2_25(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_26(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_,_|Nss] = Ss, - NewStack = yeccpars2_26_(Stack), - yeccgoto_bindinglist(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - -yeccpars2_27(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_,_,_|Nss] = Ss, - NewStack = yeccpars2_27_(Stack), - yeccgoto_app(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - --dialyzer({nowarn_function, yeccpars2_28/7}). -yeccpars2_28(S, lparen, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 30, Ss, Stack, T, Ts, Tzr); -yeccpars2_28(_, _, _, _, T, _, _) -> - yeccerror(T). - --dialyzer({nowarn_function, yeccpars2_29/7}). -yeccpars2_29(S, in, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 56, Ss, Stack, T, Ts, Tzr); -yeccpars2_29(S, lbrace, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 57, Ss, Stack, T, Ts, Tzr); -yeccpars2_29(_, _, _, _, T, _, _) -> - yeccerror(T). - --dialyzer({nowarn_function, yeccpars2_30/7}). -yeccpars2_30(S, id, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr); -yeccpars2_30(S, ltag, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 35, Ss, Stack, T, Ts, Tzr); -yeccpars2_30(_, _, _, _, T, _, _) -> - yeccerror(T). - --dialyzer({nowarn_function, yeccpars2_31/7}). -yeccpars2_31(S, colon, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 44, Ss, Stack, T, Ts, Tzr); -yeccpars2_31(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_32(S, id, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr); -yeccpars2_32(S, ltag, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 35, Ss, Stack, T, Ts, Tzr); -yeccpars2_32(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_32_(Stack), - yeccgoto_paramlist(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - -yeccpars2_33(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_33_(Stack), - yeccgoto_param(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - -yeccpars2_34(S, lparen, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 38, Ss, Stack, T, Ts, Tzr); -yeccpars2_34(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_34_(Stack), - yeccgoto_name(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - --dialyzer({nowarn_function, yeccpars2_35/7}). -yeccpars2_35(S, id, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr); -yeccpars2_35(_, _, _, _, T, _, _) -> - yeccerror(T). - --dialyzer({nowarn_function, yeccpars2_36/7}). -yeccpars2_36(S, rtag, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 37, Ss, Stack, T, Ts, Tzr); -yeccpars2_36(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_37(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_,_|Nss] = Ss, - NewStack = yeccpars2_37_(Stack), - yeccgoto_param(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - --dialyzer({nowarn_function, yeccpars2_38/7}). -yeccpars2_38(S, file, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 39, Ss, Stack, T, Ts, Tzr); -yeccpars2_38(S, string, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 40, Ss, Stack, T, Ts, Tzr); -yeccpars2_38(_, _, _, _, T, _, _) -> - yeccerror(T). - --dialyzer({nowarn_function, yeccpars2_39/7}). -yeccpars2_39(S, rparen, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 42, Ss, Stack, T, Ts, Tzr); -yeccpars2_39(_, _, _, _, T, _, _) -> - yeccerror(T). - --dialyzer({nowarn_function, yeccpars2_40/7}). -yeccpars2_40(S, rparen, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 41, Ss, Stack, T, Ts, Tzr); -yeccpars2_40(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_,_,_|Nss] = Ss, - NewStack = yeccpars2_41_(Stack), - yeccgoto_name(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - -yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_,_,_|Nss] = Ss, - NewStack = yeccpars2_42_(Stack), - yeccgoto_name(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - -yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_|Nss] = Ss, - NewStack = yeccpars2_43_(Stack), - yeccgoto_paramlist(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - --dialyzer({nowarn_function, yeccpars2_44/7}). -yeccpars2_44(S, id, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr); -yeccpars2_44(S, lsquarebr, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 48, Ss, Stack, T, Ts, Tzr); -yeccpars2_44(S, ltag, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 35, Ss, Stack, T, Ts, Tzr); -yeccpars2_44(S, rparen, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 49, Ss, Stack, T, Ts, Tzr); -yeccpars2_44(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_45(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccgoto_inparam(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). - --dialyzer({nowarn_function, yeccpars2_46/7}). -yeccpars2_46(S, rparen, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 55, Ss, Stack, T, Ts, Tzr); -yeccpars2_46(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_47(S, id, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr); -yeccpars2_47(S, lsquarebr, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 48, Ss, Stack, T, Ts, Tzr); -yeccpars2_47(S, ltag, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 35, Ss, Stack, T, Ts, Tzr); -yeccpars2_47(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_47_(Stack), - yeccgoto_inparamlist(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - -%% yeccpars2_48: see yeccpars2_35 - -yeccpars2_49(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_,_,_|Nss] = Ss, - NewStack = yeccpars2_49_(Stack), - yeccgoto_sign(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - --dialyzer({nowarn_function, yeccpars2_50/7}). -yeccpars2_50(S, rsquarebr, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 53, Ss, Stack, T, Ts, Tzr); -yeccpars2_50(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_51(S, id, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr); -yeccpars2_51(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_51_(Stack), - yeccgoto_namelist(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - -yeccpars2_52(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_|Nss] = Ss, - NewStack = yeccpars2_52_(Stack), - yeccgoto_namelist(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - -yeccpars2_53(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_,_|Nss] = Ss, - NewStack = yeccpars2_53_(Stack), - yeccgoto_inparam(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - -yeccpars2_54(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_|Nss] = Ss, - NewStack = yeccpars2_54_(Stack), - yeccgoto_inparamlist(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - -yeccpars2_55(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_,_,_,_|Nss] = Ss, - NewStack = yeccpars2_55_(Stack), - yeccgoto_sign(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - --dialyzer({nowarn_function, yeccpars2_56/7}). -yeccpars2_56(S, bash, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 67, Ss, Stack, T, Ts, Tzr); -yeccpars2_56(S, python, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 68, Ss, Stack, T, Ts, Tzr); -yeccpars2_56(S, r, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 69, Ss, Stack, T, Ts, Tzr); -yeccpars2_56(_, _, _, _, T, _, _) -> - yeccerror(T). - --dialyzer({nowarn_function, yeccpars2_57/7}). -yeccpars2_57(S, beginif, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr); -yeccpars2_57(S, id, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 13, Ss, Stack, T, Ts, Tzr); -yeccpars2_57(S, intlit, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 14, Ss, Stack, T, Ts, Tzr); -yeccpars2_57(S, strlit, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 16, Ss, Stack, T, Ts, Tzr); -yeccpars2_57(_, _, _, _, T, _, _) -> - yeccerror(T). - --dialyzer({nowarn_function, yeccpars2_58/7}). -yeccpars2_58(S, eq, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 63, Ss, Stack, T, Ts, Tzr); -yeccpars2_58(_, _, _, _, T, _, _) -> - yeccerror(T). - --dialyzer({nowarn_function, yeccpars2_59/7}). -yeccpars2_59(S, rbrace, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 62, Ss, Stack, T, Ts, Tzr); -yeccpars2_59(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_60(S, beginif, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr); -yeccpars2_60(S, id, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 13, Ss, Stack, T, Ts, Tzr); -yeccpars2_60(S, intlit, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 14, Ss, Stack, T, Ts, Tzr); -yeccpars2_60(S, strlit, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 16, Ss, Stack, T, Ts, Tzr); -yeccpars2_60(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccgoto_assignlist(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). - -yeccpars2_61(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_|Nss] = Ss, - NewStack = yeccpars2_61_(Stack), - yeccgoto_assignlist(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - -yeccpars2_62(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_,_,_,_,_|Nss] = Ss, - NewStack = yeccpars2_62_(Stack), - yeccgoto_defun(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - -%% yeccpars2_63: see yeccpars2_11 - --dialyzer({nowarn_function, yeccpars2_64/7}). -yeccpars2_64(S, semicolon, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 65, Ss, Stack, T, Ts, Tzr); -yeccpars2_64(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_65(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_,_,_|Nss] = Ss, - NewStack = yeccpars2_65_(Stack), - yeccgoto_assign(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - --dialyzer({nowarn_function, yeccpars2_66/7}). -yeccpars2_66(S, body, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 70, Ss, Stack, T, Ts, Tzr); -yeccpars2_66(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_67(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_67_(Stack), - yeccgoto_lang(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - -yeccpars2_68(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_68_(Stack), - yeccgoto_lang(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - -yeccpars2_69(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - NewStack = yeccpars2_69_(Stack), - yeccgoto_lang(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). - -yeccpars2_70(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_,_,_,_,_|Nss] = Ss, - NewStack = yeccpars2_70_(Stack), - yeccgoto_defun(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - --dialyzer({nowarn_function, yeccpars2_71/7}). -yeccpars2_71(S, then, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 72, Ss, Stack, T, Ts, Tzr); -yeccpars2_71(_, _, _, _, T, _, _) -> - yeccerror(T). - -%% yeccpars2_72: see yeccpars2_11 - --dialyzer({nowarn_function, yeccpars2_73/7}). -yeccpars2_73(S, else, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 74, Ss, Stack, T, Ts, Tzr); -yeccpars2_73(_, _, _, _, T, _, _) -> - yeccerror(T). - -%% yeccpars2_74: see yeccpars2_11 - --dialyzer({nowarn_function, yeccpars2_75/7}). -yeccpars2_75(S, endif, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 76, Ss, Stack, T, Ts, Tzr); -yeccpars2_75(_, _, _, _, T, _, _) -> - yeccerror(T). - -yeccpars2_76(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_,_,_,_,_,_|Nss] = Ss, - NewStack = yeccpars2_76_(Stack), - yeccgoto_cnd(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - -yeccpars2_77(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_|Nss] = Ss, - NewStack = yeccpars2_77_(Stack), - yeccgoto_query(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - -yeccpars2_78(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_|Nss] = Ss, - NewStack = yeccpars2_78_(Stack), - yeccgoto_exprlist(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - -yeccpars2_79(_S, Cat, Ss, Stack, T, Ts, Tzr) -> - [_|Nss] = Ss, - NewStack = yeccpars2_79_(Stack), - yeccgoto_script(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). - -yeccgoto_app(0=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_app(1=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_app(5=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_app(11=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_app(22=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_app(57=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_app(60=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_app(63=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_app(72=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_app(74=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_assign(0=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_9(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_assign(1=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_9(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_assign(57, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_60(60, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_assign(60, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_60(60, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_assignlist(57, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_59(59, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_assignlist(60=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_61(_S, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_binding(17, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_19(19, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_binding(25, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_19(19, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_bindinglist(17, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_18(18, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_bindinglist(25=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_26(_S, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_cnd(0=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_cnd(1=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_cnd(5=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_cnd(11=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_cnd(22=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_cnd(57=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_cnd(60=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_cnd(63=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_cnd(72=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_cnd(74=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_compoundexpr(0, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_7(7, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_compoundexpr(1, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_7(7, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_compoundexpr(11, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_71(71, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_compoundexpr(22=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_compoundexpr(63, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_64(64, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_compoundexpr(72, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_73(73, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_compoundexpr(74, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_75(75, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_defun(0=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_6(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_defun(1=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_6(_S, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_expr(0, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_expr(1, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_expr(5, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_expr(11, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_expr(22, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_expr(57, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_expr(60, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_expr(63, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_expr(72, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_expr(74, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_exprlist(0, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_4(4, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_exprlist(1, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_4(4, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_exprlist(5=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_78(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_exprlist(11=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_exprlist(22=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_exprlist(57, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_58(58, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_exprlist(60, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_58(58, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_exprlist(63=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_exprlist(72=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_exprlist(74=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_inparam(44, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_47(47, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_inparam(47, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_47(47, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_inparamlist(44, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_46(46, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_inparamlist(47=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_54(_S, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_lang(56, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_66(66, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_name(30=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_33(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_name(32=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_33(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_name(35, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_name(44=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_33(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_name(47=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_33(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_name(48, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_51(51, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_name(51, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_51(51, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_namelist(48, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_50(50, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_namelist(51=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_52(_S, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_param(30, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_param(32, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_param(44=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_45(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_param(47=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_45(_S, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_paramlist(30, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_31(31, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_paramlist(32=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_query(0=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_3(_S, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_query(1=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_3(_S, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_script(0, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_2(2, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_script(1=_S, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_79(_S, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_sign(28, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr). - -yeccgoto_stat(0, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_1(1, Cat, Ss, Stack, T, Ts, Tzr); -yeccgoto_stat(1, Cat, Ss, Stack, T, Ts, Tzr) -> - yeccpars2_1(1, Cat, Ss, Stack, T, Ts, Tzr). - --compile({inline,yeccpars2_3_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 40). -yeccpars2_3_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - { __1 , # { } , # { } } - end | __Stack]. - --compile({inline,yeccpars2_5_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 67). -yeccpars2_5_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - [ __1 ] - end | __Stack]. - --compile({inline,yeccpars2_6_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 42). -yeccpars2_6_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - { undef , # { } , __1 } - end | __Stack]. - --compile({inline,yeccpars2_9_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 41). -yeccpars2_9_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - { undef , __1 , # { } } - end | __Stack]. - --compile({inline,yeccpars2_13_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 63). -yeccpars2_13_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - mk_var ( __1 ) - end | __Stack]. - --compile({inline,yeccpars2_14_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 61). -yeccpars2_14_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - mk_str ( __1 ) - end | __Stack]. - --compile({inline,yeccpars2_15_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 58). -yeccpars2_15_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - [ ] - end | __Stack]. - --compile({inline,yeccpars2_16_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 62). -yeccpars2_16_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - mk_str ( __1 ) - end | __Stack]. - --compile({inline,yeccpars2_21_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 73). -yeccpars2_21_(__Stack0) -> - [__3,__2,__1 | __Stack] = __Stack0, - [begin - { app , get_line ( __1 ) , 1 , mk_var ( __1 ) , # { } } - end | __Stack]. - --compile({inline,yeccpars2_24_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 76). -yeccpars2_24_(__Stack0) -> - [__3,__2,__1 | __Stack] = __Stack0, - [begin - mk_binding ( __1 , __3 ) - end | __Stack]. - --compile({inline,yeccpars2_26_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 79). -yeccpars2_26_(__Stack0) -> - [__3,__2,__1 | __Stack] = __Stack0, - [begin - maps : merge ( __1 , __3 ) - end | __Stack]. - --compile({inline,yeccpars2_27_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 74). -yeccpars2_27_(__Stack0) -> - [__4,__3,__2,__1 | __Stack] = __Stack0, - [begin - { app , get_line ( __1 ) , 1 , mk_var ( __1 ) , __3 } - end | __Stack]. - --compile({inline,yeccpars2_32_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 93). -yeccpars2_32_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - [ __1 ] - end | __Stack]. - --compile({inline,yeccpars2_33_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 90). -yeccpars2_33_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - { param , __1 , false } - end | __Stack]. - --compile({inline,yeccpars2_34_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 96). -yeccpars2_34_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - { name , get_name ( __1 ) , false } - end | __Stack]. - --compile({inline,yeccpars2_37_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 91). -yeccpars2_37_(__Stack0) -> - [__3,__2,__1 | __Stack] = __Stack0, - [begin - { param , __2 , true } - end | __Stack]. - --compile({inline,yeccpars2_41_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 97). -yeccpars2_41_(__Stack0) -> - [__4,__3,__2,__1 | __Stack] = __Stack0, - [begin - { name , get_name ( __1 ) , false } - end | __Stack]. - --compile({inline,yeccpars2_42_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 98). -yeccpars2_42_(__Stack0) -> - [__4,__3,__2,__1 | __Stack] = __Stack0, - [begin - { name , get_name ( __1 ) , true } - end | __Stack]. - --compile({inline,yeccpars2_43_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 94). -yeccpars2_43_(__Stack0) -> - [__2,__1 | __Stack] = __Stack0, - [begin - [ __1 | __2 ] - end | __Stack]. - --compile({inline,yeccpars2_47_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 87). -yeccpars2_47_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - [ __1 ] - end | __Stack]. - --compile({inline,yeccpars2_49_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 81). -yeccpars2_49_(__Stack0) -> - [__4,__3,__2,__1 | __Stack] = __Stack0, - [begin - { sign , __2 , [ ] } - end | __Stack]. - --compile({inline,yeccpars2_51_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 100). -yeccpars2_51_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - [ __1 ] - end | __Stack]. - --compile({inline,yeccpars2_52_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 101). -yeccpars2_52_(__Stack0) -> - [__2,__1 | __Stack] = __Stack0, - [begin - [ __1 | __2 ] - end | __Stack]. - --compile({inline,yeccpars2_53_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 85). -yeccpars2_53_(__Stack0) -> - [__3,__2,__1 | __Stack] = __Stack0, - [begin - { correl , __2 } - end | __Stack]. - --compile({inline,yeccpars2_54_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 88). -yeccpars2_54_(__Stack0) -> - [__2,__1 | __Stack] = __Stack0, - [begin - [ __1 | __2 ] - end | __Stack]. - --compile({inline,yeccpars2_55_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 82). -yeccpars2_55_(__Stack0) -> - [__5,__4,__3,__2,__1 | __Stack] = __Stack0, - [begin - { sign , __2 , __4 } - end | __Stack]. - --compile({inline,yeccpars2_61_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 49). -yeccpars2_61_(__Stack0) -> - [__2,__1 | __Stack] = __Stack0, - [begin - maps : merge ( __1 , __2 ) - end | __Stack]. - --compile({inline,yeccpars2_62_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 51). -yeccpars2_62_(__Stack0) -> - [__6,__5,__4,__3,__2,__1 | __Stack] = __Stack0, - [begin - mk_natlam ( __1 , __2 , __3 , __5 ) - end | __Stack]. - --compile({inline,yeccpars2_65_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 46). -yeccpars2_65_(__Stack0) -> - [__4,__3,__2,__1 | __Stack] = __Stack0, - [begin - mk_assign ( __1 , __3 , 1 ) - end | __Stack]. - --compile({inline,yeccpars2_67_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 54). -yeccpars2_67_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - bash - end | __Stack]. - --compile({inline,yeccpars2_68_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 55). -yeccpars2_68_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - python - end | __Stack]. - --compile({inline,yeccpars2_69_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 56). -yeccpars2_69_(__Stack0) -> - [__1 | __Stack] = __Stack0, - [begin - r - end | __Stack]. - --compile({inline,yeccpars2_70_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 52). -yeccpars2_70_(__Stack0) -> - [__6,__5,__4,__3,__2,__1 | __Stack] = __Stack0, - [begin - mk_forlam ( __1 , __2 , __3 , __5 , __6 ) - end | __Stack]. - --compile({inline,yeccpars2_76_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 71). -yeccpars2_76_(__Stack0) -> - [__7,__6,__5,__4,__3,__2,__1 | __Stack] = __Stack0, - [begin - { cnd , get_line ( __1 ) , __2 , __4 , __6 } - end | __Stack]. - --compile({inline,yeccpars2_77_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 44). -yeccpars2_77_(__Stack0) -> - [__2,__1 | __Stack] = __Stack0, - [begin - __1 - end | __Stack]. - --compile({inline,yeccpars2_78_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 68). -yeccpars2_78_(__Stack0) -> - [__2,__1 | __Stack] = __Stack0, - [begin - [ __1 | __2 ] - end | __Stack]. - --compile({inline,yeccpars2_79_/1}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 38). -yeccpars2_79_(__Stack0) -> - [__2,__1 | __Stack] = __Stack0, - [begin - combine ( __1 , __2 ) - end | __Stack]. - - --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_parse.yrl", 308). diff --git a/src/cf_scan.erl b/src/cf_scan.erl deleted file mode 100644 index 34ec090..0000000 --- a/src/cf_scan.erl +++ /dev/null @@ -1,1676 +0,0 @@ --file("/usr/local/lib/erlang/lib/parsetools-2.1.1/include/leexinc.hrl", 0). -%% The source of this file is part of leex distribution, as such it -%% has the same Copyright as the other files in the leex -%% distribution. The Copyright is defined in the accompanying file -%% COPYRIGHT. However, the resultant scanner generated by leex is the -%% property of the creator of the scanner and is not covered by that -%% Copyright. - --module(cf_scan). - --export([string/1,string/2,token/2,token/3,tokens/2,tokens/3]). --export([format_error/1]). - -%% User code. This is placed here to allow extra attributes. --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 114). - --author( "Jorgen Brandt " ). - --export( [yyrev/2] ). - --ifdef( TEST ). --include_lib( "eunit/include/eunit.hrl" ). --endif. - -trim_body( S ) -> - string:substr( S, 3, length( S )-4 ). - -trim_strlit( S ) -> - string:substr( S, 2, length( S )-2 ). - - - -%% ============================================================================= -%% Unit Tests -%% ============================================================================= - - --ifdef( TEST ). - - - -bash_style_comment_should_be_recognized_test() -> - ?assertEqual( {ok, [], 1}, string( "#this is a comment" ) ). - -c_style_comment_should_be_recognized_test() -> - ?assertEqual( {ok, [], 1}, string( "//this is a comment" ) ). - -erlang_style_comment_should_be_recognized_test() -> - ?assertEqual( {ok, [], 1}, string( "%this is a comment" ) ). - - -multiline_comment_should_be_recognized_test() -> - [?assertEqual( {ok, [], 1}, string( "/**/" ) ), - ?assertEqual( {ok, [], 1}, string( "/*x*/" ) ), - ?assertEqual( {ok, [], 1}, string( "/*xy*/" ) ), - ?assertEqual( {ok, [], 2}, string( "/*x\ny*/" ) )]. - -bash_should_be_recognized_test() -> - ?assertEqual( {ok, [{bash, 1, "bash"}], 1}, string( "bash" ) ). - -beginif_should_be_recognized_test() -> - ?assertEqual( {ok, [{beginif, 1, "if"}], 1}, string( "if" ) ). - -colon_should_be_recognized_test() -> - ?assertEqual( {ok, [{colon, 1, ":"}], 1}, string( ":" ) ). - -deftask_should_be_recognized_test() -> - ?assertEqual( {ok, [{deftask, 1, "deftask"}], 1}, string( "deftask" ) ). - -else_should_be_recognized_test() -> - ?assertEqual( {ok, [{else, 1, "else"}], 1}, string( "else" ) ). - -endif_should_be_recognized_test() -> - ?assertEqual( {ok, [{endif, 1, "end"}], 1}, string( "end" ) ). - -eq_should_be_recognized_test() -> - ?assertEqual( {ok, [{eq, 1, "="}], 1}, string( "=" ) ). - -file_should_be_recognized_test() -> - ?assertEqual( {ok, [{file, 1, "File"}], 1}, string( "File" ) ). - -in_should_be_recognized_test() -> - ?assertEqual( {ok, [{in, 1, "in"}], 1}, string( "in" ) ). - -id_should_be_recognized_test() -> - [?assertEqual( {ok, [{id, 1, "inp"}], 1}, string( "inp" ) ), - ?assertEqual( {ok, [{id, 1, "a0"}], 1}, string( "a0" ) ), - ?assertEqual( {ok, [{id, 1, "a9"}], 1}, string( "a9" ) ), - ?assertEqual( {ok, [{id, 1, "a."}], 1}, string( "a." ) ), - ?assertEqual( {ok, [{id, 1, "a-"}], 1}, string( "a-" ) ), - ?assertEqual( {ok, [{id, 1, "a_"}], 1}, string( "a_" ) )]. - -python_should_be_recognized_test() -> - ?assertEqual( {ok, [{python, 1, "python"}], 1}, string( "python" ) ). - -r_should_be_recognized_test() -> - [?assertEqual( {ok, [{r, 1, "r"}], 1}, string( "r" ) ), - ?assertEqual( {ok, [{r, 1, "R"}], 1}, string( "R" ) )]. - -lbrace_should_be_recognized_test() -> - ?assertEqual( {ok, [{lbrace, 1, "{"}], 1}, string( "{" ) ). - -lparen_should_be_recognized_test() -> - ?assertEqual( {ok, [{lparen, 1, "("}], 1}, string( "(" ) ). - -lsquarebr_should_be_recognized_test() -> - ?assertEqual( {ok, [{lsquarebr, 1, "["}], 1}, string( "[" ) ). - -ltag_should_be_recognized_test() -> - ?assertEqual( {ok, [{ltag, 1, "<"}], 1}, string( "<" ) ). - -nil_should_be_recognized_test() -> - ?assertEqual( {ok, [{nil, 1, "nil"}], 1}, string( "nil" ) ). - -rbrace_should_be_recognized_test() -> - ?assertEqual( {ok, [{rbrace, 1, "}"}], 1}, string( "}" ) ). - -rparen_should_be_recognized_test() -> - ?assertEqual( {ok, [{rparen, 1, ")"}], 1}, string( ")" ) ). - -rsquarebr_should_be_recognized_test() -> - ?assertEqual( {ok, [{rsquarebr, 1, "]"}], 1}, string( "]" ) ). - -rtag_should_be_recognized_test() -> - ?assertEqual( {ok, [{rtag, 1, ">"}], 1}, string( ">" ) ). - -semicolon_should_be_recognized_test() -> - ?assertEqual( {ok, [{semicolon, 1, ";"}], 1}, string( ";" ) ). - -string_should_be_recognized_test() -> - ?assertEqual( {ok, [{string, 1, "String"}], 1}, string( "String" ) ). - -then_should_be_recognized_test() -> - ?assertEqual( {ok, [{then, 1, "then"}], 1}, string( "then" ) ). - -intlit_should_be_recognized_test() -> - [?assertEqual( {ok, [{intlit, 1, "10"}], 1}, string( "10" ) ), - ?assertEqual( {ok, [{intlit, 1, "-10"}], 1}, string( "-10" ) ), - ?assertEqual( {ok, [{intlit, 1, "9"}], 1}, string( "9" ) ), - ?assertEqual( {ok, [{intlit, 1, "0"}], 1}, string( "0" ) )]. - -body_should_be_recognized_test() -> - [?assertEqual( {ok, [{body, 1, ""}], 1}, string( "*{}*" ) ), - ?assertEqual( {ok, [{body, 1, "x"}], 1}, string( "*{x}*" ) ), - ?assertEqual( {ok, [{body, 1, "xy"}], 1}, string( "*{xy}*" ) ), - ?assertEqual( {ok, [{body, 1, "x\ny"}], 2}, string( "*{x\ny}*" ) )]. - -strlit_should_be_recognized_test() -> - [?assertEqual( {ok, [{strlit, 1, ""}], 1}, string( "\"\"" ) ), - ?assertEqual( {ok, [{strlit, 1, "x"}], 1}, string( "\"x\"" ) ), - ?assertEqual( {ok, [{strlit, 1, "xy"}], 1}, string( "\"xy\"" ) )]. - - - - - --endif. - - - --file("/usr/local/lib/erlang/lib/parsetools-2.1.1/include/leexinc.hrl", 14). - -format_error({illegal,S}) -> ["illegal characters ",io_lib:write_string(S)]; -format_error({user,S}) -> S. - -string(String) -> string(String, 1). - -string(String, Line) -> string(String, Line, String, []). - -%% string(InChars, Line, TokenChars, Tokens) -> -%% {ok,Tokens,Line} | {error,ErrorInfo,Line}. -%% Note the line number going into yystate, L0, is line of token -%% start while line number returned is line of token end. We want line -%% of token start. - -string([], L, [], Ts) -> % No partial tokens! - {ok,yyrev(Ts),L}; -string(Ics0, L0, Tcs, Ts) -> - case yystate(yystate(), Ics0, L0, 0, reject, 0) of - {A,Alen,Ics1,L1} -> % Accepting end state - string_cont(Ics1, L1, yyaction(A, Alen, Tcs, L0), Ts); - {A,Alen,Ics1,L1,_S1} -> % Accepting transistion state - string_cont(Ics1, L1, yyaction(A, Alen, Tcs, L0), Ts); - {reject,_Alen,Tlen,_Ics1,L1,_S1} -> % After a non-accepting state - {error,{L0,?MODULE,{illegal,yypre(Tcs, Tlen+1)}},L1}; - {A,Alen,_Tlen,_Ics1,_L1,_S1} -> - string_cont(yysuf(Tcs, Alen), L0, yyaction(A, Alen, Tcs, L0), Ts) - end. - -%% string_cont(RestChars, Line, Token, Tokens) -%% Test for and remove the end token wrapper. Push back characters -%% are prepended to RestChars. - --dialyzer({nowarn_function, string_cont/4}). - -string_cont(Rest, Line, {token,T}, Ts) -> - string(Rest, Line, Rest, [T|Ts]); -string_cont(Rest, Line, {token,T,Push}, Ts) -> - NewRest = Push ++ Rest, - string(NewRest, Line, NewRest, [T|Ts]); -string_cont(Rest, Line, {end_token,T}, Ts) -> - string(Rest, Line, Rest, [T|Ts]); -string_cont(Rest, Line, {end_token,T,Push}, Ts) -> - NewRest = Push ++ Rest, - string(NewRest, Line, NewRest, [T|Ts]); -string_cont(Rest, Line, skip_token, Ts) -> - string(Rest, Line, Rest, Ts); -string_cont(Rest, Line, {skip_token,Push}, Ts) -> - NewRest = Push ++ Rest, - string(NewRest, Line, NewRest, Ts); -string_cont(_Rest, Line, {error,S}, _Ts) -> - {error,{Line,?MODULE,{user,S}},Line}. - -%% token(Continuation, Chars) -> -%% token(Continuation, Chars, Line) -> -%% {more,Continuation} | {done,ReturnVal,RestChars}. -%% Must be careful when re-entering to append the latest characters to the -%% after characters in an accept. The continuation is: -%% {token,State,CurrLine,TokenChars,TokenLen,TokenLine,AccAction,AccLen} - -token(Cont, Chars) -> token(Cont, Chars, 1). - -token([], Chars, Line) -> - token(yystate(), Chars, Line, Chars, 0, Line, reject, 0); -token({token,State,Line,Tcs,Tlen,Tline,Action,Alen}, Chars, _) -> - token(State, Chars, Line, Tcs ++ Chars, Tlen, Tline, Action, Alen). - -%% token(State, InChars, Line, TokenChars, TokenLen, TokenLine, -%% AcceptAction, AcceptLen) -> -%% {more,Continuation} | {done,ReturnVal,RestChars}. -%% The argument order is chosen to be more efficient. - -token(S0, Ics0, L0, Tcs, Tlen0, Tline, A0, Alen0) -> - case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of - %% Accepting end state, we have a token. - {A1,Alen1,Ics1,L1} -> - token_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline)); - %% Accepting transition state, can take more chars. - {A1,Alen1,[],L1,S1} -> % Need more chars to check - {more,{token,S1,L1,Tcs,Alen1,Tline,A1,Alen1}}; - {A1,Alen1,Ics1,L1,_S1} -> % Take what we got - token_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline)); - %% After a non-accepting state, maybe reach accept state later. - {A1,Alen1,Tlen1,[],L1,S1} -> % Need more chars to check - {more,{token,S1,L1,Tcs,Tlen1,Tline,A1,Alen1}}; - {reject,_Alen1,Tlen1,eof,L1,_S1} -> % No token match - %% Check for partial token which is error. - Ret = if Tlen1 > 0 -> {error,{Tline,?MODULE, - %% Skip eof tail in Tcs. - {illegal,yypre(Tcs, Tlen1)}},L1}; - true -> {eof,L1} - end, - {done,Ret,eof}; - {reject,_Alen1,Tlen1,Ics1,L1,_S1} -> % No token match - Error = {Tline,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}}, - {done,{error,Error,L1},Ics1}; - {A1,Alen1,_Tlen1,_Ics1,_L1,_S1} -> % Use last accept match - token_cont(yysuf(Tcs, Alen1), L0, yyaction(A1, Alen1, Tcs, Tline)) - end. - -%% token_cont(RestChars, Line, Token) -%% If we have a token or error then return done, else if we have a -%% skip_token then continue. - --dialyzer({nowarn_function, token_cont/3}). - -token_cont(Rest, Line, {token,T}) -> - {done,{ok,T,Line},Rest}; -token_cont(Rest, Line, {token,T,Push}) -> - NewRest = Push ++ Rest, - {done,{ok,T,Line},NewRest}; -token_cont(Rest, Line, {end_token,T}) -> - {done,{ok,T,Line},Rest}; -token_cont(Rest, Line, {end_token,T,Push}) -> - NewRest = Push ++ Rest, - {done,{ok,T,Line},NewRest}; -token_cont(Rest, Line, skip_token) -> - token(yystate(), Rest, Line, Rest, 0, Line, reject, 0); -token_cont(Rest, Line, {skip_token,Push}) -> - NewRest = Push ++ Rest, - token(yystate(), NewRest, Line, NewRest, 0, Line, reject, 0); -token_cont(Rest, Line, {error,S}) -> - {done,{error,{Line,?MODULE,{user,S}},Line},Rest}. - -%% tokens(Continuation, Chars, Line) -> -%% {more,Continuation} | {done,ReturnVal,RestChars}. -%% Must be careful when re-entering to append the latest characters to the -%% after characters in an accept. The continuation is: -%% {tokens,State,CurrLine,TokenChars,TokenLen,TokenLine,Tokens,AccAction,AccLen} -%% {skip_tokens,State,CurrLine,TokenChars,TokenLen,TokenLine,Error,AccAction,AccLen} - -tokens(Cont, Chars) -> tokens(Cont, Chars, 1). - -tokens([], Chars, Line) -> - tokens(yystate(), Chars, Line, Chars, 0, Line, [], reject, 0); -tokens({tokens,State,Line,Tcs,Tlen,Tline,Ts,Action,Alen}, Chars, _) -> - tokens(State, Chars, Line, Tcs ++ Chars, Tlen, Tline, Ts, Action, Alen); -tokens({skip_tokens,State,Line,Tcs,Tlen,Tline,Error,Action,Alen}, Chars, _) -> - skip_tokens(State, Chars, Line, Tcs ++ Chars, Tlen, Tline, Error, Action, Alen). - -%% tokens(State, InChars, Line, TokenChars, TokenLen, TokenLine, Tokens, -%% AcceptAction, AcceptLen) -> -%% {more,Continuation} | {done,ReturnVal,RestChars}. - -tokens(S0, Ics0, L0, Tcs, Tlen0, Tline, Ts, A0, Alen0) -> - case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of - %% Accepting end state, we have a token. - {A1,Alen1,Ics1,L1} -> - tokens_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Ts); - %% Accepting transition state, can take more chars. - {A1,Alen1,[],L1,S1} -> % Need more chars to check - {more,{tokens,S1,L1,Tcs,Alen1,Tline,Ts,A1,Alen1}}; - {A1,Alen1,Ics1,L1,_S1} -> % Take what we got - tokens_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Ts); - %% After a non-accepting state, maybe reach accept state later. - {A1,Alen1,Tlen1,[],L1,S1} -> % Need more chars to check - {more,{tokens,S1,L1,Tcs,Tlen1,Tline,Ts,A1,Alen1}}; - {reject,_Alen1,Tlen1,eof,L1,_S1} -> % No token match - %% Check for partial token which is error, no need to skip here. - Ret = if Tlen1 > 0 -> {error,{Tline,?MODULE, - %% Skip eof tail in Tcs. - {illegal,yypre(Tcs, Tlen1)}},L1}; - Ts == [] -> {eof,L1}; - true -> {ok,yyrev(Ts),L1} - end, - {done,Ret,eof}; - {reject,_Alen1,Tlen1,_Ics1,L1,_S1} -> - %% Skip rest of tokens. - Error = {L1,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}}, - skip_tokens(yysuf(Tcs, Tlen1+1), L1, Error); - {A1,Alen1,_Tlen1,_Ics1,_L1,_S1} -> - Token = yyaction(A1, Alen1, Tcs, Tline), - tokens_cont(yysuf(Tcs, Alen1), L0, Token, Ts) - end. - -%% tokens_cont(RestChars, Line, Token, Tokens) -%% If we have an end_token or error then return done, else if we have -%% a token then save it and continue, else if we have a skip_token -%% just continue. - --dialyzer({nowarn_function, tokens_cont/4}). - -tokens_cont(Rest, Line, {token,T}, Ts) -> - tokens(yystate(), Rest, Line, Rest, 0, Line, [T|Ts], reject, 0); -tokens_cont(Rest, Line, {token,T,Push}, Ts) -> - NewRest = Push ++ Rest, - tokens(yystate(), NewRest, Line, NewRest, 0, Line, [T|Ts], reject, 0); -tokens_cont(Rest, Line, {end_token,T}, Ts) -> - {done,{ok,yyrev(Ts, [T]),Line},Rest}; -tokens_cont(Rest, Line, {end_token,T,Push}, Ts) -> - NewRest = Push ++ Rest, - {done,{ok,yyrev(Ts, [T]),Line},NewRest}; -tokens_cont(Rest, Line, skip_token, Ts) -> - tokens(yystate(), Rest, Line, Rest, 0, Line, Ts, reject, 0); -tokens_cont(Rest, Line, {skip_token,Push}, Ts) -> - NewRest = Push ++ Rest, - tokens(yystate(), NewRest, Line, NewRest, 0, Line, Ts, reject, 0); -tokens_cont(Rest, Line, {error,S}, _Ts) -> - skip_tokens(Rest, Line, {Line,?MODULE,{user,S}}). - -%%skip_tokens(InChars, Line, Error) -> {done,{error,Error,Line},Ics}. -%% Skip tokens until an end token, junk everything and return the error. - -skip_tokens(Ics, Line, Error) -> - skip_tokens(yystate(), Ics, Line, Ics, 0, Line, Error, reject, 0). - -%% skip_tokens(State, InChars, Line, TokenChars, TokenLen, TokenLine, Tokens, -%% AcceptAction, AcceptLen) -> -%% {more,Continuation} | {done,ReturnVal,RestChars}. - -skip_tokens(S0, Ics0, L0, Tcs, Tlen0, Tline, Error, A0, Alen0) -> - case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of - {A1,Alen1,Ics1,L1} -> % Accepting end state - skip_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Error); - {A1,Alen1,[],L1,S1} -> % After an accepting state - {more,{skip_tokens,S1,L1,Tcs,Alen1,Tline,Error,A1,Alen1}}; - {A1,Alen1,Ics1,L1,_S1} -> - skip_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Error); - {A1,Alen1,Tlen1,[],L1,S1} -> % After a non-accepting state - {more,{skip_tokens,S1,L1,Tcs,Tlen1,Tline,Error,A1,Alen1}}; - {reject,_Alen1,_Tlen1,eof,L1,_S1} -> - {done,{error,Error,L1},eof}; - {reject,_Alen1,Tlen1,_Ics1,L1,_S1} -> - skip_tokens(yysuf(Tcs, Tlen1+1), L1, Error); - {A1,Alen1,_Tlen1,_Ics1,L1,_S1} -> - Token = yyaction(A1, Alen1, Tcs, Tline), - skip_cont(yysuf(Tcs, Alen1), L1, Token, Error) - end. - -%% skip_cont(RestChars, Line, Token, Error) -%% Skip tokens until we have an end_token or error then return done -%% with the original rror. - --dialyzer({nowarn_function, skip_cont/4}). - -skip_cont(Rest, Line, {token,_T}, Error) -> - skip_tokens(yystate(), Rest, Line, Rest, 0, Line, Error, reject, 0); -skip_cont(Rest, Line, {token,_T,Push}, Error) -> - NewRest = Push ++ Rest, - skip_tokens(yystate(), NewRest, Line, NewRest, 0, Line, Error, reject, 0); -skip_cont(Rest, Line, {end_token,_T}, Error) -> - {done,{error,Error,Line},Rest}; -skip_cont(Rest, Line, {end_token,_T,Push}, Error) -> - NewRest = Push ++ Rest, - {done,{error,Error,Line},NewRest}; -skip_cont(Rest, Line, skip_token, Error) -> - skip_tokens(yystate(), Rest, Line, Rest, 0, Line, Error, reject, 0); -skip_cont(Rest, Line, {skip_token,Push}, Error) -> - NewRest = Push ++ Rest, - skip_tokens(yystate(), NewRest, Line, NewRest, 0, Line, Error, reject, 0); -skip_cont(Rest, Line, {error,_S}, Error) -> - skip_tokens(yystate(), Rest, Line, Rest, 0, Line, Error, reject, 0). - -yyrev(List) -> lists:reverse(List). -yyrev(List, Tail) -> lists:reverse(List, Tail). -yypre(List, N) -> lists:sublist(List, N). -yysuf(List, N) -> lists:nthtail(N, List). - -%% yystate() -> InitialState. -%% yystate(State, InChars, Line, CurrTokLen, AcceptAction, AcceptLen) -> -%% {Action, AcceptLen, RestChars, Line} | -%% {Action, AcceptLen, RestChars, Line, State} | -%% {reject, AcceptLen, CurrTokLen, RestChars, Line, State} | -%% {Action, AcceptLen, CurrTokLen, RestChars, Line, State}. -%% Generated state transition functions. The non-accepting end state -%% return signal either an unrecognised character or end of current -%% input. - --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.erl", 428). -yystate() -> 69. - -yystate(72, [122|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(72, [121|Ics], Line, Tlen, _, _) -> - yystate(68, Ics, Line, Tlen+1, 27, Tlen); -yystate(72, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(72, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(72, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(72, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(72, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(72, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 120 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(72, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,72}; -yystate(71, Ics, Line, Tlen, _, _) -> - {30,Tlen,Ics,Line}; -yystate(70, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 2, Tlen); -yystate(70, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 2, Tlen); -yystate(70, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 2, Tlen); -yystate(70, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 2, Tlen); -yystate(70, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 2, Tlen); -yystate(70, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 2, Tlen); -yystate(70, Ics, Line, Tlen, _, _) -> - {2,Tlen,Ics,Line,70}; -yystate(69, [125|Ics], Line, Tlen, Action, Alen) -> - yystate(65, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [123|Ics], Line, Tlen, Action, Alen) -> - yystate(61, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [116|Ics], Line, Tlen, Action, Alen) -> - yystate(57, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [115|Ics], Line, Tlen, Action, Alen) -> - yystate(41, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [114|Ics], Line, Tlen, Action, Alen) -> - yystate(70, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [113|Ics], Line, Tlen, Action, Alen) -> - yystate(41, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [112|Ics], Line, Tlen, Action, Alen) -> - yystate(72, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [111|Ics], Line, Tlen, Action, Alen) -> - yystate(41, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [110|Ics], Line, Tlen, Action, Alen) -> - yystate(37, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [105|Ics], Line, Tlen, Action, Alen) -> - yystate(25, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [101|Ics], Line, Tlen, Action, Alen) -> - yystate(13, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [100|Ics], Line, Tlen, Action, Alen) -> - yystate(10, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [99|Ics], Line, Tlen, Action, Alen) -> - yystate(41, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [98|Ics], Line, Tlen, Action, Alen) -> - yystate(32, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [97|Ics], Line, Tlen, Action, Alen) -> - yystate(41, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [93|Ics], Line, Tlen, Action, Alen) -> - yystate(38, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [91|Ics], Line, Tlen, Action, Alen) -> - yystate(42, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [83|Ics], Line, Tlen, Action, Alen) -> - yystate(46, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [82|Ics], Line, Tlen, Action, Alen) -> - yystate(70, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [81|Ics], Line, Tlen, Action, Alen) -> - yystate(41, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [80|Ics], Line, Tlen, Action, Alen) -> - yystate(72, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [70|Ics], Line, Tlen, Action, Alen) -> - yystate(48, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [66|Ics], Line, Tlen, Action, Alen) -> - yystate(32, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [65|Ics], Line, Tlen, Action, Alen) -> - yystate(41, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [62|Ics], Line, Tlen, Action, Alen) -> - yystate(16, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [61|Ics], Line, Tlen, Action, Alen) -> - yystate(12, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [60|Ics], Line, Tlen, Action, Alen) -> - yystate(8, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [59|Ics], Line, Tlen, Action, Alen) -> - yystate(4, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [58|Ics], Line, Tlen, Action, Alen) -> - yystate(0, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [48|Ics], Line, Tlen, Action, Alen) -> - yystate(7, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [47|Ics], Line, Tlen, Action, Alen) -> - yystate(11, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [45|Ics], Line, Tlen, Action, Alen) -> - yystate(27, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [44|Ics], Line, Tlen, Action, Alen) -> - yystate(31, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [42|Ics], Line, Tlen, Action, Alen) -> - yystate(35, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [41|Ics], Line, Tlen, Action, Alen) -> - yystate(51, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [40|Ics], Line, Tlen, Action, Alen) -> - yystate(55, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [37|Ics], Line, Tlen, Action, Alen) -> - yystate(59, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [35|Ics], Line, Tlen, Action, Alen) -> - yystate(59, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [34|Ics], Line, Tlen, Action, Alen) -> - yystate(67, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [10|Ics], Line, Tlen, Action, Alen) -> - yystate(71, Ics, Line+1, Tlen+1, Action, Alen); -yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 0, C =< 9 -> - yystate(71, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 11, C =< 32 -> - yystate(71, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 49, C =< 57 -> - yystate(3, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 67, C =< 69 -> - yystate(41, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 71, C =< 79 -> - yystate(41, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 84, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 102, C =< 104 -> - yystate(41, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 106, C =< 109 -> - yystate(41, Ics, Line, Tlen+1, Action, Alen); -yystate(69, [C|Ics], Line, Tlen, Action, Alen) when C >= 117, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, Action, Alen); -yystate(69, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,69}; -yystate(68, [116|Ics], Line, Tlen, _, _) -> - yystate(64, Ics, Line, Tlen+1, 27, Tlen); -yystate(68, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(68, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(68, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(68, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(68, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(68, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 115 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(68, [C|Ics], Line, Tlen, _, _) when C >= 117, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(68, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,68}; -yystate(67, [34|Ics], Line, Tlen, Action, Alen) -> - yystate(63, Ics, Line, Tlen+1, Action, Alen); -yystate(67, [10|Ics], Line, Tlen, Action, Alen) -> - yystate(67, Ics, Line+1, Tlen+1, Action, Alen); -yystate(67, [C|Ics], Line, Tlen, Action, Alen) when C >= 0, C =< 9 -> - yystate(67, Ics, Line, Tlen+1, Action, Alen); -yystate(67, [C|Ics], Line, Tlen, Action, Alen) when C >= 11, C =< 33 -> - yystate(67, Ics, Line, Tlen+1, Action, Alen); -yystate(67, [C|Ics], Line, Tlen, Action, Alen) when C >= 35 -> - yystate(67, Ics, Line, Tlen+1, Action, Alen); -yystate(67, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,67}; -yystate(66, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 25, Tlen); -yystate(66, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 25, Tlen); -yystate(66, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 25, Tlen); -yystate(66, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 25, Tlen); -yystate(66, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 25, Tlen); -yystate(66, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 25, Tlen); -yystate(66, Ics, Line, Tlen, _, _) -> - {25,Tlen,Ics,Line,66}; -yystate(65, Ics, Line, Tlen, _, _) -> - {20,Tlen,Ics,Line}; -yystate(64, [104|Ics], Line, Tlen, _, _) -> - yystate(60, Ics, Line, Tlen+1, 27, Tlen); -yystate(64, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(64, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(64, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(64, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(64, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(64, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 103 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(64, [C|Ics], Line, Tlen, _, _) when C >= 105, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(64, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,64}; -yystate(63, Ics, Line, Tlen, _, _) -> - {4,Tlen,Ics,Line}; -yystate(62, [103|Ics], Line, Tlen, _, _) -> - yystate(66, Ics, Line, Tlen+1, 27, Tlen); -yystate(62, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(62, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(62, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(62, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(62, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(62, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 102 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(62, [C|Ics], Line, Tlen, _, _) when C >= 104, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(62, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,62}; -yystate(61, Ics, Line, Tlen, _, _) -> - {15,Tlen,Ics,Line}; -yystate(60, [111|Ics], Line, Tlen, _, _) -> - yystate(56, Ics, Line, Tlen+1, 27, Tlen); -yystate(60, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(60, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(60, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(60, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(60, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(60, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 110 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(60, [C|Ics], Line, Tlen, _, _) when C >= 112, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(60, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,60}; -yystate(59, [C|Ics], Line, Tlen, _, _) when C >= 0, C =< 9 -> - yystate(59, Ics, Line, Tlen+1, 28, Tlen); -yystate(59, [C|Ics], Line, Tlen, _, _) when C >= 11 -> - yystate(59, Ics, Line, Tlen+1, 28, Tlen); -yystate(59, Ics, Line, Tlen, _, _) -> - {28,Tlen,Ics,Line,59}; -yystate(58, [110|Ics], Line, Tlen, _, _) -> - yystate(62, Ics, Line, Tlen+1, 27, Tlen); -yystate(58, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(58, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(58, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(58, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(58, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(58, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 109 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(58, [C|Ics], Line, Tlen, _, _) when C >= 111, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(58, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,58}; -yystate(57, [104|Ics], Line, Tlen, _, _) -> - yystate(53, Ics, Line, Tlen+1, 27, Tlen); -yystate(57, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(57, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(57, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(57, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(57, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(57, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 103 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(57, [C|Ics], Line, Tlen, _, _) when C >= 105, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(57, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,57}; -yystate(56, [110|Ics], Line, Tlen, _, _) -> - yystate(52, Ics, Line, Tlen+1, 27, Tlen); -yystate(56, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(56, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(56, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(56, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(56, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(56, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 109 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(56, [C|Ics], Line, Tlen, _, _) when C >= 111, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(56, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,56}; -yystate(55, Ics, Line, Tlen, _, _) -> - {16,Tlen,Ics,Line}; -yystate(54, [105|Ics], Line, Tlen, _, _) -> - yystate(58, Ics, Line, Tlen+1, 27, Tlen); -yystate(54, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(54, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(54, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(54, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(54, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(54, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 104 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(54, [C|Ics], Line, Tlen, _, _) when C >= 106, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(54, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,54}; -yystate(53, [101|Ics], Line, Tlen, _, _) -> - yystate(49, Ics, Line, Tlen+1, 27, Tlen); -yystate(53, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(53, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(53, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(53, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(53, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(53, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 100 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(53, [C|Ics], Line, Tlen, _, _) when C >= 102, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(53, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,53}; -yystate(52, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 1, Tlen); -yystate(52, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 1, Tlen); -yystate(52, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 1, Tlen); -yystate(52, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 1, Tlen); -yystate(52, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 1, Tlen); -yystate(52, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 1, Tlen); -yystate(52, Ics, Line, Tlen, _, _) -> - {1,Tlen,Ics,Line,52}; -yystate(51, Ics, Line, Tlen, _, _) -> - {21,Tlen,Ics,Line}; -yystate(50, [114|Ics], Line, Tlen, _, _) -> - yystate(54, Ics, Line, Tlen+1, 27, Tlen); -yystate(50, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(50, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(50, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(50, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(50, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(50, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 113 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(50, [C|Ics], Line, Tlen, _, _) when C >= 115, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(50, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,50}; -yystate(49, [110|Ics], Line, Tlen, _, _) -> - yystate(45, Ics, Line, Tlen+1, 27, Tlen); -yystate(49, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(49, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(49, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(49, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(49, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(49, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 109 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(49, [C|Ics], Line, Tlen, _, _) when C >= 111, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(49, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,49}; -yystate(48, [105|Ics], Line, Tlen, _, _) -> - yystate(44, Ics, Line, Tlen+1, 27, Tlen); -yystate(48, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(48, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(48, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(48, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(48, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(48, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 104 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(48, [C|Ics], Line, Tlen, _, _) when C >= 106, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(48, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,48}; -yystate(47, [125|Ics], Line, Tlen, Action, Alen) -> - yystate(39, Ics, Line, Tlen+1, Action, Alen); -yystate(47, [10|Ics], Line, Tlen, Action, Alen) -> - yystate(47, Ics, Line+1, Tlen+1, Action, Alen); -yystate(47, [C|Ics], Line, Tlen, Action, Alen) when C >= 0, C =< 9 -> - yystate(47, Ics, Line, Tlen+1, Action, Alen); -yystate(47, [C|Ics], Line, Tlen, Action, Alen) when C >= 11, C =< 124 -> - yystate(47, Ics, Line, Tlen+1, Action, Alen); -yystate(47, [C|Ics], Line, Tlen, Action, Alen) when C >= 126 -> - yystate(47, Ics, Line, Tlen+1, Action, Alen); -yystate(47, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,47}; -yystate(46, [116|Ics], Line, Tlen, _, _) -> - yystate(50, Ics, Line, Tlen+1, 27, Tlen); -yystate(46, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(46, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(46, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(46, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(46, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(46, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 115 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(46, [C|Ics], Line, Tlen, _, _) when C >= 117, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(46, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,46}; -yystate(45, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 26, Tlen); -yystate(45, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 26, Tlen); -yystate(45, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 26, Tlen); -yystate(45, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 26, Tlen); -yystate(45, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 26, Tlen); -yystate(45, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 26, Tlen); -yystate(45, Ics, Line, Tlen, _, _) -> - {26,Tlen,Ics,Line,45}; -yystate(44, [108|Ics], Line, Tlen, _, _) -> - yystate(40, Ics, Line, Tlen+1, 27, Tlen); -yystate(44, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(44, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(44, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(44, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(44, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(44, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 107 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(44, [C|Ics], Line, Tlen, _, _) when C >= 109, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(44, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,44}; -yystate(43, Ics, Line, Tlen, _, _) -> - {5,Tlen,Ics,Line}; -yystate(42, Ics, Line, Tlen, _, _) -> - {17,Tlen,Ics,Line}; -yystate(41, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(41, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(41, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(41, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(41, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(41, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(41, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,41}; -yystate(40, [101|Ics], Line, Tlen, _, _) -> - yystate(36, Ics, Line, Tlen+1, 27, Tlen); -yystate(40, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(40, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(40, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(40, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(40, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(40, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 100 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(40, [C|Ics], Line, Tlen, _, _) when C >= 102, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(40, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,40}; -yystate(39, [125|Ics], Line, Tlen, Action, Alen) -> - yystate(39, Ics, Line, Tlen+1, Action, Alen); -yystate(39, [42|Ics], Line, Tlen, Action, Alen) -> - yystate(43, Ics, Line, Tlen+1, Action, Alen); -yystate(39, [10|Ics], Line, Tlen, Action, Alen) -> - yystate(47, Ics, Line+1, Tlen+1, Action, Alen); -yystate(39, [C|Ics], Line, Tlen, Action, Alen) when C >= 0, C =< 9 -> - yystate(47, Ics, Line, Tlen+1, Action, Alen); -yystate(39, [C|Ics], Line, Tlen, Action, Alen) when C >= 11, C =< 41 -> - yystate(47, Ics, Line, Tlen+1, Action, Alen); -yystate(39, [C|Ics], Line, Tlen, Action, Alen) when C >= 43, C =< 124 -> - yystate(47, Ics, Line, Tlen+1, Action, Alen); -yystate(39, [C|Ics], Line, Tlen, Action, Alen) when C >= 126 -> - yystate(47, Ics, Line, Tlen+1, Action, Alen); -yystate(39, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,39}; -yystate(38, Ics, Line, Tlen, _, _) -> - {22,Tlen,Ics,Line}; -yystate(37, [105|Ics], Line, Tlen, _, _) -> - yystate(33, Ics, Line, Tlen+1, 27, Tlen); -yystate(37, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(37, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(37, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(37, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(37, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(37, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 104 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(37, [C|Ics], Line, Tlen, _, _) when C >= 106, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(37, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,37}; -yystate(36, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 13, Tlen); -yystate(36, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 13, Tlen); -yystate(36, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 13, Tlen); -yystate(36, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 13, Tlen); -yystate(36, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 13, Tlen); -yystate(36, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 13, Tlen); -yystate(36, Ics, Line, Tlen, _, _) -> - {13,Tlen,Ics,Line,36}; -yystate(35, [123|Ics], Line, Tlen, Action, Alen) -> - yystate(47, Ics, Line, Tlen+1, Action, Alen); -yystate(35, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,35}; -yystate(34, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 9, Tlen); -yystate(34, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 9, Tlen); -yystate(34, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 9, Tlen); -yystate(34, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 9, Tlen); -yystate(34, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 9, Tlen); -yystate(34, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 9, Tlen); -yystate(34, Ics, Line, Tlen, _, _) -> - {9,Tlen,Ics,Line,34}; -yystate(33, [108|Ics], Line, Tlen, _, _) -> - yystate(29, Ics, Line, Tlen+1, 27, Tlen); -yystate(33, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(33, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(33, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(33, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(33, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(33, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 107 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(33, [C|Ics], Line, Tlen, _, _) when C >= 109, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(33, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,33}; -yystate(32, [97|Ics], Line, Tlen, _, _) -> - yystate(28, Ics, Line, Tlen+1, 27, Tlen); -yystate(32, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(32, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(32, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(32, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(32, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(32, [C|Ics], Line, Tlen, _, _) when C >= 98, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(32, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,32}; -yystate(31, Ics, Line, Tlen, _, _) -> - {8,Tlen,Ics,Line}; -yystate(30, [107|Ics], Line, Tlen, _, _) -> - yystate(34, Ics, Line, Tlen+1, 27, Tlen); -yystate(30, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(30, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(30, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(30, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(30, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(30, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 106 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(30, [C|Ics], Line, Tlen, _, _) when C >= 108, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(30, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,30}; -yystate(29, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 19, Tlen); -yystate(29, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 19, Tlen); -yystate(29, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 19, Tlen); -yystate(29, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 19, Tlen); -yystate(29, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 19, Tlen); -yystate(29, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 19, Tlen); -yystate(29, Ics, Line, Tlen, _, _) -> - {19,Tlen,Ics,Line,29}; -yystate(28, [115|Ics], Line, Tlen, _, _) -> - yystate(24, Ics, Line, Tlen+1, 27, Tlen); -yystate(28, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(28, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(28, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(28, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(28, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(28, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 114 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(28, [C|Ics], Line, Tlen, _, _) when C >= 116, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(28, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,28}; -yystate(27, [48|Ics], Line, Tlen, Action, Alen) -> - yystate(7, Ics, Line, Tlen+1, Action, Alen); -yystate(27, [C|Ics], Line, Tlen, Action, Alen) when C >= 49, C =< 57 -> - yystate(3, Ics, Line, Tlen+1, Action, Alen); -yystate(27, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,27}; -yystate(26, [115|Ics], Line, Tlen, _, _) -> - yystate(30, Ics, Line, Tlen+1, 27, Tlen); -yystate(26, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(26, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(26, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(26, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(26, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(26, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 114 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(26, [C|Ics], Line, Tlen, _, _) when C >= 116, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(26, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,26}; -yystate(25, [110|Ics], Line, Tlen, _, _) -> - yystate(21, Ics, Line, Tlen+1, 27, Tlen); -yystate(25, [102|Ics], Line, Tlen, _, _) -> - yystate(17, Ics, Line, Tlen+1, 27, Tlen); -yystate(25, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(25, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(25, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(25, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(25, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(25, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 101 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(25, [C|Ics], Line, Tlen, _, _) when C >= 103, C =< 109 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(25, [C|Ics], Line, Tlen, _, _) when C >= 111, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(25, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,25}; -yystate(24, [104|Ics], Line, Tlen, _, _) -> - yystate(20, Ics, Line, Tlen+1, 27, Tlen); -yystate(24, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(24, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(24, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(24, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(24, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(24, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 103 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(24, [C|Ics], Line, Tlen, _, _) when C >= 105, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(24, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,24}; -yystate(23, [42|Ics], Line, Tlen, Action, Alen) -> - yystate(15, Ics, Line, Tlen+1, Action, Alen); -yystate(23, [10|Ics], Line, Tlen, Action, Alen) -> - yystate(23, Ics, Line+1, Tlen+1, Action, Alen); -yystate(23, [C|Ics], Line, Tlen, Action, Alen) when C >= 0, C =< 9 -> - yystate(23, Ics, Line, Tlen+1, Action, Alen); -yystate(23, [C|Ics], Line, Tlen, Action, Alen) when C >= 11, C =< 41 -> - yystate(23, Ics, Line, Tlen+1, Action, Alen); -yystate(23, [C|Ics], Line, Tlen, Action, Alen) when C >= 43 -> - yystate(23, Ics, Line, Tlen+1, Action, Alen); -yystate(23, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,23}; -yystate(22, [97|Ics], Line, Tlen, _, _) -> - yystate(26, Ics, Line, Tlen+1, 27, Tlen); -yystate(22, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(22, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(22, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(22, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(22, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(22, [C|Ics], Line, Tlen, _, _) when C >= 98, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(22, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,22}; -yystate(21, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 14, Tlen); -yystate(21, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 14, Tlen); -yystate(21, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 14, Tlen); -yystate(21, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 14, Tlen); -yystate(21, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 14, Tlen); -yystate(21, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 14, Tlen); -yystate(21, Ics, Line, Tlen, _, _) -> - {14,Tlen,Ics,Line,21}; -yystate(20, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 0, Tlen); -yystate(20, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 0, Tlen); -yystate(20, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 0, Tlen); -yystate(20, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 0, Tlen); -yystate(20, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 0, Tlen); -yystate(20, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 0, Tlen); -yystate(20, Ics, Line, Tlen, _, _) -> - {0,Tlen,Ics,Line,20}; -yystate(19, Ics, Line, Tlen, _, _) -> - {29,Tlen,Ics,Line}; -yystate(18, [116|Ics], Line, Tlen, _, _) -> - yystate(22, Ics, Line, Tlen+1, 27, Tlen); -yystate(18, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(18, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(18, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(18, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(18, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(18, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 115 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(18, [C|Ics], Line, Tlen, _, _) when C >= 117, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(18, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,18}; -yystate(17, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 6, Tlen); -yystate(17, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 6, Tlen); -yystate(17, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 6, Tlen); -yystate(17, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 6, Tlen); -yystate(17, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 6, Tlen); -yystate(17, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 6, Tlen); -yystate(17, Ics, Line, Tlen, _, _) -> - {6,Tlen,Ics,Line,17}; -yystate(16, Ics, Line, Tlen, _, _) -> - {23,Tlen,Ics,Line}; -yystate(15, [47|Ics], Line, Tlen, Action, Alen) -> - yystate(19, Ics, Line, Tlen+1, Action, Alen); -yystate(15, [42|Ics], Line, Tlen, Action, Alen) -> - yystate(15, Ics, Line, Tlen+1, Action, Alen); -yystate(15, [10|Ics], Line, Tlen, Action, Alen) -> - yystate(23, Ics, Line+1, Tlen+1, Action, Alen); -yystate(15, [C|Ics], Line, Tlen, Action, Alen) when C >= 0, C =< 9 -> - yystate(23, Ics, Line, Tlen+1, Action, Alen); -yystate(15, [C|Ics], Line, Tlen, Action, Alen) when C >= 11, C =< 41 -> - yystate(23, Ics, Line, Tlen+1, Action, Alen); -yystate(15, [C|Ics], Line, Tlen, Action, Alen) when C >= 43, C =< 46 -> - yystate(23, Ics, Line, Tlen+1, Action, Alen); -yystate(15, [C|Ics], Line, Tlen, Action, Alen) when C >= 48 -> - yystate(23, Ics, Line, Tlen+1, Action, Alen); -yystate(15, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,15}; -yystate(14, [102|Ics], Line, Tlen, _, _) -> - yystate(18, Ics, Line, Tlen+1, 27, Tlen); -yystate(14, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(14, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(14, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(14, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(14, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(14, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 101 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(14, [C|Ics], Line, Tlen, _, _) when C >= 103, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(14, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,14}; -yystate(13, [110|Ics], Line, Tlen, _, _) -> - yystate(9, Ics, Line, Tlen+1, 27, Tlen); -yystate(13, [109|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(13, [108|Ics], Line, Tlen, _, _) -> - yystate(1, Ics, Line, Tlen+1, 27, Tlen); -yystate(13, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(13, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(13, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(13, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(13, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(13, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 107 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(13, [C|Ics], Line, Tlen, _, _) when C >= 111, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(13, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,13}; -yystate(12, Ics, Line, Tlen, _, _) -> - {12,Tlen,Ics,Line}; -yystate(11, [47|Ics], Line, Tlen, Action, Alen) -> - yystate(59, Ics, Line, Tlen+1, Action, Alen); -yystate(11, [42|Ics], Line, Tlen, Action, Alen) -> - yystate(23, Ics, Line, Tlen+1, Action, Alen); -yystate(11, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,11}; -yystate(10, [101|Ics], Line, Tlen, _, _) -> - yystate(14, Ics, Line, Tlen+1, 27, Tlen); -yystate(10, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(10, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(10, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(10, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(10, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(10, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 100 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(10, [C|Ics], Line, Tlen, _, _) when C >= 102, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(10, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,10}; -yystate(9, [100|Ics], Line, Tlen, _, _) -> - yystate(5, Ics, Line, Tlen+1, 27, Tlen); -yystate(9, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(9, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(9, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(9, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(9, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(9, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 99 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(9, [C|Ics], Line, Tlen, _, _) when C >= 101, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(9, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,9}; -yystate(8, Ics, Line, Tlen, _, _) -> - {18,Tlen,Ics,Line}; -yystate(7, Ics, Line, Tlen, _, _) -> - {3,Tlen,Ics,Line}; -yystate(6, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 10, Tlen); -yystate(6, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 10, Tlen); -yystate(6, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 10, Tlen); -yystate(6, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 10, Tlen); -yystate(6, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 10, Tlen); -yystate(6, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 10, Tlen); -yystate(6, Ics, Line, Tlen, _, _) -> - {10,Tlen,Ics,Line,6}; -yystate(5, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 11, Tlen); -yystate(5, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 11, Tlen); -yystate(5, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 11, Tlen); -yystate(5, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 11, Tlen); -yystate(5, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 11, Tlen); -yystate(5, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 11, Tlen); -yystate(5, Ics, Line, Tlen, _, _) -> - {11,Tlen,Ics,Line,5}; -yystate(4, Ics, Line, Tlen, _, _) -> - {24,Tlen,Ics,Line}; -yystate(3, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(3, Ics, Line, Tlen+1, 3, Tlen); -yystate(3, Ics, Line, Tlen, _, _) -> - {3,Tlen,Ics,Line,3}; -yystate(2, [101|Ics], Line, Tlen, _, _) -> - yystate(6, Ics, Line, Tlen+1, 27, Tlen); -yystate(2, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(2, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(2, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(2, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(2, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(2, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 100 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(2, [C|Ics], Line, Tlen, _, _) when C >= 102, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(2, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,2}; -yystate(1, [115|Ics], Line, Tlen, _, _) -> - yystate(2, Ics, Line, Tlen+1, 27, Tlen); -yystate(1, [95|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(1, [45|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(1, [46|Ics], Line, Tlen, _, _) -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(1, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(1, [C|Ics], Line, Tlen, _, _) when C >= 65, C =< 90 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(1, [C|Ics], Line, Tlen, _, _) when C >= 97, C =< 114 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(1, [C|Ics], Line, Tlen, _, _) when C >= 116, C =< 122 -> - yystate(41, Ics, Line, Tlen+1, 27, Tlen); -yystate(1, Ics, Line, Tlen, _, _) -> - {27,Tlen,Ics,Line,1}; -yystate(0, Ics, Line, Tlen, _, _) -> - {7,Tlen,Ics,Line}; -yystate(S, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,S}. - -%% yyaction(Action, TokenLength, TokenChars, TokenLine) -> -%% {token,Token} | {end_token, Token} | skip_token | {error,String}. -%% Generated action function. - -yyaction(0, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_0(TokenChars, TokenLine); -yyaction(1, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_1(TokenChars, TokenLine); -yyaction(2, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_2(TokenChars, TokenLine); -yyaction(3, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_3(TokenChars, TokenLine); -yyaction(4, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_4(TokenChars, TokenLine); -yyaction(5, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_5(TokenChars, TokenLine); -yyaction(6, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_6(TokenChars, TokenLine); -yyaction(7, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_7(TokenChars, TokenLine); -yyaction(8, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_8(TokenChars, TokenLine); -yyaction(9, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_9(TokenChars, TokenLine); -yyaction(10, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_10(TokenChars, TokenLine); -yyaction(11, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_11(TokenChars, TokenLine); -yyaction(12, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_12(TokenChars, TokenLine); -yyaction(13, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_13(TokenChars, TokenLine); -yyaction(14, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_14(TokenChars, TokenLine); -yyaction(15, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_15(TokenChars, TokenLine); -yyaction(16, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_16(TokenChars, TokenLine); -yyaction(17, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_17(TokenChars, TokenLine); -yyaction(18, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_18(TokenChars, TokenLine); -yyaction(19, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_19(TokenChars, TokenLine); -yyaction(20, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_20(TokenChars, TokenLine); -yyaction(21, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_21(TokenChars, TokenLine); -yyaction(22, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_22(TokenChars, TokenLine); -yyaction(23, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_23(TokenChars, TokenLine); -yyaction(24, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_24(TokenChars, TokenLine); -yyaction(25, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_25(TokenChars, TokenLine); -yyaction(26, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_26(TokenChars, TokenLine); -yyaction(27, TokenLen, YYtcs, TokenLine) -> - TokenChars = yypre(YYtcs, TokenLen), - yyaction_27(TokenChars, TokenLine); -yyaction(28, _, _, _) -> - yyaction_28(); -yyaction(29, _, _, _) -> - yyaction_29(); -yyaction(30, _, _, _) -> - yyaction_30(); -yyaction(_, _, _, _) -> error. - --compile({inline,yyaction_0/2}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 69). -yyaction_0(TokenChars, TokenLine) -> - { token, { bash, TokenLine, TokenChars } } . - --compile({inline,yyaction_1/2}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 70). -yyaction_1(TokenChars, TokenLine) -> - { token, { python, TokenLine, TokenChars } } . - --compile({inline,yyaction_2/2}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 71). -yyaction_2(TokenChars, TokenLine) -> - { token, { r, TokenLine, TokenChars } } . - --compile({inline,yyaction_3/2}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 73). -yyaction_3(TokenChars, TokenLine) -> - { token, { intlit, TokenLine, TokenChars } } . - --compile({inline,yyaction_4/2}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 74). -yyaction_4(TokenChars, TokenLine) -> - { token, { strlit, TokenLine, trim_strlit (TokenChars) } } . - --compile({inline,yyaction_5/2}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 75). -yyaction_5(TokenChars, TokenLine) -> - { token, { body, TokenLine, trim_body (TokenChars) } } . - --compile({inline,yyaction_6/2}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 76). -yyaction_6(TokenChars, TokenLine) -> - { token, { beginif, TokenLine, TokenChars } } . - --compile({inline,yyaction_7/2}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 77). -yyaction_7(TokenChars, TokenLine) -> - { token, { colon, TokenLine, TokenChars } } . - --compile({inline,yyaction_8/2}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 78). -yyaction_8(TokenChars, TokenLine) -> - { token, { comma, TokenLine, TokenChars } } . - --compile({inline,yyaction_9/2}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 79). -yyaction_9(TokenChars, TokenLine) -> - { token, { deftask, TokenLine, TokenChars } } . - --compile({inline,yyaction_10/2}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 80). -yyaction_10(TokenChars, TokenLine) -> - { token, { else, TokenLine, TokenChars } } . - --compile({inline,yyaction_11/2}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 81). -yyaction_11(TokenChars, TokenLine) -> - { token, { endif, TokenLine, TokenChars } } . - --compile({inline,yyaction_12/2}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 82). -yyaction_12(TokenChars, TokenLine) -> - { token, { eq, TokenLine, TokenChars } } . - --compile({inline,yyaction_13/2}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 83). -yyaction_13(TokenChars, TokenLine) -> - { token, { file, TokenLine, TokenChars } } . - --compile({inline,yyaction_14/2}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 84). -yyaction_14(TokenChars, TokenLine) -> - { token, { in, TokenLine, TokenChars } } . - --compile({inline,yyaction_15/2}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 85). -yyaction_15(TokenChars, TokenLine) -> - { token, { lbrace, TokenLine, TokenChars } } . - --compile({inline,yyaction_16/2}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 86). -yyaction_16(TokenChars, TokenLine) -> - { token, { lparen, TokenLine, TokenChars } } . - --compile({inline,yyaction_17/2}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 87). -yyaction_17(TokenChars, TokenLine) -> - { token, { lsquarebr, TokenLine, TokenChars } } . - --compile({inline,yyaction_18/2}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 88). -yyaction_18(TokenChars, TokenLine) -> - { token, { ltag, TokenLine, TokenChars } } . - --compile({inline,yyaction_19/2}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 89). -yyaction_19(TokenChars, TokenLine) -> - { token, { nil, TokenLine, TokenChars } } . - --compile({inline,yyaction_20/2}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 90). -yyaction_20(TokenChars, TokenLine) -> - { token, { rbrace, TokenLine, TokenChars } } . - --compile({inline,yyaction_21/2}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 91). -yyaction_21(TokenChars, TokenLine) -> - { token, { rparen, TokenLine, TokenChars } } . - --compile({inline,yyaction_22/2}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 92). -yyaction_22(TokenChars, TokenLine) -> - { token, { rsquarebr, TokenLine, TokenChars } } . - --compile({inline,yyaction_23/2}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 93). -yyaction_23(TokenChars, TokenLine) -> - { token, { rtag, TokenLine, TokenChars } } . - --compile({inline,yyaction_24/2}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 94). -yyaction_24(TokenChars, TokenLine) -> - { token, { semicolon, TokenLine, TokenChars } } . - --compile({inline,yyaction_25/2}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 95). -yyaction_25(TokenChars, TokenLine) -> - { token, { string, TokenLine, TokenChars } } . - --compile({inline,yyaction_26/2}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 96). -yyaction_26(TokenChars, TokenLine) -> - { token, { then, TokenLine, TokenChars } } . - --compile({inline,yyaction_27/2}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 98). -yyaction_27(TokenChars, TokenLine) -> - { token, { id, TokenLine, TokenChars } } . - --compile({inline,yyaction_28/0}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 100). -yyaction_28() -> - skip_token . - --compile({inline,yyaction_29/0}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 101). -yyaction_29() -> - skip_token . - --compile({inline,yyaction_30/0}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/cf_scan.xrl", 102). -yyaction_30() -> - skip_token . - --file("/usr/local/lib/erlang/lib/parsetools-2.1.1/include/leexinc.hrl", 290). diff --git a/src/pre_scan.erl b/src/pre_scan.erl deleted file mode 100644 index 114c89d..0000000 --- a/src/pre_scan.erl +++ /dev/null @@ -1,464 +0,0 @@ --file("/usr/local/lib/erlang/lib/parsetools-2.1.1/include/leexinc.hrl", 0). -%% The source of this file is part of leex distribution, as such it -%% has the same Copyright as the other files in the leex -%% distribution. The Copyright is defined in the accompanying file -%% COPYRIGHT. However, the resultant scanner generated by leex is the -%% property of the creator of the scanner and is not covered by that -%% Copyright. - --module(pre_scan). - --export([string/1,string/2,token/2,token/3,tokens/2,tokens/3]). --export([format_error/1]). - -%% User code. This is placed here to allow extra attributes. --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 56). - --author( "Jorgen Brandt " ). - --export( [yyrev/2] ). --file("/usr/local/lib/erlang/lib/parsetools-2.1.1/include/leexinc.hrl", 14). - -format_error({illegal,S}) -> ["illegal characters ",io_lib:write_string(S)]; -format_error({user,S}) -> S. - -string(String) -> string(String, 1). - -string(String, Line) -> string(String, Line, String, []). - -%% string(InChars, Line, TokenChars, Tokens) -> -%% {ok,Tokens,Line} | {error,ErrorInfo,Line}. -%% Note the line number going into yystate, L0, is line of token -%% start while line number returned is line of token end. We want line -%% of token start. - -string([], L, [], Ts) -> % No partial tokens! - {ok,yyrev(Ts),L}; -string(Ics0, L0, Tcs, Ts) -> - case yystate(yystate(), Ics0, L0, 0, reject, 0) of - {A,Alen,Ics1,L1} -> % Accepting end state - string_cont(Ics1, L1, yyaction(A, Alen, Tcs, L0), Ts); - {A,Alen,Ics1,L1,_S1} -> % Accepting transistion state - string_cont(Ics1, L1, yyaction(A, Alen, Tcs, L0), Ts); - {reject,_Alen,Tlen,_Ics1,L1,_S1} -> % After a non-accepting state - {error,{L0,?MODULE,{illegal,yypre(Tcs, Tlen+1)}},L1}; - {A,Alen,_Tlen,_Ics1,_L1,_S1} -> - string_cont(yysuf(Tcs, Alen), L0, yyaction(A, Alen, Tcs, L0), Ts) - end. - -%% string_cont(RestChars, Line, Token, Tokens) -%% Test for and remove the end token wrapper. Push back characters -%% are prepended to RestChars. - --dialyzer({nowarn_function, string_cont/4}). - -string_cont(Rest, Line, {token,T}, Ts) -> - string(Rest, Line, Rest, [T|Ts]); -string_cont(Rest, Line, {token,T,Push}, Ts) -> - NewRest = Push ++ Rest, - string(NewRest, Line, NewRest, [T|Ts]); -string_cont(Rest, Line, {end_token,T}, Ts) -> - string(Rest, Line, Rest, [T|Ts]); -string_cont(Rest, Line, {end_token,T,Push}, Ts) -> - NewRest = Push ++ Rest, - string(NewRest, Line, NewRest, [T|Ts]); -string_cont(Rest, Line, skip_token, Ts) -> - string(Rest, Line, Rest, Ts); -string_cont(Rest, Line, {skip_token,Push}, Ts) -> - NewRest = Push ++ Rest, - string(NewRest, Line, NewRest, Ts); -string_cont(_Rest, Line, {error,S}, _Ts) -> - {error,{Line,?MODULE,{user,S}},Line}. - -%% token(Continuation, Chars) -> -%% token(Continuation, Chars, Line) -> -%% {more,Continuation} | {done,ReturnVal,RestChars}. -%% Must be careful when re-entering to append the latest characters to the -%% after characters in an accept. The continuation is: -%% {token,State,CurrLine,TokenChars,TokenLen,TokenLine,AccAction,AccLen} - -token(Cont, Chars) -> token(Cont, Chars, 1). - -token([], Chars, Line) -> - token(yystate(), Chars, Line, Chars, 0, Line, reject, 0); -token({token,State,Line,Tcs,Tlen,Tline,Action,Alen}, Chars, _) -> - token(State, Chars, Line, Tcs ++ Chars, Tlen, Tline, Action, Alen). - -%% token(State, InChars, Line, TokenChars, TokenLen, TokenLine, -%% AcceptAction, AcceptLen) -> -%% {more,Continuation} | {done,ReturnVal,RestChars}. -%% The argument order is chosen to be more efficient. - -token(S0, Ics0, L0, Tcs, Tlen0, Tline, A0, Alen0) -> - case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of - %% Accepting end state, we have a token. - {A1,Alen1,Ics1,L1} -> - token_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline)); - %% Accepting transition state, can take more chars. - {A1,Alen1,[],L1,S1} -> % Need more chars to check - {more,{token,S1,L1,Tcs,Alen1,Tline,A1,Alen1}}; - {A1,Alen1,Ics1,L1,_S1} -> % Take what we got - token_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline)); - %% After a non-accepting state, maybe reach accept state later. - {A1,Alen1,Tlen1,[],L1,S1} -> % Need more chars to check - {more,{token,S1,L1,Tcs,Tlen1,Tline,A1,Alen1}}; - {reject,_Alen1,Tlen1,eof,L1,_S1} -> % No token match - %% Check for partial token which is error. - Ret = if Tlen1 > 0 -> {error,{Tline,?MODULE, - %% Skip eof tail in Tcs. - {illegal,yypre(Tcs, Tlen1)}},L1}; - true -> {eof,L1} - end, - {done,Ret,eof}; - {reject,_Alen1,Tlen1,Ics1,L1,_S1} -> % No token match - Error = {Tline,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}}, - {done,{error,Error,L1},Ics1}; - {A1,Alen1,_Tlen1,_Ics1,_L1,_S1} -> % Use last accept match - token_cont(yysuf(Tcs, Alen1), L0, yyaction(A1, Alen1, Tcs, Tline)) - end. - -%% token_cont(RestChars, Line, Token) -%% If we have a token or error then return done, else if we have a -%% skip_token then continue. - --dialyzer({nowarn_function, token_cont/3}). - -token_cont(Rest, Line, {token,T}) -> - {done,{ok,T,Line},Rest}; -token_cont(Rest, Line, {token,T,Push}) -> - NewRest = Push ++ Rest, - {done,{ok,T,Line},NewRest}; -token_cont(Rest, Line, {end_token,T}) -> - {done,{ok,T,Line},Rest}; -token_cont(Rest, Line, {end_token,T,Push}) -> - NewRest = Push ++ Rest, - {done,{ok,T,Line},NewRest}; -token_cont(Rest, Line, skip_token) -> - token(yystate(), Rest, Line, Rest, 0, Line, reject, 0); -token_cont(Rest, Line, {skip_token,Push}) -> - NewRest = Push ++ Rest, - token(yystate(), NewRest, Line, NewRest, 0, Line, reject, 0); -token_cont(Rest, Line, {error,S}) -> - {done,{error,{Line,?MODULE,{user,S}},Line},Rest}. - -%% tokens(Continuation, Chars, Line) -> -%% {more,Continuation} | {done,ReturnVal,RestChars}. -%% Must be careful when re-entering to append the latest characters to the -%% after characters in an accept. The continuation is: -%% {tokens,State,CurrLine,TokenChars,TokenLen,TokenLine,Tokens,AccAction,AccLen} -%% {skip_tokens,State,CurrLine,TokenChars,TokenLen,TokenLine,Error,AccAction,AccLen} - -tokens(Cont, Chars) -> tokens(Cont, Chars, 1). - -tokens([], Chars, Line) -> - tokens(yystate(), Chars, Line, Chars, 0, Line, [], reject, 0); -tokens({tokens,State,Line,Tcs,Tlen,Tline,Ts,Action,Alen}, Chars, _) -> - tokens(State, Chars, Line, Tcs ++ Chars, Tlen, Tline, Ts, Action, Alen); -tokens({skip_tokens,State,Line,Tcs,Tlen,Tline,Error,Action,Alen}, Chars, _) -> - skip_tokens(State, Chars, Line, Tcs ++ Chars, Tlen, Tline, Error, Action, Alen). - -%% tokens(State, InChars, Line, TokenChars, TokenLen, TokenLine, Tokens, -%% AcceptAction, AcceptLen) -> -%% {more,Continuation} | {done,ReturnVal,RestChars}. - -tokens(S0, Ics0, L0, Tcs, Tlen0, Tline, Ts, A0, Alen0) -> - case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of - %% Accepting end state, we have a token. - {A1,Alen1,Ics1,L1} -> - tokens_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Ts); - %% Accepting transition state, can take more chars. - {A1,Alen1,[],L1,S1} -> % Need more chars to check - {more,{tokens,S1,L1,Tcs,Alen1,Tline,Ts,A1,Alen1}}; - {A1,Alen1,Ics1,L1,_S1} -> % Take what we got - tokens_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Ts); - %% After a non-accepting state, maybe reach accept state later. - {A1,Alen1,Tlen1,[],L1,S1} -> % Need more chars to check - {more,{tokens,S1,L1,Tcs,Tlen1,Tline,Ts,A1,Alen1}}; - {reject,_Alen1,Tlen1,eof,L1,_S1} -> % No token match - %% Check for partial token which is error, no need to skip here. - Ret = if Tlen1 > 0 -> {error,{Tline,?MODULE, - %% Skip eof tail in Tcs. - {illegal,yypre(Tcs, Tlen1)}},L1}; - Ts == [] -> {eof,L1}; - true -> {ok,yyrev(Ts),L1} - end, - {done,Ret,eof}; - {reject,_Alen1,Tlen1,_Ics1,L1,_S1} -> - %% Skip rest of tokens. - Error = {L1,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}}, - skip_tokens(yysuf(Tcs, Tlen1+1), L1, Error); - {A1,Alen1,_Tlen1,_Ics1,_L1,_S1} -> - Token = yyaction(A1, Alen1, Tcs, Tline), - tokens_cont(yysuf(Tcs, Alen1), L0, Token, Ts) - end. - -%% tokens_cont(RestChars, Line, Token, Tokens) -%% If we have an end_token or error then return done, else if we have -%% a token then save it and continue, else if we have a skip_token -%% just continue. - --dialyzer({nowarn_function, tokens_cont/4}). - -tokens_cont(Rest, Line, {token,T}, Ts) -> - tokens(yystate(), Rest, Line, Rest, 0, Line, [T|Ts], reject, 0); -tokens_cont(Rest, Line, {token,T,Push}, Ts) -> - NewRest = Push ++ Rest, - tokens(yystate(), NewRest, Line, NewRest, 0, Line, [T|Ts], reject, 0); -tokens_cont(Rest, Line, {end_token,T}, Ts) -> - {done,{ok,yyrev(Ts, [T]),Line},Rest}; -tokens_cont(Rest, Line, {end_token,T,Push}, Ts) -> - NewRest = Push ++ Rest, - {done,{ok,yyrev(Ts, [T]),Line},NewRest}; -tokens_cont(Rest, Line, skip_token, Ts) -> - tokens(yystate(), Rest, Line, Rest, 0, Line, Ts, reject, 0); -tokens_cont(Rest, Line, {skip_token,Push}, Ts) -> - NewRest = Push ++ Rest, - tokens(yystate(), NewRest, Line, NewRest, 0, Line, Ts, reject, 0); -tokens_cont(Rest, Line, {error,S}, _Ts) -> - skip_tokens(Rest, Line, {Line,?MODULE,{user,S}}). - -%%skip_tokens(InChars, Line, Error) -> {done,{error,Error,Line},Ics}. -%% Skip tokens until an end token, junk everything and return the error. - -skip_tokens(Ics, Line, Error) -> - skip_tokens(yystate(), Ics, Line, Ics, 0, Line, Error, reject, 0). - -%% skip_tokens(State, InChars, Line, TokenChars, TokenLen, TokenLine, Tokens, -%% AcceptAction, AcceptLen) -> -%% {more,Continuation} | {done,ReturnVal,RestChars}. - -skip_tokens(S0, Ics0, L0, Tcs, Tlen0, Tline, Error, A0, Alen0) -> - case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of - {A1,Alen1,Ics1,L1} -> % Accepting end state - skip_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Error); - {A1,Alen1,[],L1,S1} -> % After an accepting state - {more,{skip_tokens,S1,L1,Tcs,Alen1,Tline,Error,A1,Alen1}}; - {A1,Alen1,Ics1,L1,_S1} -> - skip_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Error); - {A1,Alen1,Tlen1,[],L1,S1} -> % After a non-accepting state - {more,{skip_tokens,S1,L1,Tcs,Tlen1,Tline,Error,A1,Alen1}}; - {reject,_Alen1,_Tlen1,eof,L1,_S1} -> - {done,{error,Error,L1},eof}; - {reject,_Alen1,Tlen1,_Ics1,L1,_S1} -> - skip_tokens(yysuf(Tcs, Tlen1+1), L1, Error); - {A1,Alen1,_Tlen1,_Ics1,L1,_S1} -> - Token = yyaction(A1, Alen1, Tcs, Tline), - skip_cont(yysuf(Tcs, Alen1), L1, Token, Error) - end. - -%% skip_cont(RestChars, Line, Token, Error) -%% Skip tokens until we have an end_token or error then return done -%% with the original rror. - --dialyzer({nowarn_function, skip_cont/4}). - -skip_cont(Rest, Line, {token,_T}, Error) -> - skip_tokens(yystate(), Rest, Line, Rest, 0, Line, Error, reject, 0); -skip_cont(Rest, Line, {token,_T,Push}, Error) -> - NewRest = Push ++ Rest, - skip_tokens(yystate(), NewRest, Line, NewRest, 0, Line, Error, reject, 0); -skip_cont(Rest, Line, {end_token,_T}, Error) -> - {done,{error,Error,Line},Rest}; -skip_cont(Rest, Line, {end_token,_T,Push}, Error) -> - NewRest = Push ++ Rest, - {done,{error,Error,Line},NewRest}; -skip_cont(Rest, Line, skip_token, Error) -> - skip_tokens(yystate(), Rest, Line, Rest, 0, Line, Error, reject, 0); -skip_cont(Rest, Line, {skip_token,Push}, Error) -> - NewRest = Push ++ Rest, - skip_tokens(yystate(), NewRest, Line, NewRest, 0, Line, Error, reject, 0); -skip_cont(Rest, Line, {error,_S}, Error) -> - skip_tokens(yystate(), Rest, Line, Rest, 0, Line, Error, reject, 0). - -yyrev(List) -> lists:reverse(List). -yyrev(List, Tail) -> lists:reverse(List, Tail). -yypre(List, N) -> lists:sublist(List, N). -yysuf(List, N) -> lists:nthtail(N, List). - -%% yystate() -> InitialState. -%% yystate(State, InChars, Line, CurrTokLen, AcceptAction, AcceptLen) -> -%% {Action, AcceptLen, RestChars, Line} | -%% {Action, AcceptLen, RestChars, Line, State} | -%% {reject, AcceptLen, CurrTokLen, RestChars, Line, State} | -%% {Action, AcceptLen, CurrTokLen, RestChars, Line, State}. -%% Generated state transition functions. The non-accepting end state -%% return signal either an unrecognised character or end of current -%% input. - --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.erl", 288). -yystate() -> 20. - -yystate(23, [101|Ics], Line, Tlen, Action, Alen) -> - yystate(21, Ics, Line, Tlen+1, Action, Alen); -yystate(23, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,23}; -yystate(22, Ics, Line, Tlen, _, _) -> - {6,Tlen,Ics,Line}; -yystate(21, Ics, Line, Tlen, _, _) -> - {1,Tlen,Ics,Line}; -yystate(20, [125|Ics], Line, Tlen, Action, Alen) -> - yystate(16, Ics, Line, Tlen+1, Action, Alen); -yystate(20, [116|Ics], Line, Tlen, Action, Alen) -> - yystate(8, Ics, Line, Tlen+1, Action, Alen); -yystate(20, [115|Ics], Line, Tlen, Action, Alen) -> - yystate(11, Ics, Line, Tlen+1, Action, Alen); -yystate(20, [114|Ics], Line, Tlen, Action, Alen) -> - yystate(18, Ics, Line, Tlen+1, Action, Alen); -yystate(20, [113|Ics], Line, Tlen, Action, Alen) -> - yystate(17, Ics, Line, Tlen+1, Action, Alen); -yystate(20, [104|Ics], Line, Tlen, Action, Alen) -> - yystate(1, Ics, Line, Tlen+1, Action, Alen); -yystate(20, [59|Ics], Line, Tlen, Action, Alen) -> - yystate(14, Ics, Line, Tlen+1, Action, Alen); -yystate(20, [10|Ics], Line, Tlen, Action, Alen) -> - yystate(22, Ics, Line+1, Tlen+1, Action, Alen); -yystate(20, [C|Ics], Line, Tlen, Action, Alen) when C >= 0, C =< 9 -> - yystate(22, Ics, Line, Tlen+1, Action, Alen); -yystate(20, [C|Ics], Line, Tlen, Action, Alen) when C >= 11, C =< 32 -> - yystate(22, Ics, Line, Tlen+1, Action, Alen); -yystate(20, [C|Ics], Line, Tlen, Action, Alen) when C >= 33, C =< 58 -> - yystate(18, Ics, Line, Tlen+1, Action, Alen); -yystate(20, [C|Ics], Line, Tlen, Action, Alen) when C >= 60, C =< 103 -> - yystate(18, Ics, Line, Tlen+1, Action, Alen); -yystate(20, [C|Ics], Line, Tlen, Action, Alen) when C >= 105, C =< 112 -> - yystate(18, Ics, Line, Tlen+1, Action, Alen); -yystate(20, [C|Ics], Line, Tlen, Action, Alen) when C >= 117, C =< 124 -> - yystate(18, Ics, Line, Tlen+1, Action, Alen); -yystate(20, [C|Ics], Line, Tlen, Action, Alen) when C >= 126 -> - yystate(18, Ics, Line, Tlen+1, Action, Alen); -yystate(20, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,20}; -yystate(19, [116|Ics], Line, Tlen, Action, Alen) -> - yystate(23, Ics, Line, Tlen+1, Action, Alen); -yystate(19, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,19}; -yystate(18, Ics, Line, Tlen, _, _) -> - {7,Tlen,Ics,Line}; -yystate(17, [117|Ics], Line, Tlen, _, _) -> - yystate(13, Ics, Line, Tlen+1, 7, Tlen); -yystate(17, Ics, Line, Tlen, _, _) -> - {7,Tlen,Ics,Line,17}; -yystate(16, [42|Ics], Line, Tlen, _, _) -> - yystate(12, Ics, Line, Tlen+1, 7, Tlen); -yystate(16, Ics, Line, Tlen, _, _) -> - {7,Tlen,Ics,Line,16}; -yystate(15, [97|Ics], Line, Tlen, Action, Alen) -> - yystate(19, Ics, Line, Tlen+1, Action, Alen); -yystate(15, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,15}; -yystate(14, Ics, Line, Tlen, _, _) -> - {5,Tlen,Ics,Line}; -yystate(13, [105|Ics], Line, Tlen, Action, Alen) -> - yystate(9, Ics, Line, Tlen+1, Action, Alen); -yystate(13, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,13}; -yystate(12, Ics, Line, Tlen, _, _) -> - {4,Tlen,Ics,Line}; -yystate(11, [116|Ics], Line, Tlen, _, _) -> - yystate(15, Ics, Line, Tlen+1, 7, Tlen); -yystate(11, Ics, Line, Tlen, _, _) -> - {7,Tlen,Ics,Line,11}; -yystate(10, Ics, Line, Tlen, _, _) -> - {3,Tlen,Ics,Line}; -yystate(9, [116|Ics], Line, Tlen, Action, Alen) -> - yystate(5, Ics, Line, Tlen+1, Action, Alen); -yystate(9, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,9}; -yystate(8, [97|Ics], Line, Tlen, _, _) -> - yystate(4, Ics, Line, Tlen+1, 7, Tlen); -yystate(8, Ics, Line, Tlen, _, _) -> - {7,Tlen,Ics,Line,8}; -yystate(7, Ics, Line, Tlen, _, _) -> - {0,Tlen,Ics,Line}; -yystate(6, [112|Ics], Line, Tlen, Action, Alen) -> - yystate(10, Ics, Line, Tlen+1, Action, Alen); -yystate(6, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,6}; -yystate(5, Ics, Line, Tlen, _, _) -> - {2,Tlen,Ics,Line}; -yystate(4, [115|Ics], Line, Tlen, Action, Alen) -> - yystate(0, Ics, Line, Tlen+1, Action, Alen); -yystate(4, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,4}; -yystate(3, [115|Ics], Line, Tlen, Action, Alen) -> - yystate(7, Ics, Line, Tlen+1, Action, Alen); -yystate(3, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,3}; -yystate(2, [108|Ics], Line, Tlen, Action, Alen) -> - yystate(6, Ics, Line, Tlen+1, Action, Alen); -yystate(2, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,2}; -yystate(1, [101|Ics], Line, Tlen, _, _) -> - yystate(2, Ics, Line, Tlen+1, 7, Tlen); -yystate(1, Ics, Line, Tlen, _, _) -> - {7,Tlen,Ics,Line,1}; -yystate(0, [107|Ics], Line, Tlen, Action, Alen) -> - yystate(3, Ics, Line, Tlen+1, Action, Alen); -yystate(0, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,0}; -yystate(S, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,S}. - -%% yyaction(Action, TokenLength, TokenChars, TokenLine) -> -%% {token,Token} | {end_token, Token} | skip_token | {error,String}. -%% Generated action function. - -yyaction(0, _, _, _) -> - yyaction_0(); -yyaction(1, _, _, _) -> - yyaction_1(); -yyaction(2, _, _, _) -> - yyaction_2(); -yyaction(3, _, _, _) -> - yyaction_3(); -yyaction(4, _, _, _) -> - yyaction_4(); -yyaction(5, _, _, _) -> - yyaction_5(); -yyaction(6, _, _, _) -> - yyaction_6(); -yyaction(7, _, _, _) -> - yyaction_7(); -yyaction(_, _, _, _) -> error. - --compile({inline,yyaction_0/0}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 40). -yyaction_0() -> - { token, tasks } . - --compile({inline,yyaction_1/0}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 41). -yyaction_1() -> - { token, state } . - --compile({inline,yyaction_2/0}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 42). -yyaction_2() -> - { token, quit } . - --compile({inline,yyaction_3/0}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 43). -yyaction_3() -> - { token, help } . - --compile({inline,yyaction_4/0}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 44). -yyaction_4() -> - { token, terminal } . - --compile({inline,yyaction_5/0}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 45). -yyaction_5() -> - { token, terminal } . - --compile({inline,yyaction_6/0}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 46). -yyaction_6() -> - skip_token . - --compile({inline,yyaction_7/0}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 47). -yyaction_7() -> - { token, nonws } . - --file("/usr/local/lib/erlang/lib/parsetools-2.1.1/include/leexinc.hrl", 290). From 1c69dc44ea22243f8b00a4c56dab3f235aa8a1ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Sat, 19 Mar 2016 12:59:32 +0100 Subject: [PATCH 37/78] Error reporting improved. --- src/cf_sem.erl | 4 ++-- src/cf_shell.erl | 8 ++++---- src/cuneiform.erl | 25 ++++++++++++++++++++++--- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/cf_sem.erl b/src/cf_sem.erl index c58b9e3..d707701 100644 --- a/src/cf_sem.erl +++ b/src/cf_sem.erl @@ -34,11 +34,11 @@ -type expr() :: str() | var() | select() | cnd() | app(). % (1) -type str() :: {str, S::string()}. % (2) -type var() :: {var, Line::pos_integer(), N::string()}. % (3) --type select() :: {select, Line::pos_integer(), C::pos_integer(), U::fut()}. % (4) +-type select() :: {select, AppLine::pos_integer(), C::pos_integer(), U::fut()}.% (4) -type fut() :: {fut, LamName::string(), R::pos_integer(), Lo::[param()]}. % (5) -type cnd() :: {cnd, Line::pos_integer(), % (6) Xc::[expr()], Xt::[expr()], Xe::[expr()]}. --type app() :: {app, Line::pos_integer(), C::pos_integer(), % (7) +-type app() :: {app, AppLine::pos_integer(), C::pos_integer(), % (7) Lambda::lam() | var(), Fa::#{string() => [expr()]}}. %% Lambda %% =================================================================== diff --git a/src/cf_shell.erl b/src/cf_shell.erl index bd1da6d..f94506f 100644 --- a/src/cf_shell.erl +++ b/src/cf_shell.erl @@ -139,15 +139,15 @@ format_error( {Line, cf_parse, S} ) -> format_error( {Line, cf_sem, S} ) -> io_lib:format( ?RED( "Line ~p: " )++?BRED( "~s" ), [Line, S] ); -format_error( {LamLine, cuneiform, {R, script_error, LamName, _Fa, {ActScript, Out}}} ) -> +format_error( {AppLine, cuneiform, {script_error, LamName, R, {ActScript, Out}}} ) -> io_lib:format( ?BYLW( "[out]~n" )++?YLW( "~s~n" ) ++?BYLW( "[script]~n" )++?YLW( "~s~n" ) ++?RED( "Line ~p: " )++?BRED( "script error in call to ~s (~p)" ), - [format_out( Out ), format_script( ActScript ), LamLine, LamName, R] ); + [format_out( Out ), format_script( ActScript ), AppLine, LamName, R] ); -format_error( {LamLine, cuneiform, {R, not_found, LamName, _Fa, MissingLst}} ) -> - io_lib:format( ?RED( "Line ~p: " )++?BRED( "precondition not met in call to ~s (~p)~n" )++?RED( "Missing files: ~p" ), [LamLine, LamName, R, MissingLst] ); +format_error( {AppLine, cuneiform, {precond, LamName, R, MissingLst}} ) -> + io_lib:format( ?RED( "Line ~p: " )++?BRED( "precondition not met in call to ~s (~p)~n" )++?RED( "Missing files: ~p" ), [AppLine, LamName, R, MissingLst] ); format_error( ErrorInfo ) -> io_lib:format( ?RED( "Error: " )++?BRED( "~p" ), [ErrorInfo] ). diff --git a/src/cuneiform.erl b/src/cuneiform.erl index 916d435..26051e6 100644 --- a/src/cuneiform.erl +++ b/src/cuneiform.erl @@ -77,8 +77,10 @@ reduce( X0, {Rho, Mu, Gamma, Omega}, DataDir ) -> false -> receive - {failed, R, R2, {LamLine, LamName, Fa1}, Data} -> - throw( {LamLine, cuneiform, {R, R2, LamName, Fa1, Data}} ); + {failed, R2, R, Data} -> + {AppLine, LamName} = hd( find_select( R, X1 ) ), + throw( {AppLine, cuneiform, {R2, LamName, R, Data}} ); + {finished, Summary} -> Ret = maps:get( ret, Summary ), @@ -103,4 +105,21 @@ when N :: string(), R :: pos_integer(). acc_delta( N, Delta0, Ret, R ) -> - Delta0#{{N, R} => maps:get( N, Ret )}. \ No newline at end of file + Delta0#{{N, R} => maps:get( N, Ret )}. + + +find_select( R, L ) when is_list( L ) -> + lists:flatmap( fun( X ) -> find_select( R, X ) end, L ); + +find_select( R, Fa ) when is_map( Fa ) -> + find_select( R, maps:values( Fa ) ); + +find_select( R, {select, AppLine, _C, {fut, LamName, R, _Lo}} ) -> + [{AppLine, LamName}]; + +find_select( R, {app, _AppLine, _C, _Lambda, Fa} ) -> + find_select( R, Fa ); + +find_select( _, _ ) -> + []. + From f6f062b5117c9f0f790643718fd38d3c1650c0ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Sat, 19 Mar 2016 13:13:08 +0100 Subject: [PATCH 38/78] Command line executable added. --- priv/cf | 3 +++ 1 file changed, 3 insertions(+) create mode 100755 priv/cf diff --git a/priv/cf b/priv/cf new file mode 100755 index 0000000..2ea6b3d --- /dev/null +++ b/priv/cf @@ -0,0 +1,3 @@ +#!/bin/bash + +erl -s cuneiform -s cf_shell server -s init stop -noshell \ No newline at end of file From 033e94060702f9141f1124d2b9714ab3d5e448e8 Mon Sep 17 00:00:00 2001 From: Jorgen Brandt Date: Sat, 19 Mar 2016 21:45:37 +0100 Subject: [PATCH 39/78] Main function added. --- priv/cf | 2 +- src/cf_parse.yrl | 15 --------------- src/cf_shell.erl | 4 ++-- src/cuneiform.erl | 20 ++++++++++++++++++-- 4 files changed, 21 insertions(+), 20 deletions(-) diff --git a/priv/cf b/priv/cf index 2ea6b3d..4a65f08 100755 --- a/priv/cf +++ b/priv/cf @@ -1,3 +1,3 @@ #!/bin/bash -erl -s cuneiform -s cf_shell server -s init stop -noshell \ No newline at end of file +erl -s cuneiform -s cf_shell -s init stop -noshell \ No newline at end of file diff --git a/src/cf_parse.yrl b/src/cf_parse.yrl index 9b8b5dd..2daab15 100644 --- a/src/cf_parse.yrl +++ b/src/cf_parse.yrl @@ -112,25 +112,10 @@ Erlang code. -author( "Jorgen Brandt " ). --export( [string/1] ). - -ifdef( TEST ). -include_lib( "eunit/include/eunit.hrl" ). -endif. -string( S ) -> - {ok, TokenList, _} = cf_scan:string( S ), - - % parse - case parse( TokenList ) of - {error, R2} -> error( R2 ); - {ok, ParseTree} -> ParseTree - end. - - - - - combine( {Target1, Rho1, Global1}, {Target2, Rho2, Global2} ) -> case Target1 of undef -> {Target2, maps:merge( Rho1, Rho2 ), maps:merge( Global1, Global2 )}; diff --git a/src/cf_shell.erl b/src/cf_shell.erl index f94506f..cd11920 100644 --- a/src/cf_shell.erl +++ b/src/cf_shell.erl @@ -23,7 +23,7 @@ %% Function Exports %% ============================================================================= --export( [server/0] ). +-export( [start/0] ). %% ============================================================================= %% Type Definitions @@ -51,7 +51,7 @@ %% ============================================================================= -server() -> +start() -> process_flag( trap_exit, true ), io:format( "~s~n~n~n", [get_banner()] ), server_loop( #{}, #{} ). diff --git a/src/cuneiform.erl b/src/cuneiform.erl index 26051e6..a381bce 100644 --- a/src/cuneiform.erl +++ b/src/cuneiform.erl @@ -20,19 +20,35 @@ -author( "Jorgen Brandt " ). % API --export( [start/0, string/2, file/1, file/2, reduce/4] ). +-export( [main/1, start/0, string/2, file/1, file/2, reduce/4] ). %% ============================================================================= %% API functions %% ============================================================================= +main( _ ) -> + start(), + cf_shell:start(). + start() -> application:start( cuneiform ). -spec string( S::string(), DataDir::string() ) -> [cf_sem:str()]. string( S, DataDir ) -> - {Query, Rho, Gamma} = cf_parse:string( S ), + + % scan + TokenLst = case cf_scan:string( S ) of + {error, R1, _} -> error( R1 ); + {ok, X, _} -> X + end, + + % parse + {Query, Rho, Gamma} = case cf_parse:parse( TokenLst ) of + {error, R2} -> error( R2 ); + {ok, Ret} -> Ret + end, + reduce( Query, Rho, Gamma, DataDir ). -spec file( Filename::string() ) -> [cf_sem:str()]. From 4276e2eeb73d0b920428994d8524c8d1c67d4bef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Sun, 20 Mar 2016 06:08:22 +0100 Subject: [PATCH 40/78] Parsing consolidated. --- src/cf_parse.yrl | 15 ++ src/cf_shell.erl | 11 +- src/cuneiform.erl | 14 +- src/pre_scan.erl | 464 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 481 insertions(+), 23 deletions(-) create mode 100644 src/pre_scan.erl diff --git a/src/cf_parse.yrl b/src/cf_parse.yrl index 2daab15..39dc3c6 100644 --- a/src/cf_parse.yrl +++ b/src/cf_parse.yrl @@ -112,10 +112,25 @@ Erlang code. -author( "Jorgen Brandt " ). +-export( [string/1] ). + -ifdef( TEST ). -include_lib( "eunit/include/eunit.hrl" ). -endif. +string( S ) -> + % scan + case cf_scan:string( S ) of + {error, ScanErrorInfo, _} -> error( ScanErrorInfo ); + {ok, TokenLst, _} -> + % parse + case cf_parse:parse( TokenLst ) of + {error, ParseErrorInfo} -> error( ParseErrorInfo ); + {ok, Triple} -> Triple + end + end. + + combine( {Target1, Rho1, Global1}, {Target2, Rho2, Global2} ) -> case Target1 of undef -> {Target2, maps:merge( Rho1, Rho2 ), maps:merge( Global1, Global2 )}; diff --git a/src/cf_shell.erl b/src/cf_shell.erl index cd11920..125debc 100644 --- a/src/cf_shell.erl +++ b/src/cf_shell.erl @@ -113,21 +113,12 @@ read( Buf ) -> end; [_|_] -> case lists:last( TokenLst ) of - terminal -> parse_string( Buf++S ); + terminal -> cf_parse:string( Buf++S ); nonws -> read( Buf++S ); C -> {ctl, C} end end. -parse_string( S ) -> - case cf_scan:string( S ) of - {error, ScanErrorInfo, _} -> {error, ScanErrorInfo}; - {ok, TokenLst, _} -> - case cf_parse:parse( TokenLst ) of - {error, ParseErrorInfo} -> {error, ParseErrorInfo}; - {ok, Triple} -> {ok, Triple} - end - end. format_error( {Line, cf_scan, {illegal, Token}} ) -> diff --git a/src/cuneiform.erl b/src/cuneiform.erl index a381bce..4b484b7 100644 --- a/src/cuneiform.erl +++ b/src/cuneiform.erl @@ -36,19 +36,7 @@ start() -> -spec string( S::string(), DataDir::string() ) -> [cf_sem:str()]. string( S, DataDir ) -> - - % scan - TokenLst = case cf_scan:string( S ) of - {error, R1, _} -> error( R1 ); - {ok, X, _} -> X - end, - - % parse - {Query, Rho, Gamma} = case cf_parse:parse( TokenLst ) of - {error, R2} -> error( R2 ); - {ok, Ret} -> Ret - end, - + {Query, Rho, Gamma} = cf_parse:string( S ), reduce( Query, Rho, Gamma, DataDir ). -spec file( Filename::string() ) -> [cf_sem:str()]. diff --git a/src/pre_scan.erl b/src/pre_scan.erl new file mode 100644 index 0000000..114c89d --- /dev/null +++ b/src/pre_scan.erl @@ -0,0 +1,464 @@ +-file("/usr/local/lib/erlang/lib/parsetools-2.1.1/include/leexinc.hrl", 0). +%% The source of this file is part of leex distribution, as such it +%% has the same Copyright as the other files in the leex +%% distribution. The Copyright is defined in the accompanying file +%% COPYRIGHT. However, the resultant scanner generated by leex is the +%% property of the creator of the scanner and is not covered by that +%% Copyright. + +-module(pre_scan). + +-export([string/1,string/2,token/2,token/3,tokens/2,tokens/3]). +-export([format_error/1]). + +%% User code. This is placed here to allow extra attributes. +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 56). + +-author( "Jorgen Brandt " ). + +-export( [yyrev/2] ). +-file("/usr/local/lib/erlang/lib/parsetools-2.1.1/include/leexinc.hrl", 14). + +format_error({illegal,S}) -> ["illegal characters ",io_lib:write_string(S)]; +format_error({user,S}) -> S. + +string(String) -> string(String, 1). + +string(String, Line) -> string(String, Line, String, []). + +%% string(InChars, Line, TokenChars, Tokens) -> +%% {ok,Tokens,Line} | {error,ErrorInfo,Line}. +%% Note the line number going into yystate, L0, is line of token +%% start while line number returned is line of token end. We want line +%% of token start. + +string([], L, [], Ts) -> % No partial tokens! + {ok,yyrev(Ts),L}; +string(Ics0, L0, Tcs, Ts) -> + case yystate(yystate(), Ics0, L0, 0, reject, 0) of + {A,Alen,Ics1,L1} -> % Accepting end state + string_cont(Ics1, L1, yyaction(A, Alen, Tcs, L0), Ts); + {A,Alen,Ics1,L1,_S1} -> % Accepting transistion state + string_cont(Ics1, L1, yyaction(A, Alen, Tcs, L0), Ts); + {reject,_Alen,Tlen,_Ics1,L1,_S1} -> % After a non-accepting state + {error,{L0,?MODULE,{illegal,yypre(Tcs, Tlen+1)}},L1}; + {A,Alen,_Tlen,_Ics1,_L1,_S1} -> + string_cont(yysuf(Tcs, Alen), L0, yyaction(A, Alen, Tcs, L0), Ts) + end. + +%% string_cont(RestChars, Line, Token, Tokens) +%% Test for and remove the end token wrapper. Push back characters +%% are prepended to RestChars. + +-dialyzer({nowarn_function, string_cont/4}). + +string_cont(Rest, Line, {token,T}, Ts) -> + string(Rest, Line, Rest, [T|Ts]); +string_cont(Rest, Line, {token,T,Push}, Ts) -> + NewRest = Push ++ Rest, + string(NewRest, Line, NewRest, [T|Ts]); +string_cont(Rest, Line, {end_token,T}, Ts) -> + string(Rest, Line, Rest, [T|Ts]); +string_cont(Rest, Line, {end_token,T,Push}, Ts) -> + NewRest = Push ++ Rest, + string(NewRest, Line, NewRest, [T|Ts]); +string_cont(Rest, Line, skip_token, Ts) -> + string(Rest, Line, Rest, Ts); +string_cont(Rest, Line, {skip_token,Push}, Ts) -> + NewRest = Push ++ Rest, + string(NewRest, Line, NewRest, Ts); +string_cont(_Rest, Line, {error,S}, _Ts) -> + {error,{Line,?MODULE,{user,S}},Line}. + +%% token(Continuation, Chars) -> +%% token(Continuation, Chars, Line) -> +%% {more,Continuation} | {done,ReturnVal,RestChars}. +%% Must be careful when re-entering to append the latest characters to the +%% after characters in an accept. The continuation is: +%% {token,State,CurrLine,TokenChars,TokenLen,TokenLine,AccAction,AccLen} + +token(Cont, Chars) -> token(Cont, Chars, 1). + +token([], Chars, Line) -> + token(yystate(), Chars, Line, Chars, 0, Line, reject, 0); +token({token,State,Line,Tcs,Tlen,Tline,Action,Alen}, Chars, _) -> + token(State, Chars, Line, Tcs ++ Chars, Tlen, Tline, Action, Alen). + +%% token(State, InChars, Line, TokenChars, TokenLen, TokenLine, +%% AcceptAction, AcceptLen) -> +%% {more,Continuation} | {done,ReturnVal,RestChars}. +%% The argument order is chosen to be more efficient. + +token(S0, Ics0, L0, Tcs, Tlen0, Tline, A0, Alen0) -> + case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of + %% Accepting end state, we have a token. + {A1,Alen1,Ics1,L1} -> + token_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline)); + %% Accepting transition state, can take more chars. + {A1,Alen1,[],L1,S1} -> % Need more chars to check + {more,{token,S1,L1,Tcs,Alen1,Tline,A1,Alen1}}; + {A1,Alen1,Ics1,L1,_S1} -> % Take what we got + token_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline)); + %% After a non-accepting state, maybe reach accept state later. + {A1,Alen1,Tlen1,[],L1,S1} -> % Need more chars to check + {more,{token,S1,L1,Tcs,Tlen1,Tline,A1,Alen1}}; + {reject,_Alen1,Tlen1,eof,L1,_S1} -> % No token match + %% Check for partial token which is error. + Ret = if Tlen1 > 0 -> {error,{Tline,?MODULE, + %% Skip eof tail in Tcs. + {illegal,yypre(Tcs, Tlen1)}},L1}; + true -> {eof,L1} + end, + {done,Ret,eof}; + {reject,_Alen1,Tlen1,Ics1,L1,_S1} -> % No token match + Error = {Tline,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}}, + {done,{error,Error,L1},Ics1}; + {A1,Alen1,_Tlen1,_Ics1,_L1,_S1} -> % Use last accept match + token_cont(yysuf(Tcs, Alen1), L0, yyaction(A1, Alen1, Tcs, Tline)) + end. + +%% token_cont(RestChars, Line, Token) +%% If we have a token or error then return done, else if we have a +%% skip_token then continue. + +-dialyzer({nowarn_function, token_cont/3}). + +token_cont(Rest, Line, {token,T}) -> + {done,{ok,T,Line},Rest}; +token_cont(Rest, Line, {token,T,Push}) -> + NewRest = Push ++ Rest, + {done,{ok,T,Line},NewRest}; +token_cont(Rest, Line, {end_token,T}) -> + {done,{ok,T,Line},Rest}; +token_cont(Rest, Line, {end_token,T,Push}) -> + NewRest = Push ++ Rest, + {done,{ok,T,Line},NewRest}; +token_cont(Rest, Line, skip_token) -> + token(yystate(), Rest, Line, Rest, 0, Line, reject, 0); +token_cont(Rest, Line, {skip_token,Push}) -> + NewRest = Push ++ Rest, + token(yystate(), NewRest, Line, NewRest, 0, Line, reject, 0); +token_cont(Rest, Line, {error,S}) -> + {done,{error,{Line,?MODULE,{user,S}},Line},Rest}. + +%% tokens(Continuation, Chars, Line) -> +%% {more,Continuation} | {done,ReturnVal,RestChars}. +%% Must be careful when re-entering to append the latest characters to the +%% after characters in an accept. The continuation is: +%% {tokens,State,CurrLine,TokenChars,TokenLen,TokenLine,Tokens,AccAction,AccLen} +%% {skip_tokens,State,CurrLine,TokenChars,TokenLen,TokenLine,Error,AccAction,AccLen} + +tokens(Cont, Chars) -> tokens(Cont, Chars, 1). + +tokens([], Chars, Line) -> + tokens(yystate(), Chars, Line, Chars, 0, Line, [], reject, 0); +tokens({tokens,State,Line,Tcs,Tlen,Tline,Ts,Action,Alen}, Chars, _) -> + tokens(State, Chars, Line, Tcs ++ Chars, Tlen, Tline, Ts, Action, Alen); +tokens({skip_tokens,State,Line,Tcs,Tlen,Tline,Error,Action,Alen}, Chars, _) -> + skip_tokens(State, Chars, Line, Tcs ++ Chars, Tlen, Tline, Error, Action, Alen). + +%% tokens(State, InChars, Line, TokenChars, TokenLen, TokenLine, Tokens, +%% AcceptAction, AcceptLen) -> +%% {more,Continuation} | {done,ReturnVal,RestChars}. + +tokens(S0, Ics0, L0, Tcs, Tlen0, Tline, Ts, A0, Alen0) -> + case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of + %% Accepting end state, we have a token. + {A1,Alen1,Ics1,L1} -> + tokens_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Ts); + %% Accepting transition state, can take more chars. + {A1,Alen1,[],L1,S1} -> % Need more chars to check + {more,{tokens,S1,L1,Tcs,Alen1,Tline,Ts,A1,Alen1}}; + {A1,Alen1,Ics1,L1,_S1} -> % Take what we got + tokens_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Ts); + %% After a non-accepting state, maybe reach accept state later. + {A1,Alen1,Tlen1,[],L1,S1} -> % Need more chars to check + {more,{tokens,S1,L1,Tcs,Tlen1,Tline,Ts,A1,Alen1}}; + {reject,_Alen1,Tlen1,eof,L1,_S1} -> % No token match + %% Check for partial token which is error, no need to skip here. + Ret = if Tlen1 > 0 -> {error,{Tline,?MODULE, + %% Skip eof tail in Tcs. + {illegal,yypre(Tcs, Tlen1)}},L1}; + Ts == [] -> {eof,L1}; + true -> {ok,yyrev(Ts),L1} + end, + {done,Ret,eof}; + {reject,_Alen1,Tlen1,_Ics1,L1,_S1} -> + %% Skip rest of tokens. + Error = {L1,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}}, + skip_tokens(yysuf(Tcs, Tlen1+1), L1, Error); + {A1,Alen1,_Tlen1,_Ics1,_L1,_S1} -> + Token = yyaction(A1, Alen1, Tcs, Tline), + tokens_cont(yysuf(Tcs, Alen1), L0, Token, Ts) + end. + +%% tokens_cont(RestChars, Line, Token, Tokens) +%% If we have an end_token or error then return done, else if we have +%% a token then save it and continue, else if we have a skip_token +%% just continue. + +-dialyzer({nowarn_function, tokens_cont/4}). + +tokens_cont(Rest, Line, {token,T}, Ts) -> + tokens(yystate(), Rest, Line, Rest, 0, Line, [T|Ts], reject, 0); +tokens_cont(Rest, Line, {token,T,Push}, Ts) -> + NewRest = Push ++ Rest, + tokens(yystate(), NewRest, Line, NewRest, 0, Line, [T|Ts], reject, 0); +tokens_cont(Rest, Line, {end_token,T}, Ts) -> + {done,{ok,yyrev(Ts, [T]),Line},Rest}; +tokens_cont(Rest, Line, {end_token,T,Push}, Ts) -> + NewRest = Push ++ Rest, + {done,{ok,yyrev(Ts, [T]),Line},NewRest}; +tokens_cont(Rest, Line, skip_token, Ts) -> + tokens(yystate(), Rest, Line, Rest, 0, Line, Ts, reject, 0); +tokens_cont(Rest, Line, {skip_token,Push}, Ts) -> + NewRest = Push ++ Rest, + tokens(yystate(), NewRest, Line, NewRest, 0, Line, Ts, reject, 0); +tokens_cont(Rest, Line, {error,S}, _Ts) -> + skip_tokens(Rest, Line, {Line,?MODULE,{user,S}}). + +%%skip_tokens(InChars, Line, Error) -> {done,{error,Error,Line},Ics}. +%% Skip tokens until an end token, junk everything and return the error. + +skip_tokens(Ics, Line, Error) -> + skip_tokens(yystate(), Ics, Line, Ics, 0, Line, Error, reject, 0). + +%% skip_tokens(State, InChars, Line, TokenChars, TokenLen, TokenLine, Tokens, +%% AcceptAction, AcceptLen) -> +%% {more,Continuation} | {done,ReturnVal,RestChars}. + +skip_tokens(S0, Ics0, L0, Tcs, Tlen0, Tline, Error, A0, Alen0) -> + case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of + {A1,Alen1,Ics1,L1} -> % Accepting end state + skip_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Error); + {A1,Alen1,[],L1,S1} -> % After an accepting state + {more,{skip_tokens,S1,L1,Tcs,Alen1,Tline,Error,A1,Alen1}}; + {A1,Alen1,Ics1,L1,_S1} -> + skip_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Error); + {A1,Alen1,Tlen1,[],L1,S1} -> % After a non-accepting state + {more,{skip_tokens,S1,L1,Tcs,Tlen1,Tline,Error,A1,Alen1}}; + {reject,_Alen1,_Tlen1,eof,L1,_S1} -> + {done,{error,Error,L1},eof}; + {reject,_Alen1,Tlen1,_Ics1,L1,_S1} -> + skip_tokens(yysuf(Tcs, Tlen1+1), L1, Error); + {A1,Alen1,_Tlen1,_Ics1,L1,_S1} -> + Token = yyaction(A1, Alen1, Tcs, Tline), + skip_cont(yysuf(Tcs, Alen1), L1, Token, Error) + end. + +%% skip_cont(RestChars, Line, Token, Error) +%% Skip tokens until we have an end_token or error then return done +%% with the original rror. + +-dialyzer({nowarn_function, skip_cont/4}). + +skip_cont(Rest, Line, {token,_T}, Error) -> + skip_tokens(yystate(), Rest, Line, Rest, 0, Line, Error, reject, 0); +skip_cont(Rest, Line, {token,_T,Push}, Error) -> + NewRest = Push ++ Rest, + skip_tokens(yystate(), NewRest, Line, NewRest, 0, Line, Error, reject, 0); +skip_cont(Rest, Line, {end_token,_T}, Error) -> + {done,{error,Error,Line},Rest}; +skip_cont(Rest, Line, {end_token,_T,Push}, Error) -> + NewRest = Push ++ Rest, + {done,{error,Error,Line},NewRest}; +skip_cont(Rest, Line, skip_token, Error) -> + skip_tokens(yystate(), Rest, Line, Rest, 0, Line, Error, reject, 0); +skip_cont(Rest, Line, {skip_token,Push}, Error) -> + NewRest = Push ++ Rest, + skip_tokens(yystate(), NewRest, Line, NewRest, 0, Line, Error, reject, 0); +skip_cont(Rest, Line, {error,_S}, Error) -> + skip_tokens(yystate(), Rest, Line, Rest, 0, Line, Error, reject, 0). + +yyrev(List) -> lists:reverse(List). +yyrev(List, Tail) -> lists:reverse(List, Tail). +yypre(List, N) -> lists:sublist(List, N). +yysuf(List, N) -> lists:nthtail(N, List). + +%% yystate() -> InitialState. +%% yystate(State, InChars, Line, CurrTokLen, AcceptAction, AcceptLen) -> +%% {Action, AcceptLen, RestChars, Line} | +%% {Action, AcceptLen, RestChars, Line, State} | +%% {reject, AcceptLen, CurrTokLen, RestChars, Line, State} | +%% {Action, AcceptLen, CurrTokLen, RestChars, Line, State}. +%% Generated state transition functions. The non-accepting end state +%% return signal either an unrecognised character or end of current +%% input. + +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.erl", 288). +yystate() -> 20. + +yystate(23, [101|Ics], Line, Tlen, Action, Alen) -> + yystate(21, Ics, Line, Tlen+1, Action, Alen); +yystate(23, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,23}; +yystate(22, Ics, Line, Tlen, _, _) -> + {6,Tlen,Ics,Line}; +yystate(21, Ics, Line, Tlen, _, _) -> + {1,Tlen,Ics,Line}; +yystate(20, [125|Ics], Line, Tlen, Action, Alen) -> + yystate(16, Ics, Line, Tlen+1, Action, Alen); +yystate(20, [116|Ics], Line, Tlen, Action, Alen) -> + yystate(8, Ics, Line, Tlen+1, Action, Alen); +yystate(20, [115|Ics], Line, Tlen, Action, Alen) -> + yystate(11, Ics, Line, Tlen+1, Action, Alen); +yystate(20, [114|Ics], Line, Tlen, Action, Alen) -> + yystate(18, Ics, Line, Tlen+1, Action, Alen); +yystate(20, [113|Ics], Line, Tlen, Action, Alen) -> + yystate(17, Ics, Line, Tlen+1, Action, Alen); +yystate(20, [104|Ics], Line, Tlen, Action, Alen) -> + yystate(1, Ics, Line, Tlen+1, Action, Alen); +yystate(20, [59|Ics], Line, Tlen, Action, Alen) -> + yystate(14, Ics, Line, Tlen+1, Action, Alen); +yystate(20, [10|Ics], Line, Tlen, Action, Alen) -> + yystate(22, Ics, Line+1, Tlen+1, Action, Alen); +yystate(20, [C|Ics], Line, Tlen, Action, Alen) when C >= 0, C =< 9 -> + yystate(22, Ics, Line, Tlen+1, Action, Alen); +yystate(20, [C|Ics], Line, Tlen, Action, Alen) when C >= 11, C =< 32 -> + yystate(22, Ics, Line, Tlen+1, Action, Alen); +yystate(20, [C|Ics], Line, Tlen, Action, Alen) when C >= 33, C =< 58 -> + yystate(18, Ics, Line, Tlen+1, Action, Alen); +yystate(20, [C|Ics], Line, Tlen, Action, Alen) when C >= 60, C =< 103 -> + yystate(18, Ics, Line, Tlen+1, Action, Alen); +yystate(20, [C|Ics], Line, Tlen, Action, Alen) when C >= 105, C =< 112 -> + yystate(18, Ics, Line, Tlen+1, Action, Alen); +yystate(20, [C|Ics], Line, Tlen, Action, Alen) when C >= 117, C =< 124 -> + yystate(18, Ics, Line, Tlen+1, Action, Alen); +yystate(20, [C|Ics], Line, Tlen, Action, Alen) when C >= 126 -> + yystate(18, Ics, Line, Tlen+1, Action, Alen); +yystate(20, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,20}; +yystate(19, [116|Ics], Line, Tlen, Action, Alen) -> + yystate(23, Ics, Line, Tlen+1, Action, Alen); +yystate(19, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,19}; +yystate(18, Ics, Line, Tlen, _, _) -> + {7,Tlen,Ics,Line}; +yystate(17, [117|Ics], Line, Tlen, _, _) -> + yystate(13, Ics, Line, Tlen+1, 7, Tlen); +yystate(17, Ics, Line, Tlen, _, _) -> + {7,Tlen,Ics,Line,17}; +yystate(16, [42|Ics], Line, Tlen, _, _) -> + yystate(12, Ics, Line, Tlen+1, 7, Tlen); +yystate(16, Ics, Line, Tlen, _, _) -> + {7,Tlen,Ics,Line,16}; +yystate(15, [97|Ics], Line, Tlen, Action, Alen) -> + yystate(19, Ics, Line, Tlen+1, Action, Alen); +yystate(15, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,15}; +yystate(14, Ics, Line, Tlen, _, _) -> + {5,Tlen,Ics,Line}; +yystate(13, [105|Ics], Line, Tlen, Action, Alen) -> + yystate(9, Ics, Line, Tlen+1, Action, Alen); +yystate(13, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,13}; +yystate(12, Ics, Line, Tlen, _, _) -> + {4,Tlen,Ics,Line}; +yystate(11, [116|Ics], Line, Tlen, _, _) -> + yystate(15, Ics, Line, Tlen+1, 7, Tlen); +yystate(11, Ics, Line, Tlen, _, _) -> + {7,Tlen,Ics,Line,11}; +yystate(10, Ics, Line, Tlen, _, _) -> + {3,Tlen,Ics,Line}; +yystate(9, [116|Ics], Line, Tlen, Action, Alen) -> + yystate(5, Ics, Line, Tlen+1, Action, Alen); +yystate(9, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,9}; +yystate(8, [97|Ics], Line, Tlen, _, _) -> + yystate(4, Ics, Line, Tlen+1, 7, Tlen); +yystate(8, Ics, Line, Tlen, _, _) -> + {7,Tlen,Ics,Line,8}; +yystate(7, Ics, Line, Tlen, _, _) -> + {0,Tlen,Ics,Line}; +yystate(6, [112|Ics], Line, Tlen, Action, Alen) -> + yystate(10, Ics, Line, Tlen+1, Action, Alen); +yystate(6, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,6}; +yystate(5, Ics, Line, Tlen, _, _) -> + {2,Tlen,Ics,Line}; +yystate(4, [115|Ics], Line, Tlen, Action, Alen) -> + yystate(0, Ics, Line, Tlen+1, Action, Alen); +yystate(4, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,4}; +yystate(3, [115|Ics], Line, Tlen, Action, Alen) -> + yystate(7, Ics, Line, Tlen+1, Action, Alen); +yystate(3, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,3}; +yystate(2, [108|Ics], Line, Tlen, Action, Alen) -> + yystate(6, Ics, Line, Tlen+1, Action, Alen); +yystate(2, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,2}; +yystate(1, [101|Ics], Line, Tlen, _, _) -> + yystate(2, Ics, Line, Tlen+1, 7, Tlen); +yystate(1, Ics, Line, Tlen, _, _) -> + {7,Tlen,Ics,Line,1}; +yystate(0, [107|Ics], Line, Tlen, Action, Alen) -> + yystate(3, Ics, Line, Tlen+1, Action, Alen); +yystate(0, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,0}; +yystate(S, Ics, Line, Tlen, Action, Alen) -> + {Action,Alen,Tlen,Ics,Line,S}. + +%% yyaction(Action, TokenLength, TokenChars, TokenLine) -> +%% {token,Token} | {end_token, Token} | skip_token | {error,String}. +%% Generated action function. + +yyaction(0, _, _, _) -> + yyaction_0(); +yyaction(1, _, _, _) -> + yyaction_1(); +yyaction(2, _, _, _) -> + yyaction_2(); +yyaction(3, _, _, _) -> + yyaction_3(); +yyaction(4, _, _, _) -> + yyaction_4(); +yyaction(5, _, _, _) -> + yyaction_5(); +yyaction(6, _, _, _) -> + yyaction_6(); +yyaction(7, _, _, _) -> + yyaction_7(); +yyaction(_, _, _, _) -> error. + +-compile({inline,yyaction_0/0}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 40). +yyaction_0() -> + { token, tasks } . + +-compile({inline,yyaction_1/0}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 41). +yyaction_1() -> + { token, state } . + +-compile({inline,yyaction_2/0}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 42). +yyaction_2() -> + { token, quit } . + +-compile({inline,yyaction_3/0}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 43). +yyaction_3() -> + { token, help } . + +-compile({inline,yyaction_4/0}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 44). +yyaction_4() -> + { token, terminal } . + +-compile({inline,yyaction_5/0}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 45). +yyaction_5() -> + { token, terminal } . + +-compile({inline,yyaction_6/0}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 46). +yyaction_6() -> + skip_token . + +-compile({inline,yyaction_7/0}). +-file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 47). +yyaction_7() -> + { token, nonws } . + +-file("/usr/local/lib/erlang/lib/parsetools-2.1.1/include/leexinc.hrl", 290). From 16caa619a96bacf972d31ac3e28d6b401dad4809 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Sun, 20 Mar 2016 06:58:15 +0100 Subject: [PATCH 41/78] Parser inconsistency fixed. --- src/{pre_scan.xrl => cf_prescan.xrl} | 0 src/cf_shell.erl | 4 +- src/pre_scan.erl | 464 --------------------------- 3 files changed, 2 insertions(+), 466 deletions(-) rename src/{pre_scan.xrl => cf_prescan.xrl} (100%) delete mode 100644 src/pre_scan.erl diff --git a/src/pre_scan.xrl b/src/cf_prescan.xrl similarity index 100% rename from src/pre_scan.xrl rename to src/cf_prescan.xrl diff --git a/src/cf_shell.erl b/src/cf_shell.erl index 125debc..69f9156 100644 --- a/src/cf_shell.erl +++ b/src/cf_shell.erl @@ -104,7 +104,7 @@ read_expression( Prompt ) -> read( Buf ) -> S = io:get_line( "" ), - {ok, TokenLst, _} = pre_scan:string( S ), + {ok, TokenLst, _} = cf_prescan:string( S ), case TokenLst of [] -> case Buf of @@ -113,7 +113,7 @@ read( Buf ) -> end; [_|_] -> case lists:last( TokenLst ) of - terminal -> cf_parse:string( Buf++S ); + terminal -> {ok, cf_parse:string( Buf++S )}; nonws -> read( Buf++S ); C -> {ctl, C} end diff --git a/src/pre_scan.erl b/src/pre_scan.erl deleted file mode 100644 index 114c89d..0000000 --- a/src/pre_scan.erl +++ /dev/null @@ -1,464 +0,0 @@ --file("/usr/local/lib/erlang/lib/parsetools-2.1.1/include/leexinc.hrl", 0). -%% The source of this file is part of leex distribution, as such it -%% has the same Copyright as the other files in the leex -%% distribution. The Copyright is defined in the accompanying file -%% COPYRIGHT. However, the resultant scanner generated by leex is the -%% property of the creator of the scanner and is not covered by that -%% Copyright. - --module(pre_scan). - --export([string/1,string/2,token/2,token/3,tokens/2,tokens/3]). --export([format_error/1]). - -%% User code. This is placed here to allow extra attributes. --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 56). - --author( "Jorgen Brandt " ). - --export( [yyrev/2] ). --file("/usr/local/lib/erlang/lib/parsetools-2.1.1/include/leexinc.hrl", 14). - -format_error({illegal,S}) -> ["illegal characters ",io_lib:write_string(S)]; -format_error({user,S}) -> S. - -string(String) -> string(String, 1). - -string(String, Line) -> string(String, Line, String, []). - -%% string(InChars, Line, TokenChars, Tokens) -> -%% {ok,Tokens,Line} | {error,ErrorInfo,Line}. -%% Note the line number going into yystate, L0, is line of token -%% start while line number returned is line of token end. We want line -%% of token start. - -string([], L, [], Ts) -> % No partial tokens! - {ok,yyrev(Ts),L}; -string(Ics0, L0, Tcs, Ts) -> - case yystate(yystate(), Ics0, L0, 0, reject, 0) of - {A,Alen,Ics1,L1} -> % Accepting end state - string_cont(Ics1, L1, yyaction(A, Alen, Tcs, L0), Ts); - {A,Alen,Ics1,L1,_S1} -> % Accepting transistion state - string_cont(Ics1, L1, yyaction(A, Alen, Tcs, L0), Ts); - {reject,_Alen,Tlen,_Ics1,L1,_S1} -> % After a non-accepting state - {error,{L0,?MODULE,{illegal,yypre(Tcs, Tlen+1)}},L1}; - {A,Alen,_Tlen,_Ics1,_L1,_S1} -> - string_cont(yysuf(Tcs, Alen), L0, yyaction(A, Alen, Tcs, L0), Ts) - end. - -%% string_cont(RestChars, Line, Token, Tokens) -%% Test for and remove the end token wrapper. Push back characters -%% are prepended to RestChars. - --dialyzer({nowarn_function, string_cont/4}). - -string_cont(Rest, Line, {token,T}, Ts) -> - string(Rest, Line, Rest, [T|Ts]); -string_cont(Rest, Line, {token,T,Push}, Ts) -> - NewRest = Push ++ Rest, - string(NewRest, Line, NewRest, [T|Ts]); -string_cont(Rest, Line, {end_token,T}, Ts) -> - string(Rest, Line, Rest, [T|Ts]); -string_cont(Rest, Line, {end_token,T,Push}, Ts) -> - NewRest = Push ++ Rest, - string(NewRest, Line, NewRest, [T|Ts]); -string_cont(Rest, Line, skip_token, Ts) -> - string(Rest, Line, Rest, Ts); -string_cont(Rest, Line, {skip_token,Push}, Ts) -> - NewRest = Push ++ Rest, - string(NewRest, Line, NewRest, Ts); -string_cont(_Rest, Line, {error,S}, _Ts) -> - {error,{Line,?MODULE,{user,S}},Line}. - -%% token(Continuation, Chars) -> -%% token(Continuation, Chars, Line) -> -%% {more,Continuation} | {done,ReturnVal,RestChars}. -%% Must be careful when re-entering to append the latest characters to the -%% after characters in an accept. The continuation is: -%% {token,State,CurrLine,TokenChars,TokenLen,TokenLine,AccAction,AccLen} - -token(Cont, Chars) -> token(Cont, Chars, 1). - -token([], Chars, Line) -> - token(yystate(), Chars, Line, Chars, 0, Line, reject, 0); -token({token,State,Line,Tcs,Tlen,Tline,Action,Alen}, Chars, _) -> - token(State, Chars, Line, Tcs ++ Chars, Tlen, Tline, Action, Alen). - -%% token(State, InChars, Line, TokenChars, TokenLen, TokenLine, -%% AcceptAction, AcceptLen) -> -%% {more,Continuation} | {done,ReturnVal,RestChars}. -%% The argument order is chosen to be more efficient. - -token(S0, Ics0, L0, Tcs, Tlen0, Tline, A0, Alen0) -> - case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of - %% Accepting end state, we have a token. - {A1,Alen1,Ics1,L1} -> - token_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline)); - %% Accepting transition state, can take more chars. - {A1,Alen1,[],L1,S1} -> % Need more chars to check - {more,{token,S1,L1,Tcs,Alen1,Tline,A1,Alen1}}; - {A1,Alen1,Ics1,L1,_S1} -> % Take what we got - token_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline)); - %% After a non-accepting state, maybe reach accept state later. - {A1,Alen1,Tlen1,[],L1,S1} -> % Need more chars to check - {more,{token,S1,L1,Tcs,Tlen1,Tline,A1,Alen1}}; - {reject,_Alen1,Tlen1,eof,L1,_S1} -> % No token match - %% Check for partial token which is error. - Ret = if Tlen1 > 0 -> {error,{Tline,?MODULE, - %% Skip eof tail in Tcs. - {illegal,yypre(Tcs, Tlen1)}},L1}; - true -> {eof,L1} - end, - {done,Ret,eof}; - {reject,_Alen1,Tlen1,Ics1,L1,_S1} -> % No token match - Error = {Tline,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}}, - {done,{error,Error,L1},Ics1}; - {A1,Alen1,_Tlen1,_Ics1,_L1,_S1} -> % Use last accept match - token_cont(yysuf(Tcs, Alen1), L0, yyaction(A1, Alen1, Tcs, Tline)) - end. - -%% token_cont(RestChars, Line, Token) -%% If we have a token or error then return done, else if we have a -%% skip_token then continue. - --dialyzer({nowarn_function, token_cont/3}). - -token_cont(Rest, Line, {token,T}) -> - {done,{ok,T,Line},Rest}; -token_cont(Rest, Line, {token,T,Push}) -> - NewRest = Push ++ Rest, - {done,{ok,T,Line},NewRest}; -token_cont(Rest, Line, {end_token,T}) -> - {done,{ok,T,Line},Rest}; -token_cont(Rest, Line, {end_token,T,Push}) -> - NewRest = Push ++ Rest, - {done,{ok,T,Line},NewRest}; -token_cont(Rest, Line, skip_token) -> - token(yystate(), Rest, Line, Rest, 0, Line, reject, 0); -token_cont(Rest, Line, {skip_token,Push}) -> - NewRest = Push ++ Rest, - token(yystate(), NewRest, Line, NewRest, 0, Line, reject, 0); -token_cont(Rest, Line, {error,S}) -> - {done,{error,{Line,?MODULE,{user,S}},Line},Rest}. - -%% tokens(Continuation, Chars, Line) -> -%% {more,Continuation} | {done,ReturnVal,RestChars}. -%% Must be careful when re-entering to append the latest characters to the -%% after characters in an accept. The continuation is: -%% {tokens,State,CurrLine,TokenChars,TokenLen,TokenLine,Tokens,AccAction,AccLen} -%% {skip_tokens,State,CurrLine,TokenChars,TokenLen,TokenLine,Error,AccAction,AccLen} - -tokens(Cont, Chars) -> tokens(Cont, Chars, 1). - -tokens([], Chars, Line) -> - tokens(yystate(), Chars, Line, Chars, 0, Line, [], reject, 0); -tokens({tokens,State,Line,Tcs,Tlen,Tline,Ts,Action,Alen}, Chars, _) -> - tokens(State, Chars, Line, Tcs ++ Chars, Tlen, Tline, Ts, Action, Alen); -tokens({skip_tokens,State,Line,Tcs,Tlen,Tline,Error,Action,Alen}, Chars, _) -> - skip_tokens(State, Chars, Line, Tcs ++ Chars, Tlen, Tline, Error, Action, Alen). - -%% tokens(State, InChars, Line, TokenChars, TokenLen, TokenLine, Tokens, -%% AcceptAction, AcceptLen) -> -%% {more,Continuation} | {done,ReturnVal,RestChars}. - -tokens(S0, Ics0, L0, Tcs, Tlen0, Tline, Ts, A0, Alen0) -> - case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of - %% Accepting end state, we have a token. - {A1,Alen1,Ics1,L1} -> - tokens_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Ts); - %% Accepting transition state, can take more chars. - {A1,Alen1,[],L1,S1} -> % Need more chars to check - {more,{tokens,S1,L1,Tcs,Alen1,Tline,Ts,A1,Alen1}}; - {A1,Alen1,Ics1,L1,_S1} -> % Take what we got - tokens_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Ts); - %% After a non-accepting state, maybe reach accept state later. - {A1,Alen1,Tlen1,[],L1,S1} -> % Need more chars to check - {more,{tokens,S1,L1,Tcs,Tlen1,Tline,Ts,A1,Alen1}}; - {reject,_Alen1,Tlen1,eof,L1,_S1} -> % No token match - %% Check for partial token which is error, no need to skip here. - Ret = if Tlen1 > 0 -> {error,{Tline,?MODULE, - %% Skip eof tail in Tcs. - {illegal,yypre(Tcs, Tlen1)}},L1}; - Ts == [] -> {eof,L1}; - true -> {ok,yyrev(Ts),L1} - end, - {done,Ret,eof}; - {reject,_Alen1,Tlen1,_Ics1,L1,_S1} -> - %% Skip rest of tokens. - Error = {L1,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}}, - skip_tokens(yysuf(Tcs, Tlen1+1), L1, Error); - {A1,Alen1,_Tlen1,_Ics1,_L1,_S1} -> - Token = yyaction(A1, Alen1, Tcs, Tline), - tokens_cont(yysuf(Tcs, Alen1), L0, Token, Ts) - end. - -%% tokens_cont(RestChars, Line, Token, Tokens) -%% If we have an end_token or error then return done, else if we have -%% a token then save it and continue, else if we have a skip_token -%% just continue. - --dialyzer({nowarn_function, tokens_cont/4}). - -tokens_cont(Rest, Line, {token,T}, Ts) -> - tokens(yystate(), Rest, Line, Rest, 0, Line, [T|Ts], reject, 0); -tokens_cont(Rest, Line, {token,T,Push}, Ts) -> - NewRest = Push ++ Rest, - tokens(yystate(), NewRest, Line, NewRest, 0, Line, [T|Ts], reject, 0); -tokens_cont(Rest, Line, {end_token,T}, Ts) -> - {done,{ok,yyrev(Ts, [T]),Line},Rest}; -tokens_cont(Rest, Line, {end_token,T,Push}, Ts) -> - NewRest = Push ++ Rest, - {done,{ok,yyrev(Ts, [T]),Line},NewRest}; -tokens_cont(Rest, Line, skip_token, Ts) -> - tokens(yystate(), Rest, Line, Rest, 0, Line, Ts, reject, 0); -tokens_cont(Rest, Line, {skip_token,Push}, Ts) -> - NewRest = Push ++ Rest, - tokens(yystate(), NewRest, Line, NewRest, 0, Line, Ts, reject, 0); -tokens_cont(Rest, Line, {error,S}, _Ts) -> - skip_tokens(Rest, Line, {Line,?MODULE,{user,S}}). - -%%skip_tokens(InChars, Line, Error) -> {done,{error,Error,Line},Ics}. -%% Skip tokens until an end token, junk everything and return the error. - -skip_tokens(Ics, Line, Error) -> - skip_tokens(yystate(), Ics, Line, Ics, 0, Line, Error, reject, 0). - -%% skip_tokens(State, InChars, Line, TokenChars, TokenLen, TokenLine, Tokens, -%% AcceptAction, AcceptLen) -> -%% {more,Continuation} | {done,ReturnVal,RestChars}. - -skip_tokens(S0, Ics0, L0, Tcs, Tlen0, Tline, Error, A0, Alen0) -> - case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of - {A1,Alen1,Ics1,L1} -> % Accepting end state - skip_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Error); - {A1,Alen1,[],L1,S1} -> % After an accepting state - {more,{skip_tokens,S1,L1,Tcs,Alen1,Tline,Error,A1,Alen1}}; - {A1,Alen1,Ics1,L1,_S1} -> - skip_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Error); - {A1,Alen1,Tlen1,[],L1,S1} -> % After a non-accepting state - {more,{skip_tokens,S1,L1,Tcs,Tlen1,Tline,Error,A1,Alen1}}; - {reject,_Alen1,_Tlen1,eof,L1,_S1} -> - {done,{error,Error,L1},eof}; - {reject,_Alen1,Tlen1,_Ics1,L1,_S1} -> - skip_tokens(yysuf(Tcs, Tlen1+1), L1, Error); - {A1,Alen1,_Tlen1,_Ics1,L1,_S1} -> - Token = yyaction(A1, Alen1, Tcs, Tline), - skip_cont(yysuf(Tcs, Alen1), L1, Token, Error) - end. - -%% skip_cont(RestChars, Line, Token, Error) -%% Skip tokens until we have an end_token or error then return done -%% with the original rror. - --dialyzer({nowarn_function, skip_cont/4}). - -skip_cont(Rest, Line, {token,_T}, Error) -> - skip_tokens(yystate(), Rest, Line, Rest, 0, Line, Error, reject, 0); -skip_cont(Rest, Line, {token,_T,Push}, Error) -> - NewRest = Push ++ Rest, - skip_tokens(yystate(), NewRest, Line, NewRest, 0, Line, Error, reject, 0); -skip_cont(Rest, Line, {end_token,_T}, Error) -> - {done,{error,Error,Line},Rest}; -skip_cont(Rest, Line, {end_token,_T,Push}, Error) -> - NewRest = Push ++ Rest, - {done,{error,Error,Line},NewRest}; -skip_cont(Rest, Line, skip_token, Error) -> - skip_tokens(yystate(), Rest, Line, Rest, 0, Line, Error, reject, 0); -skip_cont(Rest, Line, {skip_token,Push}, Error) -> - NewRest = Push ++ Rest, - skip_tokens(yystate(), NewRest, Line, NewRest, 0, Line, Error, reject, 0); -skip_cont(Rest, Line, {error,_S}, Error) -> - skip_tokens(yystate(), Rest, Line, Rest, 0, Line, Error, reject, 0). - -yyrev(List) -> lists:reverse(List). -yyrev(List, Tail) -> lists:reverse(List, Tail). -yypre(List, N) -> lists:sublist(List, N). -yysuf(List, N) -> lists:nthtail(N, List). - -%% yystate() -> InitialState. -%% yystate(State, InChars, Line, CurrTokLen, AcceptAction, AcceptLen) -> -%% {Action, AcceptLen, RestChars, Line} | -%% {Action, AcceptLen, RestChars, Line, State} | -%% {reject, AcceptLen, CurrTokLen, RestChars, Line, State} | -%% {Action, AcceptLen, CurrTokLen, RestChars, Line, State}. -%% Generated state transition functions. The non-accepting end state -%% return signal either an unrecognised character or end of current -%% input. - --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.erl", 288). -yystate() -> 20. - -yystate(23, [101|Ics], Line, Tlen, Action, Alen) -> - yystate(21, Ics, Line, Tlen+1, Action, Alen); -yystate(23, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,23}; -yystate(22, Ics, Line, Tlen, _, _) -> - {6,Tlen,Ics,Line}; -yystate(21, Ics, Line, Tlen, _, _) -> - {1,Tlen,Ics,Line}; -yystate(20, [125|Ics], Line, Tlen, Action, Alen) -> - yystate(16, Ics, Line, Tlen+1, Action, Alen); -yystate(20, [116|Ics], Line, Tlen, Action, Alen) -> - yystate(8, Ics, Line, Tlen+1, Action, Alen); -yystate(20, [115|Ics], Line, Tlen, Action, Alen) -> - yystate(11, Ics, Line, Tlen+1, Action, Alen); -yystate(20, [114|Ics], Line, Tlen, Action, Alen) -> - yystate(18, Ics, Line, Tlen+1, Action, Alen); -yystate(20, [113|Ics], Line, Tlen, Action, Alen) -> - yystate(17, Ics, Line, Tlen+1, Action, Alen); -yystate(20, [104|Ics], Line, Tlen, Action, Alen) -> - yystate(1, Ics, Line, Tlen+1, Action, Alen); -yystate(20, [59|Ics], Line, Tlen, Action, Alen) -> - yystate(14, Ics, Line, Tlen+1, Action, Alen); -yystate(20, [10|Ics], Line, Tlen, Action, Alen) -> - yystate(22, Ics, Line+1, Tlen+1, Action, Alen); -yystate(20, [C|Ics], Line, Tlen, Action, Alen) when C >= 0, C =< 9 -> - yystate(22, Ics, Line, Tlen+1, Action, Alen); -yystate(20, [C|Ics], Line, Tlen, Action, Alen) when C >= 11, C =< 32 -> - yystate(22, Ics, Line, Tlen+1, Action, Alen); -yystate(20, [C|Ics], Line, Tlen, Action, Alen) when C >= 33, C =< 58 -> - yystate(18, Ics, Line, Tlen+1, Action, Alen); -yystate(20, [C|Ics], Line, Tlen, Action, Alen) when C >= 60, C =< 103 -> - yystate(18, Ics, Line, Tlen+1, Action, Alen); -yystate(20, [C|Ics], Line, Tlen, Action, Alen) when C >= 105, C =< 112 -> - yystate(18, Ics, Line, Tlen+1, Action, Alen); -yystate(20, [C|Ics], Line, Tlen, Action, Alen) when C >= 117, C =< 124 -> - yystate(18, Ics, Line, Tlen+1, Action, Alen); -yystate(20, [C|Ics], Line, Tlen, Action, Alen) when C >= 126 -> - yystate(18, Ics, Line, Tlen+1, Action, Alen); -yystate(20, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,20}; -yystate(19, [116|Ics], Line, Tlen, Action, Alen) -> - yystate(23, Ics, Line, Tlen+1, Action, Alen); -yystate(19, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,19}; -yystate(18, Ics, Line, Tlen, _, _) -> - {7,Tlen,Ics,Line}; -yystate(17, [117|Ics], Line, Tlen, _, _) -> - yystate(13, Ics, Line, Tlen+1, 7, Tlen); -yystate(17, Ics, Line, Tlen, _, _) -> - {7,Tlen,Ics,Line,17}; -yystate(16, [42|Ics], Line, Tlen, _, _) -> - yystate(12, Ics, Line, Tlen+1, 7, Tlen); -yystate(16, Ics, Line, Tlen, _, _) -> - {7,Tlen,Ics,Line,16}; -yystate(15, [97|Ics], Line, Tlen, Action, Alen) -> - yystate(19, Ics, Line, Tlen+1, Action, Alen); -yystate(15, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,15}; -yystate(14, Ics, Line, Tlen, _, _) -> - {5,Tlen,Ics,Line}; -yystate(13, [105|Ics], Line, Tlen, Action, Alen) -> - yystate(9, Ics, Line, Tlen+1, Action, Alen); -yystate(13, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,13}; -yystate(12, Ics, Line, Tlen, _, _) -> - {4,Tlen,Ics,Line}; -yystate(11, [116|Ics], Line, Tlen, _, _) -> - yystate(15, Ics, Line, Tlen+1, 7, Tlen); -yystate(11, Ics, Line, Tlen, _, _) -> - {7,Tlen,Ics,Line,11}; -yystate(10, Ics, Line, Tlen, _, _) -> - {3,Tlen,Ics,Line}; -yystate(9, [116|Ics], Line, Tlen, Action, Alen) -> - yystate(5, Ics, Line, Tlen+1, Action, Alen); -yystate(9, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,9}; -yystate(8, [97|Ics], Line, Tlen, _, _) -> - yystate(4, Ics, Line, Tlen+1, 7, Tlen); -yystate(8, Ics, Line, Tlen, _, _) -> - {7,Tlen,Ics,Line,8}; -yystate(7, Ics, Line, Tlen, _, _) -> - {0,Tlen,Ics,Line}; -yystate(6, [112|Ics], Line, Tlen, Action, Alen) -> - yystate(10, Ics, Line, Tlen+1, Action, Alen); -yystate(6, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,6}; -yystate(5, Ics, Line, Tlen, _, _) -> - {2,Tlen,Ics,Line}; -yystate(4, [115|Ics], Line, Tlen, Action, Alen) -> - yystate(0, Ics, Line, Tlen+1, Action, Alen); -yystate(4, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,4}; -yystate(3, [115|Ics], Line, Tlen, Action, Alen) -> - yystate(7, Ics, Line, Tlen+1, Action, Alen); -yystate(3, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,3}; -yystate(2, [108|Ics], Line, Tlen, Action, Alen) -> - yystate(6, Ics, Line, Tlen+1, Action, Alen); -yystate(2, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,2}; -yystate(1, [101|Ics], Line, Tlen, _, _) -> - yystate(2, Ics, Line, Tlen+1, 7, Tlen); -yystate(1, Ics, Line, Tlen, _, _) -> - {7,Tlen,Ics,Line,1}; -yystate(0, [107|Ics], Line, Tlen, Action, Alen) -> - yystate(3, Ics, Line, Tlen+1, Action, Alen); -yystate(0, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,0}; -yystate(S, Ics, Line, Tlen, Action, Alen) -> - {Action,Alen,Tlen,Ics,Line,S}. - -%% yyaction(Action, TokenLength, TokenChars, TokenLine) -> -%% {token,Token} | {end_token, Token} | skip_token | {error,String}. -%% Generated action function. - -yyaction(0, _, _, _) -> - yyaction_0(); -yyaction(1, _, _, _) -> - yyaction_1(); -yyaction(2, _, _, _) -> - yyaction_2(); -yyaction(3, _, _, _) -> - yyaction_3(); -yyaction(4, _, _, _) -> - yyaction_4(); -yyaction(5, _, _, _) -> - yyaction_5(); -yyaction(6, _, _, _) -> - yyaction_6(); -yyaction(7, _, _, _) -> - yyaction_7(); -yyaction(_, _, _, _) -> error. - --compile({inline,yyaction_0/0}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 40). -yyaction_0() -> - { token, tasks } . - --compile({inline,yyaction_1/0}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 41). -yyaction_1() -> - { token, state } . - --compile({inline,yyaction_2/0}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 42). -yyaction_2() -> - { token, quit } . - --compile({inline,yyaction_3/0}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 43). -yyaction_3() -> - { token, help } . - --compile({inline,yyaction_4/0}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 44). -yyaction_4() -> - { token, terminal } . - --compile({inline,yyaction_5/0}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 45). -yyaction_5() -> - { token, terminal } . - --compile({inline,yyaction_6/0}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 46). -yyaction_6() -> - skip_token . - --compile({inline,yyaction_7/0}). --file("/home/jorgen/git/cuneiform/_build/default/lib/cuneiform/src/pre_scan.xrl", 47). -yyaction_7() -> - { token, nonws } . - --file("/usr/local/lib/erlang/lib/parsetools-2.1.1/include/leexinc.hrl", 290). From 33c0f8999d0d98279e05b90a55f3393d376f4787 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Sun, 20 Mar 2016 10:09:54 +0100 Subject: [PATCH 42/78] Improvement. --- Makefile | 4 +- src/cf_parse.yrl | 125 +++++++++++++------------- src/cf_shell.erl | 2 +- src/cuneiform.erl | 2 +- src/cuneiform_app.erl | 2 +- src/{cf_sup.erl => cuneiform_sup.erl} | 2 +- 6 files changed, 69 insertions(+), 68 deletions(-) rename src/{cf_sup.erl => cuneiform_sup.erl} (98%) diff --git a/Makefile b/Makefile index 071b355..76462b2 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,5 @@ all: - rebar3 compile - rebar3 eunit - rebar3 dialyzer + rebar3 do compile, eunit, dialyzer clean: rebar3 clean diff --git a/src/cf_parse.yrl b/src/cf_parse.yrl index 39dc3c6..db74d45 100644 --- a/src/cf_parse.yrl +++ b/src/cf_parse.yrl @@ -47,7 +47,7 @@ stat -> defun : {undef, #{}, '$1'}. query -> compoundexpr semicolon : '$1'. -assign -> exprlist eq compoundexpr semicolon : mk_assign( '$1', '$3', 1 ). +assign -> exprlist eq compoundexpr semicolon : mk_assign( get_line( '$2' ), '$1', '$3', 1 ). assignlist -> assign : '$1'. assignlist -> assign assignlist : maps:merge( '$1', '$2' ). @@ -119,15 +119,14 @@ Erlang code. -endif. string( S ) -> - % scan case cf_scan:string( S ) of - {error, ScanErrorInfo, _} -> error( ScanErrorInfo ); + {error, ScanErrorInfo, _} -> {error, ScanErrorInfo}; {ok, TokenLst, _} -> - % parse - case cf_parse:parse( TokenLst ) of - {error, ParseErrorInfo} -> error( ParseErrorInfo ); - {ok, Triple} -> Triple - end + try parse( TokenLst ) of + Ret -> Ret + catch + error:E -> {error, E} + end end. @@ -153,20 +152,20 @@ get_name( {id, _Line, Name} ) -> Name. mk_binding( {id, _, Name}, ExprList ) -> #{Name => ExprList}. -mk_assign( [], _ExprList, _Channel ) -> #{}; +mk_assign( _Line, [], _ExprList, _Channel ) -> #{}; -mk_assign( [{var, _Line, Name}|Rest], ExprList, Channel ) -> - Rho = mk_assign( Rest, ExprList, Channel+1 ), - Value = lists:flatmap( fun( E ) -> set_channel( E, Channel ) end, ExprList ), +mk_assign( Line, [{var, _Line, Name}|Rest], ExprList, Channel ) -> + Rho = mk_assign( Line, Rest, ExprList, Channel+1 ), + Value = lists:flatmap( fun( E ) -> set_channel( Line, E, Channel ) end, ExprList ), Rho#{Name => Value}; -mk_assign( [E|_Rest], _ExprList, _Channel ) -> - error( {parser, nonvar_expr_left_of_eq, element( 1, E ), element( 2, E )} ). +mk_assign( Line, [E|_Rest], _ExprList, _Channel ) -> + error( {Line, cf_parse, {nonvar_expr_left_of_eq, element( 1, E )}} ). -set_channel( {app, Line, _Channel, LamList, Binding}, N ) -> [{app, Line, N, LamList, Binding}]; -set_channel( E, 1 ) -> [E]; -set_channel( E, _ ) -> error( {parser, nonapp_expr, element( 1, E ), element( 2, E )} ). +set_channel( _Line, {app, AppLine, _Channel, LamList, Binding}, N ) -> [{app, AppLine, N, LamList, Binding}]; +set_channel( _Line, E, 1 ) -> [E]; +set_channel( Line, E, _ ) -> error( {Line, cf_parse, {set_channel_on_nonapp_expr, element( 1, E )}} ). mk_natlam( {deftask, Line, _}, {id, _, Name}, Sign, Block ) -> #{Name => {lam, Line, Name, Sign, {natbody, Block}}}. @@ -174,7 +173,6 @@ mk_natlam( {deftask, Line, _}, {id, _, Name}, Sign, Block ) -> mk_forlam( {deftask, Line, _}, {id, _, Name}, Sign, Lang, {body, _, Code} ) -> #{Name => {lam, Line, Name, Sign, {forbody, Lang, Code}}}. - %% ============================================================================= %% Unit Tests %% ============================================================================= @@ -182,124 +180,129 @@ mk_forlam( {deftask, Line, _}, {id, _, Name}, Sign, Lang, {body, _, Code} ) -> -ifdef( TEST ). nil_should_be_recognized_test() -> - ?assertEqual( {[], #{}, #{}}, string( "nil;" ) ). + ?assertEqual( {ok, {[], #{}, #{}}}, string( "nil;" ) ). var_should_be_recognized_test() -> - ?assertEqual( {[{var, 1, "blub"}], #{}, #{}}, string( "blub;" ) ). + ?assertEqual( {ok, {[{var, 1, "blub"}], #{}, #{}}}, string( "blub;" ) ). multi_element_compoundexpr_should_be_recognized_test() -> - ?assertEqual( {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}, + ?assertEqual( {ok, {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}}, string( "bla blub;" ) ). multiple_queries_should_be_joined_test() -> - ?assertEqual( {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}, + ?assertEqual( {ok, {[{var, 1, "bla"}, {var, 1, "blub"}], #{}, #{}}}, string( "bla; blub;" ) ). strlit_should_be_recognized_test() -> - ?assertEqual( {[{str, "bla"}], #{}, #{}}, string( "\"bla\";" ) ). + ?assertEqual( {ok, {[{str, "bla"}], #{}, #{}}}, string( "\"bla\";" ) ). intlit_should_be_recognized_test() -> - ?assertEqual( {[{str, "-5"}], #{}, #{}}, string( "-5;" ) ). + ?assertEqual( {ok, {[{str, "-5"}], #{}, #{}}}, string( "-5;" ) ). cnd_should_be_recognized_test() -> - ?assertEqual( {[{cnd, 1, [], [{str, "bla"}], [{str, "blub"}]}], - #{}, #{}}, + ?assertEqual( {ok, {[{cnd, 1, [], [{str, "bla"}], [{str, "blub"}]}], + #{}, #{}}}, string( "if nil then \"bla\" else \"blub\" end;" ) ). app_should_be_recognized_test() -> - [?assertEqual( {[{app, 1, 1, {var, 1, "f"}, #{}}], #{}, #{}}, + [?assertEqual( {ok, {[{app, 1, 1, {var, 1, "f"}, #{}}], #{}, #{}}}, string( "f();" ) ), - ?assertEqual( {[{app, 1, 1, {var, 1, "f"}, #{"x" => [{var, 1, "x"}]}}], - #{}, #{}}, string( "f( x: x );" ) ), - ?assertEqual( {[{app, 1, 1, {var, 1, "f"}, + ?assertEqual( {ok, {[{app, 1, 1, {var, 1, "f"}, #{"x" => [{var, 1, "x"}]}}], + #{}, #{}}}, string( "f( x: x );" ) ), + ?assertEqual( {ok, {[{app, 1, 1, {var, 1, "f"}, #{"x" => [{var, 1, "x"}], - "y" => [{str, "y"}]}}], #{}, #{}}, + "y" => [{str, "y"}]}}], #{}, #{}}}, string( "f( x: x, y: \"y\" );" ) )]. assign_should_be_recognized_test() -> - [?assertEqual( {undef, #{"x" => [{str, "x"}]}, #{}}, string( "x = \"x\";" ) ), - ?assertEqual( {undef, #{"x" => [{app, 1, 1, {var, 1, "f"}, #{}}], "y" => [{app, 1, 2, {var, 1, "f"}, #{}}]}, #{}}, string( "x y = f();" ) ), - ?assertError( {parser, nonapp_expr, str, "A"}, string( "x y = \"A\";" ) ), - ?assertError( {parser, nonvar_expr_left_of_eq, str, "a"}, string( "\"a\" = \"A\";" ) )]. + [?assertEqual( {ok, {undef, #{"x" => [{str, "x"}]}, #{}}}, + string( "x = \"x\";" ) ), + ?assertEqual( {ok, {undef, #{"x" => [{app, 1, 1, {var, 1, "f"}, #{}}], + "y" => [{app, 1, 2, {var, 1, "f"}, #{}}]}, + #{}}}, string( "x y = f();" ) ), + ?assertEqual( {error, {1, cf_parse, {set_channel_on_nonapp_expr, str}}}, + string( "x y = \"A\";" ) ), + ?assertEqual( {error, {1, cf_parse, {nonvar_expr_left_of_eq, str}}}, + string( "\"a\" = \"A\";" ) )]. native_deftask_should_be_recognized_test() -> - ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", + ?assertEqual( {ok, {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, - {natbody, #{"out" => [{str, "A"}]}}}}}, + {natbody, #{"out" => [{str, "A"}]}}}}}}, string( "deftask f( out : ) { out = \"A\"; }" ) ). foreign_deftask_should_be_recognized_test() -> - [?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", + [?assertEqual( {ok, {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, - {forbody, bash, "out=A"}}}}, + {forbody, bash, "out=A"}}}}}, string( "deftask f( out : )in bash *{out=A}*" ) ), - ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", + ?assertEqual( {ok, {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, - {forbody, r, "out=\"A\""}}}}, + {forbody, r, "out=\"A\""}}}}}, string( "deftask f( out : )in R *{out=\"A\"}*" ) ), - ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", + ?assertEqual( {ok, {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], []}, - {forbody, python, ""}}}}, + {forbody, python, ""}}}}}, string( "deftask f( out : )in python *{}*" ) )]. sign_with_inparam_should_be_recognized_test() -> - [?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", + [?assertEqual( {ok, {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], [{param, {name, "inp", false}, false}]}, - {forbody, python, "(defparameter out \"A\")"}}}}, + {forbody, python, "(defparameter out \"A\")"}}}}}, string( "deftask f( out : inp )in python *{(defparameter out \"A\")}*" ) ), - ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", + ?assertEqual( {ok, {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], [{param, {name, "a", false}, false}, {param, {name, "b", false}, false}]}, - {forbody, python, "(defparameter out \"A\")"}}}}, + {forbody, python, "(defparameter out \"A\")"}}}}}, string( "deftask f( out : a b )in python *{(defparameter out \"A\")}*" ) )]. param_should_be_recognized_test() -> - [?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", + [?assertEqual( {ok, {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], [{param, {name, "inp", false}, false}]}, - {forbody, bash, "blub"}}}}, + {forbody, bash, "blub"}}}}}, string( "deftask f( out( String ) : inp( String ) )in bash *{blub}*" ) ), - ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", + ?assertEqual( {ok, {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", true}, false}], [{param, {name, "inp", true}, false}]}, - {forbody, bash, "blub"}}}}, + {forbody, bash, "blub"}}}}}, string( "deftask f( out( File ) : inp( File ) )in bash *{blub}*" ) ), - ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", + ?assertEqual( {ok, {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, true}], [{param, {name, "inp", false}, true}]}, - {forbody, bash, "blub"}}}}, + {forbody, bash, "blub"}}}}}, string( "deftask f( : )in bash *{blub}*" ) ), - ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", + ?assertEqual( {ok, {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, true}], [{param, {name, "inp", false}, true}]}, - {forbody, bash, "blub"}}}}, + {forbody, bash, "blub"}}}}}, string( "deftask f( : )in bash *{blub}*" ) ), - ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", + ?assertEqual( {ok, {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", true}, true}], [{param, {name, "inp", true}, true}]}, - {forbody, bash, "blub"}}}}, + {forbody, bash, "blub"}}}}}, string( "deftask f( : )in bash *{blub}*" ) )]. correl_inparam_should_be_recognized_test() -> - [?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", + [?assertEqual( {ok, {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], [{correl, [{name, "a", true}, {name, "b", true}]}]}, - {forbody, bash, "blub"}}}}, + {forbody, bash, "blub"}}}}}, string( "deftask f( out : [a( File ) b( File )] )in bash *{blub}*" ) ), - ?assertEqual( {undef, #{}, #{"f" => {lam, 1, "f", + ?assertEqual( {ok, {undef, #{}, #{"f" => {lam, 1, "f", {sign, [{param, {name, "out", false}, false}], [{correl, [{name, "a", true}, {name, "b", true}]}, {param, {name, "c", false}, false}]}, - {forbody, bash, "blub"}}}}, + {forbody, bash, "blub"}}}}}, string( "deftask f( out : [a( File ) b( File )] c )in bash *{blub}*" ) )]. -endif. diff --git a/src/cf_shell.erl b/src/cf_shell.erl index 69f9156..0a834c3 100644 --- a/src/cf_shell.erl +++ b/src/cf_shell.erl @@ -113,7 +113,7 @@ read( Buf ) -> end; [_|_] -> case lists:last( TokenLst ) of - terminal -> {ok, cf_parse:string( Buf++S )}; + terminal -> cf_parse:string( Buf++S ); nonws -> read( Buf++S ); C -> {ctl, C} end diff --git a/src/cuneiform.erl b/src/cuneiform.erl index 4b484b7..2ae136b 100644 --- a/src/cuneiform.erl +++ b/src/cuneiform.erl @@ -36,7 +36,7 @@ start() -> -spec string( S::string(), DataDir::string() ) -> [cf_sem:str()]. string( S, DataDir ) -> - {Query, Rho, Gamma} = cf_parse:string( S ), + {ok, {Query, Rho, Gamma}} = cf_parse:string( S ), reduce( Query, Rho, Gamma, DataDir ). -spec file( Filename::string() ) -> [cf_sem:str()]. diff --git a/src/cuneiform_app.erl b/src/cuneiform_app.erl index 4ee9e58..585392d 100644 --- a/src/cuneiform_app.erl +++ b/src/cuneiform_app.erl @@ -32,7 +32,7 @@ start( normal, [] ) -> % TODO: load and hand down configuration - cf_sup:start_link(). + cuneiform_sup:start_link(). stop( _State ) -> ok. diff --git a/src/cf_sup.erl b/src/cuneiform_sup.erl similarity index 98% rename from src/cf_sup.erl rename to src/cuneiform_sup.erl index 153965b..0d72df3 100644 --- a/src/cf_sup.erl +++ b/src/cuneiform_sup.erl @@ -16,7 +16,7 @@ % See the License for the specific language governing permissions and % limitations under the License. --module(cf_sup). +-module(cuneiform_sup). -author( "Jorgen Brandt " ). -behaviour( supervisor ). From a54984c14e388dad6348fb568b627f2fd21d4dc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Sun, 20 Mar 2016 23:25:08 +0100 Subject: [PATCH 43/78] Error reporting. --- priv/cf | 3 --- src/cf_parse.yrl | 14 ++++++-------- src/cf_shell.erl | 31 ++++++++++++++++--------------- 3 files changed, 22 insertions(+), 26 deletions(-) delete mode 100755 priv/cf diff --git a/priv/cf b/priv/cf deleted file mode 100755 index 4a65f08..0000000 --- a/priv/cf +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -erl -s cuneiform -s cf_shell -s init stop -noshell \ No newline at end of file diff --git a/src/cf_parse.yrl b/src/cf_parse.yrl index db74d45..4357200 100644 --- a/src/cf_parse.yrl +++ b/src/cf_parse.yrl @@ -125,7 +125,7 @@ string( S ) -> try parse( TokenLst ) of Ret -> Ret catch - error:E -> {error, E} + throw:E -> {error, E} end end. @@ -159,13 +159,13 @@ mk_assign( Line, [{var, _Line, Name}|Rest], ExprList, Channel ) -> Value = lists:flatmap( fun( E ) -> set_channel( Line, E, Channel ) end, ExprList ), Rho#{Name => Value}; -mk_assign( Line, [E|_Rest], _ExprList, _Channel ) -> - error( {Line, cf_parse, {nonvar_expr_left_of_eq, element( 1, E )}} ). +mk_assign( Line, [_E|_Rest], _ExprList, _Channel ) -> + throw( {Line, cf_parse, "non-variable expression on left-hand side of assignment."} ). set_channel( _Line, {app, AppLine, _Channel, LamList, Binding}, N ) -> [{app, AppLine, N, LamList, Binding}]; set_channel( _Line, E, 1 ) -> [E]; -set_channel( Line, E, _ ) -> error( {Line, cf_parse, {set_channel_on_nonapp_expr, element( 1, E )}} ). +set_channel( Line, _, _ ) -> throw( {Line, cf_parse, "multiple value bind on non-application expression"} ). mk_natlam( {deftask, Line, _}, {id, _, Name}, Sign, Block ) -> #{Name => {lam, Line, Name, Sign, {natbody, Block}}}. @@ -221,10 +221,8 @@ assign_should_be_recognized_test() -> ?assertEqual( {ok, {undef, #{"x" => [{app, 1, 1, {var, 1, "f"}, #{}}], "y" => [{app, 1, 2, {var, 1, "f"}, #{}}]}, #{}}}, string( "x y = f();" ) ), - ?assertEqual( {error, {1, cf_parse, {set_channel_on_nonapp_expr, str}}}, - string( "x y = \"A\";" ) ), - ?assertEqual( {error, {1, cf_parse, {nonvar_expr_left_of_eq, str}}}, - string( "\"a\" = \"A\";" ) )]. + ?assertMatch( {error, {1, cf_parse, _}}, string( "x y = \"A\";" ) ), + ?assertMatch( {error, {1, cf_parse, _}}, string( "\"a\" = \"A\";" ) )]. native_deftask_should_be_recognized_test() -> ?assertEqual( {ok, {undef, #{}, #{"f" => {lam, 1, "f", diff --git a/src/cf_shell.erl b/src/cf_shell.erl index 0a834c3..551db9a 100644 --- a/src/cf_shell.erl +++ b/src/cf_shell.erl @@ -88,8 +88,6 @@ server_loop( Rho, Gamma ) -> end end. - - read_expression( Prompt ) -> Read = fun() -> io:format( Prompt ), @@ -103,19 +101,22 @@ read_expression( Prompt ) -> end. read( Buf ) -> - S = io:get_line( "" ), - {ok, TokenLst, _} = cf_prescan:string( S ), - case TokenLst of - [] -> - case Buf of - [] -> {ok, {undef, #{}, #{}}}; - [_|_] -> read( Buf ) - end; - [_|_] -> - case lists:last( TokenLst ) of - terminal -> cf_parse:string( Buf++S ); - nonws -> read( Buf++S ); - C -> {ctl, C} + case io:get_line( "" ) of + eof -> {ctl, quit}; + S -> + {ok, TokenLst, _} = cf_prescan:string( S ), + case TokenLst of + [] -> + case Buf of + [] -> {ok, {undef, #{}, #{}}}; + [_|_] -> read( Buf ) + end; + [_|_] -> + case lists:last( TokenLst ) of + terminal -> cf_parse:string( Buf++S ); + nonws -> read( Buf++S ); + C -> {ctl, C} + end end end. From 3224a8c0e61e4b23ed95d6b99288b93ddd2de48f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Sun, 20 Mar 2016 23:26:09 +0100 Subject: [PATCH 44/78] Executable is now generated. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 76462b2..a54410e 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ all: - rebar3 do compile, eunit, dialyzer + rebar3 do escriptize, eunit, dialyzer clean: rebar3 clean From e7fc35335094a85286e7d08ec97690d437bf50b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Sun, 20 Mar 2016 23:27:22 +0100 Subject: [PATCH 45/78] full stop removed. --- src/cf_parse.yrl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cf_parse.yrl b/src/cf_parse.yrl index 4357200..20d16fc 100644 --- a/src/cf_parse.yrl +++ b/src/cf_parse.yrl @@ -160,7 +160,7 @@ mk_assign( Line, [{var, _Line, Name}|Rest], ExprList, Channel ) -> Rho#{Name => Value}; mk_assign( Line, [_E|_Rest], _ExprList, _Channel ) -> - throw( {Line, cf_parse, "non-variable expression on left-hand side of assignment."} ). + throw( {Line, cf_parse, "non-variable expression on left-hand side of assignment"} ). set_channel( _Line, {app, AppLine, _Channel, LamList, Binding}, N ) -> [{app, AppLine, N, LamList, Binding}]; From 6059f1c5c0ba8f1acaad56d490158a5ac33d39fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Sun, 20 Mar 2016 23:59:55 +0100 Subject: [PATCH 46/78] Shell simplified. --- src/cf_shell.erl | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/cf_shell.erl b/src/cf_shell.erl index 551db9a..47b2cb1 100644 --- a/src/cf_shell.erl +++ b/src/cf_shell.erl @@ -57,7 +57,7 @@ start() -> server_loop( #{}, #{} ). server_loop( Rho, Gamma ) -> - case read_expression( ?PROMPT ) of + case read_expression2( ?PROMPT ) of {ctl, quit} -> ok; {ctl, help} -> @@ -89,16 +89,8 @@ server_loop( Rho, Gamma ) -> end. read_expression( Prompt ) -> - Read = fun() -> - io:format( Prompt ), - Ret = read( [] ), - exit( Ret ) - end, - Rdr = spawn_link( Read ), - receive - {'EXIT', Rdr, Ret} -> Ret; - Msg -> error( {bad_msg, Msg} ) - end. + io:format( Prompt ), + read( [] ). read( Buf ) -> case io:get_line( "" ) of From 81bc15981a78825dfee42447fe058bd4baa51d69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Mon, 21 Mar 2016 09:14:23 +0100 Subject: [PATCH 47/78] Mispelled function call fixed. --- Makefile | 5 ++++- rebar.config | 1 - src/cf_shell.erl | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index a54410e..9d3384b 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,8 @@ all: - rebar3 do escriptize, eunit, dialyzer + rebar3 escriptize + +dev: + rebar3 do escriptize, eunit, dialyzer, cover clean: rebar3 clean diff --git a/rebar.config b/rebar.config index 30c0fff..e484257 100644 --- a/rebar.config +++ b/rebar.config @@ -1,4 +1,3 @@ -{cover_enabled, true}. {deps, [ {cre, "0.1.0", {git, "https://github.com/joergen7/cre.git", diff --git a/src/cf_shell.erl b/src/cf_shell.erl index 47b2cb1..8c1421a 100644 --- a/src/cf_shell.erl +++ b/src/cf_shell.erl @@ -57,7 +57,7 @@ start() -> server_loop( #{}, #{} ). server_loop( Rho, Gamma ) -> - case read_expression2( ?PROMPT ) of + case read_expression( ?PROMPT ) of {ctl, quit} -> ok; {ctl, help} -> From 6812f397ab707885f309363ec116239270f6fa91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Mon, 21 Mar 2016 10:38:53 +0100 Subject: [PATCH 48/78] Shell fixed. --- src/cf_prescan.xrl | 4 ++++ src/cf_shell.erl | 25 ++++++++++++++++++------- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/cf_prescan.xrl b/src/cf_prescan.xrl index fb302e5..d82f898 100644 --- a/src/cf_prescan.xrl +++ b/src/cf_prescan.xrl @@ -23,6 +23,8 @@ Definitions. +LS = ls +CWD = cwd HELP = help NONWS = . QUIT = quit @@ -39,6 +41,8 @@ WS = [\000-\s] Rules. +{LS} : {token, ls}. +{CWD} : {token, cwd}. {TASKS} : {token, tasks}. {STATE} : {token, state}. {QUIT} : {token, quit}. diff --git a/src/cf_shell.erl b/src/cf_shell.erl index 8c1421a..2cb3084 100644 --- a/src/cf_shell.erl +++ b/src/cf_shell.erl @@ -60,8 +60,17 @@ server_loop( Rho, Gamma ) -> case read_expression( ?PROMPT ) of {ctl, quit} -> ok; + {ctl, ls} -> + {ok, Dir} = file:get_cwd(), + {ok, FileLst} = file:list_dir( Dir ), + io:format( "~p~n", [FileLst] ), + server_loop( Rho, Gamma ); + {ctl, cwd} -> + {ok, Dir} = file:get_cwd(), + io:format( "~s~n", [Dir] ), + server_loop( Rho, Gamma ); {ctl, help} -> - io:format( "~n~s~n~n", [get_help()] ), + io:format( "~s~n", [get_help()] ), server_loop( Rho, Gamma ); {ctl, state} -> io:format( "~p~n", [Rho] ), @@ -149,18 +158,20 @@ get_banner() -> " @@WB Cuneiform", " @@E_____ "++?VSN++" "++?BUILD, " _g@@@@@WWWWWWL", - " g@@#*`3@B Type "++?BYLW( "help" )++" for usage info.", - " @@P 3@B Type "++?BYLW( "quit" )++" to quit.", + " g@@#*`3@B "++?YLW( "Type " )++?BYLW( "help" )++?YLW( " for usage info." ), + " @@P 3@B", " @N____ 3@B Docs: "++?BLU( "http://www.cuneiform-lang.org" ), " \"W@@@WF3@B Code: "++?BLU( "https://github.com/joergen7/cuneiform" ) ], "\n" ). get_help() -> string:join( - ["help -- Show this usage info", - "quit -- Quit the shell", - "state -- Show variable bindings", - "tasks -- Show task definitions" + [?YLW( "help" )++" show this usage info", + ?YLW( "state" )++" show variable bindings", + ?YLW( "tasks" )++" show task definitions", + ?YLW( "ls" )++" list files", + ?YLW( "cwd" )++" current working directory", + ?YLW( "quit" )++" quit the shell" ], "\n" ). From dfc3c3016f2ac171ace4910a0acb38a15f88bf99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Mon, 21 Mar 2016 14:22:26 +0100 Subject: [PATCH 49/78] CRE included in project. --- rebar.config | 5 +- src/condor_submit.erl | 225 +++++++++++++++++++++++++++++++++++++ src/cre.erl | 252 ++++++++++++++++++++++++++++++++++++++++++ src/gen_queue.erl | 99 +++++++++++++++++ src/local.erl | 95 ++++++++++++++++ 5 files changed, 674 insertions(+), 2 deletions(-) create mode 100644 src/condor_submit.erl create mode 100644 src/cre.erl create mode 100644 src/gen_queue.erl create mode 100644 src/local.erl diff --git a/rebar.config b/rebar.config index e484257..c71351f 100644 --- a/rebar.config +++ b/rebar.config @@ -1,5 +1,6 @@ {deps, [ - {cre, "0.1.0", - {git, "https://github.com/joergen7/cre.git", + {effi, "0.1.0", + {git, "https://github.com/joergen7/effi.git", {branch, "master"}}} ]}. +{escript_incl_apps, [getopt]}. \ No newline at end of file diff --git a/src/condor_submit.erl b/src/condor_submit.erl new file mode 100644 index 0000000..db72f46 --- /dev/null +++ b/src/condor_submit.erl @@ -0,0 +1,225 @@ +%%%------------------------------------------------------------------- +%%% @author mac +%%% @copyright (C) 2016, +%%% @doc +%%% +%%% @end +%%% Created : 21. Feb 2016 8:49 PM +%%% +%%% This is utility module that produces condor_submit file contents from 3 sources of possible inputs, +%%% in the following order of priority if there is a parameter key conflict: +%%% +%%% 1. Mandatory CF condor parameters: executable, log, error, output +%%% 2. Optional task-level condor parameters, i.e. universe, RequestMemory, RequestCpus +%%% 3. Optional default condor parameters, i.e. universe, should_transfer_files, etc. +%%% +%%% One exception is transfer_input_files: instead of choosing just one of the corresponding +%%% lists, the lists are merged. This way any custom input files can be specified as well. +%%% Also, input file names are validated to be real files, therefore transfer_input_files param +%%% is the only one expected to be a list of files rather than a complete string and it will +%%% be converted back to comma-separated string once the validation and possibly merging is done +%%% +%%% Mandatory condor parameters that aren't provided in either of the "sources" +%%% will be filled in with VANILLA_DEFAULS +%%%------------------------------------------------------------------- +-module(condor_submit). + +-ifdef( TEST ). +-include_lib( "eunit/include/eunit.hrl" ). +-endif. + +%% API +-export([ + generate_condor_submit/1, + generate_condor_submit/2, + generate_condor_submit/3]). + +-define(VANILLA_DEFAULTS, + #{universe => "vanilla", + should_transfer_files => "YES", + run_as_owner => "True", + when_to_transfer_output => "ON_EXIT"}). + +%% +%% This method expects 1 argument +%% 1. Mandatory CF-generated condor parameters, like 'executable', 'log', etc. +%% All the missing necessary parameters like 'universe' will be filled default values +generate_condor_submit(CFParams) -> generate_condor_submit(CFParams, #{}). +%% +%% This method expects 2 arguments: +%% 1. Mandatory CF-generated condor parameters, like 'executable', 'log', etc. +%% 2. declared default condor parameters +%% +generate_condor_submit(#{ executable := Executable, + log := Log, + output := Output, + error := Error, + initialdir := InitialDir} = CFParams, + DeclaredParams) when + is_list(Executable), length(Executable) > 0, + is_list(Log), length(Log) > 0, + is_list(Output), length(Output) > 0, + is_list(Error), length(Error) > 0, + is_list(InitialDir), length(InitialDir) > 0, + is_map(DeclaredParams) -> + CondorParams0 = combine_params(CFParams, DeclaredParams), + CondorParams = maps:merge(?VANILLA_DEFAULTS, CondorParams0), + create_submitfile(CondorParams). + +%% +%% This method expects 3 arguments: +%% 1. Mandatory CF-generated condor parameters, like 'executable', 'log', etc. +%% 2. declared default condor parameters +%% 3. declared task-level condor parameters (any task-level parameters take precedence over defaults) +%% +generate_condor_submit(CFParams, DeclaredDefaultParams, DeclaredTaskParams) + when is_map(DeclaredDefaultParams), is_map(DeclaredTaskParams)-> + DefaultParams = combine_params(DeclaredTaskParams, DeclaredDefaultParams), + generate_condor_submit(CFParams, DefaultParams). + + +%% INTERNAL methods + +validate_input_files( #{ transfer_input_files := [] } = Params) -> + maps:remove(transfer_input_files, Params); +validate_input_files( #{ transfer_input_files := InputFiles} = Params) + when is_list(InputFiles) -> + case lists:all(fun(Elem) -> filelib:is_file(Elem) end, InputFiles) of + true -> Params; + false -> {error, io_lib:format("Invalid input file(s) in ~p!", [InputFiles])} + end; +validate_input_files(#{} = Params) -> Params. + + +%%% This method will combine parameters from two maps in such a a way that +%% Params1 will take precedence over Params2, but if there is tranfer_input_files parameter +%% present in both it will merge the list of input files into one +combine_params( #{ transfer_input_files := InputFiles1 } = Params1, + #{ transfer_input_files := InputFiles2 } = Params2 ) + when is_list(InputFiles1), is_list(InputFiles2) -> + InputFiles = InputFiles1 ++ InputFiles2, + combine_params( + maps:put(transfer_input_files, InputFiles, Params1), + maps:remove(transfer_input_files, Params2) + ); +combine_params(Params1, Params2) when is_map(Params1), is_map(Params2) -> + maps:merge(validate_input_files(Params2), validate_input_files(Params1)). + + +%%% The only parameter that might come here as a list instead of complete cs-string +%%% is transfer_input_files because it might be generated by cuneiform and it needs file validation +%%% Therefore any decalred transfer_input_files params need to be first parsed from cs-string +%%% into a list, and once they are validated and possibly merged, they are converted back to cs-string here +input_files_to_cs_string(#{transfer_input_files := InputFiles} = CondorParams) -> + InputFilesCS = string:join(InputFiles, ", "), + maps:put(transfer_input_files, InputFilesCS, CondorParams); +input_files_to_cs_string(CondorParams) -> CondorParams. + +%%% Just take the param map and output into a string having 'key = value' format +%%% The order of key-value pairs in condor config file doesn't matter at all (I tested) +%%% The resulting string is a complete valid condor submit file contents -- +%%% leaving it to cre_htcondor module to decide the name of the file to write them to +create_submitfile(CondorParams0) -> + CondorParams1 = input_files_to_cs_string(CondorParams0), + LineSep = io_lib:nl(), + SubmitFileStr = maps:fold(fun(K, V, Acc) -> [Acc, io_lib:format("~p = ~s", [K,V]), LineSep] end, "", CondorParams1), + iolist_to_binary([LineSep, lists:flatten(SubmitFileStr), LineSep, "Queue", LineSep]). + + +-ifdef( TEST ). + +-define (GOOD_CF_PARAMS, + #{ executable => "do_something.sh", + log => "job123.log", + output => "job123.stdout", + error => "job123.stderr", + initialdir => ".", + transfer_input_files => []}). + +%%% For testing with condor create `do_something.sh` in the same dir where you run +%%% `condor_submit /tmp/cf_params_test +cf_params_test() -> + CondorSubmitStr = generate_condor_submit(?GOOD_CF_PARAMS), + file:write_file("/tmp/cf_params_test", [CondorSubmitStr]). +%% condor_submit("/tmp/cf_params_test"). + +%%% If files at the end aren't deleted it produces a valid submitfile: /tmp/default_parameters_test +%%% If run with `condor_submit /tmp/default_parameters_test` +%%% Gives a `WARNING: the line 'docker_image = some_image:latest' was unused by condor_submit. Is it a typo?` +%%% Demonstrating that if some params or their combo are invalid condor will handle the errors/warnings +%%% So cuneiform doesn't have to yet it retains full power of condor submit +default_params_test() -> + DefaultParams = #{ universe => "docker", + docker_image => "some_image:latest", + transfer_input_files => ["/tmp/d1.tmp", "/tmp/d2.tmp"], + should_transfer_files => "NO" }, + + CFParams = maps:put(transfer_input_files, ["/tmp/cf1.tmp", "/tmp/cf2.tmp", "/tmp/cf3.tmp"], ?GOOD_CF_PARAMS), + +%% generate_condor_submit(CFParams, DefaultParams), + + Files = maps:get(transfer_input_files, DefaultParams) ++ maps:get(transfer_input_files, CFParams), + create_temp_files(Files), + CondorSubmitStr = generate_condor_submit(CFParams, DefaultParams), + file:write_file("/tmp/default_params_test", CondorSubmitStr). +%% condor_submit("/tmp/default_params_test"). + +% task_params_test() -> +% DefaultParams = #{ universe => "docker", +% docker_image => "some_image:latest", +% transfer_input_files => ["/tmp/d1.tmp", "/tmp/d2.tmp"], +% should_transfer_files => "NO" }, + +% TaskParams = #{ requestMemory => "256M", +% transfer_input_files => ["/tmp/t1.tmp", "/tmp/t2.tmp"]}, + +% CFParams = maps:put(transfer_input_files, ["/tmp/cf1.tmp", "/tmp/cf2.tmp", "/tmp/cf3.tmp"], ?GOOD_CF_PARAMS), + +% %% generate_condor_submit(CFParams, DefaultParams, TaskParams), + +% Files = maps:get(transfer_input_files, DefaultParams) ++ +% maps:get(transfer_input_files, TaskParams) ++ +% maps:get(transfer_input_files, CFParams), + +% CondorSubmitStr = generate_condor_submit(CFParams, DefaultParams, TaskParams), +% file:write_file("/tmp/task_params_test_error", CondorSubmitStr), + +% create_temp_files(Files), +% CondorSubmitStr = generate_condor_submit(CFParams, DefaultParams, TaskParams), +% file:write_file("/tmp/task_params_test", CondorSubmitStr). +%% condor_submit("/tmp/task_params_test"). + +create_temp_files(Files) when is_list(Files) -> + lists:foreach(fun(F) -> file:write_file(F, "") end, Files). + +%%% TODO: move out of here into CT, IMPROVE TEST COVERAGE, and uncomment condor_submits + +%% DELETE to test with condor +%% delete_temp_files(Files) -> +%% lists:foreach(fun(F) -> file:delete(F) end, Files). + +%% condor_submit(CondorSubmitFile) -> +%% Out = os:cmd(["condor_submit", CondorSubmitFile]), +%% OutFile = io_lib:format("/tmp/~s_submit_result", [CondorSubmitFile]), +%% file:write_file(OutFile, Out). + +-endif. + + + + + + + + + + + + + + + + + + + diff --git a/src/cre.erl b/src/cre.erl new file mode 100644 index 0000000..203b6f2 --- /dev/null +++ b/src/cre.erl @@ -0,0 +1,252 @@ +%% -*- erlang -*- +% +% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis +% +% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser +% +% Licensed under the Apache License, Version 2.0 (the "License"); +% you may not use this file except in compliance with the License. +% You may obtain a copy of the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, +% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +% See the License for the specific language governing permissions and +% limitations under the License. + +%% @author Jörgen Brandt +%% @doc The Cuneiform Runtime Environment (CRE). +%% ```+-------+ +-------+ +%% | Query | | Query | +%% +-------+ +-------+ +%% \ / +%% +-----+ +%% | CRE | +%% +-----+''' + + +-module( cre ). +-author( "Jorgen Brandt " ). +-behaviour( gen_server ). + +%% ============================================================================= +%% Function Exports +%% ============================================================================= + +-export( [start_link/0, submit/2] ). + +-export( [code_change/3, handle_cast/2, handle_info/2, init/1, terminate/2, + handle_call/3] ). + +%% ============================================================================= +%% Includes +%% ============================================================================= + +-ifdef( TEST ). +-include_lib( "eunit/include/eunit.hrl" ). +-endif. + +%% ============================================================================= +%% Callback Function Declarations +%% ============================================================================= + + +-callback init() -> {ok, State::term()}. + +-callback handle_submit( Lam, Fa, R, DataDir, ModState ) -> ok +when Lam :: lam(), + Fa :: #{string() => [str()]}, + R :: pos_integer(), + DataDir :: string(), + ModState :: term(). + +%% ============================================================================= +%% Type Definitions +%% ============================================================================= + +-type str() :: {str, S::string()}. + +-type lam() :: {lam, LamLine::pos_integer(), Name::string(), + S::sign(), B::forbody()}. + +-type sign() :: {sign, Lo::[param()], Li::[param()]}. + +-type param() :: {param, M::name(), Pl::boolean()}. + +-type name() :: {name, N::string(), Pf::boolean()}. + +-type forbody() :: {forbody, L::lang(), S::string()}. + +-type lang() :: bash | python | r. + +-type fut() :: {fut, LamName::string(), R::pos_integer(), + Lo::[param()]}. + +-type app() :: {app, AppLine::pos_integer(), C::pos_integer(), + Lambda::lam(), Fa::#{string() => [str()]}}. + +-type ckey() :: {lam(), #{string() => [str()]}, string()}. + +-type response() :: {failed, pos_integer(), atom(), term()} + | {finished, #{atom() => term()}}. + +-type cre_state() :: {Mod::atom(), + SubscrMap::#{pos_integer() => sets:set( pid() )}, + ReplyMap::#{pos_integer() => response()}, + Cache::#{ckey() => fut()}, + R::pos_integer(), + ModState::term()}. + +-type submit() :: {submit, app(), string()}. + +%% ============================================================================= +%% Generic Server Functions +%% ============================================================================= + +code_change( _OldVsn, State, _Extra ) -> {ok, State}. +handle_cast( Request, _State ) -> error( {bad_request, Request} ). +terminate( _Reason, _State ) -> ok. + +%% @doc Generates the initial state of the CRE. + +-spec init( [] ) -> {ok, cre_state()}. + +init( [] ) -> + Mod = local, % CRE callback module implementing the stage function + SubscrMap = #{}, % mapping of a future to a set of subscriber pids + ReplyMap = #{}, % mapping of a future to a response + Cache = #{}, % cache mapping a cache key to a future + R = 1, % next id + + % initialize CRE + {ok, ModState} = apply( Mod, init, [] ), + + {ok, {Mod, SubscrMap, ReplyMap, Cache, R, ModState}}. + +%% @doc On receiving a call containing a subission, a future is generated and +%% returned. +%% +%% When a submission request is received by the CRE, it returns a future by +%% either creating a future, and spawning a corresponding job, or by +%% returning a future from its cache, if a corresponding job has already +%% been started. +%% +%% Additionally, the source of the call is added to the subscriber list for +%% the corresponding future. All subscribers to a future eventually +%% receive a notification about the result of the submission. +%% +%% If the future is served from the cache and a reply has already been +%% received, the subscriber is immediately notified. +%% +-spec handle_call( Request, From, State ) -> {reply, fut(), cre_state()} +when Request :: submit(), + From :: {pid(), term()}, + State :: cre_state(). + +handle_call( {submit, App, DataDir}, {Pid, _Tag}, {Mod, SubscrMap, ReplyMap, Cache, R, ModState} ) -> + + {app, _AppLine, _Channel, Lam, Fa} = App, + {lam, _LamLine, LamName, {sign, Lo, _Li}, _Body} = Lam, + + % construct cache key + Ckey = {Lam, Fa, DataDir}, + + case maps:is_key( Ckey, Cache ) of + + false -> + + % create new future + Fut = {fut, LamName, R, Lo}, + + % start process + apply( Mod, handle_submit, [Lam, Fa, R, DataDir, ModState] ), + + SubscrMap1 = SubscrMap#{R => sets:from_list( [Pid] )}, + Cache1 = Cache#{Ckey => Fut}, + R1 = R+1, + + {reply, Fut, {Mod, SubscrMap1, ReplyMap, Cache1, R1, ModState}}; + + true -> + + % retrieve future from cache + Fut = maps:get( Ckey, Cache ), + + {fut, _, S, _} = Fut, + #{S := SubscrSet} = SubscrMap, + + SubscrMap1 = SubscrMap#{S => sets:add_element( Pid, SubscrSet )}, + + case maps:is_key( S, ReplyMap ) of + false -> ok; + true -> Pid ! maps:get( S, ReplyMap ) + end, + + {reply, Fut, {Mod, SubscrMap1, ReplyMap, Cache, R, ModState}} + end. + +%% Info Handler %% + +-spec handle_info( Info, State ) -> {noreply, cre_state()} +when Info :: response(), + State :: cre_state(). + +handle_info( Info={failed, Reason, S, Data}, {Mod, SubscrMap, ReplyMap, Cache, R, ModState} ) -> + + % retrieve subscriber set + #{S := SubscrSet} = SubscrMap, + + % notify subscribers + lists:foreach( fun( Subscr ) -> + Subscr ! {failed, Reason, S, Data} + end, + sets:to_list( SubscrSet ) ), + + ReplyMap1 = ReplyMap#{S => Info}, + + {noreply, {Mod, SubscrMap, ReplyMap1, Cache, R, ModState}}; + +handle_info( Info={finished, Sum}, {Mod, SubscrMap, ReplyMap, Cache, R, ModState} ) -> + + % retrieve subscriber set + #{id := S} = Sum, + #{S := SubscrSet} = SubscrMap, + + % notify subscribers + lists:foreach( fun( Subscr ) -> + Subscr ! {finished, Sum} + end, + sets:to_list( SubscrSet ) ), + + + ReplyMap1 = ReplyMap#{S => Info}, + + {noreply, {Mod, SubscrMap, ReplyMap1, Cache, R, ModState}}. + +%% ============================================================================= +%% API Functions +%% ============================================================================= + +-spec start_link() -> {ok, pid()} | ignore | {error, Error} +when Error :: {already_started, pid()} | term(). + +start_link() -> + gen_server:start_link( {local, ?MODULE}, ?MODULE, [], [] ). + + +-spec submit( App::app(), DataDir::string() ) -> fut(). + +submit( App, DataDir ) -> + gen_server:call( ?MODULE, {submit, App, DataDir} ). + +%% ============================================================================= +%% Internal Functions +%% ============================================================================= + + +-ifdef( TEST ). + + +-endif. \ No newline at end of file diff --git a/src/gen_queue.erl b/src/gen_queue.erl new file mode 100644 index 0000000..f060e6d --- /dev/null +++ b/src/gen_queue.erl @@ -0,0 +1,99 @@ +%% -*- erlang -*- +% +% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis +% +% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser +% +% Licensed under the Apache License, Version 2.0 (the "License"); +% you may not use this file except in compliance with the License. +% You may obtain a copy of the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, +% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +% See the License for the specific language governing permissions and +% limitations under the License. + +-module( gen_queue ). +-author( "Jorgen Brandt " ). +-behaviour( gen_server ). + +%% ============================================================================= +%% Function Exports +%% ============================================================================= + +-export( [start_link/0, start_link/1, stage_reply/2] ). + +-export( [code_change/3, handle_cast/2, handle_info/2, init/1, terminate/2, + handle_call/3] ). + +%% ============================================================================= +%% Type Definitions +%% ============================================================================= + +-type job() :: {Mod::atom(), Fun::atom(), ArgLst::[term()]}. +-type request() :: {request, pid(), job()}. +-type queue_state() :: {NSlot::non_neg_integer(), Q::[request()]}. + +%% ============================================================================= +%% Generic Server Functions +%% ============================================================================= + +code_change( _OldVsn, State, _Extra ) -> {ok, State}. +handle_call( Request, _From, _State ) -> error( {bad_request, Request} ). +terminate( _Reason, _State ) -> ok. +handle_info( Info, _State ) -> error( {bad_msg, Info} ). + +-spec init( NSlot::pos_integer() ) -> {ok, queue_state()}. + +init( NSlot ) -> {ok, {NSlot,[]}}. + +-spec handle_cast( Request, State ) -> {noreply, queue_state()} +when Request :: request(), + State :: queue_state(). + +handle_cast( continue, {NSlot, []} ) -> + {noreply, {NSlot+1, []}}; + +handle_cast( continue, {NSlot, [H|T]} ) -> + stage_reply( self(), H ), + {noreply, {NSlot, T}}; + +handle_cast( Request, {0, Q} ) -> + {noreply, {0, [Request|Q]}}; + +handle_cast( Request, {NSlot, []} ) -> + stage_reply( self(), Request ), + {noreply, {NSlot-1, []}}. + +%% ============================================================================= +%% API Functions +%% ============================================================================= + +-spec start_link() -> {ok, pid()} | ignore | {error, term()}. + +start_link() -> + NSlot = erlang:system_info( logical_processors_available ), + start_link( NSlot ). + +-spec start_link( NSlot ) -> {ok, pid()} | ignore | {error, term()} +when NSlot :: pos_integer(). + +start_link( NSlot ) +when is_integer( NSlot ), NSlot > 0 -> + gen_server:start_link( ?MODULE, NSlot, [] ). + +-spec stage_reply( QueueRef, Request ) -> ok +when QueueRef :: pid(), + Request :: request(). + +stage_reply( QueueRef, {request, Pid, {Mod, Fun, ArgLst}} ) +when is_pid( QueueRef ), + is_pid( Pid ), + is_atom( Mod ), + is_atom( Fun ), + is_list( ArgLst ) -> + Pid ! apply( Mod, Fun, ArgLst ), + gen_server:cast( QueueRef, continue ). \ No newline at end of file diff --git a/src/local.erl b/src/local.erl new file mode 100644 index 0000000..b89837d --- /dev/null +++ b/src/local.erl @@ -0,0 +1,95 @@ +%% -*- erlang -*- +% +% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis +% +% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser +% +% Licensed under the Apache License, Version 2.0 (the "License"); +% you may not use this file except in compliance with the License. +% You may obtain a copy of the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, +% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +% See the License for the specific language governing permissions and +% limitations under the License. + +-module( local ). +-author( "Jorgen Brandt " ). + +-behaviour( cre ). +-export( [init/0, handle_submit/5, stage/4] ). + +-define( BASEDIR, "/tmp/cf" ). +-define( WORK, "work" ). +-define( REPO, "repo" ). + +-spec init() -> {ok, pid()}. + +init() -> + _Output = os:cmd( string:join( ["rm", "-rf", ?BASEDIR], " " ) ), + gen_queue:start_link(). + + +-spec handle_submit( Lam, Fa, R, DataDir, QueueRef ) -> ok +when Lam :: cre:lam(), + Fa :: #{string() => [cre:str()]}, + R :: pos_integer(), + DataDir :: string(), + QueueRef :: pid(). + +handle_submit( Lam, Fa, R, DataDir, QueueRef ) -> + gen_server:cast( QueueRef, {request, self(), {?MODULE, stage, [Lam, Fa, R, DataDir]}} ). + + +-spec stage( Lam, Fa, R, DataDir ) -> cre:response() +when Lam :: cre:lam(), + Fa :: #{string() => [cre:str()]}, + R :: pos_integer(), + DataDir :: string(). + +stage( Lam={lam, _LamLine, _LamName, {sign, Lo, Li}, _Body}, + Fa, R, DataDir ) -> + + Dir = string:join( [?BASEDIR, ?WORK, integer_to_list( R )], "/" ), + RepoDir = string:join( [?BASEDIR, ?REPO], "/" ), + + % create working directory + case filelib:ensure_dir( [Dir, "/"] ) of + {error, R1} -> error( {R1, ensure_dir, [Dir, "/"]} ); + ok -> ok + end, + + % resolve input files + Triple1 = refactor:get_refactoring( Li, Fa, Dir, [DataDir, RepoDir], R ), + {RefactorLst1, MissingLst1, Fa1} = Triple1, + + case MissingLst1 of + [_|_] -> {failed, precond, R, MissingLst1}; + [] -> + + % link in input files + refactor:apply_refactoring( RefactorLst1 ), + + % start effi + case effi:check_run( Lam, Fa1, R, Dir ) of + + {failed, R2, R, Data} -> {failed, R2, R, Data}; + + {finished, Sum} -> + + Ret1 = maps:get( ret, Sum ), + + % resolve output files + Triple2 = refactor:get_refactoring( Lo, Ret1, RepoDir, [Dir], R ), + {RefactorLst2, [], Ret2} = Triple2, + + % link out output files + refactor:apply_refactoring( RefactorLst2 ), + + % update result map + {finished, Sum#{ret => Ret2}} + end + end. \ No newline at end of file From fe4b6c71c4fea34f699d8d18f65ddcd8a7a4578c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Mon, 21 Mar 2016 18:25:37 +0100 Subject: [PATCH 50/78] Tail recursion is now optimized. --- rebar.config | 1 + src/cf_sem.erl | 14 +++++++++++++- test/cf_sem_test.erl | 16 +++++++++++++--- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/rebar.config b/rebar.config index c71351f..9d36f5c 100644 --- a/rebar.config +++ b/rebar.config @@ -1,3 +1,4 @@ +{cover_enabled, true}. {deps, [ {effi, "0.1.0", {git, "https://github.com/joergen7/effi.git", diff --git a/src/cf_sem.erl b/src/cf_sem.erl index d707701..1fe16f7 100644 --- a/src/cf_sem.erl +++ b/src/cf_sem.erl @@ -133,6 +133,18 @@ pen( {select, _, C, {fut, _, _R, Lo}} ) -> not Pl; pen( _T ) -> false. +-spec pindep( X ) -> boolean() % (37) +when X :: #{string() => [expr()]} | [expr()] | expr(). + +pindep( Fa ) when is_map( Fa ) -> pindep( maps:values( Fa ) ); % (38) +pindep( X ) when is_list( X ) -> lists:all( fun pindep/1, X ); % (39,40) +pindep( {str, _} ) -> true; % (41) +pindep( {select, _, _, _} ) -> true; % (42) +pindep( {cnd, _, Xc, Xt, Xe} ) -> % (43) + pindep( Xc ) andalso pindep( Xt ) andalso pindep( Xe ); +pindep( {app, _, _, _, Fa} ) -> pindep( Fa ); % (44) +pindep( _ ) -> false. + %% ============================================================================= %% Evaluation %% ============================================================================= @@ -212,7 +224,7 @@ step( X={app, AppLine, C, {param, {name, N, _}, Pl} = lists:nth( C, Lo ), V0 = maps:get( N, Fb ), V1 = step( V0, {maps:merge( Fb, Fa ), Mu, Gamma, Omega} ), - case pfinal( V1 ) of + case pindep( V1 ) of false -> [{app, AppLine, C, % (56) {lam, LamLine, LamName, S, {natbody, Fb#{ N => V1}}}, diff --git a/test/cf_sem_test.erl b/test/cf_sem_test.erl index 2d37da2..9c75d38 100644 --- a/test/cf_sem_test.erl +++ b/test/cf_sem_test.erl @@ -251,12 +251,23 @@ foreign_app_with_select_param_is_left_untouched_test() -> app_non_final_result_preserves_app_test() -> Sign = {sign, [{param, {name, "out", false}, false}], []}, - Body = {natbody, #{"out" => [{select, 1, 1, {fut, "f", 1234, [{param, {name, "out", false}, false}]}}]}}, + Select = [{select, 1, 1, {fut, "f", 1234, [{param, {name, "out", false}, false}]}}], + Cnd = [{cnd, 1, Select, [{var, 2, "x"}], [{var, 3, "y"}]}], + Body = {natbody, #{"out" => Cnd}}, Lam = {lam, 3, "g", Sign, Body}, App = [{app, 4, 1, Lam, #{}}], X = cf_sem:eval( App, ?THETA0 ), ?assertMatch( App, X ). +app_tail_recursion_is_optimized_test() -> + Sign = {sign, [{param, {name, "out", false}, false}], []}, + Select = [{select, 1, 1, {fut, "f", 1234, [{param, {name, "out", false}, false}]}}], + Body = {natbody, #{"out" => Select}}, + Lam = {lam, 3, "g", Sign, Body}, + App = [{app, 4, 1, Lam, #{}}], + X = cf_sem:eval( App, ?THETA0 ), + ?assertMatch( Select, X ). + app_non_final_result_preserves_app_with_new_lam_test() -> CSign = {sign, [{param, {name, "out", false}, true}], []}, CLam = {lam, 1, "f", CSign, {forbody, bash, "shalala"}}, @@ -279,8 +290,7 @@ nested_app_undergoes_reduction_test() -> Lam2 = {lam, 3, "g", Sign, Body2}, App2 = [{app, 4, 1, Lam2, #{}}], X = cf_sem:eval( App2, ?THETA0 ), - [{app, 4, 1, {lam, 3, "g", _, {natbody, Fb}}, _}] = X, - [{select, 2, 1, {fut, "f", R, _}}] = maps:get( "out", Fb ), + [{select, 2, 1, {fut, "f", R, _}}] = X, Omega = #{{"out", R} => [{str, "A"}]}, Y = cf_sem:eval( X, {#{}, fun mu/1, #{}, Omega} ), ?assertEqual( [{str, "A"}], Y ). From 4c7e10e7c66a4d94ada943f66892c47425730a91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Mon, 21 Mar 2016 19:05:13 +0100 Subject: [PATCH 51/78] Paren matching now correctly accomplished by cf_prescan. --- src/cf_prescan.xrl | 12 ++++++++--- src/cf_shell.erl | 51 ++++++++++++++++++++++++++++------------------ 2 files changed, 40 insertions(+), 23 deletions(-) diff --git a/src/cf_prescan.xrl b/src/cf_prescan.xrl index d82f898..2c0d8b1 100644 --- a/src/cf_prescan.xrl +++ b/src/cf_prescan.xrl @@ -28,8 +28,11 @@ CWD = cwd HELP = help NONWS = . QUIT = quit -RMMECB = \}\* SEMICOLON = ; +LBRACE = \{ +LMMECB = \*\{ +RBRACE = \} +RMMECB = \}\* STATE = state TASKS = tasks WS = [\000-\s] @@ -47,8 +50,11 @@ Rules. {STATE} : {token, state}. {QUIT} : {token, quit}. {HELP} : {token, help}. -{RMMECB} : {token, terminal}. -{SEMICOLON} : {token, terminal}. +{SEMICOLON} : {token, semicolon}. +{LBRACE} : {token, lbrace}. +{RBRACE} : {token, rbrace}. +{LMMECB} : {token, lmmecb}. +{RMMECB} : {token, rmmecb}. {WS} : skip_token. {NONWS} : {token, nonws}. diff --git a/src/cf_shell.erl b/src/cf_shell.erl index 2cb3084..67a157c 100644 --- a/src/cf_shell.erl +++ b/src/cf_shell.erl @@ -54,46 +54,44 @@ start() -> process_flag( trap_exit, true ), io:format( "~s~n~n~n", [get_banner()] ), - server_loop( #{}, #{} ). + server_loop( #{}, #{}, "." ). -server_loop( Rho, Gamma ) -> +server_loop( Rho, Gamma, Cwd ) -> case read_expression( ?PROMPT ) of {ctl, quit} -> ok; {ctl, ls} -> - {ok, Dir} = file:get_cwd(), - {ok, FileLst} = file:list_dir( Dir ), + {ok, FileLst} = file:list_dir( Cwd ), io:format( "~p~n", [FileLst] ), - server_loop( Rho, Gamma ); + server_loop( Rho, Gamma, Cwd ); {ctl, cwd} -> - {ok, Dir} = file:get_cwd(), - io:format( "~s~n", [Dir] ), - server_loop( Rho, Gamma ); + io:format( "~s~n", [Cwd] ), + server_loop( Rho, Gamma, Cwd ); {ctl, help} -> io:format( "~s~n", [get_help()] ), - server_loop( Rho, Gamma ); + server_loop( Rho, Gamma, Cwd ); {ctl, state} -> io:format( "~p~n", [Rho] ), - server_loop( Rho, Gamma ); + server_loop( Rho, Gamma, Cwd ); {ctl, tasks} -> io:format( "~p~n", [Gamma] ), - server_loop( Rho, Gamma ); + server_loop( Rho, Gamma, Cwd ); {error, ErrorInfo} -> S = format_error( ErrorInfo ), io:format( "~s~n", [S] ), - server_loop( Rho, Gamma ); + server_loop( Rho, Gamma, Cwd ); {ok, {Query, DRho, DGamma}} -> Rho1 = maps:merge( Rho, DRho ), Gamma1 = maps:merge( Gamma, DGamma ), case Query of - undef -> server_loop( Rho1, Gamma1 ); + undef -> server_loop( Rho1, Gamma1, Cwd ); _ -> try cuneiform:reduce( Query, Rho, Gamma, "." ) of X -> io:format( "~s~n", [format_result( X )] ) catch throw:T -> io:format( "~s~n", [format_error( T )] ) end, - server_loop( Rho, Gamma ) + server_loop( Rho, Gamma, Cwd ) end end. @@ -105,7 +103,7 @@ read( Buf ) -> case io:get_line( "" ) of eof -> {ctl, quit}; S -> - {ok, TokenLst, _} = cf_prescan:string( S ), + {ok, TokenLst, _} = cf_prescan:string( Buf++S ), case TokenLst of [] -> case Buf of @@ -113,15 +111,28 @@ read( Buf ) -> [_|_] -> read( Buf ) end; [_|_] -> - case lists:last( TokenLst ) of - terminal -> cf_parse:string( Buf++S ); - nonws -> read( Buf++S ); - C -> {ctl, C} + case is_open( TokenLst ) of + true -> read( Buf++S ); + false -> + case lists:last( TokenLst ) of + semicolon -> cf_parse:string( Buf++S ); + rbrace -> cf_parse:string( Buf++S ); + lbrace -> cf_parse:string( Buf++S ); + rmmecb -> cf_parse:string( Buf++S ); + lmmecb -> cf_parse:string( Buf++S ); + nonws -> read( Buf++S ); + C -> {ctl, C} + end end end end. - +is_open( TokenLst ) -> + NOpen1 = length( [lbrace || lbrace <- TokenLst] ), + NClose1 = length( [rbrace || rbrace <- TokenLst] ), + NOpen2 = length( [lmmecb || lmmecb <- TokenLst] ), + NClose2 = length( [rmmecb || rmmecb <- TokenLst] ), + NOpen1 > NClose1 orelse NOpen2 > NClose2. format_error( {Line, cf_scan, {illegal, Token}} ) -> io_lib:format( ?RED( "Line ~p: " )++?BRED( "illegal token ~s" ), [Line, Token] ); From 2d18f34827fbd1f408e9733822f8744a30b1ad41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Mon, 21 Mar 2016 19:12:43 +0100 Subject: [PATCH 52/78] Comments added. --- src/cf_shell.erl | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/cf_shell.erl b/src/cf_shell.erl index 67a157c..444fa6c 100644 --- a/src/cf_shell.erl +++ b/src/cf_shell.erl @@ -103,24 +103,28 @@ read( Buf ) -> case io:get_line( "" ) of eof -> {ctl, quit}; S -> - {ok, TokenLst, _} = cf_prescan:string( Buf++S ), + T = Buf++S + {ok, TokenLst, _} = cf_prescan:string( T ), case TokenLst of [] -> case Buf of - [] -> {ok, {undef, #{}, #{}}}; - [_|_] -> read( Buf ) + [] -> {ok, {undef, #{}, #{}}}; % nothing entered or buffered + [_|_] -> read( Buf ) % nothing new entered end; - [_|_] -> + [_|_] -> % something was entered case is_open( TokenLst ) of - true -> read( Buf++S ); + true -> read( T ); % closing paren missing false -> case lists:last( TokenLst ) of - semicolon -> cf_parse:string( Buf++S ); - rbrace -> cf_parse:string( Buf++S ); - lbrace -> cf_parse:string( Buf++S ); - rmmecb -> cf_parse:string( Buf++S ); - lmmecb -> cf_parse:string( Buf++S ); - nonws -> read( Buf++S ); + semicolon -> cf_parse:string( T ); + rbrace -> cf_parse:string( T ); + rmmecb -> cf_parse:string( T ); + + lbrace -> cf_parse:string( T ); % these are in fact error + lmmecb -> cf_parse:string( T ); % cases but cf_parse will + % figure it out + + nonws -> read( T ); C -> {ctl, C} end end From af93f9f77387a780581275b17fbb5559782bf0af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Mon, 21 Mar 2016 19:17:10 +0100 Subject: [PATCH 53/78] Syntax error fixed. --- src/cf_shell.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cf_shell.erl b/src/cf_shell.erl index 444fa6c..444412c 100644 --- a/src/cf_shell.erl +++ b/src/cf_shell.erl @@ -65,7 +65,7 @@ server_loop( Rho, Gamma, Cwd ) -> io:format( "~p~n", [FileLst] ), server_loop( Rho, Gamma, Cwd ); {ctl, cwd} -> - io:format( "~s~n", [Cwd] ), + io:format( "~s~n", [filename:absname( Cwd )] ), server_loop( Rho, Gamma, Cwd ); {ctl, help} -> io:format( "~s~n", [get_help()] ), @@ -103,7 +103,7 @@ read( Buf ) -> case io:get_line( "" ) of eof -> {ctl, quit}; S -> - T = Buf++S + T = Buf++S, {ok, TokenLst, _} = cf_prescan:string( T ), case TokenLst of [] -> From e0620ac65272a51c54c01465caf0cf699dae016d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Tue, 22 Mar 2016 09:03:27 +0100 Subject: [PATCH 54/78] Take on command line interface. --- Makefile | 3 ++- rebar.config | 5 +++- src/cf_shell.erl | 70 ++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 71 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 9d3384b..3e4c0e6 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,8 @@ all: rebar3 escriptize dev: - rebar3 do escriptize, eunit, dialyzer, cover + git pull + rebar3 do upgrade, escriptize, eunit, dialyzer, cover clean: rebar3 clean diff --git a/rebar.config b/rebar.config index 9d36f5c..af13cb0 100644 --- a/rebar.config +++ b/rebar.config @@ -2,6 +2,9 @@ {deps, [ {effi, "0.1.0", {git, "https://github.com/joergen7/effi.git", - {branch, "master"}}} + {branch, "master"}}}, + {getopt, "v0.8.2", + {git, "https://github.com/jcomellas/getopt.git", + {branch, "v0.8.2"}}} ]}. {escript_incl_apps, [getopt]}. \ No newline at end of file diff --git a/src/cf_shell.erl b/src/cf_shell.erl index 444412c..5a114cf 100644 --- a/src/cf_shell.erl +++ b/src/cf_shell.erl @@ -18,6 +18,7 @@ -module( cf_shell ). -author( "Jorgen Brandt " ). +-vsn( "2.2.0" ). %% ============================================================================= %% Function Exports @@ -34,8 +35,7 @@ %% Macro Definitions %% ============================================================================= --define( VSN, "2.2.0" ). --define( BUILD, "2016-03-17" ). +-define( BUILD, "2016-03-22" ). -define( RED( Str ), "\e[31m" ++ Str ++ "\e[0m" ). -define( BRED( Str ), "\e[1;31m" ++ Str ++ "\e[0m" ). @@ -167,11 +167,13 @@ format_result( StrLst ) -> io_lib:format( ?GRN( "~s" ), [lists:foldl( F, "", StrLst )] ). +-spec get_banner() -> iolist(). + get_banner() -> string:join( [" ___", " @@WB Cuneiform", - " @@E_____ "++?VSN++" "++?BUILD, + " @@E_____ "++get_vsn()++" "++?BUILD, " _g@@@@@WWWWWWL", " g@@#*`3@B "++?YLW( "Type " )++?BYLW( "help" )++?YLW( " for usage info." ), " @@P 3@B", @@ -179,6 +181,8 @@ get_banner() -> " \"W@@@WF3@B Code: "++?BLU( "https://github.com/joergen7/cuneiform" ) ], "\n" ). +-spec get_help() -> iolist(). + get_help() -> string:join( [?YLW( "help" )++" show this usage info", @@ -192,14 +196,70 @@ get_help() -> - +-spec format_out( [binary()] ) -> iolist(). format_out( Out ) -> [io_lib:format( "~s~n", [Line] ) || Line <- Out]. + + +-spec format_script( ActScript::iolist() ) -> iolist(). + format_script( ActScript ) -> {_, S} = lists:foldl( fun( Line, {N, S} ) -> {N+1, io_lib:format( "~s~4.B ~s~n", [S, N, Line] )} end, {1, []}, re:split( ActScript, "\n" ) ), - S. \ No newline at end of file + S. + + +-spec get_vsn() -> string(). + +get_vsn() -> + {vsn, Vsn} = lists:keyfind( vsn, 1, module_info( attributes ) ), + Vsn. + + +%% print_bibtex/0 +% +-spec print_bibtex() -> ok. + +print_bibtex() -> io:format( "~n~s~n~n", [get_bibtex()] ). + + +%% get_bibtex/0 +% +-spec get_bibtex() -> iolist(). + +get_bibtex() -> + string:join( ["@InProceedings{Brandt2015,", + " Title = {Cuneiform: A Functional Language for Large Scale Scientific Data Analysis},", + " Author = {Brandt, J{\"o}rgen and Bux, Marc and Leser, Ulf},", + " Booktitle = {Proceedings of the Workshops of the EDBT/ICDT},", + " Year = {2015},", + " Address = {Brussels, Belgium},", + " Month = {March},", + " Pages = {17--26},", + " Volume = {1330},", + " Abstract = {The need to analyze massive scientific data sets on the one hand and the availability of distributed compute resources with an increasing number of CPU cores on the other hand have promoted the development of a variety of languages and systems for parallel, distributed data analysis. Among them are data-parallel query languages such as Pig Latin or Spark as well as scientific workflow languages such as Swift or Pegasus DAX. While data-parallel query languages focus on the exploitation of data parallelism, scientific workflow languages focus on the integration of external tools and libraries. However, a language that combines easy integration of arbitrary tools, treated as black boxes, with the ability to fully exploit data parallelism does not exist yet. Here, we present Cuneiform, a novel language for large-scale scientific data analysis. We highlight its functionality with respect to a set of desirable features for such languages, introduce its syntax and semantics by example, and show its flexibility and conciseness with use cases, including a complex real-life workflow from the area of genome research. Cuneiform scripts are executed dynamically on the workflow execution platform Hi-WAY which is based on Hadoop YARN. The language Cuneiform, including tool support for programming, workflow visualization, debugging, logging, and provenance-tracing, and the parallel execution engine Hi-WAY are fully implemented.},", + " Doi = {10.13140/RG.2.1.3547.6561},", + " Url = {http://ceur-ws.org/Vol-1330/paper-03.pdf}", + "}"], "\n" ). + +%% print_usage/0 +% +-spec print_usage() -> ok. + +print_usage() -> getopt:usage( get_optspec_lst(), "cuneiform", "" ). + + +%% opt_spec_list/0 +% +-spec get_optspec_lst() -> [{atom(), char(), string(), undefined, string()}]. + +get_optspec_lst() -> + [ + {version, $v, "version", undefined, "Show Cuneiform version"}, + {help, $h, "help", undefined, "Show command line options"}, + {cite, $c, "cite", undefined, "Show Bibtex entry for citation"} + ]. \ No newline at end of file From 57d69a3cbebf0e82ecca53c9aa34ecbb8e4f9da7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Tue, 22 Mar 2016 10:25:57 +0100 Subject: [PATCH 55/78] Rebar dependency fixed. --- rebar.config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rebar.config b/rebar.config index af13cb0..bdfbaa6 100644 --- a/rebar.config +++ b/rebar.config @@ -3,8 +3,8 @@ {effi, "0.1.0", {git, "https://github.com/joergen7/effi.git", {branch, "master"}}}, - {getopt, "v0.8.2", + {getopt, "0.8.2", {git, "https://github.com/jcomellas/getopt.git", - {branch, "v0.8.2"}}} + {branch, "master"}}} ]}. {escript_incl_apps, [getopt]}. \ No newline at end of file From 70ab9f4b63b60948b9ce789339c87d1fb79b5910 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Tue, 22 Mar 2016 10:58:59 +0100 Subject: [PATCH 56/78] Command line interface improved. --- Makefile | 2 +- include/cuneiform.hrl | 8 ++++ src/cf_shell.erl | 93 +++++-------------------------------- src/cre.erl | 35 +++----------- src/cuneiform.erl | 104 ++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 128 insertions(+), 114 deletions(-) create mode 100644 include/cuneiform.hrl diff --git a/Makefile b/Makefile index 3e4c0e6..84ae778 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ all: dev: git pull - rebar3 do upgrade, escriptize, eunit, dialyzer, cover + rebar3 do upgrade, escriptize, eunit, dialyzer, cover, edoc clean: rebar3 clean diff --git a/include/cuneiform.hrl b/include/cuneiform.hrl new file mode 100644 index 0000000..62782f2 --- /dev/null +++ b/include/cuneiform.hrl @@ -0,0 +1,8 @@ +-define( BUILD, "2016-03-22" ). + +-define( RED( Str ), "\e[31m" ++ Str ++ "\e[0m" ). +-define( BRED( Str ), "\e[1;31m" ++ Str ++ "\e[0m" ). +-define( GRN( Str ), "\e[32m" ++ Str ++ "\e[0m" ). +-define( YLW( Str ), "\e[33m" ++ Str ++ "\e[0m" ). +-define( BYLW( Str ), "\e[1;33m" ++ Str ++ "\e[0m" ). +-define( BLU( Str ), "\e[1;34m" ++ Str ++ "\e[0m" ). diff --git a/src/cf_shell.erl b/src/cf_shell.erl index 5a114cf..0c90881 100644 --- a/src/cf_shell.erl +++ b/src/cf_shell.erl @@ -18,43 +18,39 @@ -module( cf_shell ). -author( "Jorgen Brandt " ). --vsn( "2.2.0" ). %% ============================================================================= %% Function Exports %% ============================================================================= --export( [start/0] ). +-export( [server/1] ). %% ============================================================================= -%% Type Definitions +%% Includes %% ============================================================================= +-include( "cuneiform.hrl" ). %% ============================================================================= %% Macro Definitions %% ============================================================================= --define( BUILD, "2016-03-22" ). - --define( RED( Str ), "\e[31m" ++ Str ++ "\e[0m" ). --define( BRED( Str ), "\e[1;31m" ++ Str ++ "\e[0m" ). --define( GRN( Str ), "\e[32m" ++ Str ++ "\e[0m" ). --define( YLW( Str ), "\e[33m" ++ Str ++ "\e[0m" ). --define( BYLW( Str ), "\e[1;33m" ++ Str ++ "\e[0m" ). --define( BLU( Str ), "\e[1;34m" ++ Str ++ "\e[0m" ). - -define( PROMPT, "> " ). %% ============================================================================= %% Internal Functions %% ============================================================================= +-spec server( Cwd::string() ) -> ok. + +server( Cwd ) -> + io:format( "~s~n~n~n", [cuneiform:get_banner()] ), + server_loop( #{}, #{}, Cwd ). -start() -> - process_flag( trap_exit, true ), - io:format( "~s~n~n~n", [get_banner()] ), - server_loop( #{}, #{}, "." ). +-spec server_loop( Rho, Gamma, Cwd ) -> ok +when Rho :: #{string() => [cuneiform:expr()]}, + Gamma :: #{string() => fun()}, + Cwd :: string(). server_loop( Rho, Gamma, Cwd ) -> case read_expression( ?PROMPT ) of @@ -166,21 +162,6 @@ format_result( StrLst ) -> end, io_lib:format( ?GRN( "~s" ), [lists:foldl( F, "", StrLst )] ). - --spec get_banner() -> iolist(). - -get_banner() -> - string:join( - [" ___", - " @@WB Cuneiform", - " @@E_____ "++get_vsn()++" "++?BUILD, - " _g@@@@@WWWWWWL", - " g@@#*`3@B "++?YLW( "Type " )++?BYLW( "help" )++?YLW( " for usage info." ), - " @@P 3@B", - " @N____ 3@B Docs: "++?BLU( "http://www.cuneiform-lang.org" ), - " \"W@@@WF3@B Code: "++?BLU( "https://github.com/joergen7/cuneiform" ) - ], "\n" ). - -spec get_help() -> iolist(). get_help() -> @@ -213,53 +194,3 @@ format_script( ActScript ) -> S. --spec get_vsn() -> string(). - -get_vsn() -> - {vsn, Vsn} = lists:keyfind( vsn, 1, module_info( attributes ) ), - Vsn. - - -%% print_bibtex/0 -% --spec print_bibtex() -> ok. - -print_bibtex() -> io:format( "~n~s~n~n", [get_bibtex()] ). - - -%% get_bibtex/0 -% --spec get_bibtex() -> iolist(). - -get_bibtex() -> - string:join( ["@InProceedings{Brandt2015,", - " Title = {Cuneiform: A Functional Language for Large Scale Scientific Data Analysis},", - " Author = {Brandt, J{\"o}rgen and Bux, Marc and Leser, Ulf},", - " Booktitle = {Proceedings of the Workshops of the EDBT/ICDT},", - " Year = {2015},", - " Address = {Brussels, Belgium},", - " Month = {March},", - " Pages = {17--26},", - " Volume = {1330},", - " Abstract = {The need to analyze massive scientific data sets on the one hand and the availability of distributed compute resources with an increasing number of CPU cores on the other hand have promoted the development of a variety of languages and systems for parallel, distributed data analysis. Among them are data-parallel query languages such as Pig Latin or Spark as well as scientific workflow languages such as Swift or Pegasus DAX. While data-parallel query languages focus on the exploitation of data parallelism, scientific workflow languages focus on the integration of external tools and libraries. However, a language that combines easy integration of arbitrary tools, treated as black boxes, with the ability to fully exploit data parallelism does not exist yet. Here, we present Cuneiform, a novel language for large-scale scientific data analysis. We highlight its functionality with respect to a set of desirable features for such languages, introduce its syntax and semantics by example, and show its flexibility and conciseness with use cases, including a complex real-life workflow from the area of genome research. Cuneiform scripts are executed dynamically on the workflow execution platform Hi-WAY which is based on Hadoop YARN. The language Cuneiform, including tool support for programming, workflow visualization, debugging, logging, and provenance-tracing, and the parallel execution engine Hi-WAY are fully implemented.},", - " Doi = {10.13140/RG.2.1.3547.6561},", - " Url = {http://ceur-ws.org/Vol-1330/paper-03.pdf}", - "}"], "\n" ). - -%% print_usage/0 -% --spec print_usage() -> ok. - -print_usage() -> getopt:usage( get_optspec_lst(), "cuneiform", "" ). - - -%% opt_spec_list/0 -% --spec get_optspec_lst() -> [{atom(), char(), string(), undefined, string()}]. - -get_optspec_lst() -> - [ - {version, $v, "version", undefined, "Show Cuneiform version"}, - {help, $h, "help", undefined, "Show command line options"}, - {cite, $c, "cite", undefined, "Show Bibtex entry for citation"} - ]. \ No newline at end of file diff --git a/src/cre.erl b/src/cre.erl index 203b6f2..5ce2941 100644 --- a/src/cre.erl +++ b/src/cre.erl @@ -56,8 +56,8 @@ -callback init() -> {ok, State::term()}. -callback handle_submit( Lam, Fa, R, DataDir, ModState ) -> ok -when Lam :: lam(), - Fa :: #{string() => [str()]}, +when Lam :: cuneiform:lam(), + Fa :: #{string() => [cuneiform:str()]}, R :: pos_integer(), DataDir :: string(), ModState :: term(). @@ -66,28 +66,7 @@ when Lam :: lam(), %% Type Definitions %% ============================================================================= --type str() :: {str, S::string()}. - --type lam() :: {lam, LamLine::pos_integer(), Name::string(), - S::sign(), B::forbody()}. - --type sign() :: {sign, Lo::[param()], Li::[param()]}. - --type param() :: {param, M::name(), Pl::boolean()}. - --type name() :: {name, N::string(), Pf::boolean()}. - --type forbody() :: {forbody, L::lang(), S::string()}. - --type lang() :: bash | python | r. - --type fut() :: {fut, LamName::string(), R::pos_integer(), - Lo::[param()]}. - --type app() :: {app, AppLine::pos_integer(), C::pos_integer(), - Lambda::lam(), Fa::#{string() => [str()]}}. - --type ckey() :: {lam(), #{string() => [str()]}, string()}. +-type ckey() :: {cuneiform:lam(), #{string() => [cuneiform:str()]}, string()}. -type response() :: {failed, pos_integer(), atom(), term()} | {finished, #{atom() => term()}}. @@ -95,11 +74,11 @@ when Lam :: lam(), -type cre_state() :: {Mod::atom(), SubscrMap::#{pos_integer() => sets:set( pid() )}, ReplyMap::#{pos_integer() => response()}, - Cache::#{ckey() => fut()}, + Cache::#{ckey() => cuneiform:fut()}, R::pos_integer(), ModState::term()}. --type submit() :: {submit, app(), string()}. +-type submit() :: {submit, cuneiform:app(), string()}. %% ============================================================================= %% Generic Server Functions @@ -140,7 +119,7 @@ init( [] ) -> %% If the future is served from the cache and a reply has already been %% received, the subscriber is immediately notified. %% --spec handle_call( Request, From, State ) -> {reply, fut(), cre_state()} +-spec handle_call( Request, From, State ) -> {reply, cuneiform:fut(), cre_state()} when Request :: submit(), From :: {pid(), term()}, State :: cre_state(). @@ -236,7 +215,7 @@ start_link() -> gen_server:start_link( {local, ?MODULE}, ?MODULE, [], [] ). --spec submit( App::app(), DataDir::string() ) -> fut(). +-spec submit( App::cuneiform:app(), DataDir::string() ) -> cuneiform:fut(). submit( App, DataDir ) -> gen_server:call( ?MODULE, {submit, App, DataDir} ). diff --git a/src/cuneiform.erl b/src/cuneiform.erl index 2ae136b..61409da 100644 --- a/src/cuneiform.erl +++ b/src/cuneiform.erl @@ -18,17 +18,40 @@ -module( cuneiform ). -author( "Jorgen Brandt " ). +-vsn( "2.2.0" ). % API --export( [main/1, start/0, string/2, file/1, file/2, reduce/4] ). +-export( [main/1, start/0, string/2, file/1, file/2, reduce/4, get_banner/0] ). + + +-include( "cuneiform.hrl" ). %% ============================================================================= %% API functions %% ============================================================================= -main( _ ) -> - start(), - cf_shell:start(). +main( CmdLine ) -> + + case getopt:parse( get_optspec_lst(), CmdLine ) of + {error, {Reason, Data}} -> error( {Reason, Data} ); + {ok, {OptLst, _NonOptLst}} -> + case lists:member( version, OptLst ) of + true -> print_vsn(); + false -> + case lists:member( help, OptLst ) of + true -> + print_usage(); + false -> + case lists:member( cite, OptLst ) of + true -> print_bibtex(); + false -> + {workdir, WorkDir} = lists:keyfind( workdir, 1, OptLst ), + start(), + cf_shell:server( WorkDir ) + end + end + end + end. start() -> application:start( cuneiform ). @@ -127,3 +150,76 @@ find_select( R, {app, _AppLine, _C, _Lambda, Fa} ) -> find_select( _, _ ) -> []. + + +%% opt_spec_list/0 +% +-spec get_optspec_lst() -> [{atom(), char(), string(), undefined, string()}]. + +get_optspec_lst() -> + [ + {version, $v, "version", undefined, "Show Cuneiform version"}, + {help, $h, "help", undefined, "Show command line options"}, + {cite, $c, "cite", undefined, "Show Bibtex entry for citation"}, + {workdir, $w, "workdir", {string, "."}, "Working directory"} + ]. + +-spec get_vsn() -> string(). + +get_vsn() -> + {vsn, Vsn} = lists:keyfind( vsn, 1, module_info( attributes ) ), + Vsn. + + +%% print_bibtex/0 +% +-spec print_bibtex() -> ok. + +print_bibtex() -> io:format( "~n~s~n~n", [get_bibtex()] ). + + +%% get_bibtex/0 +% +-spec get_bibtex() -> iolist(). + +get_bibtex() -> + string:join( ["@InProceedings{Brandt2015,", + " Title = {Cuneiform: A Functional Language for Large Scale Scientific Data Analysis},", + " Author = {Brandt, J{\"o}rgen and Bux, Marc and Leser, Ulf},", + " Booktitle = {Proceedings of the Workshops of the EDBT/ICDT},", + " Year = {2015},", + " Address = {Brussels, Belgium},", + " Month = {March},", + " Pages = {17--26},", + " Volume = {1330},", + " Abstract = {The need to analyze massive scientific data sets on the one hand and the availability of distributed compute resources with an increasing number of CPU cores on the other hand have promoted the development of a variety of languages and systems for parallel, distributed data analysis. Among them are data-parallel query languages such as Pig Latin or Spark as well as scientific workflow languages such as Swift or Pegasus DAX. While data-parallel query languages focus on the exploitation of data parallelism, scientific workflow languages focus on the integration of external tools and libraries. However, a language that combines easy integration of arbitrary tools, treated as black boxes, with the ability to fully exploit data parallelism does not exist yet. Here, we present Cuneiform, a novel language for large-scale scientific data analysis. We highlight its functionality with respect to a set of desirable features for such languages, introduce its syntax and semantics by example, and show its flexibility and conciseness with use cases, including a complex real-life workflow from the area of genome research. Cuneiform scripts are executed dynamically on the workflow execution platform Hi-WAY which is based on Hadoop YARN. The language Cuneiform, including tool support for programming, workflow visualization, debugging, logging, and provenance-tracing, and the parallel execution engine Hi-WAY are fully implemented.},", + " Doi = {10.13140/RG.2.1.3547.6561},", + " Url = {http://ceur-ws.org/Vol-1330/paper-03.pdf}", + "}"], "\n" ). + +%% print_usage/0 +% +-spec print_usage() -> ok. + +print_usage() -> getopt:usage( get_optspec_lst(), "cuneiform", "[scriptfile]" ). + + +%% print_vsn/0 +% +-spec print_vsn() -> ok. + +print_vsn() -> io:format( "~s~n", [get_vsn()] ). + +-spec get_banner() -> iolist(). + +get_banner() -> + string:join( + [" ___", + " @@WB Cuneiform", + " @@E_____ "++get_vsn()++" "++?BUILD, + " _g@@@@@WWWWWWL", + " g@@#*`3@B "++?YLW( "Type " )++?BYLW( "help" )++?YLW( " for usage info." ), + " @@P 3@B", + " @N____ 3@B Docs: "++?BLU( "http://www.cuneiform-lang.org" ), + " \"W@@@WF3@B Code: "++?BLU( "https://github.com/joergen7/cuneiform" ) + ], "\n" ). From 37aa2eea683fb0acdaac1eb89d40112134f95bdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Tue, 22 Mar 2016 12:05:38 +0100 Subject: [PATCH 57/78] Main function extended. --- src/{cre.erl => cf_cre.erl} | 16 ++--- src/cf_parse.yrl | 11 +++- src/cf_shell.erl | 56 +++++------------ src/cuneiform.erl | 120 +++++++++++++++++++++++------------- src/cuneiform_sup.erl | 2 +- src/local.erl | 2 +- 6 files changed, 114 insertions(+), 93 deletions(-) rename src/{cre.erl => cf_cre.erl} (93%) diff --git a/src/cre.erl b/src/cf_cre.erl similarity index 93% rename from src/cre.erl rename to src/cf_cre.erl index 5ce2941..7bbcb52 100644 --- a/src/cre.erl +++ b/src/cf_cre.erl @@ -27,7 +27,7 @@ %% +-----+''' --module( cre ). +-module( cf_cre ). -author( "Jorgen Brandt " ). -behaviour( gen_server ). @@ -56,8 +56,8 @@ -callback init() -> {ok, State::term()}. -callback handle_submit( Lam, Fa, R, DataDir, ModState ) -> ok -when Lam :: cuneiform:lam(), - Fa :: #{string() => [cuneiform:str()]}, +when Lam :: cf_sem:lam(), + Fa :: #{string() => [cf_sem:str()]}, R :: pos_integer(), DataDir :: string(), ModState :: term(). @@ -66,7 +66,7 @@ when Lam :: cuneiform:lam(), %% Type Definitions %% ============================================================================= --type ckey() :: {cuneiform:lam(), #{string() => [cuneiform:str()]}, string()}. +-type ckey() :: {cf_sem:lam(), #{string() => [cf_sem:str()]}, string()}. -type response() :: {failed, pos_integer(), atom(), term()} | {finished, #{atom() => term()}}. @@ -74,11 +74,11 @@ when Lam :: cuneiform:lam(), -type cre_state() :: {Mod::atom(), SubscrMap::#{pos_integer() => sets:set( pid() )}, ReplyMap::#{pos_integer() => response()}, - Cache::#{ckey() => cuneiform:fut()}, + Cache::#{ckey() => cf_sem:fut()}, R::pos_integer(), ModState::term()}. --type submit() :: {submit, cuneiform:app(), string()}. +-type submit() :: {submit, cf_sem:app(), string()}. %% ============================================================================= %% Generic Server Functions @@ -119,7 +119,7 @@ init( [] ) -> %% If the future is served from the cache and a reply has already been %% received, the subscriber is immediately notified. %% --spec handle_call( Request, From, State ) -> {reply, cuneiform:fut(), cre_state()} +-spec handle_call( Request, From, State ) -> {reply, cf_sem:fut(), cre_state()} when Request :: submit(), From :: {pid(), term()}, State :: cre_state(). @@ -215,7 +215,7 @@ start_link() -> gen_server:start_link( {local, ?MODULE}, ?MODULE, [], [] ). --spec submit( App::cuneiform:app(), DataDir::string() ) -> cuneiform:fut(). +-spec submit( App::cf_sem:app(), DataDir::string() ) -> cf_sem:fut(). submit( App, DataDir ) -> gen_server:call( ?MODULE, {submit, App, DataDir} ). diff --git a/src/cf_parse.yrl b/src/cf_parse.yrl index 20d16fc..1f7f9ac 100644 --- a/src/cf_parse.yrl +++ b/src/cf_parse.yrl @@ -112,7 +112,7 @@ Erlang code. -author( "Jorgen Brandt " ). --export( [string/1] ). +-export( [string/1, file/1] ). -ifdef( TEST ). -include_lib( "eunit/include/eunit.hrl" ). @@ -129,6 +129,15 @@ string( S ) -> end end. +file( Filename ) -> + case file:read_file( Filename ) of + {error, Reason} -> {error, Reason}; + {ok, B} -> + S = binary_to_list( B ), + string( S ) + end. + + combine( {Target1, Rho1, Global1}, {Target2, Rho2, Global2} ) -> case Target1 of diff --git a/src/cf_shell.erl b/src/cf_shell.erl index 0c90881..2710905 100644 --- a/src/cf_shell.erl +++ b/src/cf_shell.erl @@ -44,7 +44,7 @@ -spec server( Cwd::string() ) -> ok. server( Cwd ) -> - io:format( "~s~n~n~n", [cuneiform:get_banner()] ), + io:format( "~s~n~n~n", [get_banner()] ), server_loop( #{}, #{}, Cwd ). -spec server_loop( Rho, Gamma, Cwd ) -> ok @@ -73,7 +73,7 @@ server_loop( Rho, Gamma, Cwd ) -> io:format( "~p~n", [Gamma] ), server_loop( Rho, Gamma, Cwd ); {error, ErrorInfo} -> - S = format_error( ErrorInfo ), + S = cuneiform:format_error( ErrorInfo ), io:format( "~s~n", [S] ), server_loop( Rho, Gamma, Cwd ); {ok, {Query, DRho, DGamma}} -> @@ -83,9 +83,9 @@ server_loop( Rho, Gamma, Cwd ) -> undef -> server_loop( Rho1, Gamma1, Cwd ); _ -> try cuneiform:reduce( Query, Rho, Gamma, "." ) of - X -> io:format( "~s~n", [format_result( X )] ) + X -> io:format( "~s~n", [cuneiform:format_result( X )] ) catch - throw:T -> io:format( "~s~n", [format_error( T )] ) + throw:T -> io:format( "~s~n", [cuneiform:format_error( T )] ) end, server_loop( Rho, Gamma, Cwd ) end @@ -134,33 +134,7 @@ is_open( TokenLst ) -> NClose2 = length( [rmmecb || rmmecb <- TokenLst] ), NOpen1 > NClose1 orelse NOpen2 > NClose2. -format_error( {Line, cf_scan, {illegal, Token}} ) -> - io_lib:format( ?RED( "Line ~p: " )++?BRED( "illegal token ~s" ), [Line, Token] ); -format_error( {Line, cf_parse, S} ) -> - io_lib:format( ?RED( "Line ~p: " )++?BRED( "~s" ), [Line, S] ); - -format_error( {Line, cf_sem, S} ) -> - io_lib:format( ?RED( "Line ~p: " )++?BRED( "~s" ), [Line, S] ); - -format_error( {AppLine, cuneiform, {script_error, LamName, R, {ActScript, Out}}} ) -> - io_lib:format( - ?BYLW( "[out]~n" )++?YLW( "~s~n" ) - ++?BYLW( "[script]~n" )++?YLW( "~s~n" ) - ++?RED( "Line ~p: " )++?BRED( "script error in call to ~s (~p)" ), - [format_out( Out ), format_script( ActScript ), AppLine, LamName, R] ); - -format_error( {AppLine, cuneiform, {precond, LamName, R, MissingLst}} ) -> - io_lib:format( ?RED( "Line ~p: " )++?BRED( "precondition not met in call to ~s (~p)~n" )++?RED( "Missing files: ~p" ), [AppLine, LamName, R, MissingLst] ); - -format_error( ErrorInfo ) -> - io_lib:format( ?RED( "Error: " )++?BRED( "~p" ), [ErrorInfo] ). - -format_result( StrLst ) -> - F = fun( {str, S}, AccIn ) -> - io_lib:format( "~s\"~s\" ", [AccIn, S] ) - end, - io_lib:format( ?GRN( "~s" ), [lists:foldl( F, "", StrLst )] ). -spec get_help() -> iolist(). @@ -177,20 +151,22 @@ get_help() -> --spec format_out( [binary()] ) -> iolist(). -format_out( Out ) -> - [io_lib:format( "~s~n", [Line] ) || Line <- Out]. --spec format_script( ActScript::iolist() ) -> iolist(). +-spec get_banner() -> iolist(). -format_script( ActScript ) -> - {_, S} = lists:foldl( fun( Line, {N, S} ) -> - {N+1, io_lib:format( "~s~4.B ~s~n", [S, N, Line] )} - end, - {1, []}, re:split( ActScript, "\n" ) ), - S. +get_banner() -> + string:join( + [" ___", + " @@WB Cuneiform", + " @@E_____ "++cuneiform:get_vsn()++" "++?BUILD, + " _g@@@@@WWWWWWL", + " g@@#*`3@B "++?YLW( "Type " )++?BYLW( "help" )++?YLW( " for usage info." ), + " @@P 3@B", + " @N____ 3@B Docs: "++?BLU( "http://www.cuneiform-lang.org" ), + " \"W@@@WF3@B Code: "++?BLU( "https://github.com/joergen7/cuneiform" ) + ], "\n" ). diff --git a/src/cuneiform.erl b/src/cuneiform.erl index 61409da..bb84f1c 100644 --- a/src/cuneiform.erl +++ b/src/cuneiform.erl @@ -21,7 +21,7 @@ -vsn( "2.2.0" ). % API --export( [main/1, start/0, string/2, file/1, file/2, reduce/4, get_banner/0] ). +-export( [main/1, file/2, start/0, reduce/4, get_vsn/0, format_result/1, format_error/1] ). -include( "cuneiform.hrl" ). @@ -31,47 +31,47 @@ %% ============================================================================= main( CmdLine ) -> - case getopt:parse( get_optspec_lst(), CmdLine ) of {error, {Reason, Data}} -> error( {Reason, Data} ); - {ok, {OptLst, _NonOptLst}} -> + {ok, {OptLst, NonOptLst}} -> case lists:member( version, OptLst ) of true -> print_vsn(); false -> case lists:member( help, OptLst ) of - true -> - print_usage(); + true -> print_usage(); false -> case lists:member( cite, OptLst ) of - true -> print_bibtex(); + true -> print_bibtex(); false -> - {workdir, WorkDir} = lists:keyfind( workdir, 1, OptLst ), + {workdir, Cwd} = lists:keyfind( workdir, 1, OptLst ), + {nthread, _NSlot} = lists:keyfind( nthread, 1, OptLst ), start(), - cf_shell:server( WorkDir ) + case NonOptLst of + [] -> cf_shell:server( Cwd ); + [File] -> file( File, Cwd ) + end end end end end. -start() -> - application:start( cuneiform ). - --spec string( S::string(), DataDir::string() ) -> [cf_sem:str()]. - -string( S, DataDir ) -> - {ok, {Query, Rho, Gamma}} = cf_parse:string( S ), - reduce( Query, Rho, Gamma, DataDir ). --spec file( Filename::string() ) -> [cf_sem:str()]. +file( File, Cwd ) -> + case cf_parse:file( File ) of + {error, ErrorInfo} -> + io:format( "~s", [format_error( ErrorInfo )] ); + {ok, {Query, Rho, Gamma}} -> + try cuneiform:reduce( Query, Rho, Gamma, Cwd ) of + X -> io:format( "~s~n", [format_result( X )] ) + catch + throw:T -> io:format( "~s~n", [format_error( T )] ) + end + end. -file( Filename ) -> file( Filename, "." ). --spec file( Filename::string(), DataDir::string() ) -> [cf_sem:str()]. +start() -> + application:start( cuneiform ). -file( Filename, DataDir ) -> - {ok, B} = file:read_file( Filename ), - S = binary_to_list( B ), - string( S, DataDir ). @@ -88,7 +88,7 @@ when X0 :: [cf_sem:expr()], DataDir :: string(). reduce( X0, Rho, Gamma, DataDir ) -> - Mu = fun( A ) -> cre:submit( A, DataDir ) end, + Mu = fun( A ) -> cf_cre:submit( A, DataDir ) end, reduce( X0, {Rho, Mu, Gamma, #{}}, DataDir ). -spec reduce( X0, Theta, DataDir ) -> [cf_sem:str()] @@ -157,11 +157,13 @@ find_select( _, _ ) -> -spec get_optspec_lst() -> [{atom(), char(), string(), undefined, string()}]. get_optspec_lst() -> + NSlot = erlang:system_info( logical_processors_available ), [ - {version, $v, "version", undefined, "Show Cuneiform version"}, - {help, $h, "help", undefined, "Show command line options"}, - {cite, $c, "cite", undefined, "Show Bibtex entry for citation"}, - {workdir, $w, "workdir", {string, "."}, "Working directory"} + {version, $v, "version", undefined, "show Cuneiform version"}, + {help, $h, "help", undefined, "show command line options"}, + {cite, $c, "cite", undefined, "show Bibtex entry for citation"}, + {workdir, $w, "workdir", {string, "."}, "working directory"}, + {nslot, $t, "nthread", {pos_integer, NSlot}, "number of threads in local mode"} ]. -spec get_vsn() -> string(). @@ -201,7 +203,7 @@ get_bibtex() -> % -spec print_usage() -> ok. -print_usage() -> getopt:usage( get_optspec_lst(), "cuneiform", "[scriptfile]" ). +print_usage() -> getopt:usage( get_optspec_lst(), "cuneiform", "[]" ). %% print_vsn/0 @@ -210,16 +212,50 @@ print_usage() -> getopt:usage( get_optspec_lst(), "cuneiform", "[scriptfile]" ). print_vsn() -> io:format( "~s~n", [get_vsn()] ). --spec get_banner() -> iolist(). - -get_banner() -> - string:join( - [" ___", - " @@WB Cuneiform", - " @@E_____ "++get_vsn()++" "++?BUILD, - " _g@@@@@WWWWWWL", - " g@@#*`3@B "++?YLW( "Type " )++?BYLW( "help" )++?YLW( " for usage info." ), - " @@P 3@B", - " @N____ 3@B Docs: "++?BLU( "http://www.cuneiform-lang.org" ), - " \"W@@@WF3@B Code: "++?BLU( "https://github.com/joergen7/cuneiform" ) - ], "\n" ). +-spec format_result( StrLst::[cf_sem:str()] ) -> iolist(). + +format_result( StrLst ) -> + F = fun( {str, S}, AccIn ) -> + io_lib:format( "~s\"~s\" ", [AccIn, S] ) + end, + io_lib:format( ?GRN( "~s" ), [lists:foldl( F, "", StrLst )] ). + + +-spec format_out( [binary()] ) -> iolist(). + +format_out( Out ) -> + [io_lib:format( "~s~n", [Line] ) || Line <- Out]. + + + +-spec format_script( ActScript::iolist() ) -> iolist(). + +format_script( ActScript ) -> + {_, S} = lists:foldl( fun( Line, {N, S} ) -> + {N+1, io_lib:format( "~s~4.B ~s~n", [S, N, Line] )} + end, + {1, []}, re:split( ActScript, "\n" ) ), + S. + + +format_error( {Line, cf_scan, {illegal, Token}} ) -> + io_lib:format( ?RED( "Line ~p: " )++?BRED( "illegal token ~s" ), [Line, Token] ); + +format_error( {Line, cf_parse, S} ) -> + io_lib:format( ?RED( "Line ~p: " )++?BRED( "~s" ), [Line, S] ); + +format_error( {Line, cf_sem, S} ) -> + io_lib:format( ?RED( "Line ~p: " )++?BRED( "~s" ), [Line, S] ); + +format_error( {AppLine, cuneiform, {script_error, LamName, R, {ActScript, Out}}} ) -> + io_lib:format( + ?BYLW( "[out]~n" )++?YLW( "~s~n" ) + ++?BYLW( "[script]~n" )++?YLW( "~s~n" ) + ++?RED( "Line ~p: " )++?BRED( "script error in call to ~s (~p)" ), + [format_out( Out ), format_script( ActScript ), AppLine, LamName, R] ); + +format_error( {AppLine, cuneiform, {precond, LamName, R, MissingLst}} ) -> + io_lib:format( ?RED( "Line ~p: " )++?BRED( "precondition not met in call to ~s (~p)~n" )++?RED( "Missing files: ~p" ), [AppLine, LamName, R, MissingLst] ); + +format_error( ErrorInfo ) -> + io_lib:format( ?RED( "Error: " )++?BRED( "~p" ), [ErrorInfo] ). \ No newline at end of file diff --git a/src/cuneiform_sup.erl b/src/cuneiform_sup.erl index 0d72df3..d04933a 100644 --- a/src/cuneiform_sup.erl +++ b/src/cuneiform_sup.erl @@ -49,7 +49,7 @@ init( [] ) -> Restart = temporary, Shutdown = 2000, Type = worker, - Cre = {cre, {cre, start_link, []}, Restart, Shutdown, Type, [cre]}, + Cre = {cre, {cf_cre, start_link, []}, Restart, Shutdown, Type, [cf_cre]}, {ok, {SupFlags, [Cre]}}. diff --git a/src/local.erl b/src/local.erl index b89837d..5341dee 100644 --- a/src/local.erl +++ b/src/local.erl @@ -19,7 +19,7 @@ -module( local ). -author( "Jorgen Brandt " ). --behaviour( cre ). +-behaviour( cf_cre ). -export( [init/0, handle_submit/5, stage/4] ). -define( BASEDIR, "/tmp/cf" ). From 87067fd08845c71b8a750dd2d9d5ad65e1698010 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Tue, 22 Mar 2016 15:04:27 +0100 Subject: [PATCH 58/78] Number of threads can be specified in command line. --- src/cuneiform.erl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cuneiform.erl b/src/cuneiform.erl index bb84f1c..155e721 100644 --- a/src/cuneiform.erl +++ b/src/cuneiform.erl @@ -30,6 +30,8 @@ %% API functions %% ============================================================================= +-spec main( CmdLine::list() ) -> ok. + main( CmdLine ) -> case getopt:parse( get_optspec_lst(), CmdLine ) of {error, {Reason, Data}} -> error( {Reason, Data} ); @@ -55,6 +57,7 @@ main( CmdLine ) -> end end. +-spec file( File::string(), Cwd::string() ) -> ok. file( File, Cwd ) -> case cf_parse:file( File ) of @@ -163,7 +166,7 @@ get_optspec_lst() -> {help, $h, "help", undefined, "show command line options"}, {cite, $c, "cite", undefined, "show Bibtex entry for citation"}, {workdir, $w, "workdir", {string, "."}, "working directory"}, - {nslot, $t, "nthread", {pos_integer, NSlot}, "number of threads in local mode"} + {nthread, $t, "nthread", {pos_integer, NSlot}, "number of threads in local mode"} ]. -spec get_vsn() -> string(). From 3a4d37cd2917e37086f4fd97b9d2f50ddbf612b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Tue, 22 Mar 2016 19:00:48 +0100 Subject: [PATCH 59/78] Application layout altered. --- rebar.config | 2 +- src/cf_cre.erl | 23 ++++++++++++----------- src/{cuneiform_sup.erl => cf_sup.erl} | 13 +++++++++---- src/cuneiform.app.src | 5 +++-- src/cuneiform.erl | 22 +++++++++++++--------- src/cuneiform_app.erl | 11 +++-------- src/gen_queue.erl | 8 +------- src/local.erl | 8 ++++---- 8 files changed, 46 insertions(+), 46 deletions(-) rename src/{cuneiform_sup.erl => cf_sup.erl} (86%) diff --git a/rebar.config b/rebar.config index bdfbaa6..ec92c57 100644 --- a/rebar.config +++ b/rebar.config @@ -7,4 +7,4 @@ {git, "https://github.com/jcomellas/getopt.git", {branch, "master"}}} ]}. -{escript_incl_apps, [getopt]}. \ No newline at end of file +{escript_incl_apps, [getopt]}. diff --git a/src/cf_cre.erl b/src/cf_cre.erl index 7bbcb52..67e7f7d 100644 --- a/src/cf_cre.erl +++ b/src/cf_cre.erl @@ -35,7 +35,7 @@ %% Function Exports %% ============================================================================= --export( [start_link/0, submit/2] ). +-export( [start_link/2, submit/2] ). -export( [code_change/3, handle_cast/2, handle_info/2, init/1, terminate/2, handle_call/3] ). @@ -53,7 +53,7 @@ %% ============================================================================= --callback init() -> {ok, State::term()}. +-callback init( Arg::term() ) -> {ok, State::term()}. -callback handle_submit( Lam, Fa, R, DataDir, ModState ) -> ok when Lam :: cf_sem:lam(), @@ -90,17 +90,16 @@ terminate( _Reason, _State ) -> ok. %% @doc Generates the initial state of the CRE. --spec init( [] ) -> {ok, cre_state()}. +-spec init( {Mod::atom(), ModArg::term()} ) -> {ok, cre_state()}. -init( [] ) -> - Mod = local, % CRE callback module implementing the stage function +init( {Mod, ModArg} ) -> SubscrMap = #{}, % mapping of a future to a set of subscriber pids ReplyMap = #{}, % mapping of a future to a response Cache = #{}, % cache mapping a cache key to a future R = 1, % next id % initialize CRE - {ok, ModState} = apply( Mod, init, [] ), + {ok, ModState} = apply( Mod, init, [ModArg] ), {ok, {Mod, SubscrMap, ReplyMap, Cache, R, ModState}}. @@ -208,17 +207,19 @@ handle_info( Info={finished, Sum}, {Mod, SubscrMap, ReplyMap, Cache, R, ModState %% API Functions %% ============================================================================= --spec start_link() -> {ok, pid()} | ignore | {error, Error} -when Error :: {already_started, pid()} | term(). +-spec start_link( Mod, ModArg ) -> {ok, pid()} | ignore | {error, Error} +when Mod :: atom(), + ModArg :: term(), + Error :: {already_started, pid()} | term(). -start_link() -> - gen_server:start_link( {local, ?MODULE}, ?MODULE, [], [] ). +start_link( Mod, ModArg ) -> + gen_server:start_link( {local, cre}, ?MODULE, {Mod, ModArg}, [] ). -spec submit( App::cf_sem:app(), DataDir::string() ) -> cf_sem:fut(). submit( App, DataDir ) -> - gen_server:call( ?MODULE, {submit, App, DataDir} ). + gen_server:call( cre, {submit, App, DataDir} ). %% ============================================================================= %% Internal Functions diff --git a/src/cuneiform_sup.erl b/src/cf_sup.erl similarity index 86% rename from src/cuneiform_sup.erl rename to src/cf_sup.erl index d04933a..dbab61c 100644 --- a/src/cuneiform_sup.erl +++ b/src/cf_sup.erl @@ -16,13 +16,13 @@ % See the License for the specific language governing permissions and % limitations under the License. --module(cuneiform_sup). +-module( cf_sup ). -author( "Jorgen Brandt " ). -behaviour( supervisor ). %% API --export( [start_link/0] ). +-export( [start_link/0, start_cre/2] ). %% Supervisor callbacks -export([init/1]). @@ -46,10 +46,15 @@ init( [] ) -> MaxSecondsBetweenRestarts = 10, SupFlags = {RestartStrategy, MaxRestarts, MaxSecondsBetweenRestarts}, + + {ok, {SupFlags, []}}. + +start_cre( Mod, ModArg ) -> + Restart = temporary, Shutdown = 2000, Type = worker, - Cre = {cre, {cf_cre, start_link, []}, Restart, Shutdown, Type, [cf_cre]}, - {ok, {SupFlags, [Cre]}}. + Cre = {cre, {cf_cre, start_link, [Mod, ModArg]}, Restart, Shutdown, Type, [cf_cre]}, + supervisor:start_child( cf_sup, Cre ). \ No newline at end of file diff --git a/src/cuneiform.app.src b/src/cuneiform.app.src index c881681..a29be47 100644 --- a/src/cuneiform.app.src +++ b/src/cuneiform.app.src @@ -1,3 +1,4 @@ + {application, cuneiform, [ {description, "Cuneiform: A Functional Language for Large Scale Scientific Data Analysis"}, @@ -7,6 +8,6 @@ kernel, stdlib ]}, - {mod, { cuneiform_app, []}}, + {mod, {cuneiform_app, []}}, {env, []} - ]}. + ]}. \ No newline at end of file diff --git a/src/cuneiform.erl b/src/cuneiform.erl index 155e721..8c9ae01 100644 --- a/src/cuneiform.erl +++ b/src/cuneiform.erl @@ -21,7 +21,7 @@ -vsn( "2.2.0" ). % API --export( [main/1, file/2, start/0, reduce/4, get_vsn/0, format_result/1, format_error/1] ). +-export( [main/1, file/2, start/2, reduce/4, get_vsn/0, format_result/1, format_error/1] ). -include( "cuneiform.hrl" ). @@ -46,18 +46,21 @@ main( CmdLine ) -> true -> print_bibtex(); false -> {workdir, Cwd} = lists:keyfind( workdir, 1, OptLst ), - {nthread, _NSlot} = lists:keyfind( nthread, 1, OptLst ), - start(), + {nthread, NSlot} = lists:keyfind( nthread, 1, OptLst ), + {ok, CrePid} = start( local, NSlot ), + link( CrePid ), case NonOptLst of [] -> cf_shell:server( Cwd ); - [File] -> file( File, Cwd ) + [File] -> + Ret = file( File, Cwd ), + io:format( "~s~n", [format_result( Ret )] ) end end end end end. --spec file( File::string(), Cwd::string() ) -> ok. +-spec file( File::string(), Cwd::string() ) -> [cf_sem:str()]. file( File, Cwd ) -> case cf_parse:file( File ) of @@ -65,15 +68,16 @@ file( File, Cwd ) -> io:format( "~s", [format_error( ErrorInfo )] ); {ok, {Query, Rho, Gamma}} -> try cuneiform:reduce( Query, Rho, Gamma, Cwd ) of - X -> io:format( "~s~n", [format_result( X )] ) + X -> X catch throw:T -> io:format( "~s~n", [format_error( T )] ) end end. -start() -> - application:start( cuneiform ). +start( Mod, ModArg ) -> + application:start( cuneiform ), + cf_sup:start_cre( Mod, ModArg ). @@ -166,7 +170,7 @@ get_optspec_lst() -> {help, $h, "help", undefined, "show command line options"}, {cite, $c, "cite", undefined, "show Bibtex entry for citation"}, {workdir, $w, "workdir", {string, "."}, "working directory"}, - {nthread, $t, "nthread", {pos_integer, NSlot}, "number of threads in local mode"} + {nthread, $t, "nthread", {integer, NSlot}, "number of threads in local mode"} ]. -spec get_vsn() -> string(). diff --git a/src/cuneiform_app.erl b/src/cuneiform_app.erl index 585392d..a2cb36d 100644 --- a/src/cuneiform_app.erl +++ b/src/cuneiform_app.erl @@ -1,3 +1,4 @@ + %% -*- erlang -*- % % Cuneiform: A Functional Language for Large Scale Scientific Data Analysis @@ -28,11 +29,5 @@ %% Application callbacks %% ============================================================================= -start( normal, [] ) -> - - % TODO: load and hand down configuration - - cuneiform_sup:start_link(). - -stop( _State ) -> - ok. +start( normal, [] ) -> cf_sup:start_link(). +stop( _State ) -> ok. \ No newline at end of file diff --git a/src/gen_queue.erl b/src/gen_queue.erl index f060e6d..132d0a6 100644 --- a/src/gen_queue.erl +++ b/src/gen_queue.erl @@ -24,7 +24,7 @@ %% Function Exports %% ============================================================================= --export( [start_link/0, start_link/1, stage_reply/2] ). +-export( [start_link/1, stage_reply/2] ). -export( [code_change/3, handle_cast/2, handle_info/2, init/1, terminate/2, handle_call/3] ). @@ -72,12 +72,6 @@ handle_cast( Request, {NSlot, []} ) -> %% API Functions %% ============================================================================= --spec start_link() -> {ok, pid()} | ignore | {error, term()}. - -start_link() -> - NSlot = erlang:system_info( logical_processors_available ), - start_link( NSlot ). - -spec start_link( NSlot ) -> {ok, pid()} | ignore | {error, term()} when NSlot :: pos_integer(). diff --git a/src/local.erl b/src/local.erl index 5341dee..89b568b 100644 --- a/src/local.erl +++ b/src/local.erl @@ -20,17 +20,17 @@ -author( "Jorgen Brandt " ). -behaviour( cf_cre ). --export( [init/0, handle_submit/5, stage/4] ). +-export( [init/1, handle_submit/5, stage/4] ). -define( BASEDIR, "/tmp/cf" ). -define( WORK, "work" ). -define( REPO, "repo" ). --spec init() -> {ok, pid()}. +-spec init( NSlot::pos_integer() ) -> {ok, pid()}. -init() -> +init( NSlot ) when is_integer( NSlot ), NSlot > 0 -> _Output = os:cmd( string:join( ["rm", "-rf", ?BASEDIR], " " ) ), - gen_queue:start_link(). + gen_queue:start_link( NSlot ). -spec handle_submit( Lam, Fa, R, DataDir, QueueRef ) -> ok From 0c8299ab33e86b1700f0784badc87becc254062e Mon Sep 17 00:00:00 2001 From: Jorgen Brandt Date: Tue, 22 Mar 2016 22:13:58 +0100 Subject: [PATCH 60/78] Change. --- src/cuneiform.erl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cuneiform.erl b/src/cuneiform.erl index 8c9ae01..6ec172c 100644 --- a/src/cuneiform.erl +++ b/src/cuneiform.erl @@ -166,11 +166,11 @@ find_select( _, _ ) -> get_optspec_lst() -> NSlot = erlang:system_info( logical_processors_available ), [ - {version, $v, "version", undefined, "show Cuneiform version"}, - {help, $h, "help", undefined, "show command line options"}, - {cite, $c, "cite", undefined, "show Bibtex entry for citation"}, - {workdir, $w, "workdir", {string, "."}, "working directory"}, - {nthread, $t, "nthread", {integer, NSlot}, "number of threads in local mode"} + {version, $v, "version", undefined, "show Cuneiform version"}, + {help, $h, "help", undefined, "show command line options"}, + {cite, $c, "cite", undefined, "show Bibtex entry for citation"}, + {workdir, $w, "workdir", {string, "."}, "working directory"}, + {nthread, $t, "nthread", {integer, NSlot}, "number of threads in local mode"} ]. -spec get_vsn() -> string(). From daf9b42cdd92103f1132adaff2591532500b12a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Wed, 23 Mar 2016 19:27:24 +0100 Subject: [PATCH 61/78] Library paths are now handed down to effi. --- Makefile | 10 ++++--- src/cf_cre.erl | 70 +++++++++++++++++++++++++++++++++-------------- src/cf_sup.erl | 12 ++++++-- src/cuneiform.erl | 60 ++++++++++++++++++++++++---------------- src/gen_queue.erl | 4 ++- src/local.erl | 26 ++++++++++++------ 6 files changed, 120 insertions(+), 62 deletions(-) diff --git a/Makefile b/Makefile index 84ae778..5ac6697 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,12 @@ all: - rebar3 escriptize + rebar3 do compile, escriptize dev: - git pull - rebar3 do upgrade, escriptize, eunit, dialyzer, cover, edoc + rebar3 do compile, escriptize, eunit, dialyzer, cover, edoc clean: - rebar3 clean + rm -rf .rebar + rm -rf _build + rm -rf doc + rm rebar.lock diff --git a/src/cf_cre.erl b/src/cf_cre.erl index 67e7f7d..0ab039e 100644 --- a/src/cf_cre.erl +++ b/src/cf_cre.erl @@ -35,7 +35,7 @@ %% Function Exports %% ============================================================================= --export( [start_link/2, submit/2] ). +-export( [start_link/3, submit/2] ). -export( [code_change/3, handle_cast/2, handle_info/2, init/1, terminate/2, handle_call/3] ). @@ -55,11 +55,12 @@ -callback init( Arg::term() ) -> {ok, State::term()}. --callback handle_submit( Lam, Fa, R, DataDir, ModState ) -> ok +-callback handle_submit( Lam, Fa, R, DataDir, LibMap, ModState ) -> ok when Lam :: cf_sem:lam(), Fa :: #{string() => [cf_sem:str()]}, R :: pos_integer(), DataDir :: string(), + LibMap :: #{cf_sem:lang() => [string()]}, ModState :: term(). %% ============================================================================= @@ -76,9 +77,10 @@ when Lam :: cf_sem:lam(), ReplyMap::#{pos_integer() => response()}, Cache::#{ckey() => cf_sem:fut()}, R::pos_integer(), + LibMap::#{cf_sem:lang() => [string()]}, ModState::term()}. --type submit() :: {submit, cf_sem:app(), string()}. +-type submit() :: {submit, App::cf_sem:app(), Cwd::string()}. %% ============================================================================= %% Generic Server Functions @@ -90,9 +92,14 @@ terminate( _Reason, _State ) -> ok. %% @doc Generates the initial state of the CRE. --spec init( {Mod::atom(), ModArg::term()} ) -> {ok, cre_state()}. +-spec init( {Mod, ModArg, LibMap} ) -> {ok, cre_state()} +when Mod :: atom(), + ModArg :: term(), + LibMap :: #{cf_sem:lang() => [string()]}. + +init( {Mod, ModArg, LibMap} ) +when is_atom( Mod ), is_map( LibMap ) -> -init( {Mod, ModArg} ) -> SubscrMap = #{}, % mapping of a future to a set of subscriber pids ReplyMap = #{}, % mapping of a future to a response Cache = #{}, % cache mapping a cache key to a future @@ -101,7 +108,7 @@ init( {Mod, ModArg} ) -> % initialize CRE {ok, ModState} = apply( Mod, init, [ModArg] ), - {ok, {Mod, SubscrMap, ReplyMap, Cache, R, ModState}}. + {ok, {Mod, SubscrMap, ReplyMap, Cache, R, LibMap, ModState}}. %% @doc On receiving a call containing a subission, a future is generated and %% returned. @@ -123,13 +130,25 @@ when Request :: submit(), From :: {pid(), term()}, State :: cre_state(). -handle_call( {submit, App, DataDir}, {Pid, _Tag}, {Mod, SubscrMap, ReplyMap, Cache, R, ModState} ) -> +handle_call( {submit, App, Cwd}, + {Pid, _Tag}, + {Mod, SubscrMap, ReplyMap, Cache, R, LibMap, ModState} ) + +when is_tuple( App ), + is_list( Cwd ), + is_pid( Pid ), + is_atom( Mod ), + is_map( SubscrMap ), + is_map( ReplyMap ), + is_map( Cache ), + is_integer( R ), R > 0, + is_map( LibMap ) -> {app, _AppLine, _Channel, Lam, Fa} = App, {lam, _LamLine, LamName, {sign, Lo, _Li}, _Body} = Lam, % construct cache key - Ckey = {Lam, Fa, DataDir}, + Ckey = {Lam, Fa, Cwd}, case maps:is_key( Ckey, Cache ) of @@ -139,13 +158,13 @@ handle_call( {submit, App, DataDir}, {Pid, _Tag}, {Mod, SubscrMap, ReplyMap, Cac Fut = {fut, LamName, R, Lo}, % start process - apply( Mod, handle_submit, [Lam, Fa, R, DataDir, ModState] ), + apply( Mod, handle_submit, [Lam, Fa, R, Cwd, LibMap, ModState] ), SubscrMap1 = SubscrMap#{R => sets:from_list( [Pid] )}, Cache1 = Cache#{Ckey => Fut}, R1 = R+1, - {reply, Fut, {Mod, SubscrMap1, ReplyMap, Cache1, R1, ModState}}; + {reply, Fut, {Mod, SubscrMap1, ReplyMap, Cache1, R1, LibMap, ModState}}; true -> @@ -162,7 +181,7 @@ handle_call( {submit, App, DataDir}, {Pid, _Tag}, {Mod, SubscrMap, ReplyMap, Cac true -> Pid ! maps:get( S, ReplyMap ) end, - {reply, Fut, {Mod, SubscrMap1, ReplyMap, Cache, R, ModState}} + {reply, Fut, {Mod, SubscrMap1, ReplyMap, Cache, R, LibMap, ModState}} end. %% Info Handler %% @@ -171,7 +190,8 @@ handle_call( {submit, App, DataDir}, {Pid, _Tag}, {Mod, SubscrMap, ReplyMap, Cac when Info :: response(), State :: cre_state(). -handle_info( Info={failed, Reason, S, Data}, {Mod, SubscrMap, ReplyMap, Cache, R, ModState} ) -> +handle_info( Info={failed, Reason, S, Data}, + {Mod, SubscrMap, ReplyMap, Cache, R, LibMap, ModState} ) -> % retrieve subscriber set #{S := SubscrSet} = SubscrMap, @@ -184,9 +204,10 @@ handle_info( Info={failed, Reason, S, Data}, {Mod, SubscrMap, ReplyMap, Cache, R ReplyMap1 = ReplyMap#{S => Info}, - {noreply, {Mod, SubscrMap, ReplyMap1, Cache, R, ModState}}; + {noreply, {Mod, SubscrMap, ReplyMap1, Cache, R, LibMap, ModState}}; -handle_info( Info={finished, Sum}, {Mod, SubscrMap, ReplyMap, Cache, R, ModState} ) -> +handle_info( Info={finished, Sum}, + {Mod, SubscrMap, ReplyMap, Cache, R, LibMap, ModState} ) -> % retrieve subscriber set #{id := S} = Sum, @@ -201,25 +222,32 @@ handle_info( Info={finished, Sum}, {Mod, SubscrMap, ReplyMap, Cache, R, ModState ReplyMap1 = ReplyMap#{S => Info}, - {noreply, {Mod, SubscrMap, ReplyMap1, Cache, R, ModState}}. + {noreply, {Mod, SubscrMap, ReplyMap1, Cache, R, LibMap, ModState}}; + +handle_info( Info, _State ) -> error( {bad_msg, Info} ). %% ============================================================================= %% API Functions %% ============================================================================= --spec start_link( Mod, ModArg ) -> {ok, pid()} | ignore | {error, Error} +-spec start_link( Mod, ModArg, LibMap ) -> {ok, pid()} | ignore | {error, Error} when Mod :: atom(), ModArg :: term(), + LibMap :: #{cf_sem:lang() => [string()]}, Error :: {already_started, pid()} | term(). -start_link( Mod, ModArg ) -> - gen_server:start_link( {local, cre}, ?MODULE, {Mod, ModArg}, [] ). +start_link( Mod, ModArg, LibMap ) +when is_atom( Mod ), is_map( LibMap ) -> + gen_server:start_link( {local, cre}, ?MODULE, {Mod, ModArg, LibMap}, [] ). --spec submit( App::cf_sem:app(), DataDir::string() ) -> cf_sem:fut(). +-spec submit( App, Cwd ) -> cf_sem:fut() +when App :: cf_sem:app(), + Cwd :: string(). -submit( App, DataDir ) -> - gen_server:call( cre, {submit, App, DataDir} ). +submit( App, Cwd ) +when is_tuple( App ), is_list( Cwd ) -> + gen_server:call( cre, {submit, App, Cwd} ). %% ============================================================================= %% Internal Functions diff --git a/src/cf_sup.erl b/src/cf_sup.erl index dbab61c..55b8f7a 100644 --- a/src/cf_sup.erl +++ b/src/cf_sup.erl @@ -22,7 +22,7 @@ -behaviour( supervisor ). %% API --export( [start_link/0, start_cre/2] ). +-export( [start_link/0, start_cre/3] ). %% Supervisor callbacks -export([init/1]). @@ -49,12 +49,18 @@ init( [] ) -> {ok, {SupFlags, []}}. -start_cre( Mod, ModArg ) -> +-spec start_cre( Mod, ModArg, LibMap ) -> {ok, pid()} +when Mod :: atom(), + ModArg :: term(), + LibMap :: #{cf_sem:lang() => [string()]}. + +start_cre( Mod, ModArg, LibMap ) +when is_atom( Mod ), is_map( LibMap ) -> Restart = temporary, Shutdown = 2000, Type = worker, - Cre = {cre, {cf_cre, start_link, [Mod, ModArg]}, Restart, Shutdown, Type, [cf_cre]}, + Cre = {cre, {cf_cre, start_link, [Mod, ModArg, LibMap]}, Restart, Shutdown, Type, [cf_cre]}, supervisor:start_child( cf_sup, Cre ). \ No newline at end of file diff --git a/src/cuneiform.erl b/src/cuneiform.erl index 6ec172c..1461a1e 100644 --- a/src/cuneiform.erl +++ b/src/cuneiform.erl @@ -21,7 +21,7 @@ -vsn( "2.2.0" ). % API --export( [main/1, file/2, start/2, reduce/4, get_vsn/0, format_result/1, format_error/1] ). +-export( [main/1, file/2, start/3, reduce/4, get_vsn/0, format_result/1, format_error/1] ). -include( "cuneiform.hrl" ). @@ -47,7 +47,8 @@ main( CmdLine ) -> false -> {workdir, Cwd} = lists:keyfind( workdir, 1, OptLst ), {nthread, NSlot} = lists:keyfind( nthread, 1, OptLst ), - {ok, CrePid} = start( local, NSlot ), + LibMap = get_libmap( OptLst ), + {ok, CrePid} = start( local, NSlot, LibMap ), link( CrePid ), case NonOptLst of [] -> cf_shell:server( Cwd ); @@ -60,7 +61,9 @@ main( CmdLine ) -> end end. --spec file( File::string(), Cwd::string() ) -> [cf_sem:str()]. +-spec file( File, Cwd ) -> [cf_sem:str()] +when File :: string(), + Cwd :: string(). file( File, Cwd ) -> case cf_parse:file( File ) of @@ -75,9 +78,10 @@ file( File, Cwd ) -> end. -start( Mod, ModArg ) -> +start( Mod, ModArg, LibMap ) +when is_atom( Mod ), is_map( LibMap ) -> application:start( cuneiform ), - cf_sup:start_cre( Mod, ModArg ). + cf_sup:start_cre( Mod, ModArg, LibMap ). @@ -86,24 +90,30 @@ start( Mod, ModArg ) -> %% Internal Functions %% ============================================================================= +get_libmap( OptLst ) -> + RLib = [P || {rlib, P} <- OptLst], + PyLib = [P || {pylib, P} <- OptLst], + #{python => PyLib, r => RLib}. + + %% Reduction %% --spec reduce( X0, Rho, Gamma, DataDir ) -> [cf_sem:str()] -when X0 :: [cf_sem:expr()], - Rho :: #{string() => [cf_sem:expr()]}, - Gamma :: #{string() => cf_sem:lam()}, - DataDir :: string(). +-spec reduce( X0, Rho, Gamma, Cwd ) -> [cf_sem:str()] +when X0 :: [cf_sem:expr()], + Rho :: #{string() => [cf_sem:expr()]}, + Gamma :: #{string() => cf_sem:lam()}, + Cwd :: string(). -reduce( X0, Rho, Gamma, DataDir ) -> - Mu = fun( A ) -> cf_cre:submit( A, DataDir ) end, - reduce( X0, {Rho, Mu, Gamma, #{}}, DataDir ). +reduce( X0, Rho, Gamma, Cwd ) -> + Mu = fun( A ) -> cf_cre:submit( A, Cwd ) end, + reduce( X0, {Rho, Mu, Gamma, #{}}, Cwd ). --spec reduce( X0, Theta, DataDir ) -> [cf_sem:str()] -when X0 :: [cf_sem:expr()], - Theta :: cf_sem:ctx(), - DataDir :: string(). +-spec reduce( X0, Theta, Cwd ) -> [cf_sem:str()] +when X0 :: [cf_sem:expr()], + Theta :: cf_sem:ctx(), + Cwd :: string(). -reduce( X0, {Rho, Mu, Gamma, Omega}, DataDir ) -> +reduce( X0, {Rho, Mu, Gamma, Omega}, Cwd ) -> X1 = cf_sem:eval( X0, {Rho, Mu, Gamma, Omega} ), case cf_sem:pfinal( X1 ) of @@ -125,7 +135,7 @@ reduce( X0, {Rho, Mu, Gamma, Omega}, DataDir ) -> end, #{}, maps:keys( Ret ) ), - reduce( X1, {Rho, Mu, Gamma, maps:merge( Omega, Delta )}, DataDir ); + reduce( X1, {Rho, Mu, Gamma, maps:merge( Omega, Delta )}, Cwd ); Msg -> error( {bad_msg, Msg} ) @@ -166,11 +176,13 @@ find_select( _, _ ) -> get_optspec_lst() -> NSlot = erlang:system_info( logical_processors_available ), [ - {version, $v, "version", undefined, "show Cuneiform version"}, - {help, $h, "help", undefined, "show command line options"}, - {cite, $c, "cite", undefined, "show Bibtex entry for citation"}, - {workdir, $w, "workdir", {string, "."}, "working directory"}, - {nthread, $t, "nthread", {integer, NSlot}, "number of threads in local mode"} + {version, $v, "version", undefined, "show Cuneiform version"}, + {help, $h, "help", undefined, "show command line options"}, + {cite, $c, "cite", undefined, "show Bibtex entry for citation"}, + {workdir, $w, "workdir", {string, "."}, "working directory"}, + {nthread, $t, "nthread", {integer, NSlot}, "number of threads in local mode"}, + {rlib, undefined, "rlib", string, "include R library path"}, + {pylib, undefined, "pylib", string, "include Python library path"} ]. -spec get_vsn() -> string(). diff --git a/src/gen_queue.erl b/src/gen_queue.erl index 132d0a6..f61511c 100644 --- a/src/gen_queue.erl +++ b/src/gen_queue.erl @@ -89,5 +89,7 @@ when is_pid( QueueRef ), is_atom( Mod ), is_atom( Fun ), is_list( ArgLst ) -> - Pid ! apply( Mod, Fun, ArgLst ), + + Reply = apply( Mod, Fun, ArgLst ), + Pid ! Reply, gen_server:cast( QueueRef, continue ). \ No newline at end of file diff --git a/src/local.erl b/src/local.erl index 89b568b..c7b2c9b 100644 --- a/src/local.erl +++ b/src/local.erl @@ -20,7 +20,7 @@ -author( "Jorgen Brandt " ). -behaviour( cf_cre ). --export( [init/1, handle_submit/5, stage/4] ). +-export( [init/1, handle_submit/6, stage/5] ). -define( BASEDIR, "/tmp/cf" ). -define( WORK, "work" ). @@ -33,25 +33,33 @@ init( NSlot ) when is_integer( NSlot ), NSlot > 0 -> gen_queue:start_link( NSlot ). --spec handle_submit( Lam, Fa, R, DataDir, QueueRef ) -> ok +-spec handle_submit( Lam, Fa, R, DataDir, LibMap, QueueRef ) -> ok when Lam :: cre:lam(), Fa :: #{string() => [cre:str()]}, R :: pos_integer(), DataDir :: string(), + LibMap :: #{cf_sem:lang() => [string()]}, QueueRef :: pid(). -handle_submit( Lam, Fa, R, DataDir, QueueRef ) -> - gen_server:cast( QueueRef, {request, self(), {?MODULE, stage, [Lam, Fa, R, DataDir]}} ). +handle_submit( Lam, Fa, R, DataDir, LibMap, QueueRef ) -> + gen_server:cast( QueueRef, {request, self(), {?MODULE, stage, [Lam, Fa, R, DataDir, LibMap]}} ). --spec stage( Lam, Fa, R, DataDir ) -> cre:response() +-spec stage( Lam, Fa, R, DataDir, LibMap ) -> cre:response() when Lam :: cre:lam(), Fa :: #{string() => [cre:str()]}, R :: pos_integer(), - DataDir :: string(). + DataDir :: string(), + LibMap :: #{cf_sem:lang() => [string()]}. stage( Lam={lam, _LamLine, _LamName, {sign, Lo, Li}, _Body}, - Fa, R, DataDir ) -> + Fa, R, DataDir, LibMap ) +when is_list( Lo ), + is_list( Li ), + is_map( Fa ), + is_integer( R ), R > 0, + is_list( DataDir ), + is_map( LibMap ) -> Dir = string:join( [?BASEDIR, ?WORK, integer_to_list( R )], "/" ), RepoDir = string:join( [?BASEDIR, ?REPO], "/" ), @@ -74,11 +82,11 @@ stage( Lam={lam, _LamLine, _LamName, {sign, Lo, Li}, _Body}, refactor:apply_refactoring( RefactorLst1 ), % start effi - case effi:check_run( Lam, Fa1, R, Dir ) of + case effi:check_run( Lam, Fa1, R, Dir, LibMap ) of {failed, R2, R, Data} -> {failed, R2, R, Data}; - {finished, Sum} -> + {finished, Sum} -> Ret1 = maps:get( ret, Sum ), From aa6c3fc0d0c0dccd994403999e38bb9f8c43ff7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Wed, 23 Mar 2016 19:57:03 +0100 Subject: [PATCH 62/78] Error reporting fixed. --- Makefile | 2 +- src/cuneiform.erl | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 5ac6697..7df58be 100644 --- a/Makefile +++ b/Makefile @@ -8,5 +8,5 @@ clean: rm -rf .rebar rm -rf _build rm -rf doc - rm rebar.lock + rm -f rebar.lock diff --git a/src/cuneiform.erl b/src/cuneiform.erl index 1461a1e..d9606b3 100644 --- a/src/cuneiform.erl +++ b/src/cuneiform.erl @@ -53,27 +53,29 @@ main( CmdLine ) -> case NonOptLst of [] -> cf_shell:server( Cwd ); [File] -> - Ret = file( File, Cwd ), - io:format( "~s~n", [format_result( Ret )] ) + case file( File, Cwd ) of + {ok, Ret} -> io:format( "~s~n", [format_result( Ret )] ); + {error, T} -> io:format( "~s~n", [format_error( T )] ) + end end end end end end. --spec file( File, Cwd ) -> [cf_sem:str()] +-spec file( File, Cwd ) -> {ok, [cf_sem:str()]} | {error, term()} when File :: string(), Cwd :: string(). file( File, Cwd ) -> case cf_parse:file( File ) of {error, ErrorInfo} -> - io:format( "~s", [format_error( ErrorInfo )] ); + {error, ErrorInfo}; {ok, {Query, Rho, Gamma}} -> try cuneiform:reduce( Query, Rho, Gamma, Cwd ) of - X -> X + X -> {ok, X} catch - throw:T -> io:format( "~s~n", [format_error( T )] ) + throw:T -> {error, T} end end. From 82feceb3b076531d524ee2ab9fd0e07523adf845 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Thu, 24 Mar 2016 07:56:12 +0100 Subject: [PATCH 63/78] ls command removed. Every Cuneiform run now creates a new temp directory. --- Makefile | 4 +++- src/cf_prescan.xrl | 2 -- src/cf_shell.erl | 4 ---- src/local.erl | 51 ++++++++++++++++++++++++++++++++++------------ 4 files changed, 41 insertions(+), 20 deletions(-) diff --git a/Makefile b/Makefile index 7df58be..3dfad51 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,6 @@ -all: +all: compile + +compile: rebar3 do compile, escriptize dev: diff --git a/src/cf_prescan.xrl b/src/cf_prescan.xrl index 2c0d8b1..1646339 100644 --- a/src/cf_prescan.xrl +++ b/src/cf_prescan.xrl @@ -23,7 +23,6 @@ Definitions. -LS = ls CWD = cwd HELP = help NONWS = . @@ -44,7 +43,6 @@ WS = [\000-\s] Rules. -{LS} : {token, ls}. {CWD} : {token, cwd}. {TASKS} : {token, tasks}. {STATE} : {token, state}. diff --git a/src/cf_shell.erl b/src/cf_shell.erl index 2710905..79abea5 100644 --- a/src/cf_shell.erl +++ b/src/cf_shell.erl @@ -56,10 +56,6 @@ server_loop( Rho, Gamma, Cwd ) -> case read_expression( ?PROMPT ) of {ctl, quit} -> ok; - {ctl, ls} -> - {ok, FileLst} = file:list_dir( Cwd ), - io:format( "~p~n", [FileLst] ), - server_loop( Rho, Gamma, Cwd ); {ctl, cwd} -> io:format( "~s~n", [filename:absname( Cwd )] ), server_loop( Rho, Gamma, Cwd ); diff --git a/src/local.erl b/src/local.erl index c7b2c9b..b29bb89 100644 --- a/src/local.erl +++ b/src/local.erl @@ -20,49 +20,74 @@ -author( "Jorgen Brandt " ). -behaviour( cf_cre ). --export( [init/1, handle_submit/6, stage/5] ). +-export( [init/1, handle_submit/6, stage/6] ). -define( BASEDIR, "/tmp/cf" ). -define( WORK, "work" ). -define( REPO, "repo" ). --spec init( NSlot::pos_integer() ) -> {ok, pid()}. +-spec create_basedir( Prefix::string(), I::pos_integer() ) -> iolist(). + +create_basedir( Prefix, I ) -> + BaseDir = [Prefix, "-", integer_to_list( I )], + case filelib:is_file( BaseDir ) of + true -> create_basedir( Prefix, I+1 ); + false -> + case filelib:ensure_dir( [BaseDir, "/"] ) of + {error, Reason} -> error( {Reason, ensure_dir, [BaseDir, "/"]} ); + ok -> BaseDir + end + end. + +-spec init( NSlot::pos_integer() ) -> {ok, {iolist(), pid()}}. init( NSlot ) when is_integer( NSlot ), NSlot > 0 -> - _Output = os:cmd( string:join( ["rm", "-rf", ?BASEDIR], " " ) ), - gen_queue:start_link( NSlot ). + BaseDir = create_basedir( ?BASEDIR, 1 ), + {ok, QueueRef} = gen_queue:start_link( NSlot ), + {ok, {BaseDir, QueueRef}}. --spec handle_submit( Lam, Fa, R, DataDir, LibMap, QueueRef ) -> ok +-spec handle_submit( Lam, Fa, R, DataDir, LibMap, {BaseDir, QueueRef} ) -> ok when Lam :: cre:lam(), Fa :: #{string() => [cre:str()]}, R :: pos_integer(), DataDir :: string(), LibMap :: #{cf_sem:lang() => [string()]}, + BaseDir :: iolist(), QueueRef :: pid(). -handle_submit( Lam, Fa, R, DataDir, LibMap, QueueRef ) -> - gen_server:cast( QueueRef, {request, self(), {?MODULE, stage, [Lam, Fa, R, DataDir, LibMap]}} ). +handle_submit( Lam, Fa, R, DataDir, LibMap, {BaseDir, QueueRef} ) +when is_tuple( Lam ), + is_map( Fa ), + is_integer( R ), R > 0, + is_list( DataDir ), + is_map( LibMap ), + is_list( BaseDir ), + is_pid( QueueRef ) -> + gen_server:cast( QueueRef, {request, self(), + {?MODULE, stage, [Lam, Fa, R, DataDir, LibMap, BaseDir]}} ). --spec stage( Lam, Fa, R, DataDir, LibMap ) -> cre:response() +-spec stage( Lam, Fa, R, DataDir, LibMap, BaseDir ) -> cre:response() when Lam :: cre:lam(), Fa :: #{string() => [cre:str()]}, R :: pos_integer(), DataDir :: string(), - LibMap :: #{cf_sem:lang() => [string()]}. + LibMap :: #{cf_sem:lang() => [string()]}, + BaseDir :: iolist(). stage( Lam={lam, _LamLine, _LamName, {sign, Lo, Li}, _Body}, - Fa, R, DataDir, LibMap ) + Fa, R, DataDir, LibMap, BaseDir ) when is_list( Lo ), is_list( Li ), is_map( Fa ), is_integer( R ), R > 0, is_list( DataDir ), - is_map( LibMap ) -> + is_map( LibMap ), + is_list( BaseDir ) -> - Dir = string:join( [?BASEDIR, ?WORK, integer_to_list( R )], "/" ), - RepoDir = string:join( [?BASEDIR, ?REPO], "/" ), + Dir = string:join( [BaseDir, ?WORK, integer_to_list( R )], "/" ), + RepoDir = string:join( [BaseDir, ?REPO], "/" ), % create working directory case filelib:ensure_dir( [Dir, "/"] ) of From 9ec7be1785fcf1892048b144c37c6330655f689f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Thu, 24 Mar 2016 17:47:14 +0100 Subject: [PATCH 64/78] Scaffold for Condor added. --- include/cuneiform.hrl | 5 ++++ src/condor.erl | 56 +++++++++++++++++++++++++++++++++++++++++++ src/cuneiform.erl | 18 +++++++------- src/local.erl | 44 ++++++++++++++++++++++++---------- 4 files changed, 102 insertions(+), 21 deletions(-) create mode 100644 src/condor.erl diff --git a/include/cuneiform.hrl b/include/cuneiform.hrl index 62782f2..df2bd36 100644 --- a/include/cuneiform.hrl +++ b/include/cuneiform.hrl @@ -6,3 +6,8 @@ -define( YLW( Str ), "\e[33m" ++ Str ++ "\e[0m" ). -define( BYLW( Str ), "\e[1;33m" ++ Str ++ "\e[0m" ). -define( BLU( Str ), "\e[1;34m" ++ Str ++ "\e[0m" ). + +-define( BASEDIR, "/tmp/cf" ). +-define( WORK, "work" ). +-define( REPO, "repo" ). + diff --git a/src/condor.erl b/src/condor.erl new file mode 100644 index 0000000..17f122b --- /dev/null +++ b/src/condor.erl @@ -0,0 +1,56 @@ +%% -*- erlang -*- +% +% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis +% +% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser +% +% Licensed under the Apache License, Version 2.0 (the "License"); +% you may not use this file except in compliance with the License. +% You may obtain a copy of the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, +% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +% See the License for the specific language governing permissions and +% limitations under the License. + +-module( condor ). +-author( "Jorgen Brandt " ). + +-include( "cuneiform.hrl" ). + +-behaviour( cf_cre ). + +-export( [init/1, handle_submit/6] ). + + +init( _ModArg ) -> + + BaseDir = local:create_basedir( ?BASEDIR, 1 ), + {ok, BaseDir}. + +handle_submit( _Lam, _Fa, R, _DataDir, _LibMap, BaseDir ) -> + + _Dir = local:create_workdir( BaseDir, ?WORK, R ), + + _RepoDir = string:join( [BaseDir, ?REPO], "/" ), + + SubmitStr = "", % TODO + + Port = open_port( {spawn, "condor_submit -terse -"}, + [exit_status, + stderr_to_stdout, + binary, + {cd, "."}, % TODO + {line, 1024}] ), + + true = port_command( Port, SubmitStr ), + + receive + + % TODO + + Msg -> error( {bad_msg, Msg} ) + end. \ No newline at end of file diff --git a/src/cuneiform.erl b/src/cuneiform.erl index d9606b3..196c717 100644 --- a/src/cuneiform.erl +++ b/src/cuneiform.erl @@ -47,8 +47,9 @@ main( CmdLine ) -> false -> {workdir, Cwd} = lists:keyfind( workdir, 1, OptLst ), {nthread, NSlot} = lists:keyfind( nthread, 1, OptLst ), + {platform, Platform} = lists:keyfind( platform, 1, OptLst ), LibMap = get_libmap( OptLst ), - {ok, CrePid} = start( local, NSlot, LibMap ), + {ok, CrePid} = start( Platform, NSlot, LibMap ), link( CrePid ), case NonOptLst of [] -> cf_shell:server( Cwd ); @@ -178,13 +179,14 @@ find_select( _, _ ) -> get_optspec_lst() -> NSlot = erlang:system_info( logical_processors_available ), [ - {version, $v, "version", undefined, "show Cuneiform version"}, - {help, $h, "help", undefined, "show command line options"}, - {cite, $c, "cite", undefined, "show Bibtex entry for citation"}, - {workdir, $w, "workdir", {string, "."}, "working directory"}, - {nthread, $t, "nthread", {integer, NSlot}, "number of threads in local mode"}, - {rlib, undefined, "rlib", string, "include R library path"}, - {pylib, undefined, "pylib", string, "include Python library path"} + {version, $v, "version", undefined, "show Cuneiform version"}, + {help, $h, "help", undefined, "show command line options"}, + {cite, $c, "cite", undefined, "show Bibtex entry for citation"}, + {workdir, $w, "workdir", {string, "."}, "working directory"}, + {nthread, $t, "nthread", {integer, NSlot}, "number of threads in local mode"}, + {platform, $p, "platform", {atom, local}, "platform to use: local, condor"}, + {rlib, undefined, "rlib", string, "include R library path"}, + {pylib, undefined, "pylib", string, "include Python library path"} ]. -spec get_vsn() -> string(). diff --git a/src/local.erl b/src/local.erl index b29bb89..883e251 100644 --- a/src/local.erl +++ b/src/local.erl @@ -19,17 +19,20 @@ -module( local ). -author( "Jorgen Brandt " ). --behaviour( cf_cre ). --export( [init/1, handle_submit/6, stage/6] ). +-include( "cuneiform.hrl" ). --define( BASEDIR, "/tmp/cf" ). --define( WORK, "work" ). --define( REPO, "repo" ). +-behaviour( cf_cre ). +-export( [init/1, handle_submit/6, stage/6, create_basedir/2, + create_workdir/3] ). -spec create_basedir( Prefix::string(), I::pos_integer() ) -> iolist(). -create_basedir( Prefix, I ) -> +create_basedir( Prefix, I ) +when is_list( Prefix ), + is_integer( I ), I > 0 -> + BaseDir = [Prefix, "-", integer_to_list( I )], + case filelib:is_file( BaseDir ) of true -> create_basedir( Prefix, I+1 ); false -> @@ -68,6 +71,25 @@ when is_tuple( Lam ), {?MODULE, stage, [Lam, Fa, R, DataDir, LibMap, BaseDir]}} ). +-spec create_workdir( BaseDir, Work, R ) -> string() +when BaseDir :: string(), + Work :: string(), + R :: pos_integer(). + +create_workdir( BaseDir, Work, R ) +when is_list( BaseDir ), + is_list( Work ), + is_integer( R ), R > 0 -> + + Dir = string:join( [BaseDir, Work, integer_to_list( R )], "/" ), + + % create working directory + case filelib:ensure_dir( [Dir, "/"] ) of + {error, R1} -> error( {R1, ensure_dir, [Dir, "/"]} ); + ok -> Dir + end. + + -spec stage( Lam, Fa, R, DataDir, LibMap, BaseDir ) -> cre:response() when Lam :: cre:lam(), Fa :: #{string() => [cre:str()]}, @@ -86,14 +108,10 @@ when is_list( Lo ), is_map( LibMap ), is_list( BaseDir ) -> - Dir = string:join( [BaseDir, ?WORK, integer_to_list( R )], "/" ), - RepoDir = string:join( [BaseDir, ?REPO], "/" ), - % create working directory - case filelib:ensure_dir( [Dir, "/"] ) of - {error, R1} -> error( {R1, ensure_dir, [Dir, "/"]} ); - ok -> ok - end, + Dir = create_workdir( BaseDir, ?WORK, R ), + + RepoDir = string:join( [BaseDir, ?REPO], "/" ), % resolve input files Triple1 = refactor:get_refactoring( Li, Fa, Dir, [DataDir, RepoDir], R ), From 34d17d8213162e29c15ac8811d77e1202db425fe Mon Sep 17 00:00:00 2001 From: Jorgen Brandt Date: Thu, 24 Mar 2016 22:59:55 +0100 Subject: [PATCH 65/78] Queue fixed. --- src/gen_queue.erl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gen_queue.erl b/src/gen_queue.erl index f61511c..b3dc82d 100644 --- a/src/gen_queue.erl +++ b/src/gen_queue.erl @@ -65,7 +65,8 @@ handle_cast( Request, {0, Q} ) -> {noreply, {0, [Request|Q]}}; handle_cast( Request, {NSlot, []} ) -> - stage_reply( self(), Request ), + QueueRef = self(), + spawn_link( fun() -> stage_reply( QueueRef, Request ) end ), {noreply, {NSlot-1, []}}. %% ============================================================================= From 7174f0c614f60c93ccf373302f8100138c3381c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Fri, 25 Mar 2016 11:54:13 +0100 Subject: [PATCH 66/78] Bug in gen_queue fixed. --- src/cuneiform.erl | 7 +++++-- src/gen_queue.erl | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/cuneiform.erl b/src/cuneiform.erl index 196c717..397ad8c 100644 --- a/src/cuneiform.erl +++ b/src/cuneiform.erl @@ -177,7 +177,10 @@ find_select( _, _ ) -> -spec get_optspec_lst() -> [{atom(), char(), string(), undefined, string()}]. get_optspec_lst() -> - NSlot = erlang:system_info( logical_processors_available ), + NSlot = case erlang:system_info( logical_processors_available ) of + unknown -> 1; + N -> N + end, [ {version, $v, "version", undefined, "show Cuneiform version"}, {help, $h, "help", undefined, "show command line options"}, @@ -274,7 +277,7 @@ format_error( {AppLine, cuneiform, {script_error, LamName, R, {ActScript, Out}}} io_lib:format( ?BYLW( "[out]~n" )++?YLW( "~s~n" ) ++?BYLW( "[script]~n" )++?YLW( "~s~n" ) - ++?RED( "Line ~p: " )++?BRED( "script error in call to ~s (~p)" ), + ++?RED( "Line ~p: " )++?BRED( "script error in call to ~s (id: ~p)" ), [format_out( Out ), format_script( ActScript ), AppLine, LamName, R] ); format_error( {AppLine, cuneiform, {precond, LamName, R, MissingLst}} ) -> diff --git a/src/gen_queue.erl b/src/gen_queue.erl index b3dc82d..262c841 100644 --- a/src/gen_queue.erl +++ b/src/gen_queue.erl @@ -58,7 +58,8 @@ handle_cast( continue, {NSlot, []} ) -> {noreply, {NSlot+1, []}}; handle_cast( continue, {NSlot, [H|T]} ) -> - stage_reply( self(), H ), + QueueRef = self(), + spawn_link( fun() -> stage_reply( QueueRef, H ) end ), {noreply, {NSlot, T}}; handle_cast( Request, {0, Q} ) -> From b80dffc8d0450c260c97aa8a585441305b9a9efd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Tue, 29 Mar 2016 12:01:12 +0200 Subject: [PATCH 67/78] Documentation in condor_submit module extended. --- CITATION | 15 ++++ src/cf_prescan.xrl | 1 - src/cf_sem.erl | 2 + src/cf_shell.erl | 2 + src/cf_sup.erl | 2 + src/condor.erl | 2 + src/condor_submit.erl | 166 +++++++++++++++++++++++++++++++----------- src/cuneiform.erl | 2 + src/cuneiform_app.erl | 2 + src/gen_queue.erl | 2 + src/local.erl | 2 + 11 files changed, 156 insertions(+), 42 deletions(-) create mode 100644 CITATION diff --git a/CITATION b/CITATION new file mode 100644 index 0000000..c7a9c3d --- /dev/null +++ b/CITATION @@ -0,0 +1,15 @@ +@InProceedings{Brandt2015, + Title = {Cuneiform: A Functional Language for Large Scale Scientific Data Analysis}, + Author = {Brandt, J{\"o}rgen and Bux, Marc and Leser, Ulf}, + Booktitle = {Proceedings of the Workshops of the EDBT/ICDT}, + Year = {2015}, + + Address = {Brussels, Belgium}, + Month = {March}, + Pages = {17--26}, + Volume = {1330}, + + Abstract = {The need to analyze massive scientific data sets on the one hand and the availability of distributed compute resources with an increasing number of CPU cores on the other hand have promoted the development of a variety of languages and systems for parallel, distributed data analysis. Among them are data-parallel query languages such as Pig Latin or Spark as well as scientific workflow languages such as Swift or Pegasus DAX. While data-parallel query languages focus on the exploitation of data parallelism, scientific workflow languages focus on the integration of external tools and libraries. However, a language that combines easy integration of arbitrary tools, treated as black boxes, with the ability to fully exploit data parallelism does not exist yet. Here, we present Cuneiform, a novel language for large-scale scientific data analysis. We highlight its functionality with respect to a set of desirable features for such languages, introduce its syntax and semantics by example, and show its flexibility and conciseness with use cases, including a complex real-life workflow from the area of genome research. Cuneiform scripts are executed dynamically on the workflow execution platform Hi-WAY which is based on Hadoop YARN. The language Cuneiform, including tool support for programming, workflow visualization, debugging, logging, and provenance-tracing, and the parallel execution engine Hi-WAY are fully implemented.}, + Doi = {10.13140/RG.2.1.3547.6561}, + Url = {http://ceur-ws.org/Vol-1330/paper-03.pdf} +} diff --git a/src/cf_prescan.xrl b/src/cf_prescan.xrl index 1646339..9e7d9b3 100644 --- a/src/cf_prescan.xrl +++ b/src/cf_prescan.xrl @@ -16,7 +16,6 @@ % See the License for the specific language governing permissions and % limitations under the License. - %% ============================================================================= %% Definitions %% ============================================================================= diff --git a/src/cf_sem.erl b/src/cf_sem.erl index 1fe16f7..a561bdc 100644 --- a/src/cf_sem.erl +++ b/src/cf_sem.erl @@ -16,6 +16,8 @@ % See the License for the specific language governing permissions and % limitations under the License. +%% @author Jörgen Brandt + -module( cf_sem ). -author( "Jorgen Brandt " ). diff --git a/src/cf_shell.erl b/src/cf_shell.erl index 79abea5..62159aa 100644 --- a/src/cf_shell.erl +++ b/src/cf_shell.erl @@ -16,6 +16,8 @@ % See the License for the specific language governing permissions and % limitations under the License. +%% @author Jörgen Brandt + -module( cf_shell ). -author( "Jorgen Brandt " ). diff --git a/src/cf_sup.erl b/src/cf_sup.erl index 55b8f7a..5298f60 100644 --- a/src/cf_sup.erl +++ b/src/cf_sup.erl @@ -16,6 +16,8 @@ % See the License for the specific language governing permissions and % limitations under the License. +%% @author Jörgen Brandt + -module( cf_sup ). -author( "Jorgen Brandt " ). diff --git a/src/condor.erl b/src/condor.erl index 17f122b..3a06199 100644 --- a/src/condor.erl +++ b/src/condor.erl @@ -16,6 +16,8 @@ % See the License for the specific language governing permissions and % limitations under the License. +%% @author Jörgen Brandt + -module( condor ). -author( "Jorgen Brandt " ). diff --git a/src/condor_submit.erl b/src/condor_submit.erl index db72f46..e22da24 100644 --- a/src/condor_submit.erl +++ b/src/condor_submit.erl @@ -1,43 +1,82 @@ -%%%------------------------------------------------------------------- -%%% @author mac -%%% @copyright (C) 2016, -%%% @doc -%%% -%%% @end -%%% Created : 21. Feb 2016 8:49 PM -%%% -%%% This is utility module that produces condor_submit file contents from 3 sources of possible inputs, -%%% in the following order of priority if there is a parameter key conflict: -%%% -%%% 1. Mandatory CF condor parameters: executable, log, error, output -%%% 2. Optional task-level condor parameters, i.e. universe, RequestMemory, RequestCpus -%%% 3. Optional default condor parameters, i.e. universe, should_transfer_files, etc. -%%% -%%% One exception is transfer_input_files: instead of choosing just one of the corresponding -%%% lists, the lists are merged. This way any custom input files can be specified as well. -%%% Also, input file names are validated to be real files, therefore transfer_input_files param -%%% is the only one expected to be a list of files rather than a complete string and it will -%%% be converted back to comma-separated string once the validation and possibly merging is done -%%% -%%% Mandatory condor parameters that aren't provided in either of the "sources" -%%% will be filled in with VANILLA_DEFAULS -%%%------------------------------------------------------------------- +%% -*- erlang -*- +% +% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis +% +% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser +% +% Licensed under the Apache License, Version 2.0 (the "License"); +% you may not use this file except in compliance with the License. +% You may obtain a copy of the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, +% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +% See the License for the specific language governing permissions and +% limitations under the License. +% + +%% @author Irina Guberman +%% @author Jörgen Brandt +%% +%% @doc Management Condor submit files. +%% +%% This utility module produces the content of a condor_submit file from 3 +%% sources of possible inputs in the following order of priority if there is a +%% parameter key conflict: +%% +%% 1. Mandatory CF condor parameters: executable, log, error, output +%% +%% 2. Optional task-level condor parameters, i.e. universe, RequestMemory, RequestCpus +%% +%% 3. Optional default condor parameters, i.e. universe, should_transfer_files, etc. +%% +%% One exception is transfer_input_files: instead of choosing just one of the corresponding +%% lists, the lists are merged. This way any custom input files can be specified as well. +%% +%% +%% Is specifying custom input files actually a good idea? +%% (i) It is a way to introduce a file avoiding to define it as a tasks +%% argument. (It is a side-effect.) +%% (ii) Imho, the semantics of the workflow script should never change due to +%% an annotation. Annotations should only be for giving additional +%% info to speed up execution. +%% +%% +%% Also, input file names are validated to be real files, therefore transfer_input_files param +%% is the only one expected to be a list of files rather than a complete string and it will +%% be converted back to comma-separated string once the validation and possibly merging is done +%% +%% +%% Validation is not necessary here. Effi checks if all files exist, before it +%% starts and fails if something is missing. It doesn't depend on Condor submit +%% info, though. Representing lists in the Condor submit file as lists in the +%% submit map is an excellent idea though. +%% +%% +%% Mandatory condor parameters that aren't provided in either of the sources of +%% possible inputs will be filled in with VANILLA_DEFAULTS. + -module(condor_submit). -ifdef( TEST ). -include_lib( "eunit/include/eunit.hrl" ). -endif. -%% API --export([ - generate_condor_submit/1, - generate_condor_submit/2, - generate_condor_submit/3]). +% API +-export( [generate_condor_submit/1, generate_condor_submit/2, + generate_condor_submit/3] ). + +% provisionary export to make all module functions, their prototypes and +% documentations visible in the docs. +-export( [validate_input_files/1, combine_params/2, input_files_to_cs_string/1, + create_submitfile/1] ). -define(VANILLA_DEFAULTS, #{universe => "vanilla", should_transfer_files => "YES", - run_as_owner => "True", + run_as_owner => "True", % is this one really necessary? when_to_transfer_output => "ON_EXIT"}). %% @@ -80,20 +119,39 @@ generate_condor_submit(CFParams, DeclaredDefaultParams, DeclaredTaskParams) %% INTERNAL methods + +%% @doc Extracts the transfer_input_files field from a Condor submit map and +%% checks if all listed files exist. +%% +%% Returns a Condor submit map having a non-empty transfer_input_files +%% field or none at all. Throws an error if an input file does not exist. +%% +-spec validate_input_files( Params ) -> #{atom() => string() | [string()]} +when Params :: #{atom() => string() | [string()]}. + validate_input_files( #{ transfer_input_files := [] } = Params) -> maps:remove(transfer_input_files, Params); + validate_input_files( #{ transfer_input_files := InputFiles} = Params) when is_list(InputFiles) -> case lists:all(fun(Elem) -> filelib:is_file(Elem) end, InputFiles) of true -> Params; false -> {error, io_lib:format("Invalid input file(s) in ~p!", [InputFiles])} end; + validate_input_files(#{} = Params) -> Params. -%%% This method will combine parameters from two maps in such a a way that -%% Params1 will take precedence over Params2, but if there is tranfer_input_files parameter -%% present in both it will merge the list of input files into one +%% @doc Combines parameters from two Condor submit maps. +%% +%% In compination, Params1 will take precedence over Params2. If there is +%% tranfer_input_files parameter present in both it will merge the list of +%% input files into one. +%% +-spec combine_params( Params1, Params2 ) -> #{atom() => string() | [string()]} +when Params1 :: #{atom() => string() | [string()]}, + Params2 :: #{atom() => string() | [string()]}. + combine_params( #{ transfer_input_files := InputFiles1 } = Params1, #{ transfer_input_files := InputFiles2 } = Params2 ) when is_list(InputFiles1), is_list(InputFiles2) -> @@ -102,23 +160,40 @@ combine_params( #{ transfer_input_files := InputFiles1 } = Params1, maps:put(transfer_input_files, InputFiles, Params1), maps:remove(transfer_input_files, Params2) ); + combine_params(Params1, Params2) when is_map(Params1), is_map(Params2) -> maps:merge(validate_input_files(Params2), validate_input_files(Params1)). -%%% The only parameter that might come here as a list instead of complete cs-string -%%% is transfer_input_files because it might be generated by cuneiform and it needs file validation -%%% Therefore any decalred transfer_input_files params need to be first parsed from cs-string -%%% into a list, and once they are validated and possibly merged, they are converted back to cs-string here +%% @doc Converts the transfer_input_files field from a Condor submit map to a +%% comma-separated string. +%% +%% The only parameter that might come here as a list instead of complete +%% cs-string is transfer_input_files because it might be generated by +%% Cuneiform and it needs file validation. Therefore any declared +%% transfer_input_files params need to be first parsed from cs-string +%% into a list, and once they are validated and possibly merged, they are +%% converted back to cs-string here. +%% +-spec input_files_to_cs_string( CondorParams ) -> #{atom() => string()} +when CondorParams :: #{atom() => string() | [string()]}. + input_files_to_cs_string(#{transfer_input_files := InputFiles} = CondorParams) -> InputFilesCS = string:join(InputFiles, ", "), maps:put(transfer_input_files, InputFilesCS, CondorParams); + input_files_to_cs_string(CondorParams) -> CondorParams. -%%% Just take the param map and output into a string having 'key = value' format -%%% The order of key-value pairs in condor config file doesn't matter at all (I tested) -%%% The resulting string is a complete valid condor submit file contents -- -%%% leaving it to cre_htcondor module to decide the name of the file to write them to +%% @doc Takes a Condor submit map and formats it as a binary. +%% +%% Takes the Condor submit map and produces a string having 'key = value' +%% format. The order of key-value pairs in the output binary is undefined. +%% The resulting binary is a complete, valid condor submit file leaving it +%% to the caller to write the content to disk. +%% +-spec create_submitfile( Condorparams0 ) -> binary() +when Condorparams0::#{atom() => string() | [string()]}. + create_submitfile(CondorParams0) -> CondorParams1 = input_files_to_cs_string(CondorParams0), LineSep = io_lib:nl(), @@ -126,6 +201,15 @@ create_submitfile(CondorParams0) -> iolist_to_binary([LineSep, lists:flatten(SubmitFileStr), LineSep, "Queue", LineSep]). + + + + + + + + + -ifdef( TEST ). -define (GOOD_CF_PARAMS, diff --git a/src/cuneiform.erl b/src/cuneiform.erl index 397ad8c..e32b412 100644 --- a/src/cuneiform.erl +++ b/src/cuneiform.erl @@ -16,6 +16,8 @@ % See the License for the specific language governing permissions and % limitations under the License. +%% @author Jörgen Brandt + -module( cuneiform ). -author( "Jorgen Brandt " ). -vsn( "2.2.0" ). diff --git a/src/cuneiform_app.erl b/src/cuneiform_app.erl index a2cb36d..61e0531 100644 --- a/src/cuneiform_app.erl +++ b/src/cuneiform_app.erl @@ -17,6 +17,8 @@ % See the License for the specific language governing permissions and % limitations under the License. +%% @author Jörgen Brandt + -module( cuneiform_app ). -author( "Jorgen Brandt " ). diff --git a/src/gen_queue.erl b/src/gen_queue.erl index 262c841..75f246b 100644 --- a/src/gen_queue.erl +++ b/src/gen_queue.erl @@ -16,6 +16,8 @@ % See the License for the specific language governing permissions and % limitations under the License. +%% @author Jörgen Brandt + -module( gen_queue ). -author( "Jorgen Brandt " ). -behaviour( gen_server ). diff --git a/src/local.erl b/src/local.erl index 883e251..ebc80fd 100644 --- a/src/local.erl +++ b/src/local.erl @@ -16,6 +16,8 @@ % See the License for the specific language governing permissions and % limitations under the License. +%% @author Jörgen Brandt + -module( local ). -author( "Jorgen Brandt " ). From fa2606e9107c1a4956936f21ff0222564bfeb83f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Tue, 29 Mar 2016 16:31:06 +0200 Subject: [PATCH 68/78] Condor support improved. Bug in shell fixed. --- src/cf_cre.erl | 8 +++--- src/cf_shell.erl | 4 +-- src/condor.erl | 65 ++++++++++++++++++++++++++++++++++--------- src/condor_submit.erl | 8 +++--- 4 files changed, 62 insertions(+), 23 deletions(-) diff --git a/src/cf_cre.erl b/src/cf_cre.erl index 0ab039e..9664e7f 100644 --- a/src/cf_cre.erl +++ b/src/cf_cre.erl @@ -191,7 +191,9 @@ when Info :: response(), State :: cre_state(). handle_info( Info={failed, Reason, S, Data}, - {Mod, SubscrMap, ReplyMap, Cache, R, LibMap, ModState} ) -> + {Mod, SubscrMap, ReplyMap, Cache, R, LibMap, ModState} ) +when is_atom( Reason ), + is_integer( S ), S > 0 -> % retrieve subscriber set #{S := SubscrSet} = SubscrMap, @@ -222,9 +224,7 @@ handle_info( Info={finished, Sum}, ReplyMap1 = ReplyMap#{S => Info}, - {noreply, {Mod, SubscrMap, ReplyMap1, Cache, R, LibMap, ModState}}; - -handle_info( Info, _State ) -> error( {bad_msg, Info} ). + {noreply, {Mod, SubscrMap, ReplyMap1, Cache, R, LibMap, ModState}}. %% ============================================================================= %% API Functions diff --git a/src/cf_shell.erl b/src/cf_shell.erl index 62159aa..ce743b3 100644 --- a/src/cf_shell.erl +++ b/src/cf_shell.erl @@ -80,12 +80,12 @@ server_loop( Rho, Gamma, Cwd ) -> case Query of undef -> server_loop( Rho1, Gamma1, Cwd ); _ -> - try cuneiform:reduce( Query, Rho, Gamma, "." ) of + try cuneiform:reduce( Query, Rho1, Gamma1, "." ) of X -> io:format( "~s~n", [cuneiform:format_result( X )] ) catch throw:T -> io:format( "~s~n", [cuneiform:format_error( T )] ) end, - server_loop( Rho, Gamma, Cwd ) + server_loop( Rho1, Gamma1, Cwd ) end end. diff --git a/src/condor.erl b/src/condor.erl index 3a06199..97de031 100644 --- a/src/condor.erl +++ b/src/condor.erl @@ -35,24 +35,63 @@ init( _ModArg ) -> handle_submit( _Lam, _Fa, R, _DataDir, _LibMap, BaseDir ) -> - _Dir = local:create_workdir( BaseDir, ?WORK, R ), + Dir = local:create_workdir( BaseDir, ?WORK, R ), _RepoDir = string:join( [BaseDir, ?REPO], "/" ), - SubmitStr = "", % TODO + LogFile = string:join( [Dir, "_log.txt"], "/" ), + SumFile = string:join( [Dir, "_summary.txt"], "/" ), + OutputFile = string:join( [Dir, "_output.txt"], "/" ), + + SubmitMap = #{universe => "VANILLA", + executable => "/usr/local/bin/effi", + arguments => string:join( ["_request.txt", + SumFile], " " ), + should_transfer_files => "IF_NEEDED", + when_to_transfer_output => "ON_EXIT", + log => LogFile, + output => OutputFile, + environment => ["\"", + string:join( ["HOME=.", + "PATH=/bin:/usr/bin:/usr/local/bin"], " " ), + "\""], + initialdir => Dir + }, + + SubmitStr = condor_submit:format_submit( SubmitMap ), + error_logger:info_msg( "~s~n", [SubmitStr] ), + + SubmitFile = string:join( [Dir, "_job.sub"], "/" ), + + ok = file:write_file( SubmitFile, SubmitStr ), + + _Response = os:cmd( string:join( ["condor_submit", SubmitFile], " " ) ), + + CreRef = self(), + F = fun() -> condor_wait( CreRef, R, LogFile, SumFile, OutputFile ) end, + _Pid = spawn_link( F ), + + ok. + + + +condor_wait( CreRef, R, LogFile, SumFile, OutputFile ) -> + + % wait until the job terminates + _Response = os:cmd( string:join( ["condor_wait", LogFile], " " ) ), + + case filelib:is_file( SumFile ) of - Port = open_port( {spawn, "condor_submit -terse -"}, - [exit_status, - stderr_to_stdout, - binary, - {cd, "."}, % TODO - {line, 1024}] ), + false -> + {ok, Out} = file:read_file( OutputFile ), + CreRef ! {failed, script_error, R, {"", re:split( Out, "\\n" )}}; % TODO: extract actual script - true = port_command( Port, SubmitStr ), + true -> + {ok, B} = file:read_file( SumFile ), + {ok, Tokens, _} = erl_scan:string( binary_to_list( B ) ), + {ok, Sum} = erl_parse:parse_term( Tokens ), + CreRef ! {finished, Sum} + end. - receive - % TODO - Msg -> error( {bad_msg, Msg} ) - end. \ No newline at end of file diff --git a/src/condor_submit.erl b/src/condor_submit.erl index e22da24..2fd31fc 100644 --- a/src/condor_submit.erl +++ b/src/condor_submit.erl @@ -71,7 +71,7 @@ % provisionary export to make all module functions, their prototypes and % documentations visible in the docs. -export( [validate_input_files/1, combine_params/2, input_files_to_cs_string/1, - create_submitfile/1] ). + format_submit/1] ). -define(VANILLA_DEFAULTS, #{universe => "vanilla", @@ -103,7 +103,7 @@ generate_condor_submit(#{ executable := Executable, is_map(DeclaredParams) -> CondorParams0 = combine_params(CFParams, DeclaredParams), CondorParams = maps:merge(?VANILLA_DEFAULTS, CondorParams0), - create_submitfile(CondorParams). + format_submit(CondorParams). %% %% This method expects 3 arguments: @@ -191,10 +191,10 @@ input_files_to_cs_string(CondorParams) -> CondorParams. %% The resulting binary is a complete, valid condor submit file leaving it %% to the caller to write the content to disk. %% --spec create_submitfile( Condorparams0 ) -> binary() +-spec format_submit( Condorparams0 ) -> binary() when Condorparams0::#{atom() => string() | [string()]}. -create_submitfile(CondorParams0) -> +format_submit(CondorParams0) -> CondorParams1 = input_files_to_cs_string(CondorParams0), LineSep = io_lib:nl(), SubmitFileStr = maps:fold(fun(K, V, Acc) -> [Acc, io_lib:format("~p = ~s", [K,V]), LineSep] end, "", CondorParams1), From 332e3dceb5a40f245965ecf43c671ee1b524d6c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Thu, 7 Apr 2016 11:34:34 +0200 Subject: [PATCH 69/78] Condor support. --- src/cf_cre.erl | 2 + src/cf_parse.yrl | 2 + src/cf_prescan.xrl | 2 + src/cf_scan.xrl | 2 + src/cf_sem.erl | 2 + src/cf_shell.erl | 13 ++--- src/cf_sup.erl | 2 + src/condor.erl | 132 ++++++++++++++++++++++++++---------------- src/cuneiform.erl | 2 +- src/cuneiform_app.erl | 2 + src/gen_queue.erl | 2 + src/local.erl | 2 + 12 files changed, 106 insertions(+), 59 deletions(-) diff --git a/src/cf_cre.erl b/src/cf_cre.erl index 9664e7f..963982d 100644 --- a/src/cf_cre.erl +++ b/src/cf_cre.erl @@ -29,6 +29,8 @@ -module( cf_cre ). -author( "Jorgen Brandt " ). +-vsn( "2.2.0-snapshot" ). + -behaviour( gen_server ). %% ============================================================================= diff --git a/src/cf_parse.yrl b/src/cf_parse.yrl index 1f7f9ac..b868aad 100644 --- a/src/cf_parse.yrl +++ b/src/cf_parse.yrl @@ -111,6 +111,8 @@ namelist -> name namelist : ['$1'|'$2']. Erlang code. -author( "Jorgen Brandt " ). +-vsn( "2.2.0-snapshot" ). + -export( [string/1, file/1] ). diff --git a/src/cf_prescan.xrl b/src/cf_prescan.xrl index 9e7d9b3..d0bb36c 100644 --- a/src/cf_prescan.xrl +++ b/src/cf_prescan.xrl @@ -63,5 +63,7 @@ Rules. Erlang code. -author( "Jorgen Brandt " ). +-vsn( "2.2.0-snapshot" ). + -export( [yyrev/2] ). \ No newline at end of file diff --git a/src/cf_scan.xrl b/src/cf_scan.xrl index 6c7c641..78f250a 100644 --- a/src/cf_scan.xrl +++ b/src/cf_scan.xrl @@ -114,6 +114,8 @@ Rules. Erlang code. -author( "Jorgen Brandt " ). +-vsn( "2.2.0-snapshot" ). + -export( [yyrev/2] ). diff --git a/src/cf_sem.erl b/src/cf_sem.erl index a561bdc..b929e8f 100644 --- a/src/cf_sem.erl +++ b/src/cf_sem.erl @@ -20,6 +20,8 @@ -module( cf_sem ). -author( "Jorgen Brandt " ). +-vsn( "2.2.0-snapshot" ). + -export( [eval/2, pfinal/1] ). diff --git a/src/cf_shell.erl b/src/cf_shell.erl index ce743b3..f668a89 100644 --- a/src/cf_shell.erl +++ b/src/cf_shell.erl @@ -20,6 +20,8 @@ -module( cf_shell ). -author( "Jorgen Brandt " ). +-vsn( "2.2.0-snapshot" ). + %% ============================================================================= %% Function Exports @@ -141,18 +143,11 @@ get_help() -> [?YLW( "help" )++" show this usage info", ?YLW( "state" )++" show variable bindings", ?YLW( "tasks" )++" show task definitions", - ?YLW( "ls" )++" list files", ?YLW( "cwd" )++" current working directory", ?YLW( "quit" )++" quit the shell" ], "\n" ). - - - - - - -spec get_banner() -> iolist(). get_banner() -> @@ -163,8 +158,8 @@ get_banner() -> " _g@@@@@WWWWWWL", " g@@#*`3@B "++?YLW( "Type " )++?BYLW( "help" )++?YLW( " for usage info." ), " @@P 3@B", - " @N____ 3@B Docs: "++?BLU( "http://www.cuneiform-lang.org" ), - " \"W@@@WF3@B Code: "++?BLU( "https://github.com/joergen7/cuneiform" ) + " @N____ 3@B "++?BLU( "http://www.cuneiform-lang.org" ), + " \"W@@@WF3@B" ], "\n" ). diff --git a/src/cf_sup.erl b/src/cf_sup.erl index 5298f60..b85954d 100644 --- a/src/cf_sup.erl +++ b/src/cf_sup.erl @@ -20,6 +20,8 @@ -module( cf_sup ). -author( "Jorgen Brandt " ). +-vsn( "2.2.0-snapshot" ). + -behaviour( supervisor ). diff --git a/src/condor.erl b/src/condor.erl index 97de031..0cc00fe 100644 --- a/src/condor.erl +++ b/src/condor.erl @@ -20,6 +20,8 @@ -module( condor ). -author( "Jorgen Brandt " ). +-vsn( "2.2.0-snapshot" ). + -include( "cuneiform.hrl" ). @@ -29,69 +31,101 @@ init( _ModArg ) -> - BaseDir = local:create_basedir( ?BASEDIR, 1 ), {ok, BaseDir}. -handle_submit( _Lam, _Fa, R, _DataDir, _LibMap, BaseDir ) -> +handle_submit( Lam, Fa, R, DataDir, LibMap, BaseDir ) -> + CreRef = self(), + _Pid = spawn_link( fun() -> CreRef ! stage( Lam, Fa, R, DataDir, LibMap, BaseDir ) end ), + ok. - Dir = local:create_workdir( BaseDir, ?WORK, R ), - _RepoDir = string:join( [BaseDir, ?REPO], "/" ), - - LogFile = string:join( [Dir, "_log.txt"], "/" ), - SumFile = string:join( [Dir, "_summary.txt"], "/" ), - OutputFile = string:join( [Dir, "_output.txt"], "/" ), - - SubmitMap = #{universe => "VANILLA", - executable => "/usr/local/bin/effi", - arguments => string:join( ["_request.txt", - SumFile], " " ), - should_transfer_files => "IF_NEEDED", - when_to_transfer_output => "ON_EXIT", - log => LogFile, - output => OutputFile, - environment => ["\"", - string:join( ["HOME=.", - "PATH=/bin:/usr/bin:/usr/local/bin"], " " ), - "\""], - initialdir => Dir - }, - - SubmitStr = condor_submit:format_submit( SubmitMap ), - error_logger:info_msg( "~s~n", [SubmitStr] ), - - SubmitFile = string:join( [Dir, "_job.sub"], "/" ), - - ok = file:write_file( SubmitFile, SubmitStr ), - - _Response = os:cmd( string:join( ["condor_submit", SubmitFile], " " ) ), - - CreRef = self(), - F = fun() -> condor_wait( CreRef, R, LogFile, SumFile, OutputFile ) end, - _Pid = spawn_link( F ), - ok. +stage( Lam={lam, _LamLine, _LamName, {sign, Lo, Li}, _Body}, Fa, R, DataDir, + LibMap, BaseDir ) -> + Dir = local:create_workdir( BaseDir, ?WORK, R ), + RepoDir = string:join( [BaseDir, ?REPO], "/" ), + + % resolve input files + Triple1 = refactor:get_refactoring( Li, Fa, Dir, [DataDir, RepoDir], R ), + {RefactorLst1, MissingLst1, Fa1} = Triple1, + + case MissingLst1 of + [_|_] -> {failed, precond, R, MissingLst1}; + [] -> + + % link in input files + refactor:apply_refactoring( RefactorLst1 ), + + + LogFile = string:join( [Dir, "_log.txt"], "/" ), + OutputFile = string:join( [Dir, "_output.txt"], "/" ), + SubmitFile = string:join( [Dir, "_job.sub"], "/" ), + EffiSumFile = string:join( [Dir, "_summary.effi"], "/" ), + EffiRequestFile = string:join( [Dir, "_request.effi"], "/" ), + + SubmitMap = #{universe => "VANILLA", + executable => "/usr/local/bin/effi", + arguments => string:join( [EffiRequestFile, + EffiSumFile], " " ), + should_transfer_files => "IF_NEEDED", + when_to_transfer_output => "ON_EXIT", + log => LogFile, + output => OutputFile, + environment => ["\"", + string:join( ["HOME=.", + "PATH=/bin:/usr/bin:/usr/local/bin"], " " ), + "\""], + initialdir => Dir + }, + + % write Effi submit file + EffiRequest = {Lam, Fa1, R}, + EffiRequestStr = io_lib:format( "~p.~n", [EffiRequest] ), + ok = file:write_file( EffiRequestFile, EffiRequestStr ), + + % write HTCondor submit file + SubmitStr = condor_submit:format_submit( SubmitMap ), + ok = file:write_file( SubmitFile, SubmitStr ), + error_logger:info_msg( "~s~n", [SubmitStr] ), + + % submit job + _Response1 = os:cmd( string:join( ["condor_submit", SubmitFile], " " ) ), + + % wait until the job terminates + _Response2 = os:cmd( string:join( ["condor_wait", LogFile], " " ) ), + + {ok, B} = file:read_file( EffiSumFile ), + {ok, Tokens, _} = erl_scan:string( binary_to_list( B ) ), + {ok, Sum} = erl_parse:parse_term( Tokens ), -condor_wait( CreRef, R, LogFile, SumFile, OutputFile ) -> + case maps:get( state, Sum ) of - % wait until the job terminates - _Response = os:cmd( string:join( ["condor_wait", LogFile], " " ) ), + ok -> - case filelib:is_file( SumFile ) of + % resolve output files + RMap = maps:get( ret, Sum ), + {lam, _Line, _LamName, Sign, _Body} = Lam, + {sign, Lo, _Li} = Sign, + {RefactorLst, [], RMap1} = refactor:get_refactoring( Lo, RMap, Dir, [Dir], R ), + ok = refactor:apply_refactoring( RefactorLst ), - false -> - {ok, Out} = file:read_file( OutputFile ), - CreRef ! {failed, script_error, R, {"", re:split( Out, "\\n" )}}; % TODO: extract actual script + {finished, maps:put( ret, RMap1, Sum )}; - true -> - {ok, B} = file:read_file( SumFile ), - {ok, Tokens, _} = erl_scan:string( binary_to_list( B ) ), - {ok, Sum} = erl_parse:parse_term( Tokens ), - CreRef ! {finished, Sum} + + + script_error -> + #{actscript := ActScript, out := Out} = Sum, + {failed, script_error, R, {ActScript, Out}}; + + R1 -> + #{missing := MissingLst2} = Sum, + {failed, R1, R, MissingLst2} + end end. + diff --git a/src/cuneiform.erl b/src/cuneiform.erl index e32b412..0cb823f 100644 --- a/src/cuneiform.erl +++ b/src/cuneiform.erl @@ -20,7 +20,7 @@ -module( cuneiform ). -author( "Jorgen Brandt " ). --vsn( "2.2.0" ). +-vsn( "2.2.0-snapshot" ). % API -export( [main/1, file/2, start/3, reduce/4, get_vsn/0, format_result/1, format_error/1] ). diff --git a/src/cuneiform_app.erl b/src/cuneiform_app.erl index 61e0531..c7fba8a 100644 --- a/src/cuneiform_app.erl +++ b/src/cuneiform_app.erl @@ -21,6 +21,8 @@ -module( cuneiform_app ). -author( "Jorgen Brandt " ). +-vsn( "2.2.0-snapshot" ). + -behaviour( application ). diff --git a/src/gen_queue.erl b/src/gen_queue.erl index 75f246b..1f39cbe 100644 --- a/src/gen_queue.erl +++ b/src/gen_queue.erl @@ -20,6 +20,8 @@ -module( gen_queue ). -author( "Jorgen Brandt " ). +-vsn( "2.2.0-snapshot" ). + -behaviour( gen_server ). %% ============================================================================= diff --git a/src/local.erl b/src/local.erl index ebc80fd..f58659c 100644 --- a/src/local.erl +++ b/src/local.erl @@ -20,6 +20,8 @@ -module( local ). -author( "Jorgen Brandt " ). +-vsn( "2.2.0-snapshot" ). + -include( "cuneiform.hrl" ). From 1fb3323cba35ccade037b7e2e063aebf9124fe9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Thu, 7 Apr 2016 11:40:51 +0200 Subject: [PATCH 70/78] Refactoring fixed. --- src/condor.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/condor.erl b/src/condor.erl index 0cc00fe..b53c546 100644 --- a/src/condor.erl +++ b/src/condor.erl @@ -109,7 +109,7 @@ stage( Lam={lam, _LamLine, _LamName, {sign, Lo, Li}, _Body}, Fa, R, DataDir, RMap = maps:get( ret, Sum ), {lam, _Line, _LamName, Sign, _Body} = Lam, {sign, Lo, _Li} = Sign, - {RefactorLst, [], RMap1} = refactor:get_refactoring( Lo, RMap, Dir, [Dir], R ), + {RefactorLst, [], RMap1} = refactor:get_refactoring( Lo, RMap, RepoDir, [Dir], R ), ok = refactor:apply_refactoring( RefactorLst ), {finished, maps:put( ret, RMap1, Sum )}; From 3a1f1a32945ef41be783467a4bed1ed9fb7ace42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Thu, 7 Apr 2016 12:12:06 +0200 Subject: [PATCH 71/78] Condor CRE now respects library path modifications. --- src/condor.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/condor.erl b/src/condor.erl index b53c546..6e2e9e9 100644 --- a/src/condor.erl +++ b/src/condor.erl @@ -82,7 +82,7 @@ stage( Lam={lam, _LamLine, _LamName, {sign, Lo, Li}, _Body}, Fa, R, DataDir, }, % write Effi submit file - EffiRequest = {Lam, Fa1, R}, + EffiRequest = {Lam, Fa1, R, LibMap}, EffiRequestStr = io_lib:format( "~p.~n", [EffiRequest] ), ok = file:write_file( EffiRequestFile, EffiRequestStr ), From 26ed7b6ab1bf062e8fa11105fb952cf6cdd07dfe Mon Sep 17 00:00:00 2001 From: Jorgen Brandt Date: Fri, 8 Apr 2016 07:54:05 +0200 Subject: [PATCH 72/78] Makefile simplified. --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 3dfad51..cf6a0ee 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,10 @@ all: compile compile: - rebar3 do compile, escriptize + rebar3 escriptize dev: - rebar3 do compile, escriptize, eunit, dialyzer, cover, edoc + rebar3 do escriptize, eunit, dialyzer, cover, edoc clean: rm -rf .rebar From ed5cb1606e87b40d1cd10c519c3610a59a5738b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Mon, 11 Apr 2016 11:23:55 +0200 Subject: [PATCH 73/78] Error reporting in HTCondor support improved. --- include/cuneiform.hrl | 2 +- src/cf_parse.yrl | 38 +++++++++++--------- src/cf_prescan.xrl | 35 +++++++++--------- src/cf_scan.xrl | 37 ++++++++++--------- src/cf_sem.erl | 33 ++++++++--------- src/cf_shell.erl | 33 ++++++++--------- src/cf_sup.erl | 33 ++++++++--------- src/condor.erl | 84 +++++++++++++++++++++++-------------------- src/condor_submit.erl | 34 +++++++++--------- src/cuneiform.erl | 33 ++++++++--------- src/cuneiform_app.erl | 34 +++++++++--------- src/gen_queue.erl | 33 ++++++++--------- src/lib_os.erl | 77 +++++++++++++++++++++++++++++++++++++++ src/local.erl | 33 ++++++++--------- 14 files changed, 321 insertions(+), 218 deletions(-) create mode 100644 src/lib_os.erl diff --git a/include/cuneiform.hrl b/include/cuneiform.hrl index df2bd36..dd0492e 100644 --- a/include/cuneiform.hrl +++ b/include/cuneiform.hrl @@ -1,4 +1,4 @@ --define( BUILD, "2016-03-22" ). +-define( BUILD, "2016-04-11" ). -define( RED( Str ), "\e[31m" ++ Str ++ "\e[0m" ). -define( BRED( Str ), "\e[1;31m" ++ Str ++ "\e[0m" ). diff --git a/src/cf_parse.yrl b/src/cf_parse.yrl index b868aad..5a9eae1 100644 --- a/src/cf_parse.yrl +++ b/src/cf_parse.yrl @@ -1,20 +1,23 @@ %% -*- erlang -*- -% -% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis -% -% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser -% -% Licensed under the Apache License, Version 2.0 (the "License"); -% you may not use this file except in compliance with the License. -% You may obtain a copy of the License at -% -% http://www.apache.org/licenses/LICENSE-2.0 -% -% Unless required by applicable law or agreed to in writing, software -% distributed under the License is distributed on an "AS IS" BASIS, -% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -% See the License for the specific language governing permissions and -% limitations under the License. +%% +%% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis +%% +%% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. + +%% @author Jörgen Brandt + %% ============================================================================= %% Symbol Declaration @@ -28,7 +31,7 @@ Nonterminals Terminals intlit strlit body bash beginif colon comma deftask else endif eq file in python r lbrace lparen lsquarebr ltag nil rbrace rparen rsquarebr rtag - semicolon string then id. + semicolon string then id perl. %% ============================================================================= @@ -56,6 +59,7 @@ defun -> deftask id sign lbrace assignlist rbrace : mk_natlam( '$1', '$2' defun -> deftask id sign in lang body : mk_forlam( '$1', '$2', '$3', '$5', '$6' ). lang -> bash : bash. +lang -> perl : perl. lang -> python : python. lang -> r : r. diff --git a/src/cf_prescan.xrl b/src/cf_prescan.xrl index d0bb36c..cf8db5d 100644 --- a/src/cf_prescan.xrl +++ b/src/cf_prescan.xrl @@ -1,20 +1,23 @@ %% -*- erlang -*- -% -% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis -% -% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser -% -% Licensed under the Apache License, Version 2.0 (the "License"); -% you may not use this file except in compliance with the License. -% You may obtain a copy of the License at -% -% http://www.apache.org/licenses/LICENSE-2.0 -% -% Unless required by applicable law or agreed to in writing, software -% distributed under the License is distributed on an "AS IS" BASIS, -% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -% See the License for the specific language governing permissions and -% limitations under the License. +%% +%% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis +%% +%% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. + +%% @author Jörgen Brandt + %% ============================================================================= %% Definitions diff --git a/src/cf_scan.xrl b/src/cf_scan.xrl index 78f250a..0facc26 100644 --- a/src/cf_scan.xrl +++ b/src/cf_scan.xrl @@ -1,20 +1,23 @@ %% -*- erlang -*- -% -% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis -% -% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser -% -% Licensed under the Apache License, Version 2.0 (the "License"); -% you may not use this file except in compliance with the License. -% You may obtain a copy of the License at -% -% http://www.apache.org/licenses/LICENSE-2.0 -% -% Unless required by applicable law or agreed to in writing, software -% distributed under the License is distributed on an "AS IS" BASIS, -% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -% See the License for the specific language governing permissions and -% limitations under the License. +%% +%% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis +%% +%% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. + +%% @author Jörgen Brandt + %% ============================================================================= %% Definitions @@ -24,6 +27,7 @@ Definitions. BASH = [Bb]ash +PERL = [Pp]erl PYTHON = [Pp]ython R = [Rr] @@ -69,6 +73,7 @@ WS = [\000-\s] Rules. {BASH} : {token, {bash, TokenLine, TokenChars}}. +{PERL} : {token, {perl, TokenLine, TokenChars}}. {PYTHON} : {token, {python, TokenLine, TokenChars}}. {R} : {token, {r, TokenLine, TokenChars}}. diff --git a/src/cf_sem.erl b/src/cf_sem.erl index b929e8f..0757cd4 100644 --- a/src/cf_sem.erl +++ b/src/cf_sem.erl @@ -1,23 +1,24 @@ %% -*- erlang -*- -% -% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis -% -% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser -% -% Licensed under the Apache License, Version 2.0 (the "License"); -% you may not use this file except in compliance with the License. -% You may obtain a copy of the License at -% -% http://www.apache.org/licenses/LICENSE-2.0 -% -% Unless required by applicable law or agreed to in writing, software -% distributed under the License is distributed on an "AS IS" BASIS, -% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -% See the License for the specific language governing permissions and -% limitations under the License. +%% +%% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis +%% +%% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. %% @author Jörgen Brandt + -module( cf_sem ). -author( "Jorgen Brandt " ). -vsn( "2.2.0-snapshot" ). diff --git a/src/cf_shell.erl b/src/cf_shell.erl index f668a89..dff555a 100644 --- a/src/cf_shell.erl +++ b/src/cf_shell.erl @@ -1,23 +1,24 @@ %% -*- erlang -*- -% -% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis -% -% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser -% -% Licensed under the Apache License, Version 2.0 (the "License"); -% you may not use this file except in compliance with the License. -% You may obtain a copy of the License at -% -% http://www.apache.org/licenses/LICENSE-2.0 -% -% Unless required by applicable law or agreed to in writing, software -% distributed under the License is distributed on an "AS IS" BASIS, -% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -% See the License for the specific language governing permissions and -% limitations under the License. +%% +%% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis +%% +%% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. %% @author Jörgen Brandt + -module( cf_shell ). -author( "Jorgen Brandt " ). -vsn( "2.2.0-snapshot" ). diff --git a/src/cf_sup.erl b/src/cf_sup.erl index b85954d..25964d2 100644 --- a/src/cf_sup.erl +++ b/src/cf_sup.erl @@ -1,23 +1,24 @@ %% -*- erlang -*- -% -% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis -% -% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser -% -% Licensed under the Apache License, Version 2.0 (the "License"); -% you may not use this file except in compliance with the License. -% You may obtain a copy of the License at -% -% http://www.apache.org/licenses/LICENSE-2.0 -% -% Unless required by applicable law or agreed to in writing, software -% distributed under the License is distributed on an "AS IS" BASIS, -% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -% See the License for the specific language governing permissions and -% limitations under the License. +%% +%% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis +%% +%% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. %% @author Jörgen Brandt + -module( cf_sup ). -author( "Jorgen Brandt " ). -vsn( "2.2.0-snapshot" ). diff --git a/src/condor.erl b/src/condor.erl index 6e2e9e9..4c8569a 100644 --- a/src/condor.erl +++ b/src/condor.erl @@ -1,20 +1,20 @@ %% -*- erlang -*- -% -% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis -% -% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser -% -% Licensed under the Apache License, Version 2.0 (the "License"); -% you may not use this file except in compliance with the License. -% You may obtain a copy of the License at -% -% http://www.apache.org/licenses/LICENSE-2.0 -% -% Unless required by applicable law or agreed to in writing, software -% distributed under the License is distributed on an "AS IS" BASIS, -% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -% See the License for the specific language governing permissions and -% limitations under the License. +%% +%% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis +%% +%% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. %% @author Jörgen Brandt @@ -92,37 +92,45 @@ stage( Lam={lam, _LamLine, _LamName, {sign, Lo, Li}, _Body}, Fa, R, DataDir, error_logger:info_msg( "~s~n", [SubmitStr] ), % submit job - _Response1 = os:cmd( string:join( ["condor_submit", SubmitFile], " " ) ), - - % wait until the job terminates - _Response2 = os:cmd( string:join( ["condor_wait", LogFile], " " ) ), + case lib_os:cmd( string:join( ["condor_submit", SubmitFile], " " ), Dir ) of - {ok, B} = file:read_file( EffiSumFile ), - {ok, Tokens, _} = erl_scan:string( binary_to_list( B ) ), - {ok, Sum} = erl_parse:parse_term( Tokens ), + {error, B1} -> {failed, cre_error, R, B1}; + ok -> - case maps:get( state, Sum ) of + % wait until the job terminates + case lib_os:cmd( string:join( ["condor_wait", LogFile], " " ), Dir ) of - ok -> + {error, B2} -> {failed, cre_error, R, B2}; + ok -> - % resolve output files - RMap = maps:get( ret, Sum ), - {lam, _Line, _LamName, Sign, _Body} = Lam, - {sign, Lo, _Li} = Sign, - {RefactorLst, [], RMap1} = refactor:get_refactoring( Lo, RMap, RepoDir, [Dir], R ), - ok = refactor:apply_refactoring( RefactorLst ), + {ok, B} = file:read_file( EffiSumFile ), + {ok, Tokens, _} = erl_scan:string( binary_to_list( B ) ), + {ok, Sum} = erl_parse:parse_term( Tokens ), - {finished, maps:put( ret, RMap1, Sum )}; + case maps:get( state, Sum ) of + ok -> + % resolve output files + RMap = maps:get( ret, Sum ), + {lam, _Line, _LamName, Sign, _Body} = Lam, + {sign, Lo, _Li} = Sign, + {RefactorLst, [], RMap1} = refactor:get_refactoring( Lo, RMap, RepoDir, [Dir], R ), + ok = refactor:apply_refactoring( RefactorLst ), - script_error -> - #{actscript := ActScript, out := Out} = Sum, - {failed, script_error, R, {ActScript, Out}}; + {finished, maps:put( ret, RMap1, Sum )}; - R1 -> - #{missing := MissingLst2} = Sum, - {failed, R1, R, MissingLst2} + script_error -> + + #{actscript := ActScript, out := Out} = Sum, + {failed, script_error, R, {ActScript, Out}}; + + R1 -> + + #{missing := MissingLst2} = Sum, + {failed, R1, R, MissingLst2} + end + end end end. diff --git a/src/condor_submit.erl b/src/condor_submit.erl index 2fd31fc..eab41e9 100644 --- a/src/condor_submit.erl +++ b/src/condor_submit.erl @@ -1,21 +1,21 @@ %% -*- erlang -*- -% -% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis -% -% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser -% -% Licensed under the Apache License, Version 2.0 (the "License"); -% you may not use this file except in compliance with the License. -% You may obtain a copy of the License at -% -% http://www.apache.org/licenses/LICENSE-2.0 -% -% Unless required by applicable law or agreed to in writing, software -% distributed under the License is distributed on an "AS IS" BASIS, -% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -% See the License for the specific language governing permissions and -% limitations under the License. -% +%% +%% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis +%% +%% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. + %% @author Irina Guberman %% @author Jörgen Brandt diff --git a/src/cuneiform.erl b/src/cuneiform.erl index 0cb823f..1fdde1c 100644 --- a/src/cuneiform.erl +++ b/src/cuneiform.erl @@ -1,23 +1,24 @@ %% -*- erlang -*- -% -% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis -% -% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser -% -% Licensed under the Apache License, Version 2.0 (the "License"); -% you may not use this file except in compliance with the License. -% You may obtain a copy of the License at -% -% http://www.apache.org/licenses/LICENSE-2.0 -% -% Unless required by applicable law or agreed to in writing, software -% distributed under the License is distributed on an "AS IS" BASIS, -% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -% See the License for the specific language governing permissions and -% limitations under the License. +%% +%% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis +%% +%% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. %% @author Jörgen Brandt + -module( cuneiform ). -author( "Jorgen Brandt " ). -vsn( "2.2.0-snapshot" ). diff --git a/src/cuneiform_app.erl b/src/cuneiform_app.erl index c7fba8a..efd785d 100644 --- a/src/cuneiform_app.erl +++ b/src/cuneiform_app.erl @@ -1,24 +1,24 @@ - %% -*- erlang -*- -% -% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis -% -% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser -% -% Licensed under the Apache License, Version 2.0 (the "License"); -% you may not use this file except in compliance with the License. -% You may obtain a copy of the License at -% -% http://www.apache.org/licenses/LICENSE-2.0 -% -% Unless required by applicable law or agreed to in writing, software -% distributed under the License is distributed on an "AS IS" BASIS, -% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -% See the License for the specific language governing permissions and -% limitations under the License. +%% +%% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis +%% +%% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. %% @author Jörgen Brandt + -module( cuneiform_app ). -author( "Jorgen Brandt " ). -vsn( "2.2.0-snapshot" ). diff --git a/src/gen_queue.erl b/src/gen_queue.erl index 1f39cbe..233bf23 100644 --- a/src/gen_queue.erl +++ b/src/gen_queue.erl @@ -1,23 +1,24 @@ %% -*- erlang -*- -% -% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis -% -% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser -% -% Licensed under the Apache License, Version 2.0 (the "License"); -% you may not use this file except in compliance with the License. -% You may obtain a copy of the License at -% -% http://www.apache.org/licenses/LICENSE-2.0 -% -% Unless required by applicable law or agreed to in writing, software -% distributed under the License is distributed on an "AS IS" BASIS, -% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -% See the License for the specific language governing permissions and -% limitations under the License. +%% +%% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis +%% +%% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. %% @author Jörgen Brandt + -module( gen_queue ). -author( "Jorgen Brandt " ). -vsn( "2.2.0-snapshot" ). diff --git a/src/lib_os.erl b/src/lib_os.erl new file mode 100644 index 0000000..8fea4b3 --- /dev/null +++ b/src/lib_os.erl @@ -0,0 +1,77 @@ +%% -*- erlang -*- +%% +%% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis +%% +%% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. + +%% @author Jörgen Brandt + +-module( lib_os ). +-vsn( "2.2.0-snapshot" ). +-author( "Jorgen Brandt " ). + +-export( [cmd/2] ). + +-define( BUF_SIZE, 1024 ). + + + + +-spec cmd( Cmd::string(), Dir::string() ) -> ok | {error, binary()}. + +cmd( Cmd, Dir ) when is_list( Cmd ), is_list( Dir ) -> + + Port = open_port( {spawn, Cmd}, + [exit_status, + stderr_to_stdout, + binary, + {cd, Dir}, + {line, ?BUF_SIZE}] ), + + listen_port( Port, <<>> ). + + + + + +-spec listen_port( Port::port(), OutAcc::binary() ) -> ok | {error, binary()}. + +listen_port( Port, OutAcc ) when is_port( Port ), is_binary( OutAcc ) -> + + receive + + % no line feed, buffer line and continue + {Port, {data, {noeol, PartLine}}} -> + OutAcc1 = <>, + listen_port( Port, OutAcc1 ); + + % line feed encountered + {Port, {data, {eol, PartLine}}} -> + OutAcc1 = <>, + listen_port( Port, OutAcc1 ); + + % process succeeded + {Port, {exit_status, 0}} -> + ok; + + % process failed + {Port, {exit_status, _}} -> + {error, OutAcc}; + + % if nothing matches, raise error + Msg -> + error( {bad_msg, Msg} ) + + end. diff --git a/src/local.erl b/src/local.erl index f58659c..b792b75 100644 --- a/src/local.erl +++ b/src/local.erl @@ -1,23 +1,24 @@ %% -*- erlang -*- -% -% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis -% -% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser -% -% Licensed under the Apache License, Version 2.0 (the "License"); -% you may not use this file except in compliance with the License. -% You may obtain a copy of the License at -% -% http://www.apache.org/licenses/LICENSE-2.0 -% -% Unless required by applicable law or agreed to in writing, software -% distributed under the License is distributed on an "AS IS" BASIS, -% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -% See the License for the specific language governing permissions and -% limitations under the License. +%% +%% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis +%% +%% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. %% @author Jörgen Brandt + -module( local ). -author( "Jorgen Brandt " ). -vsn( "2.2.0-snapshot" ). From 1fdb9f5f8230f9f7caeb18fc48477ba9508b0604 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Mon, 11 Apr 2016 15:30:25 +0200 Subject: [PATCH 74/78] Bug in enumeration fixed. --- src/cf_sem.erl | 28 +++++++++++++++++++++++++--- test/cf_sem_test.erl | 28 +++++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/src/cf_sem.erl b/src/cf_sem.erl index 0757cd4..56bc507 100644 --- a/src/cf_sem.erl +++ b/src/cf_sem.erl @@ -294,7 +294,7 @@ estep( L=[H={correl, Lc}|T], F ) when length( Lc ) > 1 -> case Pen of false -> [{L, F}]; % (72) true -> - Z = corrstep( Lc, F, F ), + Z = corr( Lc, F ), aug( [{T, G} || G <- Z], H ) % (73) end. @@ -315,8 +315,18 @@ aug_argpair( {L0, F}, {correl, Lc} ) -> %% Correlation %% +-spec corr( Lc, F ) -> [#{string() => [expr()]}] +when Lc :: [name()], + F :: #{string() => [expr()]}. + +corr( Lc, F ) -> + case corrstep( Lc, F, F ) of + [] -> []; + [H,T] -> [H|corr( Lc, T )] + end. + -spec corrstep( Lc, Facc, F0 ) -> [#{string() => [expr()]}] % (79) -when Lc :: [string()], +when Lc :: [name()], Facc :: #{string() => [expr()]}, F0 :: #{string() => [expr()]}. @@ -556,7 +566,19 @@ can_augment_argpairlist_with_correl_test() -> %% Correlation %% - +corrstep_should_separate_first_value_single_test() -> + Lc = [{name, "a", false}], + F0 = #{"a" => [{str, "1"}, {str, "2"}, {str, "3"}]}, + Y = [#{"a" => [{str, "1"}]}, #{"a" => [{str, "2"}, {str, "3"}]}], + X = corrstep( Lc, F0, F0 ), + ?assertEqual( Y, X ). + +corrstep_should_separate_first_value_two_test() -> + Lc = [{name, "a", false}, {name, "b", false}], + F0 = #{"a" => [{str, "1"}, {str, "2"}, {str, "3"}], "b" => [{str, "A"}, {str, "B"}, {str, "C"}]}, + Y = [#{"a" => [{str, "1"}], "b" => [{str, "A"}]}, #{"a" => [{str, "2"}, {str, "3"}], "b" => [{str, "B"}, {str, "C"}]}], + X = corrstep( Lc, F0, F0 ), + ?assertEqual( Y, X ). diff --git a/test/cf_sem_test.erl b/test/cf_sem_test.erl index 9c75d38..c046368 100644 --- a/test/cf_sem_test.erl +++ b/test/cf_sem_test.erl @@ -164,7 +164,20 @@ cross_product_should_be_derivable_test() -> [?assertEqual( F1, cf_sem:eval( App1, ?THETA0 ) ), ?assertEqual( F2, cf_sem:eval( App2, ?THETA0 ) )]. -dot_product_should_be_derivable_test() -> +dot_product_should_be_derivable1_test() -> + Sign = {sign, [{param, {name, "out1", false}, false}, {param, {name, "out2", false}, false}], + [{correl, [{name, "p1", false}, {name, "p2", false}]}]}, + E1 = [{str, "A"}], + E2 = [{str, "1"}], + Body = {natbody, #{"out1" => [{var, 5, "p1"}], "out2" => [{var, 6, "p2"}]}}, + Lam = {lam, 7, "f", Sign, Body}, + Binding = #{"p1" => E1, "p2" => E2}, + App1 = [{app, 8, 1, Lam, Binding}], + App2 = [{app, 9, 2, Lam, Binding}], + [?assertEqual( E1, cf_sem:eval( App1, ?THETA0 ) ), + ?assertEqual( E2, cf_sem:eval( App2, ?THETA0 ) )]. + +dot_product_should_be_derivable2_test() -> Sign = {sign, [{param, {name, "out1", false}, false}, {param, {name, "out2", false}, false}], [{correl, [{name, "p1", false}, {name, "p2", false}]}]}, E1 = [{str, "A"}, {str, "B"}], @@ -177,6 +190,19 @@ dot_product_should_be_derivable_test() -> [?assertEqual( E1, cf_sem:eval( App1, ?THETA0 ) ), ?assertEqual( E2, cf_sem:eval( App2, ?THETA0 ) )]. +dot_product_should_be_derivable3_test() -> + Sign = {sign, [{param, {name, "out1", false}, false}, {param, {name, "out2", false}, false}], + [{correl, [{name, "p1", false}, {name, "p2", false}]}]}, + E1 = [{str, "A"}, {str, "B"}, {str, "C"}], + E2 = [{str, "1"}, {str, "2"}, {str, "3"}], + Body = {natbody, #{"out1" => [{var, 5, "p1"}], "out2" => [{var, 6, "p2"}]}}, + Lam = {lam, 7, "f", Sign, Body}, + Binding = #{"p1" => E1, "p2" => E2}, + App1 = [{app, 8, 1, Lam, Binding}], + App2 = [{app, 9, 2, Lam, Binding}], + [?assertEqual( E1, cf_sem:eval( App1, ?THETA0 ) ), + ?assertEqual( E2, cf_sem:eval( App2, ?THETA0 ) )]. + aggregate_should_consume_whole_list_test() -> Sign = {sign, [{param, {name, "out", false}, true}], [{param, {name, "inp", false}, true}]}, From 82e3b6fe38ab7f1e67f28ed8fe04910242596c55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Mon, 11 Apr 2016 16:11:54 +0200 Subject: [PATCH 75/78] Installation procedure added to Makefile. --- Makefile | 13 +- src/condor.erl | 25 +++- src/condor_submit.erl | 309 ------------------------------------------ src/local.erl | 8 +- 4 files changed, 35 insertions(+), 320 deletions(-) delete mode 100644 src/condor_submit.erl diff --git a/Makefile b/Makefile index cf6a0ee..f62d110 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,15 @@ -all: compile +XRL=cf_scan cf_prescan +YRL=cf_parse +SRC=cf_cre cf_sem cf_shell cf_sup condor cuneiform cuneiform_app gen_queue lib_os local +INC=cuneiform +PWD=$(shell pwd) -compile: +all: _build/default/bin/cuneiform + +install: _build/default/bin/cuneiform + ln -sf $(PWD)/_build/default/bin/cuneiform /usr/local/bin/cuneiform + +_build/default/bin/cuneiform: $(SRC:%=src/%.erl) $(INC:%=include/%.hrl) $(XRL:%=src/%.xrl) $(YRL:%=src/%.yrl) rebar3 escriptize dev: diff --git a/src/condor.erl b/src/condor.erl index 4c8569a..ff77041 100644 --- a/src/condor.erl +++ b/src/condor.erl @@ -49,7 +49,7 @@ stage( Lam={lam, _LamLine, _LamName, {sign, Lo, Li}, _Body}, Fa, R, DataDir, RepoDir = string:join( [BaseDir, ?REPO], "/" ), % resolve input files - Triple1 = refactor:get_refactoring( Li, Fa, Dir, [DataDir, RepoDir], R ), + Triple1 = lib_refactor:get_refactoring( Li, Fa, Dir, [DataDir, RepoDir], R ), {RefactorLst1, MissingLst1, Fa1} = Triple1, case MissingLst1 of @@ -57,7 +57,7 @@ stage( Lam={lam, _LamLine, _LamName, {sign, Lo, Li}, _Body}, Fa, R, DataDir, [] -> % link in input files - refactor:apply_refactoring( RefactorLst1 ), + lib_refactor:apply_refactoring( RefactorLst1 ), LogFile = string:join( [Dir, "_log.txt"], "/" ), @@ -87,7 +87,7 @@ stage( Lam={lam, _LamLine, _LamName, {sign, Lo, Li}, _Body}, Fa, R, DataDir, ok = file:write_file( EffiRequestFile, EffiRequestStr ), % write HTCondor submit file - SubmitStr = condor_submit:format_submit( SubmitMap ), + SubmitStr = format_submit( SubmitMap ), ok = file:write_file( SubmitFile, SubmitStr ), error_logger:info_msg( "~s~n", [SubmitStr] ), @@ -115,8 +115,8 @@ stage( Lam={lam, _LamLine, _LamName, {sign, Lo, Li}, _Body}, Fa, R, DataDir, RMap = maps:get( ret, Sum ), {lam, _Line, _LamName, Sign, _Body} = Lam, {sign, Lo, _Li} = Sign, - {RefactorLst, [], RMap1} = refactor:get_refactoring( Lo, RMap, RepoDir, [Dir], R ), - ok = refactor:apply_refactoring( RefactorLst ), + {RefactorLst, [], RMap1} = lib_refactor:get_refactoring( Lo, RMap, RepoDir, [Dir], R ), + ok = lib_refactor:apply_refactoring( RefactorLst ), {finished, maps:put( ret, RMap1, Sum )}; @@ -136,4 +136,19 @@ stage( Lam={lam, _LamLine, _LamName, {sign, Lo, Li}, _Body}, Fa, R, DataDir, +%% @doc Takes a Condor submit map and formats it as a binary. +%% +%% Takes the Condor submit map and produces a string having 'key = value' +%% format. The order of key-value pairs in the output binary is undefined. +%% The resulting binary is a complete, valid condor submit file leaving it +%% to the caller to write the content to disk. +%% +-spec format_submit( Condorparams0 ) -> binary() +when Condorparams0::#{atom() => string() | [string()]}. + +format_submit(CondorParams0) -> + CondorParams1 = input_files_to_cs_string(CondorParams0), + LineSep = io_lib:nl(), + SubmitFileStr = maps:fold(fun(K, V, Acc) -> [Acc, io_lib:format("~p = ~s", [K,V]), LineSep] end, "", CondorParams1), + iolist_to_binary([LineSep, lists:flatten(SubmitFileStr), LineSep, "Queue", LineSep]). diff --git a/src/condor_submit.erl b/src/condor_submit.erl deleted file mode 100644 index eab41e9..0000000 --- a/src/condor_submit.erl +++ /dev/null @@ -1,309 +0,0 @@ -%% -*- erlang -*- -%% -%% Cuneiform: A Functional Language for Large Scale Scientific Data Analysis -%% -%% Copyright 2016 Jörgen Brandt, Marc Bux, and Ulf Leser -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. - - -%% @author Irina Guberman -%% @author Jörgen Brandt -%% -%% @doc Management Condor submit files. -%% -%% This utility module produces the content of a condor_submit file from 3 -%% sources of possible inputs in the following order of priority if there is a -%% parameter key conflict: -%% -%% 1. Mandatory CF condor parameters: executable, log, error, output -%% -%% 2. Optional task-level condor parameters, i.e. universe, RequestMemory, RequestCpus -%% -%% 3. Optional default condor parameters, i.e. universe, should_transfer_files, etc. -%% -%% One exception is transfer_input_files: instead of choosing just one of the corresponding -%% lists, the lists are merged. This way any custom input files can be specified as well. -%% -%% -%% Is specifying custom input files actually a good idea? -%% (i) It is a way to introduce a file avoiding to define it as a tasks -%% argument. (It is a side-effect.) -%% (ii) Imho, the semantics of the workflow script should never change due to -%% an annotation. Annotations should only be for giving additional -%% info to speed up execution. -%% -%% -%% Also, input file names are validated to be real files, therefore transfer_input_files param -%% is the only one expected to be a list of files rather than a complete string and it will -%% be converted back to comma-separated string once the validation and possibly merging is done -%% -%% -%% Validation is not necessary here. Effi checks if all files exist, before it -%% starts and fails if something is missing. It doesn't depend on Condor submit -%% info, though. Representing lists in the Condor submit file as lists in the -%% submit map is an excellent idea though. -%% -%% -%% Mandatory condor parameters that aren't provided in either of the sources of -%% possible inputs will be filled in with VANILLA_DEFAULTS. - --module(condor_submit). - --ifdef( TEST ). --include_lib( "eunit/include/eunit.hrl" ). --endif. - -% API --export( [generate_condor_submit/1, generate_condor_submit/2, - generate_condor_submit/3] ). - -% provisionary export to make all module functions, their prototypes and -% documentations visible in the docs. --export( [validate_input_files/1, combine_params/2, input_files_to_cs_string/1, - format_submit/1] ). - --define(VANILLA_DEFAULTS, - #{universe => "vanilla", - should_transfer_files => "YES", - run_as_owner => "True", % is this one really necessary? - when_to_transfer_output => "ON_EXIT"}). - -%% -%% This method expects 1 argument -%% 1. Mandatory CF-generated condor parameters, like 'executable', 'log', etc. -%% All the missing necessary parameters like 'universe' will be filled default values -generate_condor_submit(CFParams) -> generate_condor_submit(CFParams, #{}). -%% -%% This method expects 2 arguments: -%% 1. Mandatory CF-generated condor parameters, like 'executable', 'log', etc. -%% 2. declared default condor parameters -%% -generate_condor_submit(#{ executable := Executable, - log := Log, - output := Output, - error := Error, - initialdir := InitialDir} = CFParams, - DeclaredParams) when - is_list(Executable), length(Executable) > 0, - is_list(Log), length(Log) > 0, - is_list(Output), length(Output) > 0, - is_list(Error), length(Error) > 0, - is_list(InitialDir), length(InitialDir) > 0, - is_map(DeclaredParams) -> - CondorParams0 = combine_params(CFParams, DeclaredParams), - CondorParams = maps:merge(?VANILLA_DEFAULTS, CondorParams0), - format_submit(CondorParams). - -%% -%% This method expects 3 arguments: -%% 1. Mandatory CF-generated condor parameters, like 'executable', 'log', etc. -%% 2. declared default condor parameters -%% 3. declared task-level condor parameters (any task-level parameters take precedence over defaults) -%% -generate_condor_submit(CFParams, DeclaredDefaultParams, DeclaredTaskParams) - when is_map(DeclaredDefaultParams), is_map(DeclaredTaskParams)-> - DefaultParams = combine_params(DeclaredTaskParams, DeclaredDefaultParams), - generate_condor_submit(CFParams, DefaultParams). - - -%% INTERNAL methods - - -%% @doc Extracts the transfer_input_files field from a Condor submit map and -%% checks if all listed files exist. -%% -%% Returns a Condor submit map having a non-empty transfer_input_files -%% field or none at all. Throws an error if an input file does not exist. -%% --spec validate_input_files( Params ) -> #{atom() => string() | [string()]} -when Params :: #{atom() => string() | [string()]}. - -validate_input_files( #{ transfer_input_files := [] } = Params) -> - maps:remove(transfer_input_files, Params); - -validate_input_files( #{ transfer_input_files := InputFiles} = Params) - when is_list(InputFiles) -> - case lists:all(fun(Elem) -> filelib:is_file(Elem) end, InputFiles) of - true -> Params; - false -> {error, io_lib:format("Invalid input file(s) in ~p!", [InputFiles])} - end; - -validate_input_files(#{} = Params) -> Params. - - -%% @doc Combines parameters from two Condor submit maps. -%% -%% In compination, Params1 will take precedence over Params2. If there is -%% tranfer_input_files parameter present in both it will merge the list of -%% input files into one. -%% --spec combine_params( Params1, Params2 ) -> #{atom() => string() | [string()]} -when Params1 :: #{atom() => string() | [string()]}, - Params2 :: #{atom() => string() | [string()]}. - -combine_params( #{ transfer_input_files := InputFiles1 } = Params1, - #{ transfer_input_files := InputFiles2 } = Params2 ) - when is_list(InputFiles1), is_list(InputFiles2) -> - InputFiles = InputFiles1 ++ InputFiles2, - combine_params( - maps:put(transfer_input_files, InputFiles, Params1), - maps:remove(transfer_input_files, Params2) - ); - -combine_params(Params1, Params2) when is_map(Params1), is_map(Params2) -> - maps:merge(validate_input_files(Params2), validate_input_files(Params1)). - - -%% @doc Converts the transfer_input_files field from a Condor submit map to a -%% comma-separated string. -%% -%% The only parameter that might come here as a list instead of complete -%% cs-string is transfer_input_files because it might be generated by -%% Cuneiform and it needs file validation. Therefore any declared -%% transfer_input_files params need to be first parsed from cs-string -%% into a list, and once they are validated and possibly merged, they are -%% converted back to cs-string here. -%% --spec input_files_to_cs_string( CondorParams ) -> #{atom() => string()} -when CondorParams :: #{atom() => string() | [string()]}. - -input_files_to_cs_string(#{transfer_input_files := InputFiles} = CondorParams) -> - InputFilesCS = string:join(InputFiles, ", "), - maps:put(transfer_input_files, InputFilesCS, CondorParams); - -input_files_to_cs_string(CondorParams) -> CondorParams. - -%% @doc Takes a Condor submit map and formats it as a binary. -%% -%% Takes the Condor submit map and produces a string having 'key = value' -%% format. The order of key-value pairs in the output binary is undefined. -%% The resulting binary is a complete, valid condor submit file leaving it -%% to the caller to write the content to disk. -%% --spec format_submit( Condorparams0 ) -> binary() -when Condorparams0::#{atom() => string() | [string()]}. - -format_submit(CondorParams0) -> - CondorParams1 = input_files_to_cs_string(CondorParams0), - LineSep = io_lib:nl(), - SubmitFileStr = maps:fold(fun(K, V, Acc) -> [Acc, io_lib:format("~p = ~s", [K,V]), LineSep] end, "", CondorParams1), - iolist_to_binary([LineSep, lists:flatten(SubmitFileStr), LineSep, "Queue", LineSep]). - - - - - - - - - - - --ifdef( TEST ). - --define (GOOD_CF_PARAMS, - #{ executable => "do_something.sh", - log => "job123.log", - output => "job123.stdout", - error => "job123.stderr", - initialdir => ".", - transfer_input_files => []}). - -%%% For testing with condor create `do_something.sh` in the same dir where you run -%%% `condor_submit /tmp/cf_params_test -cf_params_test() -> - CondorSubmitStr = generate_condor_submit(?GOOD_CF_PARAMS), - file:write_file("/tmp/cf_params_test", [CondorSubmitStr]). -%% condor_submit("/tmp/cf_params_test"). - -%%% If files at the end aren't deleted it produces a valid submitfile: /tmp/default_parameters_test -%%% If run with `condor_submit /tmp/default_parameters_test` -%%% Gives a `WARNING: the line 'docker_image = some_image:latest' was unused by condor_submit. Is it a typo?` -%%% Demonstrating that if some params or their combo are invalid condor will handle the errors/warnings -%%% So cuneiform doesn't have to yet it retains full power of condor submit -default_params_test() -> - DefaultParams = #{ universe => "docker", - docker_image => "some_image:latest", - transfer_input_files => ["/tmp/d1.tmp", "/tmp/d2.tmp"], - should_transfer_files => "NO" }, - - CFParams = maps:put(transfer_input_files, ["/tmp/cf1.tmp", "/tmp/cf2.tmp", "/tmp/cf3.tmp"], ?GOOD_CF_PARAMS), - -%% generate_condor_submit(CFParams, DefaultParams), - - Files = maps:get(transfer_input_files, DefaultParams) ++ maps:get(transfer_input_files, CFParams), - create_temp_files(Files), - CondorSubmitStr = generate_condor_submit(CFParams, DefaultParams), - file:write_file("/tmp/default_params_test", CondorSubmitStr). -%% condor_submit("/tmp/default_params_test"). - -% task_params_test() -> -% DefaultParams = #{ universe => "docker", -% docker_image => "some_image:latest", -% transfer_input_files => ["/tmp/d1.tmp", "/tmp/d2.tmp"], -% should_transfer_files => "NO" }, - -% TaskParams = #{ requestMemory => "256M", -% transfer_input_files => ["/tmp/t1.tmp", "/tmp/t2.tmp"]}, - -% CFParams = maps:put(transfer_input_files, ["/tmp/cf1.tmp", "/tmp/cf2.tmp", "/tmp/cf3.tmp"], ?GOOD_CF_PARAMS), - -% %% generate_condor_submit(CFParams, DefaultParams, TaskParams), - -% Files = maps:get(transfer_input_files, DefaultParams) ++ -% maps:get(transfer_input_files, TaskParams) ++ -% maps:get(transfer_input_files, CFParams), - -% CondorSubmitStr = generate_condor_submit(CFParams, DefaultParams, TaskParams), -% file:write_file("/tmp/task_params_test_error", CondorSubmitStr), - -% create_temp_files(Files), -% CondorSubmitStr = generate_condor_submit(CFParams, DefaultParams, TaskParams), -% file:write_file("/tmp/task_params_test", CondorSubmitStr). -%% condor_submit("/tmp/task_params_test"). - -create_temp_files(Files) when is_list(Files) -> - lists:foreach(fun(F) -> file:write_file(F, "") end, Files). - -%%% TODO: move out of here into CT, IMPROVE TEST COVERAGE, and uncomment condor_submits - -%% DELETE to test with condor -%% delete_temp_files(Files) -> -%% lists:foreach(fun(F) -> file:delete(F) end, Files). - -%% condor_submit(CondorSubmitFile) -> -%% Out = os:cmd(["condor_submit", CondorSubmitFile]), -%% OutFile = io_lib:format("/tmp/~s_submit_result", [CondorSubmitFile]), -%% file:write_file(OutFile, Out). - --endif. - - - - - - - - - - - - - - - - - - - diff --git a/src/local.erl b/src/local.erl index b792b75..7cb59d8 100644 --- a/src/local.erl +++ b/src/local.erl @@ -119,7 +119,7 @@ when is_list( Lo ), RepoDir = string:join( [BaseDir, ?REPO], "/" ), % resolve input files - Triple1 = refactor:get_refactoring( Li, Fa, Dir, [DataDir, RepoDir], R ), + Triple1 = lib_refactor:get_refactoring( Li, Fa, Dir, [DataDir, RepoDir], R ), {RefactorLst1, MissingLst1, Fa1} = Triple1, case MissingLst1 of @@ -127,7 +127,7 @@ when is_list( Lo ), [] -> % link in input files - refactor:apply_refactoring( RefactorLst1 ), + lib_refactor:apply_refactoring( RefactorLst1 ), % start effi case effi:check_run( Lam, Fa1, R, Dir, LibMap ) of @@ -139,11 +139,11 @@ when is_list( Lo ), Ret1 = maps:get( ret, Sum ), % resolve output files - Triple2 = refactor:get_refactoring( Lo, Ret1, RepoDir, [Dir], R ), + Triple2 = lib_refactor:get_refactoring( Lo, Ret1, RepoDir, [Dir], R ), {RefactorLst2, [], Ret2} = Triple2, % link out output files - refactor:apply_refactoring( RefactorLst2 ), + lib_refactor:apply_refactoring( RefactorLst2 ), % update result map {finished, Sum#{ret => Ret2}} From 740993c7b3309fc8903953563d80ea6237e56aba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Mon, 11 Apr 2016 16:14:43 +0200 Subject: [PATCH 76/78] Missing function added. --- src/condor.erl | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/condor.erl b/src/condor.erl index ff77041..0863a4d 100644 --- a/src/condor.erl +++ b/src/condor.erl @@ -152,3 +152,21 @@ format_submit(CondorParams0) -> SubmitFileStr = maps:fold(fun(K, V, Acc) -> [Acc, io_lib:format("~p = ~s", [K,V]), LineSep] end, "", CondorParams1), iolist_to_binary([LineSep, lists:flatten(SubmitFileStr), LineSep, "Queue", LineSep]). +%% @doc Converts the transfer_input_files field from a Condor submit map to a +%% comma-separated string. +%% +%% The only parameter that might come here as a list instead of complete +%% cs-string is transfer_input_files because it might be generated by +%% Cuneiform and it needs file validation. Therefore any declared +%% transfer_input_files params need to be first parsed from cs-string +%% into a list, and once they are validated and possibly merged, they are +%% converted back to cs-string here. +%% +-spec input_files_to_cs_string( CondorParams ) -> #{atom() => string()} +when CondorParams :: #{atom() => string() | [string()]}. + +input_files_to_cs_string(#{transfer_input_files := InputFiles} = CondorParams) -> + InputFilesCS = string:join(InputFiles, ", "), + maps:put(transfer_input_files, InputFilesCS, CondorParams); + +input_files_to_cs_string(CondorParams) -> CondorParams. \ No newline at end of file From 1e41be40a8e6250c4d9de0eefc925b3b0c82dfc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rgen=20Brandt?= Date: Mon, 11 Apr 2016 16:16:11 +0200 Subject: [PATCH 77/78] Authorship extended. --- src/condor.erl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/condor.erl b/src/condor.erl index 0863a4d..6413bc4 100644 --- a/src/condor.erl +++ b/src/condor.erl @@ -17,9 +17,11 @@ %% limitations under the License. %% @author Jörgen Brandt +%% @author Irina Guberman -module( condor ). -author( "Jorgen Brandt " ). +-author( "Irina Guberman " ). -vsn( "2.2.0-snapshot" ). From 9fe0a67d596286d37cee522a9da823faf5e30b20 Mon Sep 17 00:00:00 2001 From: Jorgen Brandt Date: Mon, 11 Apr 2016 19:36:38 +0200 Subject: [PATCH 78/78] Makefile simplified. --- Makefile | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index f62d110..c8b2e97 100644 --- a/Makefile +++ b/Makefile @@ -1,15 +1,11 @@ -XRL=cf_scan cf_prescan -YRL=cf_parse -SRC=cf_cre cf_sem cf_shell cf_sup condor cuneiform cuneiform_app gen_queue lib_os local -INC=cuneiform PWD=$(shell pwd) -all: _build/default/bin/cuneiform +all: compile -install: _build/default/bin/cuneiform +install: compile ln -sf $(PWD)/_build/default/bin/cuneiform /usr/local/bin/cuneiform -_build/default/bin/cuneiform: $(SRC:%=src/%.erl) $(INC:%=include/%.hrl) $(XRL:%=src/%.xrl) $(YRL:%=src/%.yrl) +compile: rebar3 escriptize dev: