diff --git a/isr-eclipse-plugin/.classpath b/isr-eclipse-plugin/.classpath new file mode 100644 index 0000000000000000000000000000000000000000..9fcbaba5baf35f1b31ead5d39ffb5f0b24206147 --- /dev/null +++ b/isr-eclipse-plugin/.classpath @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry exported="true" kind="lib" path="lib/xom-1.2.8.jar"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="src" path="src"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/isr-eclipse-plugin/.project b/isr-eclipse-plugin/.project new file mode 100644 index 0000000000000000000000000000000000000000..06d27cbecd297a0065a9377491f4806a5975d1cd --- /dev/null +++ b/isr-eclipse-plugin/.project @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>IsrGrammarEditorPlugIn</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/isr-eclipse-plugin/.settings/org.eclipse.jdt.core.prefs b/isr-eclipse-plugin/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000000000000000000000000000000000..55bf6b7dad1d197b65d20de4440b843ddf4c2b59 --- /dev/null +++ b/isr-eclipse-plugin/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Mon Sep 17 13:55:06 CEST 2012 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/isr-eclipse-plugin/META-INF/MANIFEST.MF b/isr-eclipse-plugin/META-INF/MANIFEST.MF new file mode 100644 index 0000000000000000000000000000000000000000..f036a901a8156c91dba9c3fb53f3234ca03fc923 --- /dev/null +++ b/isr-eclipse-plugin/META-INF/MANIFEST.MF @@ -0,0 +1,26 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: IsrGrammarPlugin +Bundle-SymbolicName: IsrGrammarPlugin;singleton:=true +Bundle-Version: 1.2.2 +Bundle-Vendor: Hendrik ter Horst +Require-Bundle: org.eclipse.core.runtime, + org.eclipse.ui, + org.eclipse.jface.text, + org.eclipse.ui.editors, + org.eclipse.ui.workbench.texteditor, + org.eclipse.ui.ide, + org.eclipse.core.resources, + org.apache.xerces, + org.eclipse.ui.views, + org.eclipse.jdt, + org.eclipse.jdt.core, + org.eclipse.jdt.ui, + org.eclipse.core.expressions, + org.eclipse.zest.layouts, + org.eclipse.zest.core +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-Activator: hterhors.Activator +Bundle-ClassPath: lib/xom-1.2.8.jar, + isreditor.jar +Bundle-ActivationPolicy: lazy diff --git a/isr-eclipse-plugin/RailroadGrammarDef.txt b/isr-eclipse-plugin/RailroadGrammarDef.txt new file mode 100644 index 0000000000000000000000000000000000000000..9f3af0739f519e8166d3bae6d5e8150066d2b49d --- /dev/null +++ b/isr-eclipse-plugin/RailroadGrammarDef.txt @@ -0,0 +1,8 @@ +GRAMMAR ::= (IGN_LIST | ( RULE_NUM ) RULE)+ +IGN_LIST ::= '%IGNORE' '=' ( TERMINAL )+ ';' +RULE_NUM ::= [0-9]+ +RULE ::= NONTERMINAL ':' BODY ( '|' BODY )* ';' +BODY ::= ( SYMBOL )* +SYMBOL ::= NONTERMINAL | TERMINAL +NONTERMINAL ::= ('$'|'$$')[a-zA-Z_"][a-zA-Z_-"0-9]* +TERMINAL ::= [a-zA-Z_"][a-zA-Z_-"0-9]* \ No newline at end of file diff --git a/isr-eclipse-plugin/TeX/Bibliographie.bib b/isr-eclipse-plugin/TeX/Bibliographie.bib new file mode 100644 index 0000000000000000000000000000000000000000..372e3922cac0746b742ac4308593971256cec791 --- /dev/null +++ b/isr-eclipse-plugin/TeX/Bibliographie.bib @@ -0,0 +1,109 @@ +% This file was created with JabRef 2.8.1. +% Encoding: Cp1252 + +@ARTICLE{GammarJar, + author = {Carl Burch and Lynn Ziegler}, + title = {Science of Computing Suite(SOCS) :Resources for a breadth-first introduction}, + journal = {Technical Symposium on Computer Science Education (SIGCSE)}, + year = {2004}, + owner = {Hendrik}, + timestamp = {2012.11.03} +} + +@ARTICLE{EarleyJay, + author = {Earley, Jay}, + title = {An efficient context-free parsing algorithm}, + journal = {Commun. ACM}, + year = {1970}, + volume = {13}, + pages = {94--102}, + number = {2}, + month = feb, + acmid = {362035}, + address = {New York, NY, USA}, + doi = {10.1145/362007.362035}, + issn = {0001-0782}, + issue_date = {Feb 1970}, + keywords = {compilers, computational complexity, context-free grammar, parsing, + syntax analysis}, + numpages = {9}, + publisher = {ACM}, + url = {http://doi.acm.org/10.1145/362007.362035} +} + +@INPROCEEDINGS{Fink, + author = {Fink, Gernot A.}, + title = {Developing HMM-Based Recognizers with ESMERALDA}, + booktitle = {Proceedings of the Second International Workshop on Text, Speech + and Dialogue}, + year = {1999}, + series = {TSD '99}, + pages = {229--234}, + address = {London, UK, UK}, + publisher = {Springer-Verlag}, + acmid = {720414}, + isbn = {3-540-66494-7}, + numpages = {6}, + url = {http://dl.acm.org/citation.cfm?id=647237.720414} +} + +@MANUAL{manpage, + title = {ESMERALDA-Manual - Format of grammar definitions}, + author = {Sven Wachsmuth \& Gernot A. Fink}, + timestamp = {2012.11.03} +} + +@ARTICLE{Eclipse, + author = {IBM Software Group, 2670 Queensview Drive, Ottawa, Ontario K2B 8K1, + Canada}, + title = {Eclipse: A platform for integrating development tools}, + journal = {IBM Systems Journal}, + year = {2004}, + volume = {43}, + pages = {371 - 383}, + owner = {Hendrik}, + timestamp = {2012.11.03} +} + +@ARTICLE{ExtensionsArchitekur, + author = {Manfred Henning, Heiko Seeberger}, + title = {Einführung in den "Extension Point"-Mechanismus von Eclipse}, + journal = {JavaSPEKTRUM}, + year = {2008}, + volume = {01}, + owner = {Hendrik}, + timestamp = {2012.11.03} +} + +@BOOK{Extensions, + title = {Development of an Open Source Software Framework as a Basis forImplementing + Plugin-Based Environmental ManagementInformation Systems (EMIS)}, + publisher = {Shaker Verlag}, + year = {2008}, + author = {Volker Wohlgemuth,Tobias Schnackenbeck, Dominik Panic and Robert-Lee + Barling}, + number = {ISBN: 978-3-8322-7313-2}, + pages = {584 - 590}, + timestamp = {2012.11.03} +} + +@BOOK{WortProbelmAlgo, + title = {Theoretische Informatik - eine algorithmenorientierte Einführung}, + publisher = {Teubner}, + year = {2008}, + author = {Ingo Wegener}, + pages = {156 - 158}, + owner = {Hendrik}, + timestamp = {2012.11.03} +} + +@comment{jabref-meta: selector_review:} + +@comment{jabref-meta: selector_publisher:} + +@comment{jabref-meta: selector_author:} + +@comment{jabref-meta: selector_journal:} + +@comment{jabref-meta: selector_keywords:} + diff --git a/isr-eclipse-plugin/TeX/Bilder/Auswertung.rar b/isr-eclipse-plugin/TeX/Bilder/Auswertung.rar new file mode 100644 index 0000000000000000000000000000000000000000..ac82ba58908c3e0ada749ef65f1514e0dc38fb44 Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/Auswertung.rar differ diff --git a/isr-eclipse-plugin/TeX/Bilder/Auswertung/A1zeitvgl.pdf b/isr-eclipse-plugin/TeX/Bilder/Auswertung/A1zeitvgl.pdf new file mode 100644 index 0000000000000000000000000000000000000000..216a218b64594b8dfe928bad63b40a806506f096 Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/Auswertung/A1zeitvgl.pdf differ diff --git a/isr-eclipse-plugin/TeX/Bilder/Auswertung/A2zeitvgl.pdf b/isr-eclipse-plugin/TeX/Bilder/Auswertung/A2zeitvgl.pdf new file mode 100644 index 0000000000000000000000000000000000000000..e1eb57eec2f3629907f418af7742b6f07eaf89bb Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/Auswertung/A2zeitvgl.pdf differ diff --git a/isr-eclipse-plugin/TeX/Bilder/Auswertung/A3zeitvgl.pdf b/isr-eclipse-plugin/TeX/Bilder/Auswertung/A3zeitvgl.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f601e3161e0bbaf980800b420d146b9724dc4e46 Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/Auswertung/A3zeitvgl.pdf differ diff --git a/isr-eclipse-plugin/TeX/Bilder/Auswertung/A8mitPlugin.pdf b/isr-eclipse-plugin/TeX/Bilder/Auswertung/A8mitPlugin.pdf new file mode 100644 index 0000000000000000000000000000000000000000..3c2028f044c8d7ef75d07da5f63b2c4068acfe54 Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/Auswertung/A8mitPlugin.pdf differ diff --git a/isr-eclipse-plugin/TeX/Bilder/Auswertung/A8ohnePlugin.pdf b/isr-eclipse-plugin/TeX/Bilder/Auswertung/A8ohnePlugin.pdf new file mode 100644 index 0000000000000000000000000000000000000000..e4fabf4bc174e7bf10712ab3c58fcd362fb45620 Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/Auswertung/A8ohnePlugin.pdf differ diff --git a/isr-eclipse-plugin/TeX/Bilder/Auswertung/F7A1vgl.pdf b/isr-eclipse-plugin/TeX/Bilder/Auswertung/F7A1vgl.pdf new file mode 100644 index 0000000000000000000000000000000000000000..9e1507f69376f5fa9f387625753a728a5ca5131e Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/Auswertung/F7A1vgl.pdf differ diff --git a/isr-eclipse-plugin/TeX/Bilder/Auswertung/F7A2vgl.pdf b/isr-eclipse-plugin/TeX/Bilder/Auswertung/F7A2vgl.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b4bbee7fc2d88a49366df7a5b4585b95941569fc Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/Auswertung/F7A2vgl.pdf differ diff --git a/isr-eclipse-plugin/TeX/Bilder/Auswertung/F7A3vgl.pdf b/isr-eclipse-plugin/TeX/Bilder/Auswertung/F7A3vgl.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b646180101c0b2f05332bac7412ab06973f3487c Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/Auswertung/F7A3vgl.pdf differ diff --git a/isr-eclipse-plugin/TeX/Bilder/Auswertung/Failvgl.pdf b/isr-eclipse-plugin/TeX/Bilder/Auswertung/Failvgl.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b53272bfd7aa45a1ef77b4d0558a7ed76d38ab8d Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/Auswertung/Failvgl.pdf differ diff --git a/isr-eclipse-plugin/TeX/Bilder/Auswertung/Lies mich.txt b/isr-eclipse-plugin/TeX/Bilder/Auswertung/Lies mich.txt new file mode 100644 index 0000000000000000000000000000000000000000..ac711964332dd40018db9f41d68df0e2e6562835 --- /dev/null +++ b/isr-eclipse-plugin/TeX/Bilder/Auswertung/Lies mich.txt @@ -0,0 +1,19 @@ +A1zeitvgl +A2zeitvgl +A3zeitvgl +Vergleichen die Zeit der versch. Aufgaben. links immer ohne und rechts mit Plugin +-------- + +A8mitPlugin +A8ohnePlugin +Zeigt wie nützlich die Funktionalitäten bewerten / eingeschätzt wurden +-------- + +F7A1vgl +F7A2vgl +F7A3vgl +Zeigt wie leicht die einzelnen Aufgaben gelöst werden konnten. +-------- + +Failvgl +Zeigt die gemachten Fehler in Prozent der drei Aufgaben. \ No newline at end of file diff --git a/isr-eclipse-plugin/TeX/Bilder/Autoformatter.pdf b/isr-eclipse-plugin/TeX/Bilder/Autoformatter.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8df495e127531340d77dfb1b42f21d3fd3141090 Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/Autoformatter.pdf differ diff --git a/isr-eclipse-plugin/TeX/Bilder/ContentAssistant.png b/isr-eclipse-plugin/TeX/Bilder/ContentAssistant.png new file mode 100644 index 0000000000000000000000000000000000000000..0c8abd9ff6e638461b1b300e8054c98e0df6e250 Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/ContentAssistant.png differ diff --git a/isr-eclipse-plugin/TeX/Bilder/Fehlermarkierung.png b/isr-eclipse-plugin/TeX/Bilder/Fehlermarkierung.png new file mode 100644 index 0000000000000000000000000000000000000000..f440810f85b830324a88f4c60f353c12fb715e4d Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/Fehlermarkierung.png differ diff --git a/isr-eclipse-plugin/TeX/Bilder/FunktionUberExtension.pdf b/isr-eclipse-plugin/TeX/Bilder/FunktionUberExtension.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f7637a8b5090d065a10b9590c68c980f532a8a7e Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/FunktionUberExtension.pdf differ diff --git a/isr-eclipse-plugin/TeX/Bilder/HyperLinks.pdf b/isr-eclipse-plugin/TeX/Bilder/HyperLinks.pdf new file mode 100644 index 0000000000000000000000000000000000000000..bb85c5eefba1b76db3dfcad6e615c7eb3912d326 Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/HyperLinks.pdf differ diff --git a/isr-eclipse-plugin/TeX/Bilder/ISRGrammatikEditor.pdf b/isr-eclipse-plugin/TeX/Bilder/ISRGrammatikEditor.pdf new file mode 100644 index 0000000000000000000000000000000000000000..6255f046e7a1dc3deba1705b10d12eeddee7831a Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/ISRGrammatikEditor.pdf differ diff --git a/isr-eclipse-plugin/TeX/Bilder/PluginArchitektur.pdf b/isr-eclipse-plugin/TeX/Bilder/PluginArchitektur.pdf new file mode 100644 index 0000000000000000000000000000000000000000..fb3c840df4dc5adf804d7f1050860f7504616349 Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/PluginArchitektur.pdf differ diff --git a/isr-eclipse-plugin/TeX/Bilder/RailroadAnhang/BODY.png b/isr-eclipse-plugin/TeX/Bilder/RailroadAnhang/BODY.png new file mode 100644 index 0000000000000000000000000000000000000000..d1cbacae062ad2ec52f3f31f1e4415039b251bc6 Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/RailroadAnhang/BODY.png differ diff --git a/isr-eclipse-plugin/TeX/Bilder/RailroadAnhang/GRAMMAR.png b/isr-eclipse-plugin/TeX/Bilder/RailroadAnhang/GRAMMAR.png new file mode 100644 index 0000000000000000000000000000000000000000..678e6738f36f33b401122f048f626701fceb75bb Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/RailroadAnhang/GRAMMAR.png differ diff --git a/isr-eclipse-plugin/TeX/Bilder/RailroadAnhang/IGN_LIST.png b/isr-eclipse-plugin/TeX/Bilder/RailroadAnhang/IGN_LIST.png new file mode 100644 index 0000000000000000000000000000000000000000..3b09d473f836be5c993d697b607123329af09e20 Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/RailroadAnhang/IGN_LIST.png differ diff --git a/isr-eclipse-plugin/TeX/Bilder/RailroadAnhang/NONTERMINAL.png b/isr-eclipse-plugin/TeX/Bilder/RailroadAnhang/NONTERMINAL.png new file mode 100644 index 0000000000000000000000000000000000000000..afaf535c87b4185b079c3bcb81d65b1459db5fee Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/RailroadAnhang/NONTERMINAL.png differ diff --git a/isr-eclipse-plugin/TeX/Bilder/RailroadAnhang/RULE.png b/isr-eclipse-plugin/TeX/Bilder/RailroadAnhang/RULE.png new file mode 100644 index 0000000000000000000000000000000000000000..caa51af601bbfc58b6b8f3df6efbf75cfe3b9bc2 Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/RailroadAnhang/RULE.png differ diff --git a/isr-eclipse-plugin/TeX/Bilder/RailroadAnhang/RULE_NUM.png b/isr-eclipse-plugin/TeX/Bilder/RailroadAnhang/RULE_NUM.png new file mode 100644 index 0000000000000000000000000000000000000000..ed53abf41e8d2415e5f9af29e9f22a377aa21685 Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/RailroadAnhang/RULE_NUM.png differ diff --git a/isr-eclipse-plugin/TeX/Bilder/RailroadAnhang/SYMBOL.png b/isr-eclipse-plugin/TeX/Bilder/RailroadAnhang/SYMBOL.png new file mode 100644 index 0000000000000000000000000000000000000000..0dbf22a1b35a43d62888126ce21a4330b84f8da1 Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/RailroadAnhang/SYMBOL.png differ diff --git a/isr-eclipse-plugin/TeX/Bilder/RailroadAnhang/TERMINAL.png b/isr-eclipse-plugin/TeX/Bilder/RailroadAnhang/TERMINAL.png new file mode 100644 index 0000000000000000000000000000000000000000..8e17b71bd856bc830ff5a9ec6eff842b110130f2 Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/RailroadAnhang/TERMINAL.png differ diff --git a/isr-eclipse-plugin/TeX/Bilder/SatzValidieren.png b/isr-eclipse-plugin/TeX/Bilder/SatzValidieren.png new file mode 100644 index 0000000000000000000000000000000000000000..cab83aa8974a84b935a76af9ea8f0f179bf26579 Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/SatzValidieren.png differ diff --git a/isr-eclipse-plugin/TeX/Bilder/Studie/Aufgaben.pdf b/isr-eclipse-plugin/TeX/Bilder/Studie/Aufgaben.pdf new file mode 100644 index 0000000000000000000000000000000000000000..566c19776f4e51810f9889ac3044a93368a87983 Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/Studie/Aufgaben.pdf differ diff --git a/isr-eclipse-plugin/TeX/Bilder/Studie/FragenMP.pdf b/isr-eclipse-plugin/TeX/Bilder/Studie/FragenMP.pdf new file mode 100644 index 0000000000000000000000000000000000000000..e8d0bfb0179a82b51048f9e131f3fbe757d50d88 Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/Studie/FragenMP.pdf differ diff --git a/isr-eclipse-plugin/TeX/Bilder/Studie/FragenMP2.pdf b/isr-eclipse-plugin/TeX/Bilder/Studie/FragenMP2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b09ff62dc1c1cecb69a2a599e6095add210a5149 Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/Studie/FragenMP2.pdf differ diff --git a/isr-eclipse-plugin/TeX/Bilder/Studie/FragenOP.pdf b/isr-eclipse-plugin/TeX/Bilder/Studie/FragenOP.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1d60633676e966c1bea3d561320f186e652ed068 Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/Studie/FragenOP.pdf differ diff --git a/isr-eclipse-plugin/TeX/Bilder/Studie/FragenOP2.pdf b/isr-eclipse-plugin/TeX/Bilder/Studie/FragenOP2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..78eeb357c58c74627dafb7266bb323bd994ca756 Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/Studie/FragenOP2.pdf differ diff --git a/isr-eclipse-plugin/TeX/Bilder/Studie/Seite1.pdf b/isr-eclipse-plugin/TeX/Bilder/Studie/Seite1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..44cb8bb6d1277296cec5cbb9a07c98f2150781f7 Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/Studie/Seite1.pdf differ diff --git a/isr-eclipse-plugin/TeX/Bilder/SyntaxHighlighting.png b/isr-eclipse-plugin/TeX/Bilder/SyntaxHighlighting.png new file mode 100644 index 0000000000000000000000000000000000000000..b3df50e56c2c597e2423c3407095b6f23330bd23 Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/SyntaxHighlighting.png differ diff --git a/isr-eclipse-plugin/TeX/Bilder/Syntaxtree.pdf b/isr-eclipse-plugin/TeX/Bilder/Syntaxtree.pdf new file mode 100644 index 0000000000000000000000000000000000000000..fc84142841d540cb99ac92681640fbcdc5e62dbc Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/Syntaxtree.pdf differ diff --git a/isr-eclipse-plugin/TeX/Bilder/Visualisierung.png b/isr-eclipse-plugin/TeX/Bilder/Visualisierung.png new file mode 100644 index 0000000000000000000000000000000000000000..04e000bb4984452cc271468270b41753d40b8eb5 Binary files /dev/null and b/isr-eclipse-plugin/TeX/Bilder/Visualisierung.png differ diff --git a/isr-eclipse-plugin/TeX/Deckblatt.tex b/isr-eclipse-plugin/TeX/Deckblatt.tex new file mode 100644 index 0000000000000000000000000000000000000000..62fa560b38eb132f0a8715a74355d76434b0aaba --- /dev/null +++ b/isr-eclipse-plugin/TeX/Deckblatt.tex @@ -0,0 +1,50 @@ +\thispagestyle{empty} +\begin{titlepage} + +\begin{center} + + %\begin{minipage}{13.5cm} + % \includegraphics[height=3cm]{Bilder/toolchain.pdf}\\ + % \textsf{ + %\hspace*{2.0cm} Fakult\"at f\"ur Elektrotechnik, Informatik und Mathematik \\ +% \hspace*{2.0cm} Heinz Nixdorf Institut und Institut f\"ur Informatik\\ +% \hspace*{2.0cm} Fachgebiet Softwaretechnik \\ +% \hspace*{2.0cm} Warburger Straße 100 \\ +% \hspace*{2.0cm} 33098 Paderborn +% } +% \end{minipage}\\[40pt] + + \begin{doublespace} + {\Huge\textbf{\meinTitel}}\\[30pt] + \end{doublespace} + + {\huge \bachelorArbeit }\\[6pt] + an der Univeristät Bielefeld im Rahmen des Studiengangs\\ + {\Large Kognitive Informatik}\\ + zur Erlangung des Grades\\[6pt] + {\Large \gradBachelor}\\[30pt] + + + von\\ + {\scshape\large \meinName}\\ + \meineStrasseHausNr\\\meinePLZundOrt\\[30pt] + + vorgelegt bei\\ + +\ifthenelse{\equal{\ausarbeitungsTyp}{\ausarbeitungsTypSeminar}\OR{\equal{\ausarbeitungsTyp}{\ausarbeitungsTypProSeminar}}} +{ + %then: nur Erstgutachter + {\large \meinErstgutachter}\\[30pt] +} +{ + %else: Erst- und Zweitgutachter + {\large \meinErstgutachter}\\ + und\\ + {\large \meinZweitgutachter}\\[30pt] +} + + %{\today} % heutiges Datum + {Bielefeld, \meinErstellungsdatum} +\end{center} + +\end{titlepage} \ No newline at end of file diff --git a/isr-eclipse-plugin/TeX/DeckblattTest.aux b/isr-eclipse-plugin/TeX/DeckblattTest.aux new file mode 100644 index 0000000000000000000000000000000000000000..87c5dec581b85d529a2bec416e4cbfe790b417d4 --- /dev/null +++ b/isr-eclipse-plugin/TeX/DeckblattTest.aux @@ -0,0 +1,37 @@ +\relax +\@setckpt{DeckblattTest}{ +\setcounter{page}{2} +\setcounter{equation}{0} +\setcounter{enumi}{0} +\setcounter{enumii}{0} +\setcounter{enumiii}{0} +\setcounter{enumiv}{0} +\setcounter{footnote}{0} +\setcounter{mpfootnote}{0} +\setcounter{part}{0} +\setcounter{chapter}{0} +\setcounter{section}{0} +\setcounter{subsection}{0} +\setcounter{subsubsection}{0} +\setcounter{paragraph}{0} +\setcounter{subparagraph}{0} +\setcounter{figure}{0} +\setcounter{table}{0} +\setcounter{subfigure}{0} +\setcounter{lofdepth}{1} +\setcounter{subtable}{0} +\setcounter{lotdepth}{1} +\setcounter{ALG@line}{0} +\setcounter{ALG@rem}{0} +\setcounter{ALG@nested}{0} +\setcounter{ALG@Lnr}{2} +\setcounter{ALG@blocknr}{10} +\setcounter{ALG@storecount}{0} +\setcounter{ALG@tmpcounter}{0} +\setcounter{parentequation}{0} +\setcounter{definition}{0} +\setcounter{Item}{0} +\setcounter{Hfootnote}{0} +\setcounter{bookmark@seq@number}{0} +\setcounter{section@level}{0} +} diff --git a/isr-eclipse-plugin/TeX/DeckblattTest.tex b/isr-eclipse-plugin/TeX/DeckblattTest.tex new file mode 100644 index 0000000000000000000000000000000000000000..d320019cd402069098cf7e0a2f151ae3b99ac452 --- /dev/null +++ b/isr-eclipse-plugin/TeX/DeckblattTest.tex @@ -0,0 +1,72 @@ +%\AddToShipoutPicture*{\BackgroundPic} +%Edit: weißes Feld + +\AddToShipoutPicture*{ + \definecolor{vRect}{rgb}{1,0.5,0} + \put(0,0){\textcolor{vRect}{ + \rule{0.18\paperwidth}{\paperheight}} + } +} + +\AddToShipoutPicture*{ + \definecolor{hRect}{rgb}{0.3,0.9,0.3} + \put(0,0.55\paperheight){\textcolor{hRect}{ + \rule{1\paperwidth}{.25\paperheight}} + } +} + + + +\AddToShipoutPicture*{ + \definecolor{hRect}{rgb}{0.1,0.7,0.1} + \put(0,0.55\paperheight){\textcolor{hRect}{ + \rule{0.18\paperwidth}{.25\paperheight}} + } +} +\AddToShipoutPicture*{ + \definecolor{hRect}{rgb}{1,0.5,0} + \put(0,0.799\paperheight){\textcolor{hRect}{ + \rule{1\paperwidth}{.01\paperheight}} + } +} + + + +\thispagestyle{empty} +\newgeometry{left=0cm,bottom=1.5cm} +\begin{titlepage} + +\begin{tabular}{p{0.2\paperwidth}c} + + +&\begin{minipage}{0.71\paperwidth} + \centering + {\huge Bachelorarbeit }\\[3cm] + \begin{doublespace} + {\Huge\textbf{\meinTitel}}\\[4cm] + \end{doublespace} + + +von\\[8pt] + {\scshape\Large \meinName}\\ +\end{minipage} +\end{tabular} +\vfill +\begin{tabular}{p{0.18\paperwidth}c} + +& \begin{minipage}{\textwidth} + + \raggedright + vorgelegt bei\\ + {\large \meinErstgutachter}\\ + {\large \meinZweitgutachter}\\[15pt] + + im Studiengang Kognitive Informatik\\ + der Technischen Fakultät\\ + der Universität Bielefeld\\[1cm] + {Bielefeld, \meinErstellungsdatum} +\end{minipage} + +\end{tabular} +\end{titlepage} +\restoregeometry \ No newline at end of file diff --git a/isr-eclipse-plugin/TeX/DokumentklasseBaMa.tex b/isr-eclipse-plugin/TeX/DokumentklasseBaMa.tex new file mode 100644 index 0000000000000000000000000000000000000000..05644743fc98a08a0e03c61d0b2666bfc970a6b0 --- /dev/null +++ b/isr-eclipse-plugin/TeX/DokumentklasseBaMa.tex @@ -0,0 +1,12 @@ +\documentclass[a4paper, % DIN A4 Format + 12pt, %Schriftgröße + %twoside, %zweiseitiges Layout (linke und rechte Seiten) + oneside, + openright, %Kapitel fangen immer auf rechter Seite an + cleardoublepage=empty, %evtl. eingefügte Seiten sind leer (ohne Seitenzahl), alternativ: cleardoublepage=plain (mit Seitenzahl) + numbers=noenddot, %hinter Kapitel- und Abschnittsnummern grundsätzlich kein Punkt am Ende + %appendixprefix, %im Anhang bei Kapiteln eine Prefixzeile verwenden, z.B. "Anhang A" + BCOR1.5cm, %Binderand + bibliography=totoc %Literaturverzeichnis ins Inhaltsverzeichnis aufnehmen + %idxtotoc %Indexverzeichnis ins Inhaltsverzeichnis aufnehmen + ]{scrbook} % Dokumentklasse aus KOMA-Paket, alternativ: scrartcl oder scrreprt \ No newline at end of file diff --git a/isr-eclipse-plugin/TeX/DokumentklasseSeminar.tex b/isr-eclipse-plugin/TeX/DokumentklasseSeminar.tex new file mode 100644 index 0000000000000000000000000000000000000000..eaaf9e0763aa534302105c986f033159e4ce72c5 --- /dev/null +++ b/isr-eclipse-plugin/TeX/DokumentklasseSeminar.tex @@ -0,0 +1,11 @@ +\documentclass[a4paper, % DIN A4 Format + 11pt, %Schriftgröße + twoside, %zweiseitiges Layout (linke und rechte Seiten) + openany, %Kapitel fangen auf bel. Seite an; alternativ: Kapitel fangen immer auf rechter Seite an: openright + cleardoublepage=plain, %evtl. eingefügte Seiten sind mit Seitenzahl, alternativ: cleardoublepage=empty (ohne Seitenzahl) + pointlessnumbers, %hinter Kapitel- und Abschnittsnummern grundsätzlich kein Punkt am Ende + appendixprefix, %im Anhang bei Kapiteln eine Prefixzeile verwenden, z.B. "Anhang A" + BCOR1.5cm, %Binderand + bibliography=totoc %Literaturverzeichnis ins Inhaltsverzeichnis aufnehmen + %idxtotoc %Indexverzeichnis ins Inhaltsverzeichnis aufnehmen + ]{scrreprt} % Dokumentklasse aus KOMA-Paket, Alternativen: scrartcl, scrreprt, scrbook \ No newline at end of file diff --git a/isr-eclipse-plugin/TeX/Dokumentstruktur.tex b/isr-eclipse-plugin/TeX/Dokumentstruktur.tex new file mode 100644 index 0000000000000000000000000000000000000000..91a5e3033d4fb94824aea35d229a87b5620a8414 --- /dev/null +++ b/isr-eclipse-plugin/TeX/Dokumentstruktur.tex @@ -0,0 +1,57 @@ +%---Silbentrennung----------------------------------------------------------------------------- + +% Silbentrennung für Wörter, in denen kein Bindestrich vorkommt +\input{meineSilbentrennung} + +%---------------------------------------------------------------------------------------------- + +\begin{document} + +% Verzeichnisse umbenennen von "...verzeichnis"; muss hier stehen, da sonst der Name nicht geändert wird +\renewcommand{\contentsname}{Inhalt} +\renewcommand{\bibname}{Literatur} + +\pagenumbering{roman} % römische Seitenzahlen, bevor der eigentliche Inhalt beginnt + +%---Schmutztitel------------------------------------------------------------------------------- + +\ifthenelse{ + \equal{\ausarbeitungsTyp}{\ausarbeitungsTypMaster} + \OR + \equal{\ausarbeitungsTyp}{\ausarbeitungsTypDiplom} + } + { + %then: Schmutztitel erstellen + \thispagestyle{empty} + \begin{center} + {\vspace*{170pt}\Large\textbf{\meinTitel}}\\[30pt] + von\\ + {\large \meinName} + \end{center} + \clearpage + } + { + %else: nichts tun + } + + +%---Titelseite--------------------------------------------------------------------------------- + +\include{DeckblattTest} + +\clearpage + + + +\input{Inhalt/Abstract} + +\input{Inhalt/Abstrakt} + +%---Inhaltsverzeichnis------------------------------------------------------------------------- +%\clearemptydoublepage +\tableofcontents + +\input{meineDokumentstruktur} +\input{Inhalt/Versicherung} + +\end{document} \ No newline at end of file diff --git a/isr-eclipse-plugin/TeX/Inhalt/Abstract.tex b/isr-eclipse-plugin/TeX/Inhalt/Abstract.tex new file mode 100644 index 0000000000000000000000000000000000000000..d55de09ced100fcc79ba078013061c041a582fb4 --- /dev/null +++ b/isr-eclipse-plugin/TeX/Inhalt/Abstract.tex @@ -0,0 +1,4 @@ +\chapter*{Abstract} +\label{cha:Abstract} +Speech recognizers nowadays play an increasingly important role in our daily lives. In order to reduce the complexity of natural language in a speech recognition process and to achieve significantly better results, a problem-specified grammar is used. Also the speech recognizer ESMERALDA which was designed at the University of Bielefeld makes use of this technique. +In this Bachelor thesis an Eclipse-Plugin has been developed which aims to simplify the creation and maintenance of a grammar. A subsequent study showed that the use of the developed plugin simplifies the use of grammar in many terms. \ No newline at end of file diff --git a/isr-eclipse-plugin/TeX/Inhalt/Abstrakt.tex b/isr-eclipse-plugin/TeX/Inhalt/Abstrakt.tex new file mode 100644 index 0000000000000000000000000000000000000000..19b3de0e0452d6fcc67c01b4a8a73d41958dd78d --- /dev/null +++ b/isr-eclipse-plugin/TeX/Inhalt/Abstrakt.tex @@ -0,0 +1,4 @@ +\chapter*{Abstract} +\label{cha:Abstract} +Spracherkenner spielen heutzutage eine immer wichtigere Rolle in unserem Alltag. Um die Komplexität der natürlichen Sprache in einem Spracherkennungsprozess zu verringern und deutlich bessere Ergebnisse zu erzielen, wird eine problemspezifizierte Grammatik verwendet. Auch der an der Universität Bielefeld entworfene ESMERALDA-Spracherkenner arbeitet mit dieser Technik. +In dieser Bachelorarbeit wurde ein Eclipse-Plugin entwickelt, welches das Erstellen und Warten einer Grammatik erleichtern soll. In einer anschließenden Studie konnte gezeigt werden, dass der Einsatz des entwickelten Plugin den Umgang mit der Grammatik in vielen Hinsichten vereinfacht. \ No newline at end of file diff --git a/isr-eclipse-plugin/TeX/Inhalt/Anhang.tex b/isr-eclipse-plugin/TeX/Inhalt/Anhang.tex new file mode 100644 index 0000000000000000000000000000000000000000..7fcf7d9a36708384a56d1486fbebba881e9d1ac3 --- /dev/null +++ b/isr-eclipse-plugin/TeX/Inhalt/Anhang.tex @@ -0,0 +1,18 @@ +\chapter*{Anhang} + +\includegraphics[width=1\textwidth]{Bilder/Studie/Seite1} + +\begin{figure}[p] +\includegraphics[width=1\textwidth]{Bilder/Studie/Aufgaben} +\end{figure} + +\begin{figure}[p] +\includegraphics[angle=90,width=1\textwidth]{Bilder/Studie/FragenMP2} +\includegraphics[angle=90,width=1\textwidth]{Bilder/Studie/FragenMP} +\end{figure} + +\begin{figure}[p] +\includegraphics[angle=90,width=1\textwidth]{Bilder/Studie/FragenOP2} +\includegraphics[angle=90,width=1\textwidth]{Bilder/Studie/FragenOP} +\end{figure} + diff --git a/isr-eclipse-plugin/TeX/Inhalt/Einleitung.tex b/isr-eclipse-plugin/TeX/Inhalt/Einleitung.tex new file mode 100644 index 0000000000000000000000000000000000000000..8f73f626d91417465e30413222ea45fb5328eef5 --- /dev/null +++ b/isr-eclipse-plugin/TeX/Inhalt/Einleitung.tex @@ -0,0 +1,31 @@ +\chapter{Einleitung} +\label{cha:Einleitung} + +\section{Motivation und Zielstellung} +\label{sec:Motivation und Zielstellung} +Spracherkennung spielt heutzutage in unserem Umfeld eine immer größere Rolle. Sei es bei automatisierten Telefonhotlines oder bei der Steuerung eines modernen mobilen Devices. Mit zunehmender Bedeutung der Robotik hat die Spracherkennung auch dort mittlerweile einen hohen Grad an Notwendigkeit erreicht. Als Teilgebiet der angewandten Informatik, beschäftigt sich die Spracherkennung mit der automatisierten Erfassung von gesprochener Sprache. Natürliche Sprache automatisiert zu erfassen, stellt jedoch weiterhin ein großes Problem dar, dessen Herausforderung vor allem in der Komplexität ihrer Struktur und Mehrdeutigkeit begründet ist. + +Ein viel versprechender Ansatz dieses Problem zu lösen, besteht darin, den Spracherkenner mit einer spezifizierten Grammatik zu verknüpfen, der diese Komplexität einschränkt. Der, an der Universität Bielefeld entworfene Spracherkenner \emph{ISR}\footnote{IncrementalSpeechRecognizer: Inkrementelle Spracherkenner}, welcher auf dem Mustererkennungsframework \emph{ESMERALDA}\footnote{ \emph{\underline{E}nvironment for \underline{S}tatistical \underline{M}odel \underline{E}stimation and \underline{R}ecognition on \underline{A}rbitrary \underline{L}inear \underline{D}ata \underline{A}rrays}}\cite{Fink} basiert, versucht dieses Problem unter Verwendung der ISR-Grammatik zu reduzieren. Um die Spracherkennung zu optimieren, wird eine Grammatik erstellt, die von vornherein nur bestimmte Satzstrukturen zulässt. Die erfassten Daten eines Sprechers brauchen daher nicht mehr gegen den gesamten Sprachumfang geprüft werden, sondern nur gegenüber den, in einer Grammatik beschrieben Regeln. Dies bedeutet implizit, dass zur Erkennung komplexer Satzmuster eine komplexe Grammatik zugrunde liegen muss. + +In dieser Bachelorarbeit wird das Problem des Erstellens komplexer Grammatiken behandelt. Eine wesentliche Motivation an dieser Aufgabe zu arbeiten, resultiert aus dem vielschichtigen Anwendungsfall des Robocup@Home\footnote{\url{http://www.ai.rug.nl/robocupathome/}}-Wettkampfes. In diesen Wettkämpfen muss ein Roboter der Universität Bielefeld autonom Aufgaben erledigen, die ihm über den ESMERALDA-Spracherkenner zugänglich gemacht werden. Dabei ist die Erstellung komplexer und die Wartung unbekannter ISR-Grammatiken schwierig. Der Gebrauch eines Standard-Texteditors wie \emph{gedit}\footnote{\url{http://projects.gnome.org/gedit/}} (\emph{GNOME Editor}) oder \emph{vim}\footnote{\url{http://www.vim.org/}} (\emph{VI Improved}) ist in der Praxis nicht sinnvoll, da er keine ausreichende Unterstützung, zum Beispiel bei der Syntaxprüfung der zu erstellenden Grammatik, bietet. Da der Prozess des Kompilierens, währenddessen auch die Prüfung der syntaktischen Korrektheit der Grammatik stattfindet, viel Zeit braucht und über dies selten eine sinnvoll interpretierbare Fehlermeldung ausgibt, bietet sich eine Prüfung der Syntax schon direkt bei der Erstellung einer Grammatik an. Des Weiteren ist das Lösen des \emph{Wortproblems}\footnote{Als Wortproblem bezeichnet man das Problem entscheiden zu können, ob ein gegebenes Wort durch eine Grammatik erstellt werden kann oder nicht.}, selbst bei einer übersichtlichen Grammatik, ohne weitere Hilfsmittel sehr aufwändig. + +Im Anwendungsfall des Robocups stehen die Anwender oft unter massivem Zeitdruck. Dies erfordert bei der Lösung der Aufgaben über einen längeren Zeitraum eine hohe Konzentration, die gleichzeitig nicht effizient genug für andere Problemlösungen genutzt werden kann. Durch den Einsatz eines Editors, der für die Lösung besonderer Aufgaben spezifiziert wurde, soll die Fehleranfälligkeit reduziert und damit dem Zeitverlust entgegen gewirkt werden. + +Da der ESMERALDA-Spracherkenner an der Universität Bielefeld konzipiert wurde und zurzeit nur in bestimmten Einsatzbereichen genutzt wird, zum Beispiel beim Robocup, wurde bisher kein Editor zur effektiven Erstellung und Wartung von ISR-Grammatiken entwickelt. Die auf dem Markt zur Verfügung stehenden Editoren, unabhängig davon, ob als Onlineservice oder als Software, die sich mit dem Thema der kontextfreien Grammatik beschäftigen, sind nicht kompatibel, mit der ISR-Grammatik, die durch eine spezifische Notation, Sonderzeichen und Sonderregeln definiert ist. + +Die Idee der Implementierung eines eigenen Editors liegt also nahe und ist sinnvoll. Dabei ist es jedoch nicht zwingend notwendig, eine StandAlone-Software zu entwickeln, da einige Editor-Frameworks bereits durch selbst geschriebene Plugins so erweitert werden können, dass eine angemessene Problemlösung möglich ist. + +Das Ziel dieser Bachelorarbeit ist es, auf Basis eines Eclipse Plugin, einen Editor zu entwickeln, der den Umgang mit der ISR-Grammatik, sowohl für Anfänger als auch für Fortgeschrittene, vereinfacht und effizienter macht. +\section{Leitfaden} +\label{sec:Leitfaden} +Der Aufbau der Bachelorarbeit gliedert sich in fünf Kapiteln. + +Kapitel Eins erläutert die Motivation und die Zielstellung. + +Das zweite Kapitel zeigt die theoretischen Grundlagen der ISR-Grammatik auf und gibt erste Einblicke in die Art der Softwaremodellierung. Zunächst wird auf den Aufbau und die Struktur der ISR-Grammatik eingegangen und dabei ihre besonderen Eigenschaften erklärt. Des Weiteren werden Anforderungen an die Software erstellt, die den Umgang mit der ISR-Grammatik erleichtern sollen. Eine mögliche Problemstellung wird in der Anwendergeschichte dargestellt. Anschließend werden die Anforderungen an die Software analysiert. + +Im dritten Kapitel werden anhand der im zweiten Kapitel entworfenen Anforderungen, die Definition der notwendigen Funktionalitäten die Softwarespezifikation erstellt. Ein weiterer Schwerpunkt liegt auf der Beschreibung der Architektur und der Implementierung der Software. + +Zur Evaluierung der im dritten Kapitel erstellten Software wurde eine Benutzerstudie durchgeführt. Darin wurde der Frage nachgegangen, ob die Software zu allen aufgestellten Anforderungen und Problemen eine Lösung bietet. Die Ergebnisse und die Auswertung der Studie werden im vierten Kapitel präsentiert und kritisch diskutiert. + +Das letzte Kapitel bildet die Zusammenfassung der Arbeit und gibt einen Ausblick auf mögliche Erweiterungen der Funktionalität des Editors, die zum Teil aus weiteren Vorüberlegungen resultieren und zum anderen Teil aus den Erkenntnissen und den Ergebnissen der Benutzerstudie hervorgegangen sind. \ No newline at end of file diff --git a/isr-eclipse-plugin/TeX/Inhalt/Evaluierung.tex b/isr-eclipse-plugin/TeX/Inhalt/Evaluierung.tex new file mode 100644 index 0000000000000000000000000000000000000000..ab28660419385e426e92265245e0bad7b0495c20 --- /dev/null +++ b/isr-eclipse-plugin/TeX/Inhalt/Evaluierung.tex @@ -0,0 +1,161 @@ +\chapter{Evaluation} +\label{cha:Evaluation} +Obwohl die Anforderungen an die Software aus einer durchdachten Anforderungsanalyse hervorgegangen sind, und darüber hinaus bei dem Entwurf der dazugehörigen Funktionalitäten auf zusätzlich externe Quellen eingegangen wurde, lässt sich nicht ausschließen, dass das Programm Fehler beinhaltet oder in der Nutzung optimiert werden könnte. Zudem ist es möglich, dass weitere Funktionalitäten von Vorteil sind oder dass bereits bestehende zu kompliziert realisiert wurden. + +Eine Evaluation der entwickelten Software soll auf diese Fragen eine Antwort geben. Dieses Kapitel gliedert sich in vier Abschnitte. Im ersten Abschnitt wird auf die Zielstellung der Studie eingegangen. Der zweite Abschnitt beschreibt die Methoden, die zur Evaluation benutzt wurden. Eine Beschreibung der Durchführung findet sich im dritten Abschnitt, im letzten werden die Ergebnisse vorgestellt und diskutiert. + +\section{Ziele} +\label{sec:Ziele} +Der Zweck der entwickelten Software ist es, dem Nutzer durch die gebotenen Funktionalitäten die Möglichkeit zu geben, einfacher, robuster und schneller mit der ISR-Grammatik umgehen zu können (siehe Kapitel \ref{sec:Anforderungsanalyse}). Daher liegt es nahe, den Einsatz dieser Funktionalitäten in einer Studie zu prüfen. Ein weiteres Ziel der Studie resultiert aus der Ungewissheit, ob die Anforderungsanalyse vollständig war. Auch wenn durch einen konkreten Anwendungsfall und einer Analyse der Probleme viele Anforderungen entstanden sind, ist nicht sicher, ob die aufgestellten Anforderungen und die daraus resultierenden Funktionalitäten, den Problemen der Praxis genügen. Des Weiteren zeigt die Evaluation Problemstellungen auf, die das Programm nicht oder nicht optimal unterstützen. + +Doch auch positive Aspekte können durch sie hervorgehoben werden, indem gezeigt wird, dass die eingesetzten Funktionalitäten genau den Anforderungen entsprechen, für die sie implementiert wurden. + +\section{Methoden und Durchführung} +\label{sec:Methoden und Durchfuhrung} +Um die Software angemessen evaluieren zu können, wurde eine aufgabenbasierte Methodik gewählt. Dazu wurden aus dem Anwendungsfall in Kapitel \ref{sec:Anwendungsfall}, Aufgabenarten extrahiert und zu jeder Art eine Aufgabe erstellt. Dabei bestand viel Spielraum, sodass beim Erstellen der Aufgaben zusätzlich darauf geachtet werden musste, diese so realistisch wie möglich zu halten. Um anschließend einen Vergleich aufstellen zu können, wurden die Aufgaben von der Hälfte der Probanden mit und von der anderen Hälfte ohne Unterstützung des Plugins gelöst. Zusätzlich, um die definierten Ziele aus Kapitel \ref{sec:Ziele} zu erreichen, beantworteten die Probanden nach der Bearbeitung der Aufgaben einen Fragebogen. + +Bei der Erstellung des Fragebogens, wurde auf bereits bewährte Techniken\footnote{\url{http://iss.leeds.ac.uk/info/312/surveys/217/guide_to_the_design_of_questionnaires/5}} zurückgegriffen. Anschließend wurde eine Testphase mit einem Testprobanden durchgeführt. In dieser wurden sowohl die gestellten Aufgaben als auch die Fragen bearbeitet, um Unklarheiten herauszufinden. Die Auffälligkeiten innerhalb der Aufgabenstellung und des Fragebogens wurden anschließend geändert und einer weiteren Testperson zur Kontrolle gegeben. Sowohl der Fragebogen wie auch der Aufgabenbogen befinden sich im Anhang. + +In der Durchführung erhielten alle Probanden drei Aufgaben, die sie nacheinander lösen sollten. In der ersten Aufgabe mussten die Teilnehmer eine schon bestehende Grammatik, welche Syntaxfehler beinhaltete, korrigieren, ohne dabei die syntaktische Struktur zu verändern; semantische Fehler sollten nicht behoben werden. In der zweiten Aufgabe musste eine Grammatik erstellt werden, die einen Pool von Sätzen abbilden sollte. Für die dritte Aufgabe wurde erneut ein Pool von Sätzen gegeben, zu denen das Wortproblem gegen eine schon bestehende Grammatik zu prüfen war. Zudem sollte von einer Satzstruktur ein Syntaxbaum erstellt werden. + +Bevor mit der ersten Aufgabe begonnen werden konnte, bekam jeder Teilnehmer eine verbale Einführung in die ISR-Grammatik. Dazu wurde an Hand der Beispielgrammatik aus Kapitel \ref{sec:Beispiel} und der im Fragebogen enthaltenen Syntaxspezifikation die Struktur der Grammatik und die Bedeutung aller Regelelemente erklärt. Bei der Wahl der Probanden wurde darauf geachtet, dass sie über die nötigen Kenntnisse des benutzen Editors verfügten. Um die Auswertung besser vergleichen zu können, wurde die Bearbeitungszeit der Probanden gestoppt. Des Weiteren wurden während der Bearbeitung Notizen zum Verhalten des Teilnehmers gemacht. Ferner durften sie während der Bearbeitung Fragen stellen, die allen Teilnehmern in gleicher Weise beantwortet wurden, um die Aussagekraft der Ergebnisse nicht zu beeinflussen. + +\section{Auswertung} +\label{sec:Auswertung} +Die Teilnehmer hatten zur Beantwortung der Fragen eine Bewertungsskala von einem bis maximal fünf Punkten zur Verfügung. Die Vergabe von fünf Punkten bedeutete eine sehr gute Bewertung, ein Punkt hingegen zeigte, dass viel Verbesserungspotenzial gesehen wurde. + +\paragraph{Kenntnisse der gegebenen Hilfsmittel} +Zunächst wurden fünf allgemeine Fragen gestellt. Die ersten zwei bezogen sich auf die Teilnehmerkenntnisse im Umgang mit den gegebenen Werkzeugen. Die durchschnittliche Punktzahl der Probanden auf die Frage, wie gut sie mit einem Computer umgehen können, lag bei ungefähr 4,8. Die Frage, wie gut sie mit dem verwendeten Editor umgehen können, sei es Eclipse oder ein anderer Editor, beurteilten 90\% der Befragten mit vier oder mehr Punkten. Die ausgeglichenen Kenntnisse über die Werkzeuge bildeten eine gute Voraussetzung für die Bearbeitung und anschließende Auswertung der gestellten Fragen. + +\paragraph{Erfahrung mit kontextfreien Grammatiken} +Zudem war es wichtig zu wissen, wie viel Erfahrung die Teilnehmer im Umgang mit kontextfreien und speziell mit der ISR-Grammatik hatten. Das Wissen über kontextfreie Grammatiken lag im Schnitt deutlich höher als das Wissen über die ISR-Grammatik. Dieses Defizit sollte durch die in Kapitel \ref{sec:Methoden und Durchfuhrung} beschriebene Einführung in die ISR-Grammatik unter Einbezug des Wissens über kontextfreie Grammatiken abgebaut werden. Im weiteren Verlauf der Studie zeigte sich, dass unabhängig vom Vorwissen und Erfahrung, die Aufgaben etwa gleich gut bewältigt werden konnten. Dies stellt ein erstes positives Indiz für eine gelungene Umsetzung der Anforderungen dar, welches durch die weiteren Ergebnissen bestätigt wird. + +\paragraph{Verständnis und Realitätsbezug der Aufgabenstellung} +Die Aufgabenstellung wurde von allen Teilnehmern mit durchschnittlich 4,6 Punkten sehr gut verstanden. Eine wichtige Zusatzfrage, die nur von den Teilnehmern beantwortet werden konnte und sollte, die bereits Erfahrung mit der ISR-Grammatik gemacht haben, bildete die Frage nach dem Realitätsbezug der gestellten Aufgaben. 90\% gaben an, dass sie die gestellten Aufgaben mit vier oder mehr Punkten als sehr realistisch einschätzen. Da die Aufgaben größtenteils aus dem Anwendungsfall aus Kapitel \ref{sec:Anwendungsfall} extrahiert wurden, zeigt auch dies, dass der Anwendungsfall realistisch konstruiert wurde. + +Im Folgenden werden nun die Antworten der drei Aufgaben ausgewertet und diskutiert. Zunächst wird jede Aufgabe aus Sicht der Plugin-Nutzer ausgewertet (Gruppe A), dann aus Sicht derer, die ohne Plugin gearbeitet haben (Gruppe B). Anschließend werden die beiden Ergebnisse verglichen und diskutiert. + +\subsection{Korrektur einer fehlerhaften Grammatik} +\label{subsec:KefG} +Das Ziel dieser Aufgabe war es zu untersuchen, wie leicht syntaktische Fehler einer Grammatik erkannt und behoben werden können. Da es viele verschiedene Wege gab, die Aufgabe zu lösen, wurde die Bedingung gestellt, dass die Teilnehmer so wenig wie möglich an der syntaktischen Struktur der Grammatik ändern durften. + +Die Benutzer des Plugin konnten sehr schnell einen Überblick über alle syntaktischen Fehler erlangen und beantworteten die Frage, wie leicht es ihnen fiel, im Schnitt mit 4,5 Punkte, wie in Abbildung \ref{fig:F7A1vgl} zu sehen ist. Dabei spielte vor allem die Funktionalität der Fehlermarkierung eine wichtige Rolle. Weniger als im Vorfeld zunächst angenommen, wurde für diese Aufgabe das Syntaxhighlighting als hilfreich erachtet. Der Mittelwert der benötigten Zeit lag in der Gruppe A bei 4,5 Minuten; hier konnte eine relativ breite Varianz von vier Minuten beobachten werden. Manche Teilnehmer versuchten die Aufgabe schnell zu lösen, wohingegen andere stärker die Funktionalität des Editors nutzten und dazu geringfügig mehr Zeit benötigten. Das Ergebnis von durchschnittlich null Fehlern ist aber ein deutliches Indiz dafür, dass das Plugin für diese Art der Aufgabe eine sehr gute Unterstützung bot. + +Auffallend war, dass die Teilnehmer, die ohne Plugin arbeiteten zwar langsamer waren aber ebenfalls eine relativ schnelle Bearbeitungszeit hatten. Sie wurden jedoch durchgehend von einer Unsicherheit über den aktuellen Stand der Aufgabe begleitet. Die Teilnehmer fragten mehrfach nach, ob die Aufgabe jetzt fertig bearbeitet sei. Die Durchschnittszeit lag bei 6,9 Minuten mit einer hohen Varianz von 7,7 Minuten. Diese Varianz erklärt sich dadurch, dass manche Probanden sich ihrer Fähigkeit, die Aufgabe gut lösen zu können sehr sicher waren, andere hingegen sehr zögerlich arbeiteten und die Grammatik mehrfach überprüften. Keinem Teilnehmer gelang es jedoch, die Fehler vollständig aus der Grammatik zu entfernen. Dementsprechend wurde die Frage, wie leicht die Aufgabe gelöst werden konnten, im Mittel mit drei Punkten beantwortet (siehe Abbildung \ref{fig:F7A1vgl}). + +\begin{figure}[h] +\includegraphics[height=0.5\textheight]{Bilder/Auswertung/F7A1vgl} +\caption{Zeigt einen Vergleich der Bewertungen wie einfach die erste Aufgabe gelöst werden konnte. Rechts die Gruppe A, links die Gruppe B.} +\label{fig:F7A1vgl} +\end{figure} + +\pagebreak +Im direkten Vergleich der Ergebnisse beider Gruppen fällt deutlich auf, dass sich die eingesetzte Software positiv auf die Bearbeitungszeit (siehe Abbildung \ref{fig:A1zeitvgl}) und wie in Abbildung \ref{fig:failvgl} zu sehen ist auch positiv auf die Fehlerrate auswirkte. Des Weiteren wurden Unsicherheiten im Erkennen von Fehlern in der Grammatik schneller beseitigt und dadurch das Lösen der Aufgabe erleichtert. Darüber hinaus bot die Software eine gute Hilfe, um eine angemessene Übersicht über den aktuellen Stand der Aufgabe zu erlangen. Dies wurde auch dadurch bestätigt, dass kein Teilnehmer der Gruppe A während der Bearbeitung dahingehend Fragen stellte. Im Gegensatz dazu stellten die Teilnehmer der Gruppe B durchschnittlich ein bis zwei Fragen. + +\begin{figure}[h] +\includegraphics[height=0.5\textheight]{Bilder/Auswertung/A1zeitvgl} +\caption{Zeigt einen Vergleich der Bearbeitungszeiten der ersten Aufgabe, in der es darum ging, eine fehlerhafte Grammatik zu korrigieren. Rechts die Gruppe A, links die Gruppe B.} +\label{fig:A1zeitvgl} +\end{figure} + + +\subsection{Erstellen einer ISR-Grammatik} +\label{subsec:EeIG} +In der zweiten Aufgabe sollte eine Grammatik erstellt werden, die einen vorgegebenen Pool von Sätzen abbildet. + +Zunächst werden die Ergebnisse der Gruppe A ausgewertet. Allen Teilnehmern fiel es sehr leicht, die Aufgabe zu lösen, wie die durchschnittliche Punktevergabe von 4,5 mit einer Varianz von 0,5 zeigt (siehe Abbildung \ref{fig:F7A2vgl}). Dies ist unter anderem auf das Syntaxhighlighting, aber auch auf die zur Verfügung stehende Fehlermarkierung zurückzuführen. Da sich die Teilnehmer auch mit weiteren Funktionalitäten des Editors vertraut machten, wie zum Beispiel dem Content Assistant, gab es anfänglich Zeitverzögerungen. Dies ist wahrscheinlich für die relativ lange Bearbeitungszeit von durchschnittlich 6,4 Minuten verantwortlich. Positiv war zu beobachten, dass die Teilnehmer die Aufgabe fehlerfrei lösen konnten. + +Die Benutzung des Standardeditors führte bei fast allen zu Problemen, sodass nur 12,5\% , wie in Abbildung \ref{fig:failvgl} zu sehen ist, die Aufgabe fehlerfrei lösten. Neben Syntaxfehlern innerhalb der Grammatik wurden des Öfteren Worte vergessen, sodass bestimmte Sätze nicht von der Grammatik abgebildet werden konnten. Diese oberflächliche Bearbeitung der Aufgabe ist der Grund, weshalb die Teilnehmer der Gruppe B zum Lösen im Mittel nur etwa 5,5 Minuten benötigten. Dass auch hier während der Bearbeitung eine Unsicherheit vorhanden war, lässt sich daran erkennen, dass nur zwei der Befragten die Aufgabe sehr gut lösen konnten und der Mittelwert trotzdem nur bei 3,4 Punkten liegt, wie in Abbildung \ref{fig:F7A2vgl} ersichtlich. + +\begin{figure}[h] +\includegraphics[height=0.5\textheight]{Bilder/Auswertung/F7A2vgl} +\caption{Zeigt einen Vergleich der Bewertungen wie einfach die zweiten Aufgabe gelöst werden konnte. Rechts die Gruppe A, links die Gruppe B.} +\label{fig:F7A2vgl} +\end{figure} + +In der Auswertung zeigte sich die zusätzliche Auffälligkeit, dass sich durch Benutzung der Software eine längere Zeit zum Lösen der Aufgabe ergab (Abbildung \ref{fig:A2zeitvgl}). Die Ursachen liegen vermutlich darin, dass die Teilnehmer zum einen das erste Mal mit dem Editor praktisch arbeiten mussten und sich in der Funktionsweise nicht sicher auskannten. Zum anderen ließen sich die Teilnehmer häufig durch die angebotenen Funktionalitäten des Editors ablenken. Dies würde nach einer längeren Benutzungsphase abflachen. Eine wichtigere Rolle als der Zeitfaktor spielte jedoch die Anzahl der auftretenden Fehler, welche die Teilnehmer während der Bearbeitung machten. Dass auch bei dieser Aufgabe durch die Benutzung des Plugin im Schnitt null Fehler gemacht wurden, zeigt deutlich, dass der Editor auch zur Erstellung einer ISR-Grammatik einen geeigneten Assistenten darstellt und dem Anwender Sicherheit gibt. + +\begin{figure} +\includegraphics[height=0.5\textheight]{Bilder/Auswertung/A2zeitvgl} +\caption{Zeigt einen Vergleich der Bearbeitungszeiten der zweiten Aufgabe, in der es darum ging, eine Grammatik für bestimmte Sätze zu bilden. Rechts die Gruppe A, links die Gruppe B.} +\label{fig:A2zeitvgl} +\end{figure} + +\subsection{Lösen des Wortproblems und Erstellen von Syntaxbäumen} +\label{subsec:LdWuEvS} +Die letzte der drei Aufgaben befasste sich mit dem Lösen des Wortproblems. Die Teilnehmer bekamen erneut einen Pool von Sätzen und sollten anhand einer ebenfalls vorgegebenen Grammatik prüfen, welche Sätze durch die Grammatik erstellt werden können. Einer der gefundenen Sätze sollte zusätzlich als Syntaxbaum dargestellt werden. + + +\begin{figure}[h] +\includegraphics[height=0.5\textheight]{Bilder/Auswertung/F7A3vgl} +\caption{Zeigt einen Vergleich der Bewertungen wie einfach die dritten Aufgabe gelöst werden konnte. Rechts die Gruppe A, links die Gruppe B.} +\label{fig:F7A3vgl} +\end{figure} + +Für die Teilnehmer, die das Plugin zur Verfügung hatten, war diese Aufgabe schnell gelöst. Im Durchschnitt benötigten sie 4,6 Minuten, mit einer Varianz von 0,4 Minuten. Die sehr geringe Varianz ist dadurch bedingt, dass für Gruppe A diese Aufgabe lediglich darin bestand, die Sätze in ein Dialogfenster einzugeben und vom Plugin prüfen zu lassen. Dies ist auch der Grund dafür, dass während dieser Aufgabe im Durchschnitt null Fehler gemacht wurden. Dementsprechend wurde die Frage hinsichtlich der leichten Lösbarkeit der Aufgabe von 87,5\% der Gruppe A mit fünf Punkten bewertet. Die Abbildung \ref{fig:F7A3vgl} verdeutlicht den Vergleich in einem Boxplot-Diagramm. + +\begin{figure}[h] +\includegraphics[height=0.5\textheight]{Bilder/Auswertung/A3zeitvgl} +\caption{Zeigt einen Vergleich der Bearbeitungszeiten der dritten Aufgabe, in der es drum ging, das Wortproblem zu lösen. Rechts die Gruppe A, links die Gruppe B.} +\label{fig:A3zeitvgl} +\end{figure} + +Diese Aufgabe zeigt starke Unterschiede in den Ergebnissen der Gruppen. Die Teilnehmer der Gruppe B hatten im Mittel einen knapp 2,5 mal höheren Zeitbedarf als die Teilnehmer der Gruppe A (siehe Abbildung \ref{fig:A3zeitvgl}). Gleichzeitig wurde von keinem der Probanden der Gruppe B - wie in der ersten Aufgabe - die Aufgabe mit null Fehlern bearbeitet. Im Schnitt hatte jeder Teilnehmer aus Gruppe B 25\% der Fragen falsch beantwortet.Die Ergebnisse zeigen deutlich, dass auch in Hinsicht der Fehlerreduzierung das Plugin einen Vorteil geschaffen hat. + +\pagebreak +Abbildung \ref{fig:failvgl} zeigt noch einmal alle Fehlerwerte der Teilnehmer die ohne das Plugin arbeiteten. Die Werte sind in Prozent angegeben, da in jeder Aufgabe unterschiedlich viele Fehler gemacht werden konnten. Ein Vergleich mit denen der Gruppe A ist nicht nötig, da alle Aufgaben von allen Teilnehmern mit null Fehlern abgeschlossen wurden. + +\begin{figure}[p] +\centering +\includegraphics[height=1\textheight]{Bilder/Auswertung/failvgl} +\caption{Zusehen sind die Fehlerwerte aller Aufgaben in Prozent. Die Werte beziehen sich auf die der Teilnehmer, die ohne das Plugin gearbeitet haben.} +\label{fig:failvgl} +\end{figure} + +\pagebreak +\subsection{Funktionalitäten} +\label{subsec:AF} +Im Folgenden werden die Antworten des Fragebogens zu den implementierten Funktionalitäten ausgewertet und diskutiert. Dazu werden zuerst die Ergebnisse der Gruppe B (Teilnehmer ohne Plugin) vorgestellt und anschließend mit denen der Gruppe A (Teilnehmer mit Plugin) verglichen. Obwohl die Gruppe B die implementierten Funktionalitäten nicht zur Verfügung hatte, wurde ein Meinungsbild erstellt, ob ihnen der Funktionsumfang für die gegebenen Aufgaben praktisch erscheine. Die Reihenfolge, zuerst die Gruppe B und anschließend die Gruppe A zu betrachten, ist sinnvoll, da die Ergebnisse der Gruppe B als Vorab-Hypothese betrachtet werden können. + +\paragraph{Fehlermarkierung}Der Nutzen der Fehlermarkierung wurde von Gruppe B mit durchschnittlich fünf Punkten geschätzt. Das Ergebnis stimmt mit dem der Gruppe A mit 4,8 Punkten im Mittel fast überein. Auch die Varianzen beider Ergebnisse liegen mit null für Gruppe A und 0,4 für Gruppe B sehr nah beieinander; die Erwartungen wurden damit fast erfüllt, aber nicht vollständig. Obwohl die Abweichung nur minimal ist, ist es wegen der geringen Abweichung der Varianz sinnvoll sie zu interpretieren. Aus weiteren Anmerkungen der Probanden in den Fragebögen geht hervor, dass es Mängel in der Visualisierung der Fehler gab und deshalb keine fünf Punkte verteilt wurden. Welche dies waren, wurden nicht dem Fragebogen hinzugefügt. + +\paragraph{Syntaxhighlighting}Mit dem Syntaxhighlighting verhält es sich in der Bewertung gegensätzlich. Die Effizienz der Funktionalität wurde im Schnitt auf 4,6 Punkte geschätzt, bekam in der Anwendung aber fünf Punkte. + +\paragraph{Content Assistant}Auch der Content Assistant und seine Funktionalität wurden hinsichtlich der Nützlichkeit mit 4,1 zu 4,6 Punkten unterschätzt. Der Punktabzug, zur vollen Punktzahl, beziehungsweise die Kritik an dem implementierten Content Assistant bezog sich darauf, dass die Benutzung zu umständlich realisiert wurde. Bemängelt wurde auch, dass er bereits vorhandene Syntax zerstört, indem er „zu viel Text“ einfügt. Vermutlich liegt die Ursache hierfür darin, dass der implementierte Content Assistant mit dem des klassischen Java-Editors verglichen wurde. Im Rahmen dieser Bachelorarbeit ist es jedoch aus Zeitgründen nicht möglich, einen vergleichbaren Content Assistant zu entwickeln. + +\paragraph{Automatische Formatierer}Die Nützlichkeit des Formatierers wurde ebenfalls unterschätzt. Sie wurde von Gruppe B mit durchschnittlich vier Punkten bewertet, bekam in der Anwendung von der Gruppe A jedoch 4,5 Punkte im Mittel. Obwohl die Teilnehmer keine weitere Kritik an dem Formatierer übten wurde seine Nützlichkeit dennoch nicht mit voller Punktzahl bewertet. Dies könnte daran gelegen haben, dass die gegebenen Grammatiken bereits formatiert waren. Zudem war die zu erstellende Grammatik in der zweiten Aufgabe nicht so komplex, dass eine stetige Formatierung nötig gewesen wäre: die Funktionalität blieb also überwiegend ungenutzt. Die Wichtigkeit des Formatierers wird vor allem bei großen und komplexen Grammatiken durch regelmäßige Anwendung erkennbar. + +\paragraph{Hoverinformation und Hyperlinks} +Ebenso verhält es sich mit den folgenden zwei Funktionalitäten: die Hoverinformation und die Hyperlinks. Auch ihre Vorteile kommen erst in komplexen Grammatiken zum Tragen. Im Rahmen dieser Arbeit war ebenfalls es aus Zeitgründen nicht möglich die zwei Nützlichkeit Funktionalitäten zu validieren. Obwohl die Funktionalitäten nicht im vollen Umfang genutzt werden konnten, empfanden sie die Teilnehmer dennoch als hilfreich und bewerteten sie im Mittel mit 3,8 Punkten. + +\paragraph{Visualisierung der Regeln} +Ein anderer Trend zeigte sich in der Visualisierung der Grammatik. Mit 3,5 Punkten wurde diese von Gruppe B als brauchbar bezeichnet. In Gruppe A fand sie hingegen in der Praxis wenig Verwendung und wurde dementsprechend mit nur 2,5 Punkten bewertet. Dies hat mehrere Gründe, zum einen war eine Visualisierung für die gestellten Aufgabentypen nicht unbedingt von Nöten. Zum anderen bietet die Visualisierung nicht jedem Nutzer eine Hilfe und ist eher als eine Alternative zur textuellen Betrachtung zu sehen. Das Ergebnis ist deshalb im unmittelbaren Zusammenhang mit der Auswahl der Probanden zu sehen. + +\paragraph{Lösen des Wortproblems} +Die Bewertung der letzten Funktionalität, das automatisierte Lösen des Wortproblems, wich leicht vom erwarteten optimalen Ergebnis von fünf Punkten ab. Das automatisierte Lösen des Wortproblems und die Erstellung eines Syntaxbaumes bezogen sich direkt auf den Inhalt der dritten Aufgabe und wurde von Gruppe B mit 4,1 Punkten bewertet. Obwohl der Wert bereits weit oben liegt, sprechen die Bemerkungen der Probanden während des Lösens der Aufgabe, z.B. „\emph{Muss ich das echt machen?}“ oder „\emph{Das dauert ja ewig!}“ für eine bessere Einschätzung der Nützlichkeit dieser Funktionen und damit einer höheren Bewertung. Dieses Ziel wurde durch die praktische Anwendung teilweise erreicht. Mit durchschnittlich 4,4 Punkten der Teilnehmer, die das Plugin zur Verfügung hatten, nähert sich der Wert der vollen Punktzahl. Aus den Zusatzbemerkungen in den Fragebögen geht hervor, dass eine bessere Integration in Eclipse erwünscht ist. Wie diese aussehen könnte, wird im folgenden Kapitel \ref{sec:Verbesserungsmoglichkeiten} gezeigt.\\ + +\noindent +Abbildung \ref{fig:A8mitPlugin} und \ref{fig:A8ohnePlugin} fassen die aufgezählten Daten noch einmal in einem Diagramm zusammen. Abbildung \ref{fig:A8mitPlugin} zeigt die Bewertung Funktionalitäten der Gruppe A, also diejenigen der Teilnehmer welche mit dem Plugin arbeiteten. Abbildung \ref{fig:A8ohnePlugin} zeigt die Schätzwerte der Gruppe B. Alle Bewertungen und Schätzungen sind über die Ergebnisse der jeweiligen Gruppe gemittelt. + +Es lässt sich also zusammenfassen, dass die Funktionalitäten im Schnitt als sehr nützlich empfunden wurden und dem Anwender eine große Hilfe im Hinblick auf den Faktor Zeitersparnis bot. Zudem konnte die Fehlerrate deutlich reduziert werden. Des Weiteren, auch dies war ein Ziel der Studie, konnten Probleme aufgezeigt werden, die das Plugin nicht oder nur suboptimal unterstützten, und daher noch Potenzial für Verbesserungen bieten. + +\begin{figure} +\centering +\includegraphics[width=1\textwidth]{Bilder/Auswertung/A8mitPlugin} +\caption{Zeigt die Bewertungen für jede Funktionalität der Gruppe A im Überblick.} +\label{fig:A8mitPlugin} + +\end{figure} +\begin{figure} +\centering +\includegraphics[width=1\textwidth]{Bilder/Auswertung/A8ohnePlugin} +\caption{Zeigt die Schätzungen für jede Funktionalität der Gruppe B im Überblick.} +\label{fig:A8ohnePlugin} +\end{figure} + +\pagebreak +\section{Verbesserungsmöglichkeiten} +\label{sec:Verbesserungsmoglichkeiten} +Die Auswertung der Fragebögen, aber auch Vorüberlegungen, die während der Implementierung entstanden und nicht mehr berücksichtigt werden konnten, führten zu einer Liste von Verbesserungen und Erweiterungen, die das Plugin intuitiver und mächtiger gestalten sollen. + +Es bestand Verbesserungsbedarf hinsichtlich der Fehlermarkierung. Es wurde angemerkt, dass die Fehlermeldungen zu ungenau seien. Eine mögliche Verbesserung wäre es, eine erweiterte Fehleranalyse anzubieten, die vor allem Anfängern einen großen Nutzen bringen würde. Ein weiterer Kritikpunkt bezog sich darauf, dass das Prüfen von Sätzen zu umständlich sei. Eine sinnvolle Konsequenz wäre, dass durch eine weitere Ansicht innerhalb der Eclipse Workbench ein Bereich geboten wird, um Sätze einzugeben, die simultan zum Erstellen der Grammatik geprüft werden. Dies hätte den Vorteil, dass die Sätze bei einem erneuten Start von Eclipse gespeichert blieben und nicht jedes Mal erneut eingegeben werden müssten. Durch das Anklicken eines Symbols könnten zu beliebigen Sätzen Syntaxbäume erstellt werden. Des Weiteren wurde angeregt, eine Übersicht mit allen Funktionalitäten und deren Tastenkombination zu erstellen. Dies wurde bereits umgesetzt und zum Plugin hinzugefügt. Ferner ist eine Verbesserung des Content Assistant vorgeschlagen worden, unter anderem mit Blick auf die Autovervollständigung und der automatischen Fehlerbehebung. Wie im Kapitel \ref{sec:Funktionalitaten} Funktionalitäten beschrieben, gibt es zahlreiche und vielfältige Möglichkeiten, den Content Assistant intelligenter zu gestalten. Eine Erweiterung des Content Assistant in späteren Projekten ist also gut vorstellbar und sinnvoll. \ No newline at end of file diff --git a/isr-eclipse-plugin/TeX/Inhalt/Fazit.tex b/isr-eclipse-plugin/TeX/Inhalt/Fazit.tex new file mode 100644 index 0000000000000000000000000000000000000000..98cfe5e73fb6ae347dd87c101ce383c23f93d1fe --- /dev/null +++ b/isr-eclipse-plugin/TeX/Inhalt/Fazit.tex @@ -0,0 +1,12 @@ +\chapter{Fazit und Ausblick} +\label{cha:FazitUndAusblick} + +Im Rahmen dieser Bachelorarbeit ist auf Basis eines Eclipse-Plugin ein Editor zur optimierten Bearbeitung von ISR-Grammatiken erstellt worden. + +Zunächst wurde durch das Erstellen von Anforderungen an die zu entwickelnde Software und eine anschließende Analyse der Anforderungen, eine Übersicht über die zu implementierenden Funktionalitäten erarbeitet. Ein detaillierter und realistischer Anwendungsfall unterstützte dabei die Auswahl und Entwicklung der Funktionalitäten. Aufgrund der konkreten Anforderungen war es sinnvoll, den Editor als Eclipse-Plugin zu entwickeln. Das ermöglichte, die zu implementierenden Funktionalitäten übersichtlich und erweiterbar einzubetten. + +Die Auswahl und die anschließende Implementierung der Funktionalitäten stellten den Kern der Bachelorarbeit dar. nach der Implementierungsphase wurde eine Studie durchgeführt, in der belegt werden konnte, dass de gewählten Funktionalitäten sinnvoll sind und ihre Nutzung einen klaren Vorteil bei der Bearbeitung der ISR-Grammatik bietet. Aus der Studie ging ebenfalls hervor, dass an einigen Stellen des Plugin Verbesserungspotential gesehen wurde. Dazu wurden die Lösungsvorschläge der Probanden miteinbezogen und zum Teil nach der Studie dem Programm hinzugefügt. Dies lieferte den Beweis, dass die gewählte Architektur der Software es ermöglicht, Funktionalitäten nachträglich zu optimieren oder neue hinzuzufügen.\\ + +In weiteren Projekten könnte die Software dahingehend verbessert werden, selektive Funktionalitäten intelligenter oder effizienter zu programmieren. Es wäre zudem möglich, bestimmte Regeln, welche wiederkehrend in Grammatiken vorkommen, auszulagern. Dazu müsste ein eigenes Format entwickelt werden, welches solche Referenzen zulässt. Es würden redundante Informationen vermieden und gleichzeitig die Grammatiken konsistent gehalten. Eine zusätzliche Erweiterung könnten weitere Metazeichen sein, die zum Beispiel zum Auskommentieren von Regeln definiert werden. \\ + +Zusammenfassend lässt sich sagen, dass der in dieser Bachelorarbeit entstandene Editor den Umgang mit der ISR-Grammatik sowohl für Anfänger als auch für Fortgeschrittene erleichtert. Darüber hinaus bietet die Erweiterbarkeit der Architektur die Möglichkeit, das Plugin zu optimieren oder um weitere Funktionalitäten zu ergänzen. \ No newline at end of file diff --git a/isr-eclipse-plugin/TeX/Inhalt/Glossar.tex b/isr-eclipse-plugin/TeX/Inhalt/Glossar.tex new file mode 100644 index 0000000000000000000000000000000000000000..14b1e2a04739a253ee76749b4722bbe4633cf327 --- /dev/null +++ b/isr-eclipse-plugin/TeX/Inhalt/Glossar.tex @@ -0,0 +1,15 @@ +\nomenclature{API}{Application Programming Interface} +\nomenclature{ARIS}{Architektur integrierter Informationssysteme} +\nomenclature{BPR}{Business Process Reengineering} +\nomenclature{eEPK}{erweiterte Ereignisgesteuerte Prozesskette} +\nomenclature{EPK}{Ereignisgesteuerte Prozesskette} +\nomenclature{JMS}{Java Message Service} +\nomenclature{SDK}{Software Development Kit} +\nomenclature{URI}{Uniform Resource Identifier} +\nomenclature{URL}{Uniform Resource Locator} +\nomenclature{URN}{Uniform Resource Name} +\nomenclature{W3C}{World Wide Web Consortium} +\nomenclature{XML}{Extensible Markup Language} +\nomenclature{XPath}{XML Path Language} +\nomenclature{XSL}{Extensible Stylesheet Language} +\nomenclature{XSLT}{XSL Transformations} diff --git a/isr-eclipse-plugin/TeX/Inhalt/Grundlagen.tex b/isr-eclipse-plugin/TeX/Inhalt/Grundlagen.tex new file mode 100644 index 0000000000000000000000000000000000000000..b4cee58ae16c8a2060f33808cb3c1d90e1623e0c --- /dev/null +++ b/isr-eclipse-plugin/TeX/Inhalt/Grundlagen.tex @@ -0,0 +1,127 @@ +\chapter{Grundlagen} +\label{cha:Grundlagen} + +\section{ISR-Grammatik} +\label{sec:ISR-Grammatik} +Die ISR-Grammatik ist eine Sammlung von kontextfreien Regeln, welche einen Ausschnitt einer natürlichen Sprache repräsentiert. Ihren Einsatz findet sie in dem an der Universität Bielefeld entwickeltem ESMERALDA-Spracherkenner. Sie dient dazu, unbrauchbare oder syntaktisch nicht gewollte Satzstrukturen von vornherein beim Erkennungsprozess der Sprache auszuschließen und damit die Leistung der Spracherkennung zu steigern. Dazu wird sie als Schnittstelle zwischen dem Spracherkenner und einem Interpretationsmodul eingesetzt. + +Obwohl die ISR-Grammatik durch kontextfreie Regeln definiert ist, können bei Bedarf besondere Symbole zur Erweiterung der Grammatik eingesetzt werden. Die unterschiedlichen Symbole und ihre Bedeutungen werden im Abschnitt \ref{subsec:Besonderheiten und Zusatzsymbole} beschrieben. Zum besseren Verständnis wird zuvor auf den Aufbau und die Struktur der Grammatik eingegangen. +\subsection{Aufbau und Struktur} +\label{sec:Aufbau und Struktur} +Der Aufbau einzelner Regeln der ISR-Grammatik ist durch ihre kontextfreie Eigenschaft größtenteils festgelegt(vgl. \emph{Chomsky Hierarchie 2})\footnote{\url{http://de.wikipedia.org/wiki/Chomsky-Hierarchie\#Typ-2-Grammatik\_.28kontextfreie\_Grammatik.29}}. Daher wird im Folgenden nur auf die symbolische Repräsentation der Grammatikelemente eingegangen. + +\textquotedblleft \texttt{\$Greeting: hello \textbar\ hi \textbar\ hi \$Name ;}\textquotedblright + +\noindent +zeigt exemplarisch den Aufbau einer Regel. Im Folgenden wird auf die Bedeutung der einzelnen Bausteine der Regel eingegangen. Das von dem Dollarsymbol und dem Doppelpunkt begrenzte \emph{Non-Terminal} \texttt{Greeting} ergibt seine Deklaration und stellt somit den Anfang einer Regel dar. Typischerweise dürfen zwei Deklarationen nicht denselben Namen tragen. Das nachfolgende Element \texttt{hello} wird als \emph{Terminal} bezeichnet. Das Pipe-Symbol \texttt{\textbar\ } repräsentiert das klassische kontextfreie Oder-Symbol. Die Benutzung eines Non-Terminals stellt das vorletzte Element der Beispielregel dar. Das Non-Terminal \texttt{Name}, gekennzeichnet durch das Dollar-Symbol, zeigt auf eine weitere Regel innerhalb der Grammatik. Der Anfang dieser Regel würde wie folgt aussehen: \texttt{\$Name:}. Das Ende jeder Regel wird durch ein Semikolon gekennzeichnet. +\\ + +\noindent +Terminale und Non-Terminale werden aus dem regulären Ausdruck + + \texttt{[a-zA-Z\_\textbackslash\textquotedblright][a-zA-Z\_\textbackslash-\textbackslash\textquotedblright0-9]*} + +\noindent +beschrieben, wobei Non-Terminale mit dem Präfix \texttt{\$} gekennzeichnet sind. Die Startregel wird durch \texttt{\$\$S:} gegeben. + +Das gerade beschriebene Beispiel zeigt nur den Standard einer Regel. Die Besonderheiten und Zusatzsymbole der Grammatik, deren Aufbau und Wirkungsweise, wird im folgendem Abschnitt erläutert. + +\subsection{Besonderheiten und Zusatzsymbole} +\label{subsec:Besonderheiten und Zusatzsymbole} +\paragraph{Joker-Symbol}Das Joker-Symbol ist ein spezielles Terminal der Grammatik, welches durch die Zeichenfolge\texttt{!*} beschrieben wird. Ist der Joker Teil einer Regel, kann vom Kompiler an genau dieser Stelle, jedes beliebige Terminal eingesetzt werden, um den Satz zu vervollständigen. + +\paragraph{Technisches Non-Terminal}Auch das technische Non-Terminal ist eine Besonderheit der ISR-Grammatik. Durch ein zweites \texttt{\$} im Präfix wird aus einem gewöhnlichen, ein technisches Non-Terminal. Ein typischer Fall, ist das Start-Symbol \texttt{\$\$S}. Dies ist für die Interpretation des Satzes irrelevant, würde aber dennoch immer an oberster Stelle eines Syntaxbaums als Non-Terminal stehen. Als technisches Non-Terminal wird es beim Erstellen jedoch ignoriert, hilft aber beim Prozess des Parsens. + +\paragraph{Ignore-List}Die Ignore-List ist eine weitere Besonderheit der ISR-Grammatik. Diese enthält eine Liste von Terminalen, die beim Validieren eines Satzes vom Kompiler ignoriert werden können. Typischerweise sind dies Füllwörter oder Unterbrechungen wie \textbf{\emph{ehh}}, \textbf{\emph{ehm}} oder \textbf{\emph{ah}}. Ihr Aufbau ist mit dem Aufbau einer gewöhnlichen Regel vergleichbar. Durch \texttt{\%Ignore=} wird dem Kompiler mitgeteilt, dass es sich im Folgendem um eine Ignore-List handelt, diese wird ebenfalls durch ein Semikolon geschlossen. Im Gegensatz zu einer Regel, sind innerhalb der Ignore-List nur Terminale erlaubt. So kann durch eine entsprechende Wahl von Terminalen erreicht werden, dass die zwei abweichenden, aber semantisch gleichen Sätze „\emph{I like red cups}“ und „\emph{I like \textbf{ehh} red cups}“ vom Kompiler äquivalent geparst werden. + +\subsection{Beispiel} +\label{sec:Beispiel} +Im Folgenden ist ein Beispiel\footnote{Quelle: Manualpage des ISR-Spracherkenner} einer ISR-Grammatik zu sehen. Anschließend werden Beispielsätze gezeigt, die mit dieser Grammatik erstellt werden können.\begin{quote} +\flushleft\texttt{\$TIME : \$DAY \$TIME\_CIRCA \$TIME\_PRECI ;\\ +\$DAY : today ;\\ +\$TIME\_CIRCA : in the morning \textbar\ ;\\ +\$TIME\_PRECI : at \$TIME\_HOUR oclock \\ +\centering\textbar\ at \$TIME\_HOUR point \$TIME\_MIN \textbar\ ; +\flushleft\$TIME\_HOUR : one \textbar\ two \textbar\ three ;\\ +\$TIME\_MIN : zero \textbar\ fifteen \textbar\ thirty ;\\ +\$\$S : \$TIME ;}\end{quote} +Aus dieser Grammatik lassen sich unter anderem folgende Sätze bilden „\textbf{\emph{Today}}“, „\textbf{\emph{Today in the morning}}“ oder „\textbf{\emph{Today at one oclock}}“. Die Abbildung \ref{fig:SynTree} stellt die Herleitung des dritten Satzes in einem Syntaxbaum dar. + +\begin{figure}[h] +\flushleft +\includegraphics[scale=0.8,width=1\textwidth]{Bilder/Syntaxtree} +\caption{In dieser Abbildung ist ein Syntaxbaum dargestellt, indem die Herleitung des Satzes „\textbf{\emph{Today at one oclock}}“ zu sehen ist.} +\label{fig:SynTree} +\end{figure} +\pagebreak +\section{Anforderungen an die Software} +\label{sec:Anforderung an die Software} +Eine Software, die den Umgang mit der ISR-Grammatik erleichtern soll, muss bestimmte Anforderungen erfüllen. Die Art, in der dem Nutzer Unterstützung geboten werden soll, ist eine grundlegende Entscheidung, die zunächst getroffen werden muss. Da die ISR-Grammatik durch eine Ansammlung textueller Regeln definiert ist, liegt es nahe, einen Texteditor zu entwerfen. Zu den Mindestanforderungen an einen Editor gehören unter anderem die Basisfunktionalitäten Kopieren, Ausschneiden, Einfügen und Suchen. Eine weitere sinnvolle Anforderung ist eine interne Dateiverwaltung. + +Als grundlegende Voraussetzung gilt, dass der Editor übersichtlich und leicht zu benutzen ist, um dadurch eine möglichst kurze Einarbeitungsphase in den Editor zu gewährleisten. + +Darüber hinaus, und das trifft auf die existierenden Editoren nicht zu, muss er eine Funktionsvielfalt bieten, die es lohnenswert macht, gerade diesen Editor zur Bearbeitung von ISR-Grammatiken zu benutzen. Um Erweiterungen oder Verbesserungen vornehmen zu können, sollte der zugrundeliegende Editor in seiner Architektur so offen sein, dass weitere Funktionalitäten leicht in das Programm integriert werden können. + +Über allen Funktionalitäten und den damit angebotenen Hilfen steht das Ziel einer effizienteren Arbeitsweise im Vordergrund. Dies gilt sowohl für Anfänger als auch für erfahrene Benutzer. + +\section{Anwendungsfall} +\label{sec:Anwendungsfall} +\begin{quote} +\emph{Im Rahmen des Robocup-Events ist Alice dazu eingeteilt worden, die erforderlichen ISR-Grammatiken für die Spracherkennung zu erstellen. Ihre erste Aufgabe ist es, alte Grammatiken nach ihrer Korrektheit zu prüfen und gegebenfalls zu korrigieren. Da der benutzte Editor ihr keine Hilfestellung bietet, fehlerhafte Dateien direkt zu erkennen, muss sie jede zu prüfende Grammatik manuell nach Fehlern durchsuchen. Als Hilfestellung greift sie auf den Kompiler der ISR-Grammatiken zurück. Nach einiger Zeit ist dieser mit dem Parsen einer Grammatik fertig. Alice durchsucht die Log-Ausgaben und findet schließlich eine Angabe, die auf einen Fehler hinweist. Alice öffnet die defekte Grammatik und sofort erscheint eine unstrukturierte Ansammlung von Regeln, die diese Grammatik spezifizieren. Als sie zu der Zeile navigieren möchte, wo der Fehler sich befinden soll, fällt ihr auf, dass die Zeilenangabe des Kompilers nicht stimmen kann oder sich nicht auf diese Datei bezieht, da die angegebene Datei nicht so viele Zeilen hat. Daher ist sie gezwungen, die komplette Grammatik letztendlich doch manuell zu durchsuchen. Eine direkte Fehleranzeige innerhalb der Grammatik hätte ihr den Fehler direkt nach dem Öffnen der Datei angezeigt und ihr damit viel Zeit erspart.} + +\emph{Nachdem Alice alle Grammatiken syntaktisch geprüft hat, besteht ihre nächste Aufgabe darin, die Semantik zu validieren. Dies bedeutet für sie zu verifizieren, ob jede Grammatik alle benötigten Sätze abbilden kann. Ist dies nicht der Fall, muss sie die Regeln der Grammatik so erweitern, dass die fehlenden Sätze abgebildet werden können. Alice öffnet die erste Grammatik und beginnt mit dem ersten Satz, indem sie das Startsymbol der Grammatik sucht. Im weiteren Verlauf, muss Alice immer wieder durch die Grammatik navigieren, um die benötigten Non-Terminale zu finden. Des öfteren kommt sie dabei durcheinander, sodass sie nach Beendigung der Aufgabe nicht sicher sein kann, ob wirklich alle benötigten Sätze von der Grammatik gebildet werden können. Das langsame Navigieren durch die Grammatik kostet sie dabei zusätzlich viel Zeit.} + +\emph{Da Alice mit dieser Aufgabe beschäftigt ist, soll Bob eine weitere Aufgabe von Alice übernehmen. Eine kürzlich erstellte Aufgabe im Regelbuch des Robocup-Events erfordert eine komplett neue Grammatik, die von Bob erstellt werden soll. Er bekommt ein Pool von Sätzen, die von der Grammatik abgebildet werden sollen. Da Bob keine Erfahrungen mit der ISR-Grammatik hat, fällt es ihm schwer einen Überblick über die syntaktische Struktur zu erlangen. Nach anfänglichen Problemen schafft er es, die Grammatik zu erstellen. Jedoch stellt sich ihm nun das gleiche Problem wie zuvor Alice. Er kann sich nicht sicher sein, ob die Grammatik sowohl semantisch als auch syntaktisch einwandfrei funktioniert.} + +\emph{Nachdem Alice ihre Aufgaben bearbeitet hat, möchte sie einen genauen Überblick über die von Bob entworfene Grammatik erhalten. Da Alice eher visuell ambitioniert ist, fällt es ihr schwer einen Überblick über die ihr unbekannte Grammatik zu bekommen.} +\end{quote} + +\section{Anforderungsanalyse} +\label{sec:Anforderungsanalyse} +Um angemessene Anforderungen stellen zu können, denen das Programm gerecht werden soll, muss zunächst analysiert werden, welche Zielgruppen und unter welchen Voraussetzungen das Programm benutzt wird. Einen Anhaltspunkt liefert das in der Motivation in Kapitel \ref{sec:Motivation und Zielstellung} beschriebene Robocup@Home-Event. Dazu wird an der Universität Bielefeld ein Robocup-Projekt angeboten, dessen Team jedes Jahr überwiegend neu zusammengesetzt wird. Daher kann angenommen werden, dass diese Studenten keine oder nur wenig Erfahrung mit der ISR-Grammatik haben. Das ESMERALDA-Spracherkennungssystem, welches diese Grammatik benutzt, wird aber auch in verschiedenen anderen Projekten eingesetzt, die überwiegend von festen Mitarbeitern der Universität geleitet werden. Diese Anwender werden, im Gegensatz zu vielen Studierenden, die mit der Software arbeiten, schon einige Erfahrungen mit der ISR-Grammatik gemacht haben und daher fundierte Kenntnisse besitzen. Aufgrund dieser Annahmen können nun angemessene Anforderungen formuliert werden. + +Einen besonderen Stellenwert hat die leichte Erlernbarkeit, da sich jedes Semester neue, unerfahrene Studierende mit dem Spracherkenner befassen werden.\\ +\paragraph{Anforderung 1:}Die Software bedarf nur einer kurzen Einarbeitungsphase.\\ + +Folglich sollte auch die Handhabung nicht zu kompliziert sein das heißt, eine intuitive Bedienung ist zwingend notwendig. \paragraph{Anforderung 2:}Die Software ist intuitiv bedienbar. \\ + +Aus der Analyse ergibt sich auch, dass das Programm eine bessere Übersicht über eine gegebene Grammatik schaffen sollte und zusätzlich das Navigieren durch große Grammatiken präzisiert. \paragraph{Anforderung 3:}Die Software gibt einen guten Überblick über die bestehenden Grammatiken.\\ + +Um auch unerfahrenen Nutzern ein effizientes Arbeiten zu ermöglichen, sollten komplizierte oder immer wiederkehrende Aufgaben durch die Funktionalitäten erleichtert oder sogar ganz übernommen werden können. \paragraph{Anforderung 4:}Die Software löst oder unterstützt die Aufgabenbearbeitung.\\ + +Eine weitere Anforderung an das Programm ist es, dem Anwender aktiv Lösungs-möglichkeiten anzubieten, deren Verwendung bei anderen Editoren fundierte Kenntnisse voraussetzten würde. +\paragraph{Anforderung 5:}Die Software bietet einen Überblick über die gegeben Lösungs-möglichkeiten.\\ + +Darüber hinaus sollte durch das Programm eine schnellere und effizientere Arbeitsweise ermöglicht werden. +\paragraph{Anforderung 6:}Die Software beschleunigt das Erstellen einer Grammatik und reduziert die Fehleranfälligkeit.\\ + +Resümierend lässt sich konstatieren, dass all diese Funktionen und Anforderungen sowohl Anfängern als auch erfahrenen Nutzern helfen sollen, die Grammatik besser zu verstehen. Der Umgang mit der Grammatik soll erleichtert und effizienter werden. + +\section{Verwandte Arbeiten} +\label{sec:Verwandte Arbeiten} +Dieses Kapitel beschäftigt sich mit Software, die ähnliche Aufgabenbereiche behandeln. Durch den detaillierten Anwendungsfall aus Kapitel \ref{sec:Anwendungsfall} gingen Informationen hervor, die bei der Modellierung der Software beachtet werden müssen. Diese Informationen können nun benutzt werden, um herauszufinden ob es möglicherweise schon bestehende Software gibt, die verwendet oder deren Funktionalitäten man erweitern kann. Dabei wurde bei der Auswahl der vorzustellenden Software darauf geachtet, dass sie möglichst den aktuellen Stand der Forschung, auf diesem Gebiet wiedergibt. Der Fokus dieses Kapitels ist auf drei verschiedene Produktarten gelegt, welche sich grundsätzlich in der Art wie sie den Anwender Unterstützen unterscheiden. + +\paragraph{Xtext} +Es gibt Software auf dem Markt, welche sich mit dem Erstellen von eigenen Sprachen beschäftigt. Ein sehr bekanntes Framework ist \textbf{\emph{Xtext}}\footnote{\url{http://www.eclipse.org/Xtext/}}, welches für die Programmierumgebung Eclipse entwickelt wurde. + +Xtext bietet in der Benutzung viele Vorteile. Besonders hervorzuheben sind die vielen Tutorials und eine sehr gute Dokumentation, welche den Einstieg erleichtern. Zudem werden durch die Benutzung von Xtext viele Funktionen implizit bereitgestellt. So wird automatisch ein Syntax-Parser über die \emph{ANTRL}\footnote{\url{http://www.antlr.org/}}-Technologie, Syntaxhighlighting, und einen Content Assistant zur erstellten Sprache mitgeliefert. + +Dies kann durchaus in vielen Projekten ein Vorteil sein, bietet für einen ISR-Grammatik-Editor aber nur bedingt Hilfe. Dadurch, dass es sich um eine kontextfreie Grammatik handelt, entstehen unter anderem dynamische \emph{Keywords}\footnote{Als Keywords werden Wörter oder Zeichenmuster genannt, die in ihrer Sprache eine besondere Bedeutung haben}, welche wiederum bei dem Syntaxhighlighting berücksichtigt werden müssen. Dies ist aber zum jetzigen Zeitpunkt in Xtext nur unkomfortabel lösbar. Auch der mitgelieferte Parser, müsste überschrieben werden, um eigene Fehlermeldungen an den Nutzer übermitteln zu können. + +Der Hauptgrund, warum Xtext den hier gestellten Anforderungen nicht genügt, liegt in der Fokussierung auf der Erstellung von Sprachen oder Grammatiken. Die Einbindung von zusätzlichen, Editor unabhängigen, Funktionalitäten wie zum Beispiel eine Hilfestellung zum Lösen des Wortproblems, eine Visualisierung oder erweiterte Exportfunktionen können nicht integriert werden. + +\paragraph{Parser-Editor} +Neben Frameworks und anderen Hilfsmitteln zur Erstellung eines Editors gibt es eine Reihe von Editoren, deren Nachteil oft darin besteht, dass sie nicht ausreichend erweiterbar sind. Ein Beispiel hierfür bildet der {\textbf{\emph{Parser-Editor}}\footnote{\url{http://www.psue.uni-hannover.de/ParserSuite/plugin.php}}, welcher an der Universität Hannover entwickelt wurde. Dieser bietet eine Programmierumgebung für kontextfreie Grammatiken. Erwähnenswert macht diesen Editor die gute Darstellung der Grammatik. Sie kann mit Hilfe von Syntaxhighlighting und weiteren Hilfsinformationen einfacher verstanden und bearbeitet werden. Der Schwerpunkt dieses Editors liegt jedoch nicht auf der Erstellung einer Grammatik, sondern wie schon aus dem Namen ersichtlich, auf der Erstellung von Parsern und Kompilern für eine kontextfreie Grammatik. Da der Parser-Editor eine eigene, von der ISR-Grammatik unterschiedliche, Notation verwendet, kann er zur Erstellung von ISR-Grammatiken jedoch nicht genutzt werden. + +\paragraph{Onlinesoftware} +Eine Produktsuche im Internet für Online-Editoren zur Gestaltung kontextfreier Grammatiken bringt wenig brauchbare Ergebnisse. Die meisten Editoren ähneln dem im Link\footnote{\url{http://smlweb.cpsc.ucalgary.ca/}} zu findenden Beispiel. Der Vorteil einer Onlinesoftware besteht jedoch darin, dass sie über jeden internetfähigen Rechner direkt zugänglich ist und keine Installation vorgenommen werden muss. Der große Nachteil besteht aber in ihrer Abgeschlossenheit. So sind die meisten Tools nur auf die vorgegebene Syntax angepasst und bieten keine Möglichkeit, das Programm zu erweitern. + +\section{Benutze Technologien} +\label{sec:Benutze Technologien} +Zunächst wurde festgelegt, dass keine StandAlone-Software entwickelt werden sollte, stattdessen wurde ein Plugin für eine schon bestehende Software präferiert. Die Entwicklungsumgebung \emph{Eclipse}\footnote{\url{http://www.eclipse.org/}} bietet mit seiner offenen Architektur eine sehr gute Grundlage für eine Erweiterung über Plugins .\cite{Eclipse} Daraus resultierend wurde für die Implementierung die Programmiersprache {\emph{Java}\footnote{\url{http://www.oracle.com/technetwork/java/index.html}} gewählt. Dies hat zusätzlich zwei wesentliche Vorteile: zum einen bietet Eclipse eine sehr gute Dokumentation und viele Beispielprojekte, zum anderen werden durch die Wahl ein Plugin zu implementieren, bereits implizit viele Anforderungen an das Programm erfüllt. Ein Editor-Plugin für Eclipse impliziert alle in der Anforderung aufgezählten Grundbausteine. Zwar müssen hinsichtlich der Übersichtlichkeit einige Abstriche gemacht werden, die es bei einer StandAlone-Software nicht gegeben hätte, jedoch werden diese größtenteils dadurch kompensiert, dass Eclipse für viele Programmierer bereits eine gewohnte Umgebung darstellt (siehe Anforderung eins und zwei der Analyse in Kapitel \ref{sec:Anforderungsanalyse}). Auch bietet Eclipse eine effiziente Dateiverwaltung und viele Schnittstellen, um eigene Funktionalitäten in das Plugin zu integrieren sodass die dritte Anforderung aus der Analyse (siehe Kapitel \ref{sec:Anforderungsanalyse}) ebenfalls erfüllt ist. + +Im weiteren Verlauf werden Technologien vorgestellt, die benutzt worden sind, um die Implementierung von Funktionalitäten des Plugins zu unterstützen. + +\paragraph{\textbf{\emph{Zest}}} Zest ist ein Tool zur Visualisierung von Strukturen und Graphen. Die im letzten Abschnitt der Anwendergeschichte (siehe Kapitel \ref{sec:Anforderungsanalyse}) vorgestellte Visualisierung kann mit Hilfe des \textbf{\emph{Zest-Frameworks}} realisiert werden. Die Entscheidung, weshalb auf Zest zurückgegriffen wurde, hat mehrere Gründe. Dazu zählt zum Beispiel, dass Eclipse eine einfache Lösung bietet Zest einzubinden. Darüber hinaus ist es dadurch, dass die Visualisierung über \emph{SWT}\footnote{\url{http://www.eclipse.org/swt/}} und \emph{Draw2d}\footnote{\url{http://www.draw2d.org/draw2d/}} geregelt wird, für das Eclipse-Plugin in der Hinsicht hilfreich, dass es eine nahtlose Einbettung, in das System von Eclipse ermöglicht.\footnote{\url{http://www.eclipse.org/gef/zest/}} + +\paragraph{\textbf{\emph{SOCS Grammar Editor}}} Das Projekt Grammar Editor ist eine Bibliothek von Java-Klassen, die einen Parser und eine Visualisierung von Syntaxbäumen bereitstellt. Um verschiedene Sätze gegenüber einer ISR-Grammatik zu validieren, wurde auf die Funktion einiger Klassen der Bibliothek zurückgegriffen.\footnote{\url{http://ozark.hendrix.edu/~burch/socs/software.html}} \ No newline at end of file diff --git a/isr-eclipse-plugin/TeX/Inhalt/Umsetzung.tex b/isr-eclipse-plugin/TeX/Inhalt/Umsetzung.tex new file mode 100644 index 0000000000000000000000000000000000000000..ddd15b72b2138d10bb6b01c35ec68922333f37b8 --- /dev/null +++ b/isr-eclipse-plugin/TeX/Inhalt/Umsetzung.tex @@ -0,0 +1,233 @@ +\chapter{Umsetzung} +\label{cha:Umsetzung} + +\section{Funktionalitäten} +\label{sec:Funktionalitaten} +Die Ergebnisse aus der Anforderungsanalyse (Kapitel \ref{sec:Anforderungsanalyse}) haben deutlich gezeigt, dass es viele nützliche Hilfen gibt, die ein Editor zum Erstellen einer ISR-Grammatik bereitstellen kann. Zusätzlich wurde die Auswahl wichtiger Funktionalitäten durch das \emph{IBM}-Tutorial \textquotedblleft \emph{Create a commercial-quality Eclipse IDE}\textquotedblright\footnote{\url{http://www.ibm.com/developerworks/opensource/tutorials/os-ecl-commplgin1/os-ecl-commplgin1-pdf.pdf}} bekräftigt. Im Folgenden werden Funktionalitäten vorgestellt, die alle Anforderungen abdecken. Um den Einstieg in die Materie zu erleichtern und den Zusammenhang mit der Anforderungsanalyse zu zeigen, beginnt dieses Kapitel mit einer allgemeinen Erklärung jeder implementierten Funktionalität. Zudem wird gezeigt, durch welche Eigenschaft die Funktionalität eine bestimmte Anforderung erfüllt. + +\subsection{Syntaxhighlighting} +\label{subsec:Syntaxcoloring} +Syntaxhighlighting ist ein elementarer Bestandteil dieses Editors. Durch farbliche Hervorhebung werden Keywords makiert. Im Gegensatz zu vielen Programmiersprachen gibt es in der ISR-Grammatik nur wenige statische Keywords, dafür unbegrenzt viele dynamische. Statische Keywords sind vorab festgelegt, zu ihnen gehören \texttt{\%IGNORE}, \texttt{\$\$S}, \texttt{!*}, \texttt{:}, \texttt{;} und \texttt{\textbar\ }. +Dynamische Keywords entstehen erst beim Erstellen der Grammatik. Jede Deklaration und jedes Non-Terminal sind dynamisch erzeugte Keywords. +Eine farbige Repräsentation der Grammatik hilft dem Nutzer, sich einfacher in ihr zurecht zu finden. Sie erhöht die Lesbarkeit und hilft ihm, wichtige von unwichtigen Bestandteilen der Grammatik zu unterscheiden und reduziert somit die Fehleranfälligkeit (Anforderung sechs, Kapitel \ref{sec:Anforderungsanalyse}). + +\subsection{Automatische Formatierung} +\label{subsec:Autoformatierung} +Um der Anforderung drei aus der Analyse (Kapitel \ref{sec:Anforderungsanalyse}) zu entsprechen wird ein weiteres wichtiges Werkzeug dem Editoren hinzugefügt, die automatische Formatierung. Diese bietet dem Nutzer die Möglichkeit, die geschriebenen Regeln automatisch in ein vorgegebenes Standardformat zu bringen. Um dies zu definieren, ist es notwendig Strategien, zu entwickeln nach dem die automatisierte Formatierung vorgehen soll. Eine solche Strategie kann zum Beispiel beinhalten, dass nach bestimmten Symbolen Umbrüche eingefügt werden. + +Ein eigenes Format ohne editorseitige Unterstützung einzuhalten, würde vermehrt Zeit in Anspruch nehmen. Ein automatischer Formatierer erhöht auf einfachem Weg die Lesbarkeit der Grammatik. Zusätzlich gewährleistet er, dass alle Nutzer dasselbe Format benutzen und genau den definierten Standard einhalten. Wird die Autoformatierung regelmäßig eingesetzt, erhalten weitere Nutzer einen schnellen Überblick über ihnen unbekannte Grammatiken. + +Abbildung \ref{fig:Syn} zeigt Regeln einer Grammatik dessen Formatierung dem entwickelten Standard entsprechen. Des Weiteren wird die Funktionsweise des Syntaxhighlighting verdeutlicht und gibt Aufschluss über die Farbwahl der Regelelemente. + +\begin{figure}[h] +\includegraphics{Bilder/SyntaxHighlighting} +\caption{Syntaxhighlighting einer standardformatierten Grammatik im ISR-Grammatik-Editor.} +\label{fig:Syn} +\end{figure} + +\subsection{Fehlermarkierung} +\label{subsec:Fehler-Markierung} +Die Prüfung der Syntax von Sprachen und vor allem die Visualisierung der auftretenden Fehler, ist ein wichtiges und mächtiges Werkzeug in einer Entwicklungsgebung. Ob es sich bei den Sprachen um eine Programmiersprache wie C, C++ oder Java handelt oder ob sie eine kontextfreie Grammatik wiedergeben, macht in dieser Hinsicht keinen Unterschied. Ein solches Werkzeug sollte daher auch in diesem Editor nicht fehlen. + +Da für die ISR-Grammatik ein Kompiler schon existiert, stellt sich die Frage, welchen Vorteil ein integrierter Parser mit sich bringt. Zwei Vorteile gehen aus Beobachtungen hervor. Die Ergebnisse des integrierten Parsers sind sehr viel leichter zu interpretieren, da er Fehler in den Regeln direkt anzeigt und gegebenenfalls Verbesserungsvorschläge anzeigt. Der Benutzer erkennt also, die Ursache des Fehlers und kann ihn direkt beheben. Des Weiteren hat der interne Parser gegenüber dem externen eine extrem kurze Kompilierzeit. Der Vorteil einer direkten Fehlermarkierung ist klar ersichtlich. Da durch sie schon während der Grammatikerstellung Syntaxfehler direkt vermieden werden, bringen sie eine enorme Zeitersparnis im Prozess der Syntaxvalidierung. Damit entspricht sie den Anforderungen drei bis sechs der Analyse in Kapitel \ref{sec:Anforderungsanalyse}. + +\subsection{Hoverinformation} +\label{subsec:Hover-Information} +Als Hoverinformation werden temporär angezeigte Fenster bezeichnet, die situationsspezifische Informationen beinhalten. Durch Positionierung des Mauszeigers über einen längeren Zeitraum auf ein in der Regel vorkommendes Element, erscheint an selber Stelle eine kontextsensitive Hoverinformation. Bei Veränderung der Position wird sie automatisch ausgeblendet. + +Ist das Wort von einer Fehlermarkierung umgeben, wird die Fehlerbeschreibung und gegebenenfalls ein Lösungsvorschlag angezeigt (siehe Anforderung fünf, Kapitel \ref{sec:Anforderungsanalyse}). Ist dies nicht der Fall, wird geprüft, ob es sich um ein Non-Terminal handelt. In diesem Fall besteht die Information aus der Deklaration des Non-Terminals. Trifft keines von beidem zu, wird kein Fenster geöffnet. + +Hoverinformationen ermöglichen dem Anwender, auf eine einfache und schnelle Art und Weise, einen Überblick über die kontextsensitive Information eines Regelelementes zu erhalten. + +Abbildung \ref{subfig:Feh} zeigt die Fehlermarkierung des ISR-Grammatik-Editors. Um an den Fehlertext zu gelangen, wurde die Funktionalität der Hoverinformation benutzt. Diese ist in dem gelben Rechteck unter Zeile Acht zu sehen. Rote Linien deuten auf einen fatalen Fehler hin, wohin gegen gelbe Linien Warnungen darstellen. Das Non-Terminal \texttt{GERMAN} hat keine zugehörige Deklaration, das Non-Terminal \texttt{NAME} hingegen ist unbenutzt. + +\begin{figure}[h] +\includegraphics{Bilder/Fehlermarkierung} +\caption{Zwei verschiedene Arten von Fehlermarkierungen. Die gelben Markierungen stellen Warnungen dar, rote zeigen fatale Fehler an. Der Fehlertext wird als Hoverinformation dargestellt.} +\label{subfig:Feh} +\end{figure} + +\subsection{Content Assistent} +\label{subsec:Content-Assistent} +Die Funktion eines Content Assistant besteht darin, dem Benutzer eine kontextsensitive Auswahl an Programmiermöglichkeiten anzubieten. Der ISR-Grammatik-Editor kann unter anderem Deklarationen, Non-Terminale oder Sondersymbole bereitstellen. Oft wird der Content Assistant auch zur automatisierten Vervollständigung benutzt. Die Möglichkeiten, den Assistenten intelligent zu gestalten, sind praktisch unbegrenzt. Zum Beispiel zeigt ein optimierter Assistent dem Programmierer fehlende Deklarationen oder ordnet die Vorschläge nach ihrer Bedeutsamkeit. Darüber hinaus kann er vorgefertigte Konstrukte oder Hinweise auf fehlende Konstrukte anbieten. + +Der Content Assistant ist vor allem dann eine große Hilfe, wenn der Anwender sich nur wenig mit der gegebenen Syntax auskennt. Doch auch für erfahrene Benutzer ist er hilfreich, denn er beschleunigt das Programmieren in vielen Situationen und reduziert durch das Einsetzen vorgefertigter Konstrukte die Fehleranfälligkeit (siehe Anforderung sechs Kapitel \ref{sec:Anforderungsanalyse}). + +Die Abbildung \ref{fig:Con} zeigt den Content Assistent bei Gebrauch. Zu sehen ist, dass das Non-Terminal \texttt{GERMAN} wie in Abbildung \ref{subfig:Feh} keine zugehörige Deklaration besitzt. Der Content Assistant wurde zwischen zwei Regeln aufgerufen und zeigt als erstes Hilfskonstrukt die fehlende Deklaration. +\begin{figure}[h] +\includegraphics[width=1\textwidth]{Bilder/ContentAssistant} +\caption{Content Assistant bei einem Aufruf zwischen zwei Regeln. Die fehlende Deklaration des Non-Terminals \texttt{GERMAN} als erste Auswahlmöglichkeit.} +\label{fig:Con} +\end{figure} + +\subsection{Hyperlinks} +\label{subsec:Hyperlinks} +Hyperlinks werden in Eclipse beim Betätigen der strg-Taste dynamisch erstellt und per Mausklick aufgerufen. Im klassischen Java-Editor werden sie benutzt, um zum Beispiel von einem Methodenaufruf zur Implementierung dieser Methode zu gelangen, ohne dabei die Grammatik durchsuchen zu müssen. Da es auf den ersten Blick innerhalb der ISR-Grammatik keine Methoden gibt, kommt die Frage auf, ob eine Portierung in einen Editor, der zur Erstellung einer ISR-Grammatik dient, sinnvoll ist. + +Beim genauen Betrachten fällt jedoch auf, dass Parallelen zu einem Methodenaufruf existieren. Nimmt man an, dass eine Deklaration eine Methode und das dazu gehörende Non-Terminal, innerhalb einer Regel, ein Methodenaufruf sei, so folgt daraus, dass es auch bei diesem Editor sinnvoll ist, die Funktionalität der Hyperlinks zu integrieren. + +Um den Anforderungen vier und sechs der Anforderungsanalyse aus Kapitel \ref{sec:Anforderungsanalyse} näher zu kommen, bieten Hyperlinks gute Unterstützung. Denn durch sie wird es möglich, schnell und präzise zwischen Regeln zu navigieren. Dem Anwender wird dadurch das Finden der Referenz von Non-Terminalen durch den Editor abgenommen. Muss der Benutzer einer Deklaration etwas hinzufügen, reicht ein einfacher strg-Klick auf das referenzierende Non-Terminal. Dies spart besonders dann Zeit, wenn die Grammatik unbekannt ist oder sehr komplex erscheint. + +\subsection{Visualisieren von Regeln} +\label{subsec:Visualisieren von Regeln} +Oft stellt es für Anwender, vor allem für Anfänger, ein Problem dar, komplexe Grammatiken zu verstehen. Selbst für einen Überblick reicht es gegebenenfalls nicht aus, wenn die Grammatik nur als Text vorliegt. Eine gute Unterstützung stellt eine farbige Visualisierung der Grammatik dar. Im Vordergrund steht dabei die Übersichtlichkeit. Eine geeignete Art der Visualisierung bietet das \emph{Railroad}\footnote{\url{http://de.wikipedia.org/wiki/Syntaxdiagramm}}-Diagramm, welches durch seine übersichtliche Darstellung dem Anwender eine adäquate Alternative zur textuellen Grammatik bietet (siehe Anforderung drei, Kapitel \ref{sec:Anforderungsanalyse}). + +\pagebreak +Die Abbildung \ref{fig:Vis} zeigt die Umsetzung der Visualisierung im ISR-Grammatik-Editor. Durch Einhalten der farbigen Darstellung ist leicht zu erkennen, um welche Regelelemente es sich im Einzelnen handelt. Visualisiert wird nur der selektierte Text. + +\begin{figure}[h] +\flushleft +\includegraphics[width=1\textwidth]{Bilder/Visualisierung} +\caption{Visualisierung zweier Regeln einer Grammatik. Links im Bild ist die Selektion der + Regeln, rechts die Darstellung.} +\label{fig:Vis} +\end{figure} + + +\subsection{Wortproblem und Syntaxbäume} +\label{subsec:Wortproblem und Syntaxbaume} +Da der Editor speziell für die ISR-Grammatik entworfen wurde und diese einen Teil einer natürlichen Sprache repräsentiert, ist es interessant, auf einfachem und schnellem Weg, das Wortproblem zu lösen. + +Doch zu wissen, dass ein Satz in einer Grammatik enthalten ist, reicht in manchen Situationen nicht aus. Sollen Sätze von einem System semantisch verstanden werden, verlangt dies nach einer genauen Interpretation der Satzstruktur. Der Aufbau eines Satzes und die dahinter liegende Struktur, ist nicht leicht aus der Grammatik abzulesen. Daher ist es nützlich, dass der Anwender bei solchen Aufgaben durch die Visualisierung der Syntaxbäume unterstützt wird (Anforderung vier, Kapitel \ref{sec:Anforderungsanalyse}). Aus dem erstellten Syntaxbaum erkennt der Anwender konkret, welches Terminal aus welchem Non-Terminal hervor gehen muss, damit der zu prüfende Satz gegenüber der Grammatik abgebildet werden kann. + +\pagebreak +Die Abbildung \ref{fig:Sat} zeigt die Benutzung und das Ergebnis dieser Funktionalität. Rechts oben bietet das System ein Dialogfenster zur Eingabe der Sätze. Im unteren Abschnitt der Abbildung ist das Ergebnis zu sehen. Rechts befindet sich eine Liste der geprüften Sätze, links eine optionale Visualisierung der Lösung des Wortproblems als Syntaxbaum. + +\begin{figure} +\includegraphics[width=1\textwidth]{Bilder/SatzValidieren} +\caption{Die Abbildung zeigt das automatische Lösen des Wortproblems. Oben die Eingabe, unten das Ergebnis, nach drücken des OK-Button} +\label{fig:Sat} +\end{figure} + +\section{Pluginarchitektur} +\label{sec:Plugin Architektur} +Betrachtet man die Eclipse-Architektur, so stellt man fest, dass die komplette Funktionalität auf Plugins beruht.\cite{Extensions} Um eine Kommunikation zwischen den verschiedenen Plugins zu ermöglichen, kann der Designer eines Plugin Extension Points definieren. Diese bieten wiederum anderen Plugins die Möglichkeit, auf die bestehenden Funktionalitäten zuzugreifen. + +Um Funktionalitäten, die bereits in einem anderen Plugin implementiert wurden, dem eigenem zur Verfügung zu stellen, muss der entsprechende Extension Point in einer impliziten Extension deklariert werden. Eine Extension gibt also den Gebrauch von Extension Points an und muss in der für das Plugin notwendigen Datei, Plugin.xml definiert werden. Der bereitgestellte Extension Point muss zusätzlich in das Manifest eingetragen werden.\cite{ExtensionsArchitekur} Dieses dient dem Plugin um Referenzen, Abhängigkeiten und erweiterte Information, wie zum Beispiel die Versionsnummer oder den Namen des Plugins zu definieren. + +Um nun ein eigenes Plugin zu aktivieren, bedarf es lediglich einer einzigen von Eclipse vorgeschriebenen Java-Klasse, dem \texttt{Activator}. Der \texttt{Activator} implementiert das Interface \texttt{org.osgi.framework.BundleActivator}. Durch dieses kann Eclipse die Methode \texttt{start} oder \texttt{stop} aufrufen, um das Plugin bei Bedarf zu starten oder zu stoppen. + +Zur einfacheren Implementierung neuer Plugins bietet Eclipse viele nützliche Ober-Klassen an, sodass viele Methoden nicht mehr selbst implementiert werden müssen. Um diesen Vorteil zu nutzen, und da es sich bei dem vorgestellten Plugin um einen Editor handelt, ist es sinnvoll den \texttt{Activator} von \\\texttt{org.eclipse.ui.AbstractUiPlugin} abzuleiten. + +Abbildung \ref{fig:PluginArchitektur} verdeutlicht die Vorgehensweise der Plugin-Architektur. +\begin{figure} +\centering +\includegraphics[angle={90},height=1\textheight]{Bilder/PluginArchitektur} +\caption{Die Abbildung zeigt die Plugin-Architektur. Links das neu erstellte Plugin, rechts die bereits vorhandene Plugins.} +\label{fig:PluginArchitektur} +\end{figure} + +\pagebreak +\section{Der ISR-Grammatik-Editor} +\label{sec:Der ISR-Grammatik-Editor} +In der Plugin.xml wird nun die erste Extension eingetragen, um Eclipse mitzuteilen, dass es sich bei dem Plugin um einen Editor handelt. Dazu integriert man den Extension Point \texttt{org.eclipse.ui.editors} und macht einen entsprechenden Eintrag in das Manifest. + +Typischerweise wird jeder Editor mit einer bestimmten Dateiendung verknüpft, sodass beim Öffnen einer derartigen Datei automatisch der richtige Editor verwendet wird. In diesem Fall ist \textbf{\emph{.grm}}, die vorgeschriebene Endung einer ISR-Grammatik. Auch diese Information wird in der Extension eingetragen. + +Um den vollen Funktionsumfang des ISR-Grammatik-Editors zu erreichen, werden drei Java-Klassen angelegt: der \texttt{ISREditor} selbst, ein Dokumenten-Provider, der \texttt{ISRDocumentProvider} und eine Konfiguration, die\\ \texttt{ISRSourceViewerConfiguration}. + +Im Folgenden wird kurz auf den Verwendungszweck dieser Klassen eingegangen. +Abbildung \ref{fig:EditorArchitektur} veranschaulicht die Editor-Architektur. +\\ +\paragraph{Die Klasse ISREditor}Der ISREditor bildet das Grundgerüst des ISR-Grammatik-Editors. Durch die Ableitung von der Oberklasse\\ \texttt{org.eclipse.ui.editors.text.TextEditor} stehen diesem die Grundfunktionen eines Texteditors und die Möglichkeit diese zu erweitern, zur Verfügung. Dazu werden die \texttt{ISRSourceViewerConfiguration} und \texttt{ISRDocumentProvider} über spezifizierte \texttt{setter}-Methoden mit dem \texttt{ISREditor} verknüpft. +\\ +\paragraph{Die Klasse ISRDocumentProvider}Der ISRDocumentProvider hat die Aufgabe, dem Editor den Text zur Verfügung zu stellen. Dazu wird der Inhalt durch \texttt{createDocument} aus einer gegebenen Datei gelesen. Als nächstes wird der Inhalt partitioniert, dafür wird er in Abschnitte eingeteilt, die jeweils mit einem Label, dem \emph{content type}\footnote{Als content type werden die Namen der Partitionierungsabschnitte bezeichnet.}, versehen werden. Die Partitionierung erfolgt nach spezifizierten Regeln, die im \texttt{IsrPartitionScanner} definiert werden. Betrachtet man die Struktur der ISR-Grammatik, fällt auf, dass sie nur zwei unterschiedliche Bereiche aufzeigt. Für eine angemessene Partitionierung wurden die zwei content types \texttt{ISR\_IGNORE} und \texttt{ISR\_RULE} definiert. Da jedoch der Fall auftreten kann, dass die gegebenen Regeln nicht den kompletten Text abbilden können, wird automatisch ein zusätzliches Default-Label vom Provider hinzugefügt:\\ \texttt{\_\_dftl\_partition\_content\_type}. + +Konkret bedeutet dies, dass jede Ignore-Regel das Label \texttt{ISR\_IGNORE}, jede Deklaration \texttt{ISR\_RULE} und alle nicht abgedeckten Bereiche, zum Beispiel die Zwischenräume der Regeln, \texttt{\_\_dftl\_partition\_content\_type} als Label erhalten. +\\ +\paragraph{Die Klasse ISRSourceViewerConfiguration}Die ISRSourceViewerConfiguration liefert ihren Beitrag durch die Definition von Funktionen und kümmert sich um die korrekte Anzeige des im \texttt{ISRDocumentProvider} bereitgestellten Textes. Durch das Überschreiben vorhandener Methoden der Oberklasse \texttt{FileDocumentProvider} wird das Plugin um weitere Funktionalitäten erweitert und ermöglicht so eine gezielte Darstellung. + +\begin{figure} +\centering +\includegraphics[angle={90},height=1\textheight]{Bilder/ISRGrammatikEditor} +\caption{Die Editor-Architektur} +\label{fig:EditorArchitektur} +\end{figure} + +\pagebreak +\section{Implementierung und Abläufe} +\label{subsec:Implementierung und Ablaufe} +Das folgende Kapitel geht auf den Ablauf und die Implementierung der zuvor genannten Funktionalitäten aus Kapitel \ref{sec:Funktionalitaten} ein. Bevor eine Funktionalität in das Plugin implementiert werden kann, muss zunächst festgestellt werden, auf welche Weise die Implementierung geschehen kann. Dazu wurden im Wesentlichen drei Ansätze benutzt. +\paragraph{Funktionalität über Extension Points}Die Implementierung von Funktionalität über Extension Points bietet eine Anbindung externer Funktionalitäten in das eigene Plugin, diese Funktionalitäten sind editorunabhängig wie zum Beispiel erweiterte Menüeinträge. +\paragraph{Funktionalität über Aktionen}Funktionalitäten welche über Aktionen implementiert werden, sind dagegen editorabhängig und können nur dann benutzt werden, wenn der im Plugin enthaltenen ISR-Grammatik-Editor aktiv, also von Eclipse durch die Methode \texttt{start} aufgerufen, ist. Diese Variante wird benutzt um globale Funktionalitäten von Eclipse durch lokal definierte zu überschreiben, dazu müssen sie vorab vom Plugin in das Eclipsesystem installiert werden. Ein Beispiel hierfür ist die benutzerdefinierte automatische Formatierung. +\paragraph{Funktionalität über direkte Implementierung}Eine weitere Anbindung weiterer Funktionalitäten bietet die direkte Implementierung. Diese benötigt keine Vorabinstallation und ist dennoch editorspezifisch. Hierunter fallen meist passive Eigenschaften des Editors wie zum Beispiel das Syntaxhighlighting. \\ + +Im Folgenden wird zuerst genauer auf jeden Ansätze eingegangen und die Implementierungen der Funktionalitäten beschrieben, welche sich auf diesen Ansatz beziehen. + +\subsection{Funktionalität über Extension Points} +\label{subsec:Funktionalitat uber Extensionpoints} +Eine Erweiterung der Plugin.xml stellt einen geeigneten Weg dar, den Editor mit zusätzlicher Funktionalität zu ergänzen. Eclipse bietet selbstständig einen breiten Pool von Extension Points, auf die zugegriffen werden kann. Die grundlegende Idee ist, dass durch die Definition neuer Extensions in der Plugin.xml, dem Editor Funktionalität aus anderen Plugins bereitzustellen. + +Dazu wird innerhalb der Plugin.xml ein \emph{Command} definiert, welcher den Extension Point \texttt{org.eclipse.ui.commands} anspricht. Innerhalb dieses Commands wird eine eindeutige ID definiert. Über diese ID können nun weitere Extensions mit dem Command verknüpft werden. Als pluginseitige Schnittstelle wird als nächstes ein weiterer Extension Point angesprochen, der \texttt{org.eclipse.ui.handlers}. Innerhalb diesem ist es möglich, eine referenzierende Klasse vom Typ\\ \texttt{org.eclipse.core.commands.AbstractHandler} anzugeben. Diese Klasse stellt eine Methode bereit, die beim Benutzen der Funktionalität aufgerufen wird und von der alle weiteren Berechnungen ausgehen. Durch sie wird die implementierungsseitige Schnittstelle angeboten. Alternativ können bestimmte Extensions eine referenzierende Klasse direkt angeben. Drei der gegebenen Funktionalitäten werden durch diese Einbettungsmethode implementiert, die Hyperlinks, die Erstellung der Syntaxbäume und die farbige Visualisierung der Regeln. +Abbildung \ref{fig:FUE} zeigt die Anbindung einer Funktionalität der fiktiven Klasse \texttt{ExampleHandler}. + +\begin{figure}[p] +\centering +\includegraphics[angle={90},height=1\textheight]{Bilder/FunktionUberExtension} +\caption{Diese Abbildung zeigt die Anbindung einer Funktionalität der Klasse ExampleHandler über Extension Points.} +\label{fig:FUE} +\end{figure} + +\pagebreak +\paragraph{Hyperlinks} Dem Editor wird es ermöglicht, durch den Extension Point\\ \texttt{org.eclipse.ui.workbench.texteditor.hyperlinkDetectors}, auf die durch \\ ein anderes Plugin bereit gestellte Funktionalität der Hyperlinks zuzugreifen und diese modifiziert zu verwenden. Das Hyperlink-System besteht aus zwei grundlegenden Java-Klassen. + +Die Klasse \texttt{IsrHyperLinkDetector}, welche das Interface\\ \texttt{org.eclipse.jface.text.hyperlink.IHyperlinkDetector} implementiert, wird als referenzierende Klasse direkt im Extension Point angegeben. Der Detektor enthält selbst nur eine wichtige Methode, \texttt{detectHyperlinks}. Sie überprüft ein Wort auf einen möglichen Hyperlink. Um dies zu realisieren, bekommt die Methode als Parameter die Position des Mauszeigers und kann dadurch das zu prüfende Wort ermitteln. Handelt es sich um ein Non-Terminal, wird daraufhin ein \texttt{IsrHyperLink} erstellt und über den Rückgabewert der Methode an Eclipse weitergeleitet. + +\texttt{IsrHyperLink} ist die zweite benötigte Klasse. Sie implementiert das Interface \texttt{org.eclipse.jface.text.hyperlink.IHyperlink}. Durch dieses enthält sie die Methode \texttt{open}, die aufgerufen wird sobald der Nutzer einen Hyperlink betätigt. Sie bekommt als Parameter das angeklickte Element und ermittelt den zugehörigen Gegenpart des Hyperlinks. Existiert dieser, werden zwei Methoden des \texttt{ISREditors} aufgerufen. Die Methode \texttt{selectAndReveal} selektiert das gefundene Element und \texttt{setFocus} setzt auf diesen den Fokus des Editors. Ohne passenden Gegenpart bleibt die Aktion unberücksichtigt. Eine Veranschaulichung des Hyperlinksystems, in Form eines Klassendiagramms, ist in Abbildung \ref{fig:HyperL} zu sehen. + +\begin{figure}[h] +\includegraphics[width=1\textwidth]{Bilder/HyperLinks} +\caption{Klassendiagramm des Hyperlinksystems} +\label{fig:HyperL} +\end{figure} + +\paragraph{Wortproblem und Syntaxbäume} +Da es bereits viele Algorithmen gibt, die einen Lösungsweg für das Wortproblem bereitstellen\cite{WortProbelmAlgo}\cite{EarleyJay}, wurde auf die Implementierung einer eigenen Lösung verzichtet und auf eine bestehenden zurückgegriffen. Dazu wurden selektiv Klassen aus dem Projekt \emph{Grammar Editor} aus der \emph{SOCS}\footnote{Sience Of Computing Suit}\cite{GammarJar} benutzt. + +Die Möglichkeit, Satzstrukturen gegen eine Grammatik zu validieren, ist nicht im Standard-Repertoire eines Editors enthalten. Es existiert also kein direkter Extension Point, der benutzt werden könnte, um die zu implementierende Funktionalität anzubinden. Eine dennoch adäquate Art der Anbindung besteht darin, einen eigenen Menüpunkt im Eclipse-Menü zu erstellen, durch welchen die Funktionalität aufgerufen werden kann. Dazu wurde die Anbindung nach dem, in der Einleitung (siehe Kapitel \ref{subsec:Funktionalitat uber Extensionpoints}) beschriebenen Verfahren realisiert. Die referenzierende Klasse, welche in dem Extension Point \texttt{org.eclipse.ui.handler} definiert wurde, ist die Klasse \texttt{SetGraphSettingsHandler}. Zur effizienteren Nutzbarkeit wurde der Extension Point \texttt{org.eclipse.ui.bindings} erstellt, in dem ein Tastenkürzel definiert und ebenfalls über die ID mit den anderen Extension Points verknüpft wurde. Des Weiteren wurde, um den erstellten Command mit dem Eclipse-Menü zu verbinden, der Extension Point \texttt{org.eclipse.ui.menus} erstellt und dieser erneut über die spezifische ID mit dem Command verknüpft. +\pagebreak +Auf der Seite des Editors dient die Klasse \texttt{SetGraphSettingsHandler} als Handler\footnote{Als Handler werden die Java-Klassen bezeichnet, die als Schnittstelle zwischen einem Command innerhalb der Plugin.xml und der Implementation der Funktionalität dient.}. In ihr wird zunächst die bestehende Grammatik in die klassische Form der kontextfreien Grammatiken gebracht. Dies bedeutet, dass dazu alle Besonderheiten und Zusatzzeichen wie in Kapitel \ref{subsec:Besonderheiten und Zusatzsymbole} beschrieben, die keinen Einfluss auf die Struktur einer Regel haben, entfernt werden. Darüber hinaus wird die Grammatik so umgeformt, dass sie als Eingabe für die Klassen der benutzen Bibliothek verwendet werden kann, welche sich um die Lösung des Wortproblems und die Visualisierung der Syntaxbäume kümmert. + +Beim Auslösen der Funktionalität, zum Beispiel beim Betätigen des Tastenkür-zels, öffnet sich zunächst ein \texttt{org.eclipse.jface.InputDialog}, über welchen der Benutzer Sätze angeben muss, die bei Bestätigung durch die Klassen der eingebundenen Bibliothek auf das Wortproblem geprüft werden. Das Resultat ist eine Liste von booleschen Werten zum jeweiligen Satz. Des Weiteren, sofern das Wortproblem gelöst wurde, wird eine Visualisierung des Syntaxbaumes erstellt (siehe auch Abbildung \ref{fig:Vis}). + +\paragraph{Visualisierung von Regeln}Die Visualisierung einer Grammatik wird als zusätzliches Fenster in der \emph{Eclipse Workbench}\footnote{\url{http://help.eclipse.org/juno/index.jsp?topic=\%2Forg.eclipse.platform.doc.user\%2Fconcepts\%2Fconcepts-2.htm}} angezeigt. Dies hat den Vorteil, dass sie nach Belieben vom Benutzer geöffnet oder geschlossen werden kann. + +Auch diese Funktionalität befindet sich nicht im Pool der Extension Points, welcher von Eclipse bereitgestellt wird. Daher wird auch diese Funktionalität erneut durch einen Eintrag im Menü von Eclipse mit dem Plugin verankert. Die weitere Implementierung auf Seiten der Plugin.xml verläuft homogen zu der Implementierung der vorherigen Funktionalität, mit Ausnahme von zwei individuell angepassten Definitionen. Dabei handelt es sich um das Tastenkürzel und den als Schnittstelle fungierende Handler, \texttt{SetGraphSettingsHandler}. Die Methode \texttt{execute}, welche beim Benutzen aufgerufen wird, regelt alle weiteren Berechnungen. Zunächst wird, über die Methode \texttt{findView} mit einer ID die zugehörige Klasse \texttt{IsrGraphView} erstellt und mittels \texttt{showView} angezeigt. Sie implementiert das Interface \texttt{org.eclipse.ui.part.ViewPart}. Dadurch wird die Klasse zu einem weiteren möglichen Fenster der Eclipse Workbench. Durch die Methode \texttt{showView} wird eine Instanz von \texttt{IsrGraphView} erstellt, wodurch automatisch die Methode \texttt{createPartControl} der Instanz aufgerufen wird. Die Funktion dieser Methode stellt das Errechnen des visuellen Kontextes dar. Dazu bedient sie sich der statischen Methode \texttt{IsrGraphBuilder.getGraph}, die aus der aktuellen Grammatik mittels des Zest-Frameworks einen Graphen erstellt, der im geöffneten Fenster angezeigt wird (siehe Abbildung \ref{fig:Vis}). + +\subsection{Funktionalität über Aktionen} +\label{subsec:Funktionalitat uber Aktionen} +Ein weiterer Weg, zusätzliche Funktionalität in das Plugin einzubinden besteht darin, sie in der Methode \texttt{createActions} zu definieren, welche im \texttt{ISREditor} bereitgestellt wird. Durch die Definition innerhalb des Editors werden zwei Effekte erzielt. Der eine Effekt ist, dass die Funktionalität zum Standard des Editors wird. Dies bedeutet, dass sie editorabhängig ist. Der andere Effekt ist die Verknüpfung mit der globalen Aktion von Eclipse, sodass über diesen Weg die global Funktionalität von der lokalen, also selbst implementierten, überschrieben wird. Ein Vorteil der hier beschriebenen Methode ist, dass unter anderem Tastenkürzel und Menüeinträge automatisch übernommen werden. Um die globale Funktionalität zu überschreiben erfordert diese Vorgehensweise eine Installation der definierten Aktion, die in der Klasse \texttt{ISREditorContributor} vorgenommen wird. Eine konkrete Implementierung erfolgt in der \texttt{ISRSourceViewerConfiguration}, in dem die funktionalitätsspezifische Methode der Oberklasse überschrieben wird. Die überschriebene Methode wird dann von Eclipse aufgerufen, sobald auf die Funktionalität zugegriffen wird. + +\paragraph{Automatische Formatierung} Zur eigenen Implementierung einer automatisierten Formatierung wurde die Methode \texttt{getContentFormatter} überschrieben. Sie erstellt eine Instanz der Klasse \texttt{org.eclipse.jface.formatter.ContentFormatter}. Bevor die Methode den erstellten Formatierer zurückgibt, müssen zuvor definierte Formatierungsstrategien mit dem Formatierer verknüpft werden. Dazu wird auf die, in der Partitionierung erstellten content types, zurückgegriffen. Zu jedem content type wurde eine eigene Formatierungsstrategie entworfen und durch die Methode \texttt{setFormattingStrategy} dem Formatierer einschließlich der dazugehörigen Strategie zugewiesen. + +Die \texttt{IgnoreFormattingStrategy} wird benutzt, wenn es sich bei dem content type um \texttt{ISR\_IGNORE} handelt. Da dieser Partition-Abschnitt keine besonderen Symbole oder komplizierte Konstrukte enthalten kann (siehe Kapitel \ref{subsec:Besonderheiten und Zusatzsymbole}), da innerhalb einer Ignore-List nur Terminale erlaubt sind, folgt daraus eine sehr einfache Strategie. Alle einfach oder mehrfach hintereinander auftretenden \emph{Whitespaces}\footnote{Als Whitespaces werden alle Zeichen einer Programmiersprache bezeichnet, die nicht gesehen werden aber dennoch (Speicher-)Platz beanspruchen. Darunter fallen zum Beispiel Leerzeichen, Umbrüche und Tabulatorzeichen.} werden durch ein einzelnes Leerzeichen ersetzt. Zusätzlich werden am Ende des Abschnittes zwei Umbrüche hinzugefügt. Diese gewährleisten einen Abstand zum nächsten Abschnitt. + +Wird die \texttt{RuleFormattingStrategy} eingesetzt, handelt es sich bei dem Abschnitt um einen Partition-Abschnitt mit dem content type \texttt{ISR\_RULE}. Zuerst werden auch hier alle überflüssigen Whitespaces entfernt und gegen ein Leerzeichen ersetzt. Des Weiteren wird vor jedem in der Regel auftretenden Oder-Symbol ein Umbruch hinzugefügt. Die Wortlänge des im Abschnitt darüber liegenden Wortes dient im zweiten Schritt als Anhaltspunkt dafür, wie weit das Oder-Symbol in der neuen Zeile nach rechts verrückt wird; auch dieser Abschnitt wird mit zwei Umbrüchen abgeschlossen. + +Die \texttt{DefaultFormattingStrategy} eliminiert überflüssige Whitespaces zwischen den Regeln. Der daraus resultierende Effekt ist, dass der Abstand zwischen den Regeln konstant bleibt. + +Beim Aufruf der automatischen Formatierung, wird jeder Abschnitt mit der passenden Formatierungsstrategie formatiert. Das Klassendiagramm in Abbildung \ref{fig:Aut} verdeutlicht noch einmal die Beziehungen zwischen den benutzten Klassen. +\begin{figure}[h] +\centering +\includegraphics[width=1\textwidth]{Bilder/Autoformatter} +\caption{Diese Abbildung zeigt das Klassendiagramm des Systems der automatischen Formatierung.} +\label{fig:Aut} +\end{figure} + +\paragraph{Content Assistant} Sobald die Funktionalität des Content Assistant aufgerufen wird, greift Eclipse auf die Methode \texttt{getContentAssistant} zurück. Diese kümmert sich um die Erstellung einer Instanz des \texttt{IsrContentAssistant}. Zur Inhaltsberechnung werden auf diesem Assistenten Prozessoren registriert. Da der Assistent, ebenfalls wie der Formatierer, vom Typ der jeweiligen Partition abhängig ist, wird jedem Prozessor ein Zuständigkeitsbereich in Form eines content type zugewiesen. \pagebreak + +Es wurden also zu den drei existierenden, die drei Prozessoren\\ \texttt{ISRContentAssistantIgnoreRuleProcessor},\\ \texttt{ISRContentAssistantDefaultProcessor} und\\ \texttt{ISRContentAssistantRuleProcessor} erstellt. In der Methode\\ \texttt{computeCompletionProposals}, welche sich durch das implementierte\\ Interface \texttt{org.eclipse.jface.text.contentassist.IConentAssistProcessor} \\in jeder Prozessorklasse befindet, werden die spezifischen Vorschläge errechnet und dem \texttt{IsrContentAssistent} bereitgestellt. + +\subsection{Funktionalität über direkte Implementierung} +\label{subsec:Funktionalitat uber direkte Implementierung} +Des Weiteren kann Funktionalität auch durch eine direkte Implementierung im \texttt{ISREditor} oder in der \texttt{ISRSourceViewerConfiguration} erfolgen, ohne einer vorherigen Definition und Installation der Aktionen. Dazu wurden entweder die im Editor vorhandenen Methoden oder wie im Abschnitt \ref{subsec:Funktionalitat uber Aktionen} zuvor, die Methoden der \texttt{ISRSourceViewerConfiguration} erweitert oder überschrieben. Auch diese Funktionalitäten sind editorspezifisch, im Gegensatz zu installierten Funktionen haben die hier implementierten eher passive Eigenschaften. + +\paragraph{Fehlermarkierung}Die Fehlermarkierung wird direkt bei der Erstellung einer Instanz des \texttt{ISREditors} initialisiert. Dazu wird ein Thread gestartet, der parallel zum Editor läuft und in regelmäßigen Abständen die Methode \texttt{validateAndMark} aufruft. Um ein überflüssiges Prüfen zu vermeiden und die Fehlermarkierung damit effizienter zu machen, ist der Thread nur dann aktiv, wenn der Inhalt des Editors verändert wird. Die Methode \texttt{validateAndMark} erstellt eine Instanz der Klasse \texttt{MarkingErrorHandler}, die den Inhalt des Editors vom Typ\\ \texttt{org.eclipse.core.IFile} präsent hat, und ruft auf ihr nacheinander zuerst die Methode \texttt{removeExistingMarker} und darauf folgend, die Methode\\ \texttt{setCurrentMarker} auf. Damit wird erreicht, dass alle bereits existierenden Marker zuerst entfernt und anschließend die neu errechneten hinzugefügt werden. + +\texttt{setCurrentMarker} ruft dazu die statischen Methoden\\ \texttt{MarkerContainer.getWarnings} und \texttt{MarkerContainer.getErrors} auf. Diese liefern jeweils eine Liste mit den aktuellen Markern zurück, die im darauf folgendem Schritt der \texttt{IFile}-Instanz hinzugefügt werden. + +Die Berechnung der Marker innerhalb des \texttt{MarkerContainer} wird durch die Hilfs-Klasse \texttt{IsrRuleValidator} realisiert. Sie implementiert verschiedene Methoden, die Fehler und Warnungen in der Grammatik ausfindig machen. Diese Methoden werden iterativ aufgerufen und erkannte Fehler und Warnungen in zwei separate Listen gespeichert. Im Folgenden werden diese Methoden beschrieben. \texttt{multipleDeclarations} überprüft die Grammatik auf doppelte Deklarationen. \texttt{checkValidStartSymbol} prüft das Vorkommen eines gültigen Startsymbols, sie erkennt aber auch doppelte Startsymbole.\\ \texttt{hasAllNonTerminalsDeclared} überprüft, ob alle verwendeten Non-Terminale eine gültige Deklaration haben. \texttt{checkSyntax} prüft die Grammatik auf Syntaxfehler und unzulässige Zeichenfolgen. \texttt{warnUnusedNonterminalDeclaration} schaut nach nicht verwendeten Deklarationen. \texttt{warnSameNamedNTAndT} schaut nach Terminale, welche gleichnamig sind wie existierende Non-Terminale. + +\paragraph{Hoverinformation}Die Verknüpfung der Hoverinformation wird durch die Überschreibung der Methode \texttt{getTextHover} innerhalb der\\ \texttt{ISRSourceViewerConfiguration} realisiert. Diese wird beim Benutzen der Funktionalität von Eclipse aufgerufen. Sie erstellt eine Instanz von \texttt{GenerateHoverInfos}, welche durch ihr Interface \texttt{org.eclipse.jface.text.ITextHover} die Methode \texttt{getHoverInfo} bereitstellt. Diese dient zur Berechnung der anzuzeigenden Information. Die Berechnung erfolgt in zwei Schritten, zunächst wird aus der Position des Mauszeigers, welche die Methode bei ihrem Aufruf übergeben bekommt, das vom Nutzer gemeinte Regelelement ermittelt. Handelt es sich bei dem Element um ein Non-Terminal, so besteht der Rückgabewert aus der Regel, welche durch die zugehörige Deklaration definiert ist; dessen Ermittlung den zweiten Schritt darstellt. Ist dies nicht der Fall, wird geprüft, ob das Wort von einer Fehlermarkierung umgeben ist. Besteht sie, wird alternativ über den \texttt{MarkerContainer} die Fehlerausgabe erworben und diese zurückgegeben. Trifft keines von beidem zu, liefert die Methode den Wert \texttt{null} und es wird keine Information angezeigt. + +\paragraph{Syntaxhighlighting}Um die Hervorhebung der Syntax aktuell zu halten, wird die Methode \texttt{getPresentationReconciler} in der \texttt{ISRSourceViewerConfiguration} überschrieben. In ihr wird ein \texttt{PresentationReconciler} erstellt, der aus einem Fehlererkenner dem \texttt{PresentationDamager} und\\ einem Korrektor dem \texttt{PresentationRepairer} besteht. Beide Klassen werden in dem \texttt{org.eclipse.jface.rules.DefaultDamageRepairer} zusammengefasst. Der \texttt{PresentationDamager} hat die Aufgabe, neu eingefügten Code aufzuspüren und die betroffene Stelle in der Regel dem \texttt{PresentationRepairer} mitzuteilen, so dass diese defekte Stelle repariert werden kann. Ähnlich zur Partitionierung arbeitet der \texttt{DefaultDamageRepairer} nach spezifizierten Regeln, welche die Farbe der Darstellung des jeweiligen Regelelementes festlegen. Alle benutzen Regeln sind in der Klasse \texttt{ISRSyntaxScanner} beschrieben, welche von\\ \texttt{org.eclipse.jface.text.rules.RuleBasedScanner} ableitet. Da die Syntax-\\Hervorhebung partitionsabhängig ist, benötigt sowohl der Damager als auch der Repairer nicht nur den \texttt{ISRSyntaxScanner} und dadurch alle enthaltenen Regeln, sondern auch den content type des Partition-Abschnittes, in dem die Änderung vorgenommen werden soll. \ No newline at end of file diff --git a/isr-eclipse-plugin/TeX/Inhalt/Versicherung.tex b/isr-eclipse-plugin/TeX/Inhalt/Versicherung.tex new file mode 100644 index 0000000000000000000000000000000000000000..5bcca3572dfb01bbc3ff59045dcf2c321032caa2 --- /dev/null +++ b/isr-eclipse-plugin/TeX/Inhalt/Versicherung.tex @@ -0,0 +1,15 @@ +\chapter*{Versicherung} +\label{sec:Versicherung} +Versicherung gem"a"s \S10a, Absatz 5 der Studien- und Pr"ufungsordnung f"ur das Bachelorstudium (BPO) an der Technischen Fakult"at der Universit"at Bielefeld vom 31. M"arz 2009.\\ +Ich versichere hiermit, dass ich meine Bachelorarbeit mit dem Thema +\begin{quote} +\textit{\meinTitel} +\end{quote} +selbst"andig verfasst und keine anderen als die angegebenen Quellen und Hilfsmittel benutzt, sowie Zitate kenntlich gemacht habe.\\ +\\ +Bielefeld, den \today + + +\rule[-0.5cm]{8cm}{0.5pt} + +\textsc{\meinName} diff --git a/isr-eclipse-plugin/TeX/Konstanten.tex b/isr-eclipse-plugin/TeX/Konstanten.tex new file mode 100644 index 0000000000000000000000000000000000000000..7ac873fd86790ea649ed94ff82c82a105de15afc --- /dev/null +++ b/isr-eclipse-plugin/TeX/Konstanten.tex @@ -0,0 +1,14 @@ +\def\ausarbeitungsTypBachelor{Bachelor} +\def\ausarbeitungsTypMaster{Master} +\def\ausarbeitungsTypDiplom{Diplom} +\def\ausarbeitungsTypSeminar{Seminar} +\def\ausarbeitungsTypProSeminar{Pro-Seminar} + +\def\bachelorArbeit{Bachelor-Arbeit} +\def\masterArbeit{Master-Arbeit} +\def\diplomArbeit{Diplomarbeit} +\def\seminarArbeit{Seminar-Ausarbeitung} + +\def\gradBachelor{Bachelor of Science} +\def\gradMaster{Master of Science} +\def\gradDiplom{Diplom-Informatiker} \ No newline at end of file diff --git a/isr-eclipse-plugin/TeX/Mathe-Definitionen.tex b/isr-eclipse-plugin/TeX/Mathe-Definitionen.tex new file mode 100644 index 0000000000000000000000000000000000000000..d80dd04a0ece2afefb2e2fe1fd657051f8525063 --- /dev/null +++ b/isr-eclipse-plugin/TeX/Mathe-Definitionen.tex @@ -0,0 +1,36 @@ +%Mathe +\usepackage{amsmath} +\usepackage{amsfonts} + +\usepackage{bbm} +\newcommand{\IN}{\mathbbm{N}} % natürliche Zahlen +\newcommand{\IZ}{\mathbbm{Z}} % ganze Zahlen +\newcommand{\IQ}{\mathbbm{Q}} % rationale Zahlen +\newcommand{\IR}{\mathbbm{R}} % reelle Zahlen +\newcommand{\IC}{\mathbbm{C}} % komplexe Zahlen +\newcommand{\IP}{\mathbbm{P}} % Primzahlen + +\renewcommand{\epsilon}{\varepsilon} % schöneres Epsilon + +\newcommand{\set}[1]{\left\{ #1 \right\}} % Menge +\newcommand{\powerset}[1]{\wp\!\left(#1\right)} % Potenzmenge +\newcommand{\abs}[1]{\left\lvert #1 \right\rvert} % Betrag +\newcommand{\norm}[1]{\left\lVert #1 \right\rVert} % Norm +\newcommand{\floor}[1]{\left\lfloor #1 \right\rfloor} % floor +\newcommand{\ceil}[1]{\left\lceil #1 \right\rceil} % ceiling + +\newcommand{\signatur}[3]{#1:#2\,\rightarrow\,#3} %Funktionen-Signatur + + +%Umgebungen +\newenvironment{bew}{\vspace{6pt}{\raggedright\textbf{Beweis: }}} {\newline\vspace{6pt}\hfill{$\square$}\vspace{6pt}\newline} + +\usepackage{theorem} +%\theoremstyle{change} %vertauscht Nummer und Titel, z.B. statt "Def. 1.1" steht "1.1 Def." +\newtheorem{definition}{Definition}[chapter] +\newtheorem{satz}[definition]{Satz} +\newtheorem{korollar}[definition]{Korollar} +\newtheorem{lemma}[definition]{Lemma} +\newtheorem{theorem}[definition]{Theorem} +\newtheorem{bsp}[definition]{Beispiel} +{\theoremstyle{changebreak}\newtheorem{bspe}[definition]{Beispiele}} %mit neuer Zeile anfangen diff --git a/isr-eclipse-plugin/TeX/SeitenLayout.tex b/isr-eclipse-plugin/TeX/SeitenLayout.tex new file mode 100644 index 0000000000000000000000000000000000000000..b90065d4c4a83a0f0a79e255e1ca43d4c39d42b6 --- /dev/null +++ b/isr-eclipse-plugin/TeX/SeitenLayout.tex @@ -0,0 +1,31 @@ +%Formatierung +\newcommand{\clearemptydoublepage}{\newpage{\pagestyle{empty}\cleardoublepage}} +\usepackage{fancyhdr} +\pagestyle{fancy} +%\pagestyle{plain} %'headings' für Seitenzahl oben, Fußzeile leer, 'plain' oder 'empty' auch möglich +%\addtolength{\headwidth}{\marginparsep} +%\addtolength{\headwidth}{\marginparwidth} +%\addtolength{\headwidth}{3cm} +\renewcommand{\chaptermark}[1]{\markboth{\sc\thechapter. #1}{}} +\renewcommand{\sectionmark}[1]{\markright{\sl\thesection~#1}} +\lhead[\fancyplain{}{\leftmark}]{} +\rhead[]{\fancyplain{}{\rightmark}} +\lfoot[\fancyplain{\bf\thepage}{\bf\thepage}]{} +\rfoot[]{\fancyplain{\bf\thepage}{\bf\thepage}} +\cfoot[]{} + +\renewcommand{\headfont}{% +\normalfont +} + + + +\onehalfspacing + +\fancypagestyle{plain}{% Neudefinition der plain-Seiten +\fancyhf{} +\fancyfoot[LE,RO]{\textbf{\thepage}} +\renewcommand{\headrulewidth}{0pt} +\renewcommand{\footrulewidth}{0pt} +} + diff --git a/isr-eclipse-plugin/TeX/deckblatt.pdf b/isr-eclipse-plugin/TeX/deckblatt.pdf new file mode 100644 index 0000000000000000000000000000000000000000..bf32b857d55d85ac20f30a7789905caac643dfda Binary files /dev/null and b/isr-eclipse-plugin/TeX/deckblatt.pdf differ diff --git a/isr-eclipse-plugin/TeX/meineArbeit.aux b/isr-eclipse-plugin/TeX/meineArbeit.aux new file mode 100644 index 0000000000000000000000000000000000000000..366ceb919c9ae241f59e75380818012f5f208ba7 --- /dev/null +++ b/isr-eclipse-plugin/TeX/meineArbeit.aux @@ -0,0 +1,209 @@ +\relax +\catcode`"\active +\providecommand\HyperFirstAtBeginDocument{\AtBeginDocument} +\HyperFirstAtBeginDocument{\ifx\hyper@anchor\@undefined +\global\let\oldcontentsline\contentsline +\gdef\contentsline#1#2#3#4{\oldcontentsline{#1}{#2}{#3}} +\global\let\oldnewlabel\newlabel +\gdef\newlabel#1#2{\newlabelxx{#1}#2} +\gdef\newlabelxx#1#2#3#4#5#6{\oldnewlabel{#1}{{#2}{#3}}} +\AtEndDocument{\ifx\hyper@anchor\@undefined +\let\contentsline\oldcontentsline +\let\newlabel\oldnewlabel +\fi} +\fi} +\global\let\hyper@last\relax +\gdef\HyperFirstAtBeginDocument#1{#1} +\providecommand\HyField@AuxAddToFields[1]{} +\bibstyle{ieeetr} +\@input{DeckblattTest.aux} +\newlabel{cha:Abstract}{{}{ii}{Abstract\relax }{chapter*.1}{}} +\newlabel{cha:Abstract}{{}{iii}{Abstract\relax }{chapter*.2}{}} +\citation{Fink} +\@writefile{toc}{\contentsline {chapter}{\numberline {1}Einleitung}{1}{chapter.1}} +\@writefile{lof}{\addvspace {10\p@ }} +\@writefile{lot}{\addvspace {10\p@ }} +\newlabel{cha:Einleitung}{{1}{1}{Einleitung\relax }{chapter.1}{}} +\@writefile{toc}{\contentsline {section}{\numberline {1.1}Motivation und Zielstellung}{1}{section.1.1}} +\newlabel{sec:Motivation und Zielstellung}{{1.1}{1}{Motivation und Zielstellung\relax }{section.1.1}{}} +\@writefile{toc}{\contentsline {section}{\numberline {1.2}Leitfaden}{3}{section.1.2}} +\newlabel{sec:Leitfaden}{{1.2}{3}{Leitfaden\relax }{section.1.2}{}} +\@writefile{toc}{\contentsline {chapter}{\numberline {2}Grundlagen}{4}{chapter.2}} +\@writefile{lof}{\addvspace {10\p@ }} +\@writefile{lot}{\addvspace {10\p@ }} +\newlabel{cha:Grundlagen}{{2}{4}{Grundlagen\relax }{chapter.2}{}} +\@writefile{toc}{\contentsline {section}{\numberline {2.1}ISR-Grammatik}{4}{section.2.1}} +\newlabel{sec:ISR-Grammatik}{{2.1}{4}{ISR-Grammatik\relax }{section.2.1}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {2.1.1}Aufbau und Struktur}{4}{subsection.2.1.1}} +\newlabel{sec:Aufbau und Struktur}{{2.1.1}{4}{Aufbau und Struktur\relax }{subsection.2.1.1}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {2.1.2}Besonderheiten und Zusatzsymbole}{5}{subsection.2.1.2}} +\newlabel{subsec:Besonderheiten und Zusatzsymbole}{{2.1.2}{5}{Besonderheiten und Zusatzsymbole\relax }{subsection.2.1.2}{}} +\@writefile{toc}{\contentsline {paragraph}{Joker-Symbol}{5}{section*.4}} +\@writefile{toc}{\contentsline {paragraph}{Technisches Non-Terminal}{5}{section*.5}} +\@writefile{toc}{\contentsline {paragraph}{Ignore-List}{6}{section*.6}} +\@writefile{toc}{\contentsline {subsection}{\numberline {2.1.3}Beispiel}{6}{subsection.2.1.3}} +\newlabel{sec:Beispiel}{{2.1.3}{6}{Beispiel\relax }{subsection.2.1.3}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {\relax 2.1}{\ignorespaces In dieser Abbildung ist ein Syntaxbaum dargestellt, indem die Herleitung des Satzes \IeC {\quotedblbase }\textbf {\emph {Today at one oclock}}\IeC {\textquotedblleft } zu sehen ist.}}{7}{figure.2.1}} +\newlabel{fig:SynTree}{{\relax 2.1}{7}{In dieser Abbildung ist ein Syntaxbaum dargestellt, indem die Herleitung des Satzes „\textbf {\emph {Today at one oclock}}“ zu sehen ist}{figure.2.1}{}} +\@writefile{toc}{\contentsline {section}{\numberline {2.2}Anforderungen an die Software}{7}{section.2.2}} +\newlabel{sec:Anforderung an die Software}{{2.2}{7}{Anforderungen an die Software\relax }{section.2.2}{}} +\@writefile{toc}{\contentsline {section}{\numberline {2.3}Anwendungsfall}{8}{section.2.3}} +\newlabel{sec:Anwendungsfall}{{2.3}{8}{Anwendungsfall\relax }{section.2.3}{}} +\@writefile{toc}{\contentsline {section}{\numberline {2.4}Anforderungsanalyse}{9}{section.2.4}} +\newlabel{sec:Anforderungsanalyse}{{2.4}{9}{Anforderungsanalyse\relax }{section.2.4}{}} +\@writefile{toc}{\contentsline {paragraph}{Anforderung 1:}{10}{section*.7}} +\@writefile{toc}{\contentsline {paragraph}{Anforderung 2:}{10}{section*.8}} +\@writefile{toc}{\contentsline {paragraph}{Anforderung 3:}{10}{section*.9}} +\@writefile{toc}{\contentsline {paragraph}{Anforderung 4:}{10}{section*.10}} +\@writefile{toc}{\contentsline {paragraph}{Anforderung 5:}{11}{section*.11}} +\@writefile{toc}{\contentsline {paragraph}{Anforderung 6:}{11}{section*.12}} +\@writefile{toc}{\contentsline {section}{\numberline {2.5}Verwandte Arbeiten}{11}{section.2.5}} +\newlabel{sec:Verwandte Arbeiten}{{2.5}{11}{Verwandte Arbeiten\relax }{section.2.5}{}} +\@writefile{toc}{\contentsline {paragraph}{Xtext}{11}{section*.13}} +\@writefile{toc}{\contentsline {paragraph}{Parser-Editor}{12}{section*.14}} +\citation{Eclipse} +\@writefile{toc}{\contentsline {paragraph}{Onlinesoftware}{13}{section*.15}} +\@writefile{toc}{\contentsline {section}{\numberline {2.6}Benutze Technologien}{13}{section.2.6}} +\newlabel{sec:Benutze Technologien}{{2.6}{13}{Benutze Technologien\relax }{section.2.6}{}} +\@writefile{toc}{\contentsline {paragraph}{\textbf {\emph {Zest}}}{14}{section*.16}} +\@writefile{toc}{\contentsline {paragraph}{\textbf {\emph {SOCS Grammar Editor}}}{14}{section*.17}} +\@writefile{toc}{\contentsline {chapter}{\numberline {3}Umsetzung}{15}{chapter.3}} +\@writefile{lof}{\addvspace {10\p@ }} +\@writefile{lot}{\addvspace {10\p@ }} +\newlabel{cha:Umsetzung}{{3}{15}{Umsetzung\relax }{chapter.3}{}} +\@writefile{toc}{\contentsline {section}{\numberline {3.1}Funktionalit\"aten}{15}{section.3.1}} +\newlabel{sec:Funktionalitaten}{{3.1}{15}{Funktionalitäten\relax }{section.3.1}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {3.1.1}Syntaxhighlighting}{15}{subsection.3.1.1}} +\newlabel{subsec:Syntaxcoloring}{{3.1.1}{15}{Syntaxhighlighting\relax }{subsection.3.1.1}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {3.1.2}Automatische Formatierung}{16}{subsection.3.1.2}} +\newlabel{subsec:Autoformatierung}{{3.1.2}{16}{Automatische Formatierung\relax }{subsection.3.1.2}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {\relax 3.1}{\ignorespaces Syntaxhighlighting einer standardformatierten Grammatik im ISR-Grammatik-Editor.}}{16}{figure.3.1}} +\newlabel{fig:Syn}{{\relax 3.1}{16}{Syntaxhighlighting einer standardformatierten Grammatik im ISR-Grammatik-Editor}{figure.3.1}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {3.1.3}Fehlermarkierung}{17}{subsection.3.1.3}} +\newlabel{subsec:Fehler-Markierung}{{3.1.3}{17}{Fehlermarkierung\relax }{subsection.3.1.3}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {3.1.4}Hoverinformation}{17}{subsection.3.1.4}} +\newlabel{subsec:Hover-Information}{{3.1.4}{17}{Hoverinformation\relax }{subsection.3.1.4}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {\relax 3.2}{\ignorespaces Zwei verschiedene Arten von Fehlermarkierungen. Die gelben Markierungen stellen Warnungen dar, rote zeigen fatale Fehler an. Der Fehlertext wird als Hoverinformation dargestellt.}}{18}{figure.3.2}} +\newlabel{subfig:Feh}{{\relax 3.2}{18}{Zwei verschiedene Arten von Fehlermarkierungen. Die gelben Markierungen stellen Warnungen dar, rote zeigen fatale Fehler an. Der Fehlertext wird als Hoverinformation dargestellt}{figure.3.2}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {3.1.5}Content Assistent}{18}{subsection.3.1.5}} +\newlabel{subsec:Content-Assistent}{{3.1.5}{18}{Content Assistent\relax }{subsection.3.1.5}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {\relax 3.3}{\ignorespaces Content Assistant bei einem Aufruf zwischen zwei Regeln. Die fehlende Deklaration des Non-Terminals \texttt {GERMAN} als erste Auswahlm\"oglichkeit.}}{19}{figure.3.3}} +\newlabel{fig:Con}{{\relax 3.3}{19}{Content Assistant bei einem Aufruf zwischen zwei Regeln. Die fehlende Deklaration des Non-Terminals \texttt {GERMAN} als erste Auswahlmöglichkeit}{figure.3.3}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {3.1.6}Hyperlinks}{19}{subsection.3.1.6}} +\newlabel{subsec:Hyperlinks}{{3.1.6}{19}{Hyperlinks\relax }{subsection.3.1.6}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {3.1.7}Visualisieren von Regeln}{20}{subsection.3.1.7}} +\newlabel{subsec:Visualisieren von Regeln}{{3.1.7}{20}{Visualisieren von Regeln\relax }{subsection.3.1.7}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {\relax 3.4}{\ignorespaces Visualisierung zweier Regeln einer Grammatik. Links im Bild ist die Selektion der Regeln, rechts die Darstellung.}}{21}{figure.3.4}} +\newlabel{fig:Vis}{{\relax 3.4}{21}{Visualisierung zweier Regeln einer Grammatik. Links im Bild ist die Selektion der Regeln, rechts die Darstellung}{figure.3.4}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {3.1.8}Wortproblem und Syntaxb\"aume}{21}{subsection.3.1.8}} +\newlabel{subsec:Wortproblem und Syntaxbaume}{{3.1.8}{21}{Wortproblem und Syntaxbäume\relax }{subsection.3.1.8}{}} +\citation{Extensions} +\citation{ExtensionsArchitekur} +\@writefile{lof}{\contentsline {figure}{\numberline {\relax 3.5}{\ignorespaces Die Abbildung zeigt das automatische L\"osen des Wortproblems. Oben die Eingabe, unten das Ergebnis, nach dr\"ucken des OK-Button}}{22}{figure.3.5}} +\newlabel{fig:Sat}{{\relax 3.5}{22}{Die Abbildung zeigt das automatische Lösen des Wortproblems. Oben die Eingabe, unten das Ergebnis, nach drücken des OK-Button\relax }{figure.3.5}{}} +\@writefile{toc}{\contentsline {section}{\numberline {3.2}Pluginarchitektur}{22}{section.3.2}} +\newlabel{sec:Plugin Architektur}{{3.2}{22}{Pluginarchitektur\relax }{section.3.2}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {\relax 3.6}{\ignorespaces Die Abbildung zeigt die Plugin-Architektur. Links das neu erstellte Plugin, rechts die bereits vorhandene Plugins.}}{24}{figure.3.6}} +\newlabel{fig:PluginArchitektur}{{\relax 3.6}{24}{Die Abbildung zeigt die Plugin-Architektur. Links das neu erstellte Plugin, rechts die bereits vorhandene Plugins}{figure.3.6}{}} +\@writefile{toc}{\contentsline {section}{\numberline {3.3}Der ISR-Grammatik-Editor}{25}{section.3.3}} +\newlabel{sec:Der ISR-Grammatik-Editor}{{3.3}{25}{Der ISR-Grammatik-Editor\relax }{section.3.3}{}} +\@writefile{toc}{\contentsline {paragraph}{Die Klasse ISREditor}{25}{section*.18}} +\@writefile{toc}{\contentsline {paragraph}{Die Klasse ISRDocumentProvider}{25}{section*.19}} +\@writefile{toc}{\contentsline {paragraph}{Die Klasse ISRSourceViewerConfiguration}{26}{section*.20}} +\@writefile{lof}{\contentsline {figure}{\numberline {\relax 3.7}{\ignorespaces Die Editor-Architektur}}{27}{figure.3.7}} +\newlabel{fig:EditorArchitektur}{{\relax 3.7}{27}{Die Editor-Architektur\relax }{figure.3.7}{}} +\@writefile{toc}{\contentsline {section}{\numberline {3.4}Implementierung und Abl\"aufe}{28}{section.3.4}} +\newlabel{subsec:Implementierung und Ablaufe}{{3.4}{28}{Implementierung und Abläufe\relax }{section.3.4}{}} +\@writefile{toc}{\contentsline {paragraph}{Funktionalit\"at \"uber Extension Points}{28}{section*.21}} +\@writefile{toc}{\contentsline {paragraph}{Funktionalit\"at \"uber Aktionen}{28}{section*.22}} +\@writefile{toc}{\contentsline {paragraph}{Funktionalit\"at \"uber direkte Implementierung}{28}{section*.23}} +\@writefile{toc}{\contentsline {subsection}{\numberline {3.4.1}Funktionalit\"at \"uber Extension Points}{28}{subsection.3.4.1}} +\newlabel{subsec:Funktionalitat uber Extensionpoints}{{3.4.1}{28}{Funktionalität über Extension Points\relax }{subsection.3.4.1}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {\relax 3.8}{\ignorespaces Diese Abbildung zeigt die Anbindung einer Funktionalit\"at der Klasse ExampleHandler \"uber Extension Points.}}{30}{figure.3.8}} +\newlabel{fig:FUE}{{\relax 3.8}{30}{Diese Abbildung zeigt die Anbindung einer Funktionalität der Klasse ExampleHandler über Extension Points}{figure.3.8}{}} +\citation{WortProbelmAlgo} +\citation{EarleyJay} +\citation{GammarJar} +\@writefile{toc}{\contentsline {paragraph}{Hyperlinks}{31}{section*.24}} +\@writefile{toc}{\contentsline {paragraph}{Wortproblem und Syntaxb\"aume}{31}{section*.25}} +\@writefile{lof}{\contentsline {figure}{\numberline {\relax 3.9}{\ignorespaces Klassendiagramm des Hyperlinksystems}}{32}{figure.3.9}} +\newlabel{fig:HyperL}{{\relax 3.9}{32}{Klassendiagramm des Hyperlinksystems\relax }{figure.3.9}{}} +\@writefile{toc}{\contentsline {paragraph}{Visualisierung von Regeln}{33}{section*.26}} +\@writefile{toc}{\contentsline {subsection}{\numberline {3.4.2}Funktionalit\"at \"uber Aktionen}{34}{subsection.3.4.2}} +\newlabel{subsec:Funktionalitat uber Aktionen}{{3.4.2}{34}{Funktionalität über Aktionen\relax }{subsection.3.4.2}{}} +\@writefile{toc}{\contentsline {paragraph}{Automatische Formatierung}{34}{section*.27}} +\@writefile{toc}{\contentsline {paragraph}{Content Assistant}{35}{section*.28}} +\@writefile{lof}{\contentsline {figure}{\numberline {\relax 3.10}{\ignorespaces Diese Abbildung zeigt das Klassendiagramm des Systems der automatischen Formatierung.}}{36}{figure.3.10}} +\newlabel{fig:Aut}{{\relax 3.10}{36}{Diese Abbildung zeigt das Klassendiagramm des Systems der automatischen Formatierung}{figure.3.10}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {3.4.3}Funktionalit\"at \"uber direkte Implementierung}{37}{subsection.3.4.3}} +\newlabel{subsec:Funktionalitat uber direkte Implementierung}{{3.4.3}{37}{Funktionalität über direkte Implementierung\relax }{subsection.3.4.3}{}} +\@writefile{toc}{\contentsline {paragraph}{Fehlermarkierung}{37}{section*.29}} +\@writefile{toc}{\contentsline {paragraph}{Hoverinformation}{38}{section*.30}} +\@writefile{toc}{\contentsline {paragraph}{Syntaxhighlighting}{38}{section*.31}} +\@writefile{toc}{\contentsline {chapter}{\numberline {4}Evaluation}{40}{chapter.4}} +\@writefile{lof}{\addvspace {10\p@ }} +\@writefile{lot}{\addvspace {10\p@ }} +\newlabel{cha:Evaluation}{{4}{40}{Evaluation\relax }{chapter.4}{}} +\@writefile{toc}{\contentsline {section}{\numberline {4.1}Ziele}{40}{section.4.1}} +\newlabel{sec:Ziele}{{4.1}{40}{Ziele\relax }{section.4.1}{}} +\@writefile{toc}{\contentsline {section}{\numberline {4.2}Methoden und Durchf\"uhrung}{41}{section.4.2}} +\newlabel{sec:Methoden und Durchfuhrung}{{4.2}{41}{Methoden und Durchführung\relax }{section.4.2}{}} +\@writefile{toc}{\contentsline {section}{\numberline {4.3}Auswertung}{42}{section.4.3}} +\newlabel{sec:Auswertung}{{4.3}{42}{Auswertung\relax }{section.4.3}{}} +\@writefile{toc}{\contentsline {paragraph}{Kenntnisse der gegebenen Hilfsmittel}{42}{section*.32}} +\@writefile{toc}{\contentsline {paragraph}{Erfahrung mit kontextfreien Grammatiken}{42}{section*.33}} +\@writefile{toc}{\contentsline {paragraph}{Verst\"andnis und Realit\"atsbezug der Aufgabenstellung}{43}{section*.34}} +\@writefile{toc}{\contentsline {subsection}{\numberline {4.3.1}Korrektur einer fehlerhaften Grammatik}{43}{subsection.4.3.1}} +\newlabel{subsec:KefG}{{4.3.1}{43}{Korrektur einer fehlerhaften Grammatik\relax }{subsection.4.3.1}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {\relax 4.1}{\ignorespaces Zeigt einen Vergleich der Bewertungen wie einfach die erste Aufgabe gel\"ost werden konnte. Rechts die Gruppe A, links die Gruppe B.}}{45}{figure.4.1}} +\newlabel{fig:F7A1vgl}{{\relax 4.1}{45}{Zeigt einen Vergleich der Bewertungen wie einfach die erste Aufgabe gelöst werden konnte. Rechts die Gruppe A, links die Gruppe B}{figure.4.1}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {\relax 4.2}{\ignorespaces Zeigt einen Vergleich der Bearbeitungszeiten der ersten Aufgabe, in der es darum ging, eine fehlerhafte Grammatik zu korrigieren. Rechts die Gruppe A, links die Gruppe B.}}{46}{figure.4.2}} +\newlabel{fig:A1zeitvgl}{{\relax 4.2}{46}{Zeigt einen Vergleich der Bearbeitungszeiten der ersten Aufgabe, in der es darum ging, eine fehlerhafte Grammatik zu korrigieren. Rechts die Gruppe A, links die Gruppe B}{figure.4.2}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {4.3.2}Erstellen einer ISR-Grammatik}{46}{subsection.4.3.2}} +\newlabel{subsec:EeIG}{{4.3.2}{46}{Erstellen einer ISR-Grammatik\relax }{subsection.4.3.2}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {\relax 4.3}{\ignorespaces Zeigt einen Vergleich der Bewertungen wie einfach die zweiten Aufgabe gel\"ost werden konnte. Rechts die Gruppe A, links die Gruppe B.}}{47}{figure.4.3}} +\newlabel{fig:F7A2vgl}{{\relax 4.3}{47}{Zeigt einen Vergleich der Bewertungen wie einfach die zweiten Aufgabe gelöst werden konnte. Rechts die Gruppe A, links die Gruppe B}{figure.4.3}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {\relax 4.4}{\ignorespaces Zeigt einen Vergleich der Bearbeitungszeiten der zweiten Aufgabe, in der es darum ging, eine Grammatik f\"ur bestimmte S\"atze zu bilden. Rechts die Gruppe A, links die Gruppe B.}}{48}{figure.4.4}} +\newlabel{fig:A2zeitvgl}{{\relax 4.4}{48}{Zeigt einen Vergleich der Bearbeitungszeiten der zweiten Aufgabe, in der es darum ging, eine Grammatik für bestimmte Sätze zu bilden. Rechts die Gruppe A, links die Gruppe B}{figure.4.4}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {4.3.3}L\"osen des Wortproblems und Erstellen von Syntaxb\"aumen}{49}{subsection.4.3.3}} +\newlabel{subsec:LdWuEvS}{{4.3.3}{49}{Lösen des Wortproblems und Erstellen von Syntaxbäumen\relax }{subsection.4.3.3}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {\relax 4.5}{\ignorespaces Zeigt einen Vergleich der Bewertungen wie einfach die dritten Aufgabe gel\"ost werden konnte. Rechts die Gruppe A, links die Gruppe B.}}{49}{figure.4.5}} +\newlabel{fig:F7A3vgl}{{\relax 4.5}{49}{Zeigt einen Vergleich der Bewertungen wie einfach die dritten Aufgabe gelöst werden konnte. Rechts die Gruppe A, links die Gruppe B}{figure.4.5}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {\relax 4.6}{\ignorespaces Zeigt einen Vergleich der Bearbeitungszeiten der dritten Aufgabe, in der es drum ging, das Wortproblem zu l\"osen. Rechts die Gruppe A, links die Gruppe B.}}{50}{figure.4.6}} +\newlabel{fig:A3zeitvgl}{{\relax 4.6}{50}{Zeigt einen Vergleich der Bearbeitungszeiten der dritten Aufgabe, in der es drum ging, das Wortproblem zu lösen. Rechts die Gruppe A, links die Gruppe B}{figure.4.6}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {\relax 4.7}{\ignorespaces Zusehen sind die Fehlerwerte aller Aufgaben in Prozent. Die Werte beziehen sich auf die der Teilnehmer, die ohne das Plugin gearbeitet haben.}}{52}{figure.4.7}} +\newlabel{fig:failvgl}{{\relax 4.7}{52}{Zusehen sind die Fehlerwerte aller Aufgaben in Prozent. Die Werte beziehen sich auf die der Teilnehmer, die ohne das Plugin gearbeitet haben}{figure.4.7}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {4.3.4}Funktionalit\"aten}{53}{subsection.4.3.4}} +\newlabel{subsec:AF}{{4.3.4}{53}{Funktionalitäten\relax }{subsection.4.3.4}{}} +\@writefile{toc}{\contentsline {paragraph}{Fehlermarkierung}{53}{section*.35}} +\@writefile{toc}{\contentsline {paragraph}{Syntaxhighlighting}{53}{section*.36}} +\@writefile{toc}{\contentsline {paragraph}{Content Assistant}{53}{section*.37}} +\@writefile{toc}{\contentsline {paragraph}{Automatische Formatierer}{54}{section*.38}} +\@writefile{toc}{\contentsline {paragraph}{Hoverinformation und Hyperlinks}{54}{section*.39}} +\@writefile{toc}{\contentsline {paragraph}{Visualisierung der Regeln}{54}{section*.40}} +\@writefile{toc}{\contentsline {paragraph}{L\"osen des Wortproblems}{55}{section*.41}} +\@writefile{lof}{\contentsline {figure}{\numberline {\relax 4.8}{\ignorespaces Zeigt die Bewertungen f\"ur jede Funktionalit\"at der Gruppe A im \"Uberblick.}}{56}{figure.4.8}} +\newlabel{fig:A8mitPlugin}{{\relax 4.8}{56}{Zeigt die Bewertungen für jede Funktionalität der Gruppe A im Überblick}{figure.4.8}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {\relax 4.9}{\ignorespaces Zeigt die Sch\"atzungen f\"ur jede Funktionalit\"at der Gruppe B im \"Uberblick.}}{56}{figure.4.9}} +\newlabel{fig:A8ohnePlugin}{{\relax 4.9}{56}{Zeigt die Schätzungen für jede Funktionalität der Gruppe B im Überblick}{figure.4.9}{}} +\@writefile{toc}{\contentsline {section}{\numberline {4.4}Verbesserungsm\"oglichkeiten}{57}{section.4.4}} +\newlabel{sec:Verbesserungsmoglichkeiten}{{4.4}{57}{Verbesserungsmöglichkeiten\relax }{section.4.4}{}} +\@writefile{toc}{\contentsline {chapter}{\numberline {5}Fazit und Ausblick}{58}{chapter.5}} +\@writefile{lof}{\addvspace {10\p@ }} +\@writefile{lot}{\addvspace {10\p@ }} +\newlabel{cha:FazitUndAusblick}{{5}{58}{Fazit und Ausblick\relax }{chapter.5}{}} +\@writefile{toc}{\vspace {2mm}} +\@writefile{toc}{\contentsline {chapter}{Anhang}{61}{appendix.A}} +\bibstyle{natdin} +\bibdata{Bibliographie} +\bibcite{Fink}{1} +\bibcite{Eclipse}{2} +\bibcite{Extensions}{3} +\bibcite{ExtensionsArchitekur}{4} +\bibcite{WortProbelmAlgo}{5} +\bibcite{EarleyJay}{6} +\bibcite{GammarJar}{7} +\@writefile{toc}{\contentsline {chapter}{Literatur}{67}{appendix*.44}} +\@writefile{lof}{\addvspace {10\p@ }} +\@writefile{lot}{\addvspace {10\p@ }} +\newlabel{sec:Versicherung}{{5}{68}{Versicherung\relax }{appendix*.45}{}} diff --git a/isr-eclipse-plugin/TeX/meineArbeit.bbl b/isr-eclipse-plugin/TeX/meineArbeit.bbl new file mode 100644 index 0000000000000000000000000000000000000000..78afe0cbff63966ee4cac917b35159afcf6fd3ab --- /dev/null +++ b/isr-eclipse-plugin/TeX/meineArbeit.bbl @@ -0,0 +1,37 @@ +\begin{thebibliography}{1} + +\bibitem{Fink} +G.~A. Fink, ``Developing hmm-based recognizers with esmeralda,'' in {\em + Proceedings of the Second International Workshop on Text, Speech and + Dialogue}, TSD '99, (London, UK, UK), pp.~229--234, Springer-Verlag, 1999. + +\bibitem{Eclipse} +O.~O. K. K.~C. IBM Software~Group, 2670 Queensview~Drive, ``Eclipse: A platform + for integrating development tools,'' {\em IBM Systems Journal}, vol.~43, + pp.~371 -- 383, 2004. + +\bibitem{Extensions} +D.~P. Volker~Wohlgemuth, Tobias~Schnackenbeck and R.-L. Barling, {\em + Development of an Open Source Software Framework as a Basis forImplementing + Plugin-Based Environmental ManagementInformation Systems (EMIS)}. +\newblock No.~ISBN: 978-3-8322-7313-2, Shaker Verlag, 2008. + +\bibitem{ExtensionsArchitekur} +H.~S. Manfred~Henning, ``Einführung in den "extension point"-mechanismus von + eclipse,'' {\em JavaSPEKTRUM}, vol.~01, 2008. + +\bibitem{WortProbelmAlgo} +I.~Wegener, {\em Theoretische Informatik - eine algorithmenorientierte + Einführung}. +\newblock Teubner, 2008. + +\bibitem{EarleyJay} +J.~Earley, ``An efficient context-free parsing algorithm,'' {\em Commun. ACM}, + vol.~13, pp.~94--102, Feb. 1970. + +\bibitem{GammarJar} +C.~Burch and L.~Ziegler, ``Science of computing suite(socs) :resources for a + breadth-first introduction,'' {\em Technical Symposium on Computer Science + Education (SIGCSE)}, 2004. + +\end{thebibliography} diff --git a/isr-eclipse-plugin/TeX/meineArbeit.blg b/isr-eclipse-plugin/TeX/meineArbeit.blg new file mode 100644 index 0000000000000000000000000000000000000000..6a6fc349ae686976037e7e4d7e524d68350d3011 --- /dev/null +++ b/isr-eclipse-plugin/TeX/meineArbeit.blg @@ -0,0 +1,14 @@ +This is BibTeX, Version 0.99dThe top-level auxiliary file: meineArbeit.aux +The style file: ieeetr.bst +A level-1 auxiliary file: DeckblattTest.aux +Illegal, another \bibstyle command---line 191 of file meineArbeit.aux + : \bibstyle + : {natdin} +I'm skipping whatever remains of this command +Database file #1: Bibliographie.bib +Too many commas in name 1 of "IBM Software Group, 2670 Queensview Drive, Ottawa, Ontario K2B 8K1, Canada" for entry Eclipse +while executing---line 963 of file ieeetr.bst +Too many commas in name 1 of "IBM Software Group, 2670 Queensview Drive, Ottawa, Ontario K2B 8K1, Canada" for entry Eclipse +while executing---line 963 of file ieeetr.bst +Warning--there's a number but no series in Extensions +(There were 3 error messages) diff --git a/isr-eclipse-plugin/TeX/meineArbeit.dvi b/isr-eclipse-plugin/TeX/meineArbeit.dvi new file mode 100644 index 0000000000000000000000000000000000000000..af675f5d3f7c4303d3fded9ab314d0e3e10d5c44 Binary files /dev/null and b/isr-eclipse-plugin/TeX/meineArbeit.dvi differ diff --git a/isr-eclipse-plugin/TeX/meineArbeit.lof b/isr-eclipse-plugin/TeX/meineArbeit.lof new file mode 100644 index 0000000000000000000000000000000000000000..2d8f9a1756a35a1a2fc2e5ca774824fe6ab6b502 --- /dev/null +++ b/isr-eclipse-plugin/TeX/meineArbeit.lof @@ -0,0 +1,26 @@ +\addvspace {10\p@ } +\addvspace {10\p@ } +\contentsline {figure}{\numberline {\relax 2.1}{\ignorespaces In dieser Abbildung ist ein Syntaxbaum dargestellt, indem die Herleitung des Satzes \IeC {\quotedblbase }\textbf {\emph {Today at one oclock}}\IeC {\textquotedblleft } zu sehen ist.}}{7}{figure.2.1} +\addvspace {10\p@ } +\contentsline {figure}{\numberline {\relax 3.1}{\ignorespaces Syntaxhighlighting einer standardformatierten Grammatik im ISR-Grammatik-Editor.}}{16}{figure.3.1} +\contentsline {figure}{\numberline {\relax 3.2}{\ignorespaces Zwei verschiedene Arten von Fehlermarkierungen. Die gelben Markierungen stellen Warnungen dar, rote zeigen fatale Fehler an. Der Fehlertext wird als Hoverinformation dargestellt.}}{18}{figure.3.2} +\contentsline {figure}{\numberline {\relax 3.3}{\ignorespaces Content Assistant bei einem Aufruf zwischen zwei Regeln. Die fehlende Deklaration des Non-Terminals \texttt {GERMAN} als erste Auswahlm\"oglichkeit.}}{19}{figure.3.3} +\contentsline {figure}{\numberline {\relax 3.4}{\ignorespaces Visualisierung zweier Regeln einer Grammatik. Links im Bild ist die Selektion der Regeln, rechts die Darstellung.}}{21}{figure.3.4} +\contentsline {figure}{\numberline {\relax 3.5}{\ignorespaces Die Abbildung zeigt das automatische L\"osen des Wortproblems. Oben die Eingabe, unten das Ergebnis, nach dr\"ucken des OK-Button}}{22}{figure.3.5} +\contentsline {figure}{\numberline {\relax 3.6}{\ignorespaces Die Abbildung zeigt die Plugin-Architektur. Links das neu erstellte Plugin, rechts die bereits vorhandene Plugins.}}{24}{figure.3.6} +\contentsline {figure}{\numberline {\relax 3.7}{\ignorespaces Die Editor-Architektur}}{27}{figure.3.7} +\contentsline {figure}{\numberline {\relax 3.8}{\ignorespaces Diese Abbildung zeigt die Anbindung einer Funktionalit\"at der Klasse ExampleHandler \"uber Extension Points.}}{30}{figure.3.8} +\contentsline {figure}{\numberline {\relax 3.9}{\ignorespaces Klassendiagramm des Hyperlinksystems}}{32}{figure.3.9} +\contentsline {figure}{\numberline {\relax 3.10}{\ignorespaces Diese Abbildung zeigt das Klassendiagramm des Systems der automatischen Formatierung.}}{36}{figure.3.10} +\addvspace {10\p@ } +\contentsline {figure}{\numberline {\relax 4.1}{\ignorespaces Zeigt einen Vergleich der Bewertungen wie einfach die erste Aufgabe gel\"ost werden konnte. Rechts die Gruppe A, links die Gruppe B.}}{45}{figure.4.1} +\contentsline {figure}{\numberline {\relax 4.2}{\ignorespaces Zeigt einen Vergleich der Bearbeitungszeiten der ersten Aufgabe, in der es darum ging, eine fehlerhafte Grammatik zu korrigieren. Rechts die Gruppe A, links die Gruppe B.}}{46}{figure.4.2} +\contentsline {figure}{\numberline {\relax 4.3}{\ignorespaces Zeigt einen Vergleich der Bewertungen wie einfach die zweiten Aufgabe gel\"ost werden konnte. Rechts die Gruppe A, links die Gruppe B.}}{47}{figure.4.3} +\contentsline {figure}{\numberline {\relax 4.4}{\ignorespaces Zeigt einen Vergleich der Bearbeitungszeiten der zweiten Aufgabe, in der es darum ging, eine Grammatik f\"ur bestimmte S\"atze zu bilden. Rechts die Gruppe A, links die Gruppe B.}}{48}{figure.4.4} +\contentsline {figure}{\numberline {\relax 4.5}{\ignorespaces Zeigt einen Vergleich der Bewertungen wie einfach die dritten Aufgabe gel\"ost werden konnte. Rechts die Gruppe A, links die Gruppe B.}}{49}{figure.4.5} +\contentsline {figure}{\numberline {\relax 4.6}{\ignorespaces Zeigt einen Vergleich der Bearbeitungszeiten der dritten Aufgabe, in der es drum ging, das Wortproblem zu l\"osen. Rechts die Gruppe A, links die Gruppe B.}}{50}{figure.4.6} +\contentsline {figure}{\numberline {\relax 4.7}{\ignorespaces Zusehen sind die Fehlerwerte aller Aufgaben in Prozent. Die Werte beziehen sich auf die der Teilnehmer, die ohne das Plugin gearbeitet haben.}}{52}{figure.4.7} +\contentsline {figure}{\numberline {\relax 4.8}{\ignorespaces Zeigt die Bewertungen f\"ur jede Funktionalit\"at der Gruppe A im \"Uberblick.}}{56}{figure.4.8} +\contentsline {figure}{\numberline {\relax 4.9}{\ignorespaces Zeigt die Sch\"atzungen f\"ur jede Funktionalit\"at der Gruppe B im \"Uberblick.}}{56}{figure.4.9} +\addvspace {10\p@ } +\addvspace {10\p@ } diff --git a/isr-eclipse-plugin/TeX/meineArbeit.out b/isr-eclipse-plugin/TeX/meineArbeit.out new file mode 100644 index 0000000000000000000000000000000000000000..f2b167e83ea33be34909184f209b98ec82223bab --- /dev/null +++ b/isr-eclipse-plugin/TeX/meineArbeit.out @@ -0,0 +1,40 @@ +\BOOKMARK [0][-]{chapter.1}{1 Einleitung}{}% 1 +\BOOKMARK [1][-]{section.1.1}{1.1 Motivation und Zielstellung}{chapter.1}% 2 +\BOOKMARK [1][-]{section.1.2}{1.2 Leitfaden}{chapter.1}% 3 +\BOOKMARK [0][-]{chapter.2}{2 Grundlagen}{}% 4 +\BOOKMARK [1][-]{section.2.1}{2.1 ISR-Grammatik}{chapter.2}% 5 +\BOOKMARK [2][-]{subsection.2.1.1}{2.1.1 Aufbau und Struktur}{section.2.1}% 6 +\BOOKMARK [2][-]{subsection.2.1.2}{2.1.2 Besonderheiten und Zusatzsymbole}{section.2.1}% 7 +\BOOKMARK [2][-]{subsection.2.1.3}{2.1.3 Beispiel}{section.2.1}% 8 +\BOOKMARK [1][-]{section.2.2}{2.2 Anforderungen an die Software}{chapter.2}% 9 +\BOOKMARK [1][-]{section.2.3}{2.3 Anwendungsfall}{chapter.2}% 10 +\BOOKMARK [1][-]{section.2.4}{2.4 Anforderungsanalyse}{chapter.2}% 11 +\BOOKMARK [1][-]{section.2.5}{2.5 Verwandte Arbeiten}{chapter.2}% 12 +\BOOKMARK [1][-]{section.2.6}{2.6 Benutze Technologien}{chapter.2}% 13 +\BOOKMARK [0][-]{chapter.3}{3 Umsetzung}{}% 14 +\BOOKMARK [1][-]{section.3.1}{3.1 Funktionalit\344ten}{chapter.3}% 15 +\BOOKMARK [2][-]{subsection.3.1.1}{3.1.1 Syntaxhighlighting}{section.3.1}% 16 +\BOOKMARK [2][-]{subsection.3.1.2}{3.1.2 Automatische Formatierung}{section.3.1}% 17 +\BOOKMARK [2][-]{subsection.3.1.3}{3.1.3 Fehlermarkierung}{section.3.1}% 18 +\BOOKMARK [2][-]{subsection.3.1.4}{3.1.4 Hoverinformation}{section.3.1}% 19 +\BOOKMARK [2][-]{subsection.3.1.5}{3.1.5 Content Assistent}{section.3.1}% 20 +\BOOKMARK [2][-]{subsection.3.1.6}{3.1.6 Hyperlinks}{section.3.1}% 21 +\BOOKMARK [2][-]{subsection.3.1.7}{3.1.7 Visualisieren von Regeln}{section.3.1}% 22 +\BOOKMARK [2][-]{subsection.3.1.8}{3.1.8 Wortproblem und Syntaxb\344ume}{section.3.1}% 23 +\BOOKMARK [1][-]{section.3.2}{3.2 Pluginarchitektur}{chapter.3}% 24 +\BOOKMARK [1][-]{section.3.3}{3.3 Der ISR-Grammatik-Editor}{chapter.3}% 25 +\BOOKMARK [1][-]{section.3.4}{3.4 Implementierung und Abl\344ufe}{chapter.3}% 26 +\BOOKMARK [2][-]{subsection.3.4.1}{3.4.1 Funktionalit\344t \374ber Extension Points}{section.3.4}% 27 +\BOOKMARK [2][-]{subsection.3.4.2}{3.4.2 Funktionalit\344t \374ber Aktionen}{section.3.4}% 28 +\BOOKMARK [2][-]{subsection.3.4.3}{3.4.3 Funktionalit\344t \374ber direkte Implementierung}{section.3.4}% 29 +\BOOKMARK [0][-]{chapter.4}{4 Evaluation}{}% 30 +\BOOKMARK [1][-]{section.4.1}{4.1 Ziele}{chapter.4}% 31 +\BOOKMARK [1][-]{section.4.2}{4.2 Methoden und Durchf\374hrung}{chapter.4}% 32 +\BOOKMARK [1][-]{section.4.3}{4.3 Auswertung}{chapter.4}% 33 +\BOOKMARK [2][-]{subsection.4.3.1}{4.3.1 Korrektur einer fehlerhaften Grammatik}{section.4.3}% 34 +\BOOKMARK [2][-]{subsection.4.3.2}{4.3.2 Erstellen einer ISR-Grammatik}{section.4.3}% 35 +\BOOKMARK [2][-]{subsection.4.3.3}{4.3.3 L\366sen des Wortproblems und Erstellen von Syntaxb\344umen}{section.4.3}% 36 +\BOOKMARK [2][-]{subsection.4.3.4}{4.3.4 Funktionalit\344ten}{section.4.3}% 37 +\BOOKMARK [1][-]{section.4.4}{4.4 Verbesserungsm\366glichkeiten}{chapter.4}% 38 +\BOOKMARK [0][-]{chapter.5}{5 Fazit und Ausblick}{}% 39 +\BOOKMARK [0][-]{appendix*.44}{Literatur}{}% 40 diff --git a/isr-eclipse-plugin/TeX/meineArbeit.pdf b/isr-eclipse-plugin/TeX/meineArbeit.pdf new file mode 100644 index 0000000000000000000000000000000000000000..42d69f99b8f598fb4d7afea298680c41b2d625c4 Binary files /dev/null and b/isr-eclipse-plugin/TeX/meineArbeit.pdf differ diff --git a/isr-eclipse-plugin/TeX/meineArbeit.synctex.gz b/isr-eclipse-plugin/TeX/meineArbeit.synctex.gz new file mode 100644 index 0000000000000000000000000000000000000000..5d1b1ed8a36533f1b8ab10a0a8970d9c2e661bdb Binary files /dev/null and b/isr-eclipse-plugin/TeX/meineArbeit.synctex.gz differ diff --git a/isr-eclipse-plugin/TeX/meineArbeit.tcp b/isr-eclipse-plugin/TeX/meineArbeit.tcp new file mode 100644 index 0000000000000000000000000000000000000000..9434ffdd9c6e606d81fb0ef1a48876ac080e32ce --- /dev/null +++ b/isr-eclipse-plugin/TeX/meineArbeit.tcp @@ -0,0 +1,12 @@ +[FormatInfo] +Type=TeXnicCenterProjectInformation +Version=4 + +[ProjectInfo] +MainFile=meineArbeit.tex +UseBibTeX=1 +UseMakeIndex=1 +ActiveProfile=LaTeX => PDF +ProjectLanguage=de +ProjectDialect=DE + diff --git a/isr-eclipse-plugin/TeX/meineArbeit.tex b/isr-eclipse-plugin/TeX/meineArbeit.tex new file mode 100644 index 0000000000000000000000000000000000000000..5efdf88f72abb6ca22b03a73b2c1b55e8e058f3f --- /dev/null +++ b/isr-eclipse-plugin/TeX/meineArbeit.tex @@ -0,0 +1,106 @@ +% -*- TeX -*- -*- DE -*- -*- UNIX -*- +\input{meineDokumentKlasse} % Dokumentklasse bestimmen + +\input{Konstanten} % Konstanten laden, z.B.: Begriffe wie Bachelor-Arbeit, Bachelor of Science, etc. +\usepackage[german]{babel} +\usepackage[ansinew]{inputenc} %Für deutsche Kodierung von Buchstaben ä,ö,ü,ß unter Windows (für Unix: 'latin1' statt 'ansinew') ansonsten muss man Folgendes schreiben: +% \"a für ä, \"o für ö, \"u für ü, \ss für ß. +\usepackage{german} % unter anderem für bessere Silbentrennung + +\input{meineDaten} % Parameter wie Autor, Titel, Datum, Gutachter, etc. + +\usepackage{ifthen} % Paket für if-then-else-Konstrukte + +\usepackage{verbatim} % z.B. für comment-Umgebung +%\usepackage{natbib} % für BibTeX mit dinat style (DIN 1505, Teil 2 und 3) +%\usepackage{bibgerm} % für BibTeX mit deutschem style z.B. geralpha +%\usepackage{makeidx} % für Index-/Stichwortverzeichnis +%\makeindex % lässt LaTeX die Indexeinträge sammeln +%\usepackage{epsfig} % zum Einfügen von EPS-Grafiken +\usepackage{array} % weitere Hilfsmittel für Tabellen +%\usepackage{float} % für weitere Gleitumgebungen außer table und figure +\usepackage{subfigure} +\usepackage{tabularx} + +\usepackage{setspace} % ermöglicht 1-fachen, 1,5-fachen oder 2-fachen Zeilenabstand + +%Pseudocode + \usepackage{algpseudocode} + + + +%\floatstyle{plain} +%\floatname{sourcecode}{Code-Fragment} +%\newfloat{sourcecode}{htbp}{loc}[chapter] % neue Gleitumgebung für Quellcode + + +\input{Mathe-Definitionen} % einige mathematische Hilfskonstrukte und Vereinfachungen + +\input{SeitenLayout} % Layout der Seiten, z.B. Kopf- und Fußzeilendefinition + +\setcounter{secnumdepth}{3} +\setcounter{tocdepth}{3} +% ueberpruefen, ob wir pdflatex ausfuehren (geht nur bei Koma-Klassen) +\ifpdfoutput +{ +% PDF wird genutzt + + \usepackage[pdftex]{graphicx,color} + % eigene Farben für Links: + %\definecolor{myLinkColor}{rgb}{0,0,.5} + %\definecolor{myCiteColor}{rgb}{0,.5,0} + %\definecolor{myFileColor}{rgb}{.5,0,0} + %\definecolor{myURLColor}{rgb}{0,0,1} + % Setzen aller Link-Farben auf Schwarz + \definecolor{myLinkColor}{rgb}{0,0,0} + \definecolor{myCiteColor}{rgb}{0,0,0} + \definecolor{myFileColor}{rgb}{0,0,0} + \definecolor{myURLColor}{rgb}{0,0,0} + \usepackage[pdftex,% + pdftitle={\meinTitel},% + pdfauthor={\meinName},% + pdfkeywords={\meinePDFStichwoerter},% Stichwörter + plainpages=false,% + pdfpagelabels,% Seitenzahl als z.B. 'ii (4 of 40)' anstatt '4 of 40' darstellen + colorlinks=true,% + linkcolor=myLinkColor,% + citecolor=myCiteColor,% + filecolor=myFileColor,% + urlcolor=myURLColor,% + bookmarks,% Lesezeichen erstellen + bookmarksnumbered, % Lesezeichen nummeriert wie im Inhaltsverzeichnis + breaklinks, % Zeilenumbrüche bei Links erlauben + %pdfpagelayout={TwoColumnRight}% zweiseitiges fortlaufendes Layout + ]{hyperref} + \pdfcompresslevel=9 %Kompressionslevel fuer Text und Grafiken + \DeclareGraphicsExtensions{.pdf, .png, .jpg, .tif, .mps} % Dateiendungen für Grafikdateien, geordnet nach Priorität für automatische Auswahl der richtigen Datei, falls Endung nicht angegeben +} +{ +% Kein PDF + + \usepackage{listings} + \usepackage{graphicx} + \usepackage{color} + \usepackage[hypertex, bookmarks,% Lesezeichen erstellen + bookmarksnumbered, % Lesezeichen nummeriert wie im Inhaltsverzeichnis + breaklinks, % Zeilenumbrüche bei Links erlauben + ]{hyperref} + \DeclareGraphicsExtensions{.eps,.ps} % Dateiendungen für Grafikdateien +} +\usepackage{eso-pic,picture} +\usepackage{geometry} +%\newcommand\BackgroundPic{ +%\put(0,0){ +%\parbox[b][\paperheight]{\paperwidth}{% +%\vfill +%\centering +%\includegraphics[width=\paperwidth,height=\paperheight, +%keepaspectratio]{deckblatt.pdf}% +%\vfill +%}}} + +\bibliographystyle{ieeetr} + + + +\input{Dokumentstruktur} % der eigentliche Inhalt und die Struktur der Arbeit \ No newline at end of file diff --git a/isr-eclipse-plugin/TeX/meineArbeit.toc b/isr-eclipse-plugin/TeX/meineArbeit.toc new file mode 100644 index 0000000000000000000000000000000000000000..dde73a65bf5f7689c5b8e0760464623597283701 --- /dev/null +++ b/isr-eclipse-plugin/TeX/meineArbeit.toc @@ -0,0 +1,80 @@ +\contentsline {chapter}{\numberline {1}Einleitung}{1}{chapter.1} +\contentsline {section}{\numberline {1.1}Motivation und Zielstellung}{1}{section.1.1} +\contentsline {section}{\numberline {1.2}Leitfaden}{3}{section.1.2} +\contentsline {chapter}{\numberline {2}Grundlagen}{4}{chapter.2} +\contentsline {section}{\numberline {2.1}ISR-Grammatik}{4}{section.2.1} +\contentsline {subsection}{\numberline {2.1.1}Aufbau und Struktur}{4}{subsection.2.1.1} +\contentsline {subsection}{\numberline {2.1.2}Besonderheiten und Zusatzsymbole}{5}{subsection.2.1.2} +\contentsline {paragraph}{Joker-Symbol}{5}{section*.4} +\contentsline {paragraph}{Technisches Non-Terminal}{5}{section*.5} +\contentsline {paragraph}{Ignore-List}{6}{section*.6} +\contentsline {subsection}{\numberline {2.1.3}Beispiel}{6}{subsection.2.1.3} +\contentsline {section}{\numberline {2.2}Anforderungen an die Software}{7}{section.2.2} +\contentsline {section}{\numberline {2.3}Anwendungsfall}{8}{section.2.3} +\contentsline {section}{\numberline {2.4}Anforderungsanalyse}{9}{section.2.4} +\contentsline {paragraph}{Anforderung 1:}{10}{section*.7} +\contentsline {paragraph}{Anforderung 2:}{10}{section*.8} +\contentsline {paragraph}{Anforderung 3:}{10}{section*.9} +\contentsline {paragraph}{Anforderung 4:}{10}{section*.10} +\contentsline {paragraph}{Anforderung 5:}{11}{section*.11} +\contentsline {paragraph}{Anforderung 6:}{11}{section*.12} +\contentsline {section}{\numberline {2.5}Verwandte Arbeiten}{11}{section.2.5} +\contentsline {paragraph}{Xtext}{11}{section*.13} +\contentsline {paragraph}{Parser-Editor}{12}{section*.14} +\contentsline {paragraph}{Onlinesoftware}{13}{section*.15} +\contentsline {section}{\numberline {2.6}Benutze Technologien}{13}{section.2.6} +\contentsline {paragraph}{\textbf {\emph {Zest}}}{14}{section*.16} +\contentsline {paragraph}{\textbf {\emph {SOCS Grammar Editor}}}{14}{section*.17} +\contentsline {chapter}{\numberline {3}Umsetzung}{15}{chapter.3} +\contentsline {section}{\numberline {3.1}Funktionalit\"aten}{15}{section.3.1} +\contentsline {subsection}{\numberline {3.1.1}Syntaxhighlighting}{15}{subsection.3.1.1} +\contentsline {subsection}{\numberline {3.1.2}Automatische Formatierung}{16}{subsection.3.1.2} +\contentsline {subsection}{\numberline {3.1.3}Fehlermarkierung}{17}{subsection.3.1.3} +\contentsline {subsection}{\numberline {3.1.4}Hoverinformation}{17}{subsection.3.1.4} +\contentsline {subsection}{\numberline {3.1.5}Content Assistent}{18}{subsection.3.1.5} +\contentsline {subsection}{\numberline {3.1.6}Hyperlinks}{19}{subsection.3.1.6} +\contentsline {subsection}{\numberline {3.1.7}Visualisieren von Regeln}{20}{subsection.3.1.7} +\contentsline {subsection}{\numberline {3.1.8}Wortproblem und Syntaxb\"aume}{21}{subsection.3.1.8} +\contentsline {section}{\numberline {3.2}Pluginarchitektur}{22}{section.3.2} +\contentsline {section}{\numberline {3.3}Der ISR-Grammatik-Editor}{25}{section.3.3} +\contentsline {paragraph}{Die Klasse ISREditor}{25}{section*.18} +\contentsline {paragraph}{Die Klasse ISRDocumentProvider}{25}{section*.19} +\contentsline {paragraph}{Die Klasse ISRSourceViewerConfiguration}{26}{section*.20} +\contentsline {section}{\numberline {3.4}Implementierung und Abl\"aufe}{28}{section.3.4} +\contentsline {paragraph}{Funktionalit\"at \"uber Extension Points}{28}{section*.21} +\contentsline {paragraph}{Funktionalit\"at \"uber Aktionen}{28}{section*.22} +\contentsline {paragraph}{Funktionalit\"at \"uber direkte Implementierung}{28}{section*.23} +\contentsline {subsection}{\numberline {3.4.1}Funktionalit\"at \"uber Extension Points}{28}{subsection.3.4.1} +\contentsline {paragraph}{Hyperlinks}{31}{section*.24} +\contentsline {paragraph}{Wortproblem und Syntaxb\"aume}{31}{section*.25} +\contentsline {paragraph}{Visualisierung von Regeln}{33}{section*.26} +\contentsline {subsection}{\numberline {3.4.2}Funktionalit\"at \"uber Aktionen}{34}{subsection.3.4.2} +\contentsline {paragraph}{Automatische Formatierung}{34}{section*.27} +\contentsline {paragraph}{Content Assistant}{35}{section*.28} +\contentsline {subsection}{\numberline {3.4.3}Funktionalit\"at \"uber direkte Implementierung}{37}{subsection.3.4.3} +\contentsline {paragraph}{Fehlermarkierung}{37}{section*.29} +\contentsline {paragraph}{Hoverinformation}{38}{section*.30} +\contentsline {paragraph}{Syntaxhighlighting}{38}{section*.31} +\contentsline {chapter}{\numberline {4}Evaluation}{40}{chapter.4} +\contentsline {section}{\numberline {4.1}Ziele}{40}{section.4.1} +\contentsline {section}{\numberline {4.2}Methoden und Durchf\"uhrung}{41}{section.4.2} +\contentsline {section}{\numberline {4.3}Auswertung}{42}{section.4.3} +\contentsline {paragraph}{Kenntnisse der gegebenen Hilfsmittel}{42}{section*.32} +\contentsline {paragraph}{Erfahrung mit kontextfreien Grammatiken}{42}{section*.33} +\contentsline {paragraph}{Verst\"andnis und Realit\"atsbezug der Aufgabenstellung}{43}{section*.34} +\contentsline {subsection}{\numberline {4.3.1}Korrektur einer fehlerhaften Grammatik}{43}{subsection.4.3.1} +\contentsline {subsection}{\numberline {4.3.2}Erstellen einer ISR-Grammatik}{46}{subsection.4.3.2} +\contentsline {subsection}{\numberline {4.3.3}L\"osen des Wortproblems und Erstellen von Syntaxb\"aumen}{49}{subsection.4.3.3} +\contentsline {subsection}{\numberline {4.3.4}Funktionalit\"aten}{53}{subsection.4.3.4} +\contentsline {paragraph}{Fehlermarkierung}{53}{section*.35} +\contentsline {paragraph}{Syntaxhighlighting}{53}{section*.36} +\contentsline {paragraph}{Content Assistant}{53}{section*.37} +\contentsline {paragraph}{Automatische Formatierer}{54}{section*.38} +\contentsline {paragraph}{Hoverinformation und Hyperlinks}{54}{section*.39} +\contentsline {paragraph}{Visualisierung der Regeln}{54}{section*.40} +\contentsline {paragraph}{L\"osen des Wortproblems}{55}{section*.41} +\contentsline {section}{\numberline {4.4}Verbesserungsm\"oglichkeiten}{57}{section.4.4} +\contentsline {chapter}{\numberline {5}Fazit und Ausblick}{58}{chapter.5} +\vspace {2mm} +\contentsline {chapter}{Anhang}{61}{appendix.A} +\contentsline {chapter}{Literatur}{67}{appendix*.44} diff --git a/isr-eclipse-plugin/TeX/meineDaten.tex b/isr-eclipse-plugin/TeX/meineDaten.tex new file mode 100644 index 0000000000000000000000000000000000000000..69e40c66fb95c229f5f1577465206c432f786277 --- /dev/null +++ b/isr-eclipse-plugin/TeX/meineDaten.tex @@ -0,0 +1,26 @@ +%#### Meine Eingabedaten ####################################### + +% die nachfolgenden Werte müssen bei jeder Arbeit angepasst werden + + +% Folgende Anweisung definiert den Typ der Arbeit, folgende Argumente sind möglich: +% \ausarbeitungsTypBachelor Bachelor-Arbeit +% \ausarbeitungsTypMaster Master-Arbeit +% \ausarbeitungsTypDiplom Diplomarbeit +% \ausarbeitungsTypSeminar Seminar-Ausarbeitung +% \ausarbeitungsTypProSeminar Pro-Seminar-Ausarbeitung +\def\ausarbeitungsTyp{\ausarbeitungsTypBachelor} + +\def\meinErstellungsdatum{November 2012} % z.B. Mai 2009 +\def\meinTitel{Eclipse-Plugin zur optimierten Erstellung und Wartung von Grammatiken +für das Spracherkennungssystem \emph{ESMERALDA}} +\def\meinName{Hendrik ter Horst} +\def\meineStrasseHausNr{Wertherstra"se 148} +\def\meinePLZundOrt{33615 Bielefeld} +\def\meinErstgutachter{M. Sc. Christian Munier} % auch bei Seminaren +\def\meinZweitgutachter{M. Sc. Leon Ziegler} % bei Seminaren irrelevant +\def\meinePDFStichwoerter{Bachelorarbeit} + +\def\titelDesSeminars{Kognitive Informatik} % nur bei Seminaren von Bedeutung + +%############################################################### \ No newline at end of file diff --git a/isr-eclipse-plugin/TeX/meineDokumentKlasse.tex b/isr-eclipse-plugin/TeX/meineDokumentKlasse.tex new file mode 100644 index 0000000000000000000000000000000000000000..2fd1c6a0e0ba6020962aa8c0b60db2d4048f0c44 --- /dev/null +++ b/isr-eclipse-plugin/TeX/meineDokumentKlasse.tex @@ -0,0 +1,7 @@ +%#### Meine Eingabedaten ####################################### + +% Hier bitte die Dokumentklasse wählen: + +\input{DokumentklasseBaMa} % Alternativen: DokumentklasseBaMa oder DokumentklasseSeminar + +%############################################################### \ No newline at end of file diff --git a/isr-eclipse-plugin/TeX/meineDokumentstruktur.tex b/isr-eclipse-plugin/TeX/meineDokumentstruktur.tex new file mode 100644 index 0000000000000000000000000000000000000000..8959d181134ca38d36e3ef6998eeba68485f427e --- /dev/null +++ b/isr-eclipse-plugin/TeX/meineDokumentstruktur.tex @@ -0,0 +1,73 @@ +% Bitte nur hier Strukturanpassungen vornehmen. + + +%---Abbildungsverzeichnis---------------------------------------------------------------------- + + + +%---Tabellenverzeichnis------------------------------------------------------------------------ + + + +%\setcounter{secnumdepth}{4} Nummerieren bis Stufe 4, also z.B.: 3.2.5.4, meist nicht notwendig + + +%######################## Kapitel 1 ###################################################### +\cleardoublepage +\pagenumbering{arabic} % wieder arabische Seitenzahlen verwenden + +\input{Inhalt/Einleitung} + +%######################## Kapitel 2 ###################################################### +%\clearemptydoublepage + +\input{Inhalt/Grundlagen} + +%######################## Kapitel 3 ###################################################### +%\clearemptydoublepage + +\input{Inhalt/Umsetzung} + + +%######################## Kapitel 4 ###################################################### +%\clearemptydoublepage + +\input{Inhalt/Evaluierung} + +%######################## Kapitel 5 ###################################################### +%\clearemptydoublepage +\input{Inhalt/Fazit} + +%######################## Anhang ######################################################### +%\clearemptydoublepage +\appendix +\addtocontents{toc}{\vspace{2mm}} +%\addcontentsline{toc}{chapter}{Anhang} +\addtocontents{toc}{\protect\contentsline {chapter}{Anhang}{61}{appendix.A}} +%\addtocontents{toc}{\vspace{-4mm}} +\input{Inhalt/Anhang} + +%Abbildungsverzeichnis +\listoffigures +%######################## Nachspann ###################################################### + +%---Literaturverzeichnis----------------------------------------------------------------------- +%\appendix +%\addtocontents{toc}{\vspace{2mm}} +%\addcontentsline{toc}{chapter}{Anhang} +%\addtocontents{toc}{\protect\contentsline {chapter}{Literatur}{57}{appendix.A}} +%\addtocontents{toc}{\vspace{-4mm}} + +%\documentclass[bibliography=totoc]{scrartcl} +%\clearemptydoublepage +%\bibliographystyle{myalphadin} +\bibliographystyle{natdin} +%\bibliographystyle{alphadin} +%\bibliographystyle{alpha} +%\bibliographystyle{geralpha} +%\bibliographystyle{dinat} +\bibliography{Bibliographie} + +%---Stichwortverzeichnis------------------------------------------------------------------------ +%\clearemptydoublepage +%\printindex \ No newline at end of file diff --git a/isr-eclipse-plugin/TeX/meineSilbentrennung.tex b/isr-eclipse-plugin/TeX/meineSilbentrennung.tex new file mode 100644 index 0000000000000000000000000000000000000000..7d06be0317b8bde415c5f250d27f3c839d91ea68 --- /dev/null +++ b/isr-eclipse-plugin/TeX/meineSilbentrennung.tex @@ -0,0 +1,10 @@ +%---Silbentrennung----------------------------------------------------------------------------- + +% Silbentrennung für Wörter, in denen kein Bindestrich vorkommt +\hyphenation{% +Sil-ben-tren-nung +Bin-de-strich +Pro-gram-me +} + +%---------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/isr-eclipse-plugin/TeX/myalphadin.bst b/isr-eclipse-plugin/TeX/myalphadin.bst new file mode 100644 index 0000000000000000000000000000000000000000..8808f9d117a84bcc479e4525b905c43bec0d5418 --- /dev/null +++ b/isr-eclipse-plugin/TeX/myalphadin.bst @@ -0,0 +1,1685 @@ +%% ALPHADIN.BST Ausgabe [8] 10/10/00 +%% (C) Klaus F. Lorenzen, Hamburg email: lorenzen.marxen@t-online.de +%% ersetzt ALPHADIN.BST Ausgabe [7,1] vom 23/11/99 +%% ersetzt DinAlpha.BST von 1994 +%% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +%% ALPHADIN.BST wurde entwickelt aus BibTeX standard bibliography style +%% `alpha'.Mit ALPHADIN.BST werden Literaturverzeichnisse gemaess der deutschen +%% Zitiernorm DIN 1505 Teil 2 formatiert. +%% Analog zu den 4 US standard styles wird ein vollstaendiger Satz von +%% 4 DIN-gerechten bst-style Dateien veroeffentlicht (alphadin.bst, +%% plaindin.bst, unsrtdin.bst, abbrvdin.bst). Die gueltige Version +%% ist am schnellsten aus dem WWW ueber folgende URL zu beziehen +%% http://www.fh-hamburg.de/pers/Lorenzen/bibtex/ +%% Stand: 16/6/99 +%% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +%% WAS IST ALPHADIN.BST ? +%% Dieser style produziert "deutsche" Literaturzitate in Literaturverzeichnis- +%% sen gemaess der deutschen Norm DIN 1505, Teil 2 vom Jan. 1984. +%% Die Literaturzitate werden alphabetisch nach Verfassern sortiert +%% und sind durch abgekuerzte Verfasserbuchstaben plus Erscheinungsjahr in +%% eckigen Klammern gekennzeichnet. +%% Es gibt Unterschiede zwischen der US- und der deutschen Zitierkonvention, +%% was die bibliographischen Typen und die verschiedenen Trennzeichen zwischen +%% den Feldern angeht. Daher ist auch keine 100%ige Abbildung der beiden +%% Regelwerke aufeinander moeglich. Dies ist aber immer durch eine achtsame +%% Erfassung beherrschbar! Die vorliegenden DIN-styles versuchen einige +%% bibliographische Beschraenkungen der Originalstyles zu ueberwinden. +%% Es laesst sich in fast allen Faellen problemlos ein Original-bib-file +%% (d.i. die Datenbank, die die bibliographischen Informationen enthaelt) +%% wahlweise nach US-Norm oder deutscher DIN-Norm verarbeiten. +%% [Beispiel: Produzieren Sie mit der XAMPL.bib-Datenbank aus dem Original- +%% paket 2 verschiedene Literaturverzeichnisse.] Zu Gunsten +%% der Allgemeingueltigkeit von bib-files ist bei den Publikationstypen +%% (entry-types) und den bibliographischen Kategorien (fields) in Zweifels- +%% faellen immer die originale US-Bedeutung beibehalten worden. +%% Bei der Erfassung von Literaturquellen in bib-files +%% gelten folglich die in der TEX-Literatur veroeffentlichten Regeln. +%% Kommt es dennoch zu kleineren "Schoenheitsfehlern" im fertig gesetzten +%% output, so koennen diese so gut wie immer durch eine leicht veraenderte +%% Erfassung im bib-inputfile beseitigt werden. Last but not least koennen +%% Sie im output-file < *.bbl > noch letzte Hand zur Korrektur ansetzen. +% +%% UMGANG MIT FEHLERMELDUNGEN +%% Noch nicht alle ueberfluessigen Fehlermeldungen des Original-style sind +%% ausgemerzt. Die meisten Warnmeldungen beruhen auf +%% den andersartigen bibliographischen Regeln nach DIN 1505 und dem damit +%% verbundenen Ermessensspielraum, sind also in Wahrheit keine "Fehler". +%% Dennoch sollten Sie diese Warnungen beachten, um herauszufinden, ob +%% evtl. eine unzulaessige Kombination von Publikationstyp (=entry-type) und +%% "fields" vorgenommen worden ist. Das fuehrt mitunter zu Wasserfallartigen +%% Fehlermeldungen: meistens duerfen Sie das einfach ignorieren. +%% +%% DANKSAGUNG +%% Hartmut Lueddecke, FH Hamburg habe ich fuer viele Verbesserungsvorschlaege +%% und stete Unterstuetzung zu danken. Vielen an dieser Stelle ungenannt +%% bleibenden Anwendern gilt mein Dank, die in den vergangenen Jahren durch +%% ihre Aufmerksamkeit dazu beigetragen haben, Fehler auszumerzen und +%% Verbesserungen vorzunehmen. +%% +%% HINWEIS: es gibt eine Kombination von ALPHADIN.BST mit dem NATBIB-Stil +%% von Patrick W.Daly), womit Literaturverzeichnisse komplett nach +%% DIN 1505 Teil 2 UND Teil 3 formatiert werden koennen. Naeheres +%% per URL http://www.fh-hamburg.de/pers/Lorenzen/bibtex/ +%% +%% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +%% Eine ausfuehrliches Internet-Tutorial mit Beispielen ist in Vorbereitung. +%% Fuer den Anfang ist diese Datei schon etwas kommentiert! +%% Kritik, Vorschlaege usw. bitte an : +%% FH Hamburg, Klaus F. Lorenzen, Grindelhof 30, 20146 Hamburg +%% e-mail: lorenzen.marxen@t-online.de +%% 16/6/99 +%% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +% version 0.99c for BibTeX versions 0.99c or later, LaTeX2e +% Copyright (C) 1985, all rights reserved. +% Copying of this file is authorized only if either +% (1) you make absolutely no changes to your copy, including name, or +% (2) if you do make changes, you name it something other than +% bstdin.doc, plaindin.bst, unsrtdin.bst, alphadin.bst, and abbrvdin.bst. +% This restriction helps ensure that all standard styles are identical. +%% ==> The file btxbst.doc has the original documentation for style 'alpha'. +%% + +ENTRY + { address %% Verlagsort + author %% persoenlicher Urheber eines Werkes + booktitle %% a) Gesamttitel eines mehrbaendigen Werkes +% %% b) Titel des Sammelwerks, das einzelne selbstaendige +% %% Beitraege mit eigenem Titel enthaelt (->incollection) + chapter %% Kapitel in einem Buch (Monographie) + edition %% Auflagevermerk + editor %% Persoenl.Herausgeber oder Koerperschaftlicher Herausgeber + howpublished %% beliebiger Verlegervermerk: von wem, wo + institution %% Institution, die e.Verlagsfreie Veroeffentlichung betreibt + isbn %% Standardnr fuer Buecher + issn %% - " - : Zeitschriften u. Serien + journal %% Titel einer Zeitschrift + key %% Zusaetzlich vergebener Sortierschluessel, mitunter notwend. + month %% naehere Bestimmung des Erscheinungsjahres (-> macro 's) + note %% freies Eingabefeld fuer zusaetzliche Informationen + number %% Mehrfachbedeutung in Abhaengigkeit vom Eingabetyp + organization %% a) Name der Organisation/des Veranstalters e. Tagung,Konferenz +% %% b) Name einer Firma/Gesellschaft, die ein ->manual herausgab + pages %% Umfangsangaben, meist Seitenzahlen + publisher %% Verlag + school %% Hochschule/Universitaet, die eine Dipl.-Arb./Dissertation veroeff. + series %% Titel e.Reihe, in der ein best. Buchtitel erschienen ist + title %% Titel einer (namentlich gekennzeichneten) Veroeffentlichung + type %% Zusatzfeld z.Kennzeichnung e.besonderen Publikationstyps + volume %% a) Zaehlung bei einem mehrbaendigen Werk (-> book) +% %% b) Jahrgang einer Zeitschrift (-> article + year %% Erscheinungsjahr + } + {} + { label extra.label sort.label } + +INTEGERS { output.state before.all mid.sentence after.sentence after.block } + +%% die folg. BOOLE'sche VAR steuern d. Ausg. ": " nach Urheber-Feldern +%% und ". - " vor ISBN oder Anmerkungen (NOTE) + +INTEGERS { colon.after period.dash } + +FUNCTION {init.state.consts} +{ #0 'before.all := + #1 'mid.sentence := + #2 'after.sentence := + #3 'after.block := + #4 'colon.after := + #5 'period.dash := +} +INTEGERS { zahl lang } + +STRINGS { h s t u v } + +%% neue DIN-Funktion, 16/2/94 + +FUNCTION {output.nonnull} +{ 's := + output.state after.block = + { add.period$ write$ + newline$ + "\newblock " write$ + } + { output.state before.all = + { write$ } + { output.state colon.after = + { ": " * write$ + newline$ + "\newblock " write$ + } + { output.state period.dash = + { ". -- " * write$ + newline$ + "\newblock " write$ + } + { output.state mid.sentence = + { ", " * write$ } + { write$ + newline$ + "\newblock " write$ + } + if$ + } + if$ + } + if$ + } + if$ + after.block 'output.state := + } + if$ + s +} + +FUNCTION {output} +{ duplicate$ empty$ + 'pop$ + 'output.nonnull + if$ +} + +FUNCTION {output.check} +{ 't := + duplicate$ empty$ + { pop$ "empty " t * " in " * cite$ * warning$ } + 'output.nonnull + if$ +} + +FUNCTION {output.bibitem} +{ newline$ + "\bibitem[" write$ + label write$ + "]{" write$ + cite$ write$ + "}" write$ + newline$ + "" + before.all 'output.state := +} + +FUNCTION {fin.entry} %%$$$ nach DIN neu 16/2/94 +{ write$ + newline$ +} + +FUNCTION {set.period.dash} %% Wenn ein ". - " die Satzteile trennen soll.! +{ output.state before.all = + 'skip$ + { period.dash 'output.state := } + if$ +} + +%% neu 16/2/94 +%% prueft, ob PAGES, ISBN- oder NOTE-Feld vh. ist und setzt dann ". - " davor. + +FUNCTION {set.period.dash.check} +{ empty$ + 'skip$ + 'set.period.dash + if$ +} + +FUNCTION {set.colon.after} %%$$$ Wenn ein ": " d. Satzteile trennen soll! +{ output.state before.all = + 'skip$ + { colon.after 'output.state := } + if$ +} + +%% neu / alt 17/2/94 Wenn ein " " die Satzteile trennen soll.! +FUNCTION {new.sentence} +{ output.state before.all = + 'skip$ + { after.sentence 'output.state := } + if$ +} + +%% neu 17/2/94 Wenn ein ", " die Satzteile trennen soll.! +FUNCTION { part.of.sentence } +{ output.state before.all = + 'skip$ + { mid.sentence 'output.state := } + if$ +} + + +FUNCTION {not} +{ { #0 } + { #1 } + if$ +} + +FUNCTION {and} +{ 'skip$ + { pop$ #0 } + if$ +} + +FUNCTION {or} +{ { pop$ #1 } + 'skip$ + if$ +} + +FUNCTION {new.sentence.checka} +{ empty$ + 'skip$ + 'new.sentence + if$ +} + +FUNCTION {field.or.null} +{ duplicate$ empty$ + { pop$ "" } + 'skip$ + if$ +} + +INTEGERS { nameptr namesleft numnames } + +STRINGS { fkt } + +FUNCTION {emphasize} +{ duplicate$ empty$ + { pop$ "" } + { "\emph{" swap$ * "}" * } + if$ +} + +%% neu, setzt Autor/Hrsg. in Kapitaelchen 9/3/94 +FUNCTION { capitalize } + { duplicate$ empty$ + { pop$ "" } + { "\textsc{" swap$ * "}" * } + if$ +} + +%%$$$ DIN-Quellenangabe : spezieller unselbst. Teil ist erschienen "In: " +%% dem bibliogr. selbst. Werk, z.B. Zeitschrift, Buch + +%% 1/4/96 +FUNCTION {article.in.journal} +{ duplicate$ empty$ + { pop$ "" } + { author missing$ + { title missing$ + { emphasize " " * * }%% wenn ein Zs-Heft als ganzes zitiert wird + { emphasize "{In: }" swap$ " " * * } + if$ + } + { emphasize "{In: }" swap$ " " * * } + if$ + } + if$ +} + +%% nach Vorschlag von H.Lueddecke, um Adelspraedikate beim Sortieren +%% nach den(m) Vornamen aufzufuehren. Lo, 2/11/94 +FUNCTION {format.names} +{ 's := + "" 'u := + #1 'nameptr := + s num.names$ 'numnames := + numnames 'namesleft := + { namesleft #0 > } + { + s nameptr "{vv~}{ll}" format.name$ 't :=%% das ergibt DIN-Ansetzung + %% Lue's Vorschlag s nameptr "{ll}" format.name$ 't := + t capitalize 't := + s nameptr "{, ff}" format.name$ 'u := + %% Lue's Vorschlag s nameptr "{, ff}{ vv}" format.name$ 'u := + u text.length$ 'lang := + #1 'zahl := + "" 'v := + { zahl lang < } + { u zahl #1 substring$ "~" = + { v "" = + { u #1 zahl #1 - substring$ 'v := } + 'skip$ + if$ + v u zahl #2 substring$ * "." * 'v := } + 'skip$ + if$ + zahl #1 + 'zahl := } + while$ + v "" = + { u 'v := } + 'skip$ + if$ +%% der string fkt enthaelt " (Hrsg.)", wenn Editorfeld nicht leer ist + t v * fkt * 't := %% Komma nach Nachnamen wird oben erledigt! + %% t enthaelt nun d. formatierten Nnamen, Vnamen + nameptr #1 > + { namesleft #1 > + { "; " * t * } + { numnames #2 > + { "" * } + 'skip$ + if$ +%% %% n. schindle's hinweis 12/1/96 erweitert + t "\textsc{others}" = t "\textsc{others} (Hrsg.)" = or +%%%% { " [u.~a.]" * }%% 13/2/94 + { " et~al." * } %% Geschmackssache, waehle eins von beiden + { "; " * t * } + if$ + } + if$ %% Ende der namesleft-Pruefung + } + 't + %% hierdurch wird bei jed. Schleifendurchgang das sich komplet- + %% tierende Zwischen-Namensergebnis wieder auf den stack gelegt + + if$ %% Ende der nameptr-Pruefung + + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ %% Ende von { namesleft #0 > } ganz oben + "" 'fkt := %% fkt wird zurueckgesetzt +} + +%%$$$ geaendert 14/2/94 + +FUNCTION {format.authors} +{ author empty$ + { "" } + { author format.names } + if$ +} + +%%$$$ geaend. 20/2/94 Anpassung an DIN, wonach Autor + Hrsg. zusammen vorkom- +%% men duerfen.!! + +FUNCTION {format.editors} +{ editor empty$ + { author empty$ + { "Weder Verfasser noch Hrsg. in " cite$ * warning$ } + 'skip$ + if$ + } + { author empty$ + { " (Hrsg.)" 'fkt := + editor format.names + } + { " (Hrsg.)" 'fkt := + " ; " * editor format.names * + } + if$ + } + if$ + } + +%% Lo, 12/5/99 neue Funktion fuer proceedings, misc usw. + +FUNCTION { format.editors.organization } +{ organization empty$ + 'skip$ + { type$ "misc" = + { organization } + { " ; " * organization " (Veranst.)" *} + if$ + } + if$ +} + +%%$$$ Sonderfall: Herausgeber bei Typ incollection, 21/2/94 +FUNCTION {format.ed.incoll} +{ editor empty$ + { "" } + { " (Hrsg.)" 'fkt := + editor format.names + } + if$ +} + +FUNCTION {format.title} +{ title empty$ + { "" } + { title } %% Text so wie er dasteht im Feld title + if$ +} + +FUNCTION {n.dashify} +{ 't := + "" + { t empty$ not } + { t #1 #1 substring$ "-" = + { t #1 #2 substring$ "--" = not + { "--" * + t #2 global.max$ substring$ 't := + } + { { t #1 #1 substring$ "-" = } + { "-" * + t #2 global.max$ substring$ 't := + } + while$ + } + if$ + } + { t #1 #1 substring$ * + t #2 global.max$ substring$ 't := + } + if$ + } + while$ +} + +%% geaendert 24/2/94 +FUNCTION {format.date} +{ year empty$ + { month empty$ + { "" } + { "there's a month but no year in " cite$ * warning$ + month + } + if$ + } + { month empty$ %% b. Buechern nur Jahr, ohne Monat ausgeb. im Impressum + 'year + { month " " * year * } + if$ + } + if$ +} + +%% +%%$$$ neue Fkt., 16/2/94 u. 14/3/94 das sog. Impressum +FUNCTION {format.address.publisher.year} +{ publisher empty$ + { address empty$ + { year empty$ + { "" } + { year } + if$ + } + { "Es gibt einen Verlagsort, aber keinen Verlag in " cite$ * warning$ + address ", " * format.date * + } + if$ + } + { address empty$ + { year empty$ + { "Es gibt nur eine Verlagsangabe in " cite$ * warning$ + publisher + } + { publisher ", " * format.date * } + if$ + } + { year empty$ + { address " : " * publisher * } + { address " : " * publisher * ", " * format.date * } + if$ + } + if$ + } + if$ +} + +FUNCTION {format.btitle} +{ title emphasize +} + + +FUNCTION {tie.or.space.connect} +{ duplicate$ text.length$ #3 < + { "~" } + { " " } + if$ + swap$ * * +} + +FUNCTION {either.or.check} +{ empty$ + 'pop$ + { "can't use both " swap$ * " fields in " * cite$ * warning$ } + if$ +} + +%% neu 8/3/94 in dieser Funkt. steckt im volume empty-Teil noch ein bug, der +%% aber ignoriert werden kann; das Ergebnis ist ok. +FUNCTION {format.btitle.vol} +{ number empty$ + { series empty$ + { volume empty$ + { title emphasize } + { title emphasize ". Bd." * volume tie.or.space.connect } + if$ + } + { volume empty$ + { title emphasize }%% ein Buch, das zusaetzl. SERIES=Reihentitel besitzt + %% jetzt kommt d. Fall des mehrbaendigen Werkes mit Gesamttitel=SERIES + %% Zaehlung=VOLUME und Bandtitel=TITLE; + { series emphasize ". Bd." * volume tie.or.space.connect + ": " * "{\emph{" * title * "}}" * } + if$ + } + if$%% series-test + } + { title emphasize }%% wenn number ex., dann immer title-Feld + if$%% Ende number-test +} + +%%$$$ neu 16/2/94 +%% Serien- / Reihentitel werden im Feld series gespeichert. Weist die +%% Serie eine Zaehlung der Einzeltitel auf, gibt man entweder nach DIN alles +%% in das Feld series so ein: ---> TITEL DER SERIE NR. (der Vorlage) <--- +%% z. B. SERIES= { Mensch und Computer 12 }. +%% [ Die Nummer der Vorlage darf auch durch " ; " abgesetzt werden. ] +%% oder: +%% man gibt die Zaehlung in das Feld NUMBER ein, z.B. NUMBER = {12}. +%% Achtung!! +%% Bei mehrbaendigen Werken steht d. Gesamttitel im Feld SERIES und die +%% Bandzaehlung im Feld VOLUME; NUMBER darf dann nicht besetzt sein! +%% Anderenfalls liegt ein Erfassungsfehler vor, da sich Reihe u. mehrbd. +%% Werk gegenseitig ausschliessen. + +FUNCTION {format.series.number.din} +{ volume empty$ + { number empty$ + { series empty$ + { "" }%% Ausstieg mit Nullstring + { "(" series * ")" * } %% d. Seriennr koennte auch gleich hier + %% im SERIES-Feld miterfasst werden + if$ + } + { series empty$ + { "(" number tie.or.space.connect ")" * + "there's a number but no series in " cite$ * warning$ + } + { "(" series * number tie.or.space.connect ")" * } + if$ + } + if$ + } + { series empty$ + { "" } + { type$ "proceedings" = %% Sonderfall, es darf VOLUME und NUMBER ex. ! + { number empty$ + { "(" series * ")" * } + { "(" series * number tie.or.space.connect ")" * } + if$ + } + { "" }%% Ausstieg mit Nullstring, s. Kommentar + if$ + }%% bei gezaehlten Reihen MUSS die Reihennr. im Feld NUMBER stehen! + if$ %% wenn also d. Feld VOLUME nicht leer ist, dann liegt ausser bei + %% Typ PROCEEDINGS falsche + } %% Erfassung vor und es erfolgt d. Ausstieg mit d. Nullstring! + if$ +} + +%% seltener Fall bei MISC: Ausgabe einer Serie; die Nummer der Serie muss +%% in SERIES miterfasst werden 16/6/99 + +FUNCTION {format.misc.series} +{ series empty$ + { "" } + { "(" series * ")" * } + if$ +} + + +%%$$$ 16/2/94 +%% Auflagenvermerke gibt man komplett, einschliesslich Abkuerzungen in +%% das Feld edition ein: ---> EDITION= { 3., erw. und verb. Aufl. } +%% oder fremdsprachlich: EDITION= { 2nd edition } + +FUNCTION {format.edition} +{ edition empty$ + { "" } + { edition } + if$ +} + +%%$$$ neu, 18/3/94 +FUNCTION { format.isbn.issn } +{ isbn empty$ + { issn empty$ + { "" } + { "ISSN" issn n.dashify tie.or.space.connect } + if$ + } + { "ISBN" isbn n.dashify tie.or.space.connect } + if$ +} + +%%$$$ geaendert, 21/2/94 gibt Seitenzahl bei BOOK-Typ und verwandten T. aus +FUNCTION {format.pages.book} +{ pages empty$ + { "" } + { "" pages n.dashify tie.or.space.connect " S" *} %% 17/12/95 + if$ +} + +%%$$$ alle anderen Seitenang. zB. Zeitschrft., INBOOK usw. a la Orig., 9/3/94 +FUNCTION {format.pages} +{ pages empty$ + { "" } + { "S." pages n.dashify tie.or.space.connect } + if$ +} + +%% Angaben v. Jahrgang, Jahr, Heftnr., Seiten bei Artikel-Typ +%% 14/3/94, 26/2/97 + +FUNCTION {format.vol.year.num.pages} +{ volume field.or.null + year empty$ + { "Es gibt einen Jahrgang, aber kein Jahr in " cite$ * warning$ } + { " (" year * ")" * * } + if$ + month empty$ + 'skip$ + { ", " month * * } + if$ + number empty$ + 'skip$ + { ", Nr. " number * * } + if$ + pages empty$%% Lo, 26/2/97 + 'skip$ + { ", " format.pages * *}%% + if$ + +%% pages empty$%% das war die Fass. Nov. 96, die auch ging +%% 'skip$ +%% { duplicate$ empty$ +%% { pop$ format.pages }%% da pages leer, wird nur "" auf stack gelegt +%% { ", " format.pages * *} +%% if$ +%% } +%% if$ + +} + +%% geaendert 21/2/94 +FUNCTION {format.chapter.pages} +{ chapter empty$ + 'format.pages + { type empty$ + { "Kapitel " } + { type } + if$ + chapter tie.or.space.connect + pages empty$ + 'skip$ + { ", " * format.pages * } + if$ + } + if$ +} + +%%$$$ geaendert 21/2/94 +FUNCTION {format.in.ed.booktitle.din} +{ booktitle empty$ + { "" } + { editor empty$ + { volume empty$ + { "{In: }" booktitle emphasize * }%% n. Belieben fettes In: + { "{In: }" booktitle emphasize * %% - " - + " Bd." volume tie.or.space.connect * + } + if$ + } + { volume empty$ + { "{In: }" format.ed.incoll * ": " * booktitle emphasize * } + { "{In: }" format.ed.incoll * ": " * booktitle emphasize * + " Bd." volume tie.or.space.connect * + } + if$ + } + if$ + } + if$ +} + +%% geaendert 1/3/94 +FUNCTION {format.thesis.type} +{ type empty$ + 'skip$ + { pop$ + type + } + if$ +} + +%% geaendert 23/2/94 i.Orig. wird zuerst die number, dann der type getestet +FUNCTION {format.tr.number.din} +{ type empty$ + { number empty$ + { " -- Forschungsbericht" } %% bei Minimalangaben besser ohne "."! + { "(" number tie.or.space.connect "). -- Forschungsbericht" * } + if$ + } + { number empty$ + { " -- " type * } %% bei Minimalangaben besser ohne "."! + { "(" number tie.or.space.connect "). -- " * type * } + if$ + } + if$ +} + + +FUNCTION {format.article.crossref} +{ key empty$ + { journal empty$ + { "need key or journal for " cite$ * " to crossref " * crossref * + warning$ + "" + } + { "{In: }{\em " journal * "\/}" * }%% + if$ + } + { "{In: }" key * }%% + if$ + "{\cite{" * crossref * "}" * "}" * ", " * format.pages * +%% " (siehe \cite{" * crossref * "}" * "), " * format.pages * +} + +%%geaendert 7/3/94 und noch einmal nach Lueddecke, s.o. +FUNCTION {format.crossref.editor} +%vorher,Lue { editor #1 "{vv~}{ll}" format.name$ " (Hrsg.)" * + { editor #1 "{ll}" format.name$ " (Hrsg.)" * + editor num.names$ duplicate$ + #2 > + { pop$ " [u.~a.]" * } +%% { pop$ " et~al." * } + { #2 < + 'skip$ + { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = + { " [u.~a.]" } +%% { " et~al." * } + { " ; " * editor #2 "{vv~}{ll}" format.name$ * " (Hrsg.)" * } + if$ + } + if$ + } + if$ +} + + +FUNCTION {format.book.crossref} +{ volume empty$ + { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ + "{\texttt{siehe}} " +%% "(siehe " + } + { ". -- Bd." volume tie.or.space.connect + " von " * + } + if$ + editor empty$ + editor field.or.null author field.or.null = + or + { key empty$ + { series empty$ + { "need editor, key, or series for " cite$ * " to crossref " * + crossref * warning$ + "" * + } + { "" * }%% dadurch kommt nach der Bandzaehl. gleich das label 2/6/99 +%% { "{\emph{" * series * "}} {\texttt{siehe}}" * } + if$ + } + { key * } + if$ + } + { "" * }%% nach der Bandzaehlung kommt gleich das label; Lo 2/6/99 +%% { format.crossref.editor * } + if$ + "{\cite{" * crossref * "}" * "}" * +%% "{\cite{" * crossref * "}" * "}" * %%"), " * format.pages * +} + +FUNCTION {format.incoll.inproc.crossref} +{ editor empty$ + editor field.or.null author field.or.null = + or + { key empty$ + { booktitle empty$ + { "need editor, key, or booktitle for " cite$ * " to crossref " * + crossref * warning$ + "" + } + { "{In: }{\emph " booktitle * "}" * }%% fettes In: n. Belieben + if$ + } + { "{In: }" }%% 26/5/99 +%% { "{In: }" key * } + if$ + } +%% { "{In: }{\em " booktitle * "\/}" * }%% + { "{In: }" }%% Lo, 10/2/99 es sieht der reine Bezug (Referenz) besser aus! + if$ +%% " (siehe \cite{" * crossref * "}" * "), " * format.pages * + "{\cite{" * crossref * "}" * "}" * ", " * format.pages *%% das fette label, Lo 23/2/99 +%% alte Vers. bis 27/2/97 " (siehe \cite{" * crossref * "}" * ")" * +} + +%%geaendert +FUNCTION {article} +{ output.bibitem + format.authors "author" output.check + set.colon.after + format.title "title" output.check + crossref missing$ + { journal article.in.journal output.nonnull % 26/2/97 + new.sentence + format.vol.year.num.pages output + } + { format.article.crossref output.nonnull } + if$ + note set.period.dash.check + note output + issn set.period.dash.check + format.isbn.issn output + fin.entry +} + +%%$$$ geaendert, 20/2/94 +FUNCTION {book} +{ output.bibitem + author empty$ + { format.editors "author and editor" output.check } + { format.authors format.editors output.nonnull } + if$ + set.colon.after + crossref missing$ + { format.btitle.vol "title" output.check } + { format.btitle "title" output.check } + if$ + format.edition "edition" output.check + format.address.publisher.year "publisher" output.check + new.sentence + crossref missing$ + { format.series.number.din output + pages set.period.dash.check%% 19/5/99 wie bei adinat.bst + format.pages.book output + } + { format.book.crossref output.nonnull + pages set.period.dash.check + format.pages.book output + } + if$ + note set.period.dash.check + note output + isbn set.period.dash.check + format.isbn.issn output + fin.entry +} + +%% geaendert 23/2/94 +FUNCTION {inbook} +{ output.bibitem +%% unselbst. Teile eines Buches werden am Anf. genannt, dann d selbst. Quelle + chapter empty$ + { "Es fehlen die Kapitelangaben in " cite$ * warning$ } + { type empty$ + { "Kap. " }%% d.i. die Standardvorgabe + { type }%% wenn man keine bes. Typform angeben will, koennte ein kl. +%% Zwischenraum gewaehlt werden, z.B. " \, " + if$ + chapter tie.or.space.connect " {In: }" * * %% n. Belieben fettes In: + } + if$ + +%% -------- jetzt kommt der bibliogr. selbst. Teil + author empty$ + { format.editors "author and editor" output.check } + { format.authors output.nonnull + } + if$ + set.colon.after + format.btitle.vol "title" output.check + crossref missing$ + { format.edition output + format.address.publisher.year "publisher" output.check + new.sentence + format.series.number.din output +%% vorher note ... + part.of.sentence + format.pages "pages" output.check + note set.period.dash.check + note output + } + { format.book.crossref output.nonnull + note set.period.dash.check + note output + } + if$ + isbn set.period.dash.check + format.isbn.issn output + fin.entry +} + +%% geaenderte Seitenzahlausgabe, wenn crossref-Feld benutzt wird, 27/2/97 +FUNCTION {incollection} +{ output.bibitem + format.authors "author" output.check + set.colon.after + format.title "title" output.check + crossref missing$ + { format.in.ed.booktitle.din "booktitle" output.check + format.edition output + format.address.publisher.year "publisher" output.check + new.sentence + format.series.number.din output + note set.period.dash.check + note output + isbn set.period.dash.check + issn set.period.dash.check + format.isbn.issn output + part.of.sentence + format.chapter.pages "pages" output.check + } + { format.incoll.inproc.crossref output.nonnull + note set.period.dash.check + note output + isbn set.period.dash.check + issn set.period.dash.check + format.isbn.issn output + } + if$ + fin.entry +} + +%% geaendert 22/2/94, 15/11/96 (Hinweis v. Alin Shindun, Uni Siegen) +FUNCTION {inproceedings} +{ output.bibitem + format.authors "author" output.check + set.colon.after + format.title "title" output.check + crossref missing$ + { format.in.ed.booktitle.din "booktitle" output.check + address empty$ + { organization new.sentence.checka + organization output + part.of.sentence + format.address.publisher.year output + } + { format.address.publisher.year "publisher" output.check } + if$ + new.sentence + series empty$ %%neu nach Hinweis v. Alin Shindun, 15/11/96 + 'skip$ + { format.series.number.din output } + if$ + note set.period.dash.check + note output + isbn set.period.dash.check + issn set.period.dash.check + format.isbn.issn output + part.of.sentence + format.pages output + } + { format.incoll.inproc.crossref output.nonnull + note set.period.dash.check + note output + isbn set.period.dash.check + issn set.period.dash.check + format.isbn.issn output + } + if$ + fin.entry +} + +FUNCTION {conference} { inproceedings }%% nach Patashnik, wg US-Kompatibilitaet + +%% geaendert, 11/6/99 +FUNCTION {manual} +{ output.bibitem + author empty$ + { organization empty$ + { title empty$ + 'skip$ + {format.btitle "title" output.check } + if$ + } + { organization output.nonnull + set.colon.after + format.btitle "title" output.check + } + if$ + } + { format.authors output.nonnull + set.colon.after + format.btitle "title" output.check + } + if$ + format.edition "edition" output.check + author empty$ + { organization empty$ + { address output + part.of.sentence + } + 'skip$ + if$ + } + { address ": " * organization * output + part.of.sentence + } + if$ + format.date output + pages set.period.dash.check + format.pages.book output + note set.period.dash.check + note output + fin.entry +} + +%% MASTERSTHESIS ersetzt zugleich PHDTHESIS !! KFL, 17/2/94 +%% Ausgabe-Standard ist "Diplomarbeit", fuer andere Abschlussarbeiten +%% bei der Erfassung TYPE="anderer Typ" eingeben. +%% z.B. TYPE={Dissertation}, TYPE={Diss.}, TYPE={Habil.}, TYPE={Magisterarb.} +%% +FUNCTION {mastersthesis} +{ output.bibitem + format.authors "author" output.check + set.colon.after + format.btitle "title" output.check + address output + part.of.sentence + school "school" output.check + part.of.sentence + "Diplomarbeit" format.thesis.type output.nonnull + part.of.sentence + format.date "year" output.check +%% pages new.sentence.checka + pages set.period.dash.check + format.pages.book output + note set.period.dash.check + note output + fin.entry +} + +FUNCTION {bachelorsthesis} %% {mastersthesis}% ist identisch bis auf Standardwert, s.o. +{ output.bibitem + format.authors "author" output.check + set.colon.after + format.btitle "title" output.check + address output + part.of.sentence + school "school" output.check + part.of.sentence + "Studienarbeit" format.thesis.type output.nonnull + part.of.sentence + format.date "year" output.check +%% pages new.sentence.checka + pages set.period.dash.check + format.pages.book output + note set.period.dash.check + note output + fin.entry +} + +FUNCTION {phdthesis} %% {mastersthesis}% ist identisch bis auf Standardwert, s.o. +{ output.bibitem + format.authors "author" output.check + set.colon.after + format.btitle "title" output.check + address output + part.of.sentence + school "school" output.check + part.of.sentence + "Dissertation" format.thesis.type output.nonnull % koennte auch `Dissertation' sein + part.of.sentence + format.date "year" output.check + pages set.period.dash.check + format.pages.book output + note set.period.dash.check + note output + fin.entry +} + +%% hiermit werden u.a. Normen erfasst +FUNCTION {misc} +{ output.bibitem + note empty$ + { title empty$ + { "" } + { format.authors format.editors output.nonnull + format.btitle output + howpublished output + format.date output + } + if$ + } + { note duplicate$ #1 #4 substring$ "Norm" = + { output new.sentence + format.date output + format.title output + } + { pop$ "" + author empty$ + { editor empty$ + { organization empty$ + { 'skip$ } + { format.editors.organization output.nonnull + set.colon.after } + if$ + } + { format.editors format.editors.organization output.nonnull + set.colon.after } + if$ + } + { format.authors format.editors output.nonnull + set.colon.after } + if$ + format.btitle output + howpublished output + format.date output + new.sentence + format.misc.series output%% neu 16/6/99 + note set.period.dash.check + note output + } + if$ + } + if$ + fin.entry +} + +FUNCTION {booklet} {misc}%% booklet ist nach dt. Vorgehensweise oft ueberfluessig + +%% geaendert 21/5/99 +FUNCTION {proceedings} +{ output.bibitem + editor empty$ + { organization empty$ + { "" } + { organization " (Veranst.)" * output } + if$ + } + { format.editors format.editors.organization output.nonnull } + if$ + set.colon.after + format.btitle "title" output.check + volume empty$ + { "" output.nonnull } + { "{\textnormal{Bd.}}" volume tie.or.space.connect emphasize "volume" output.check } + if$ + format.address.publisher.year "publisher" output.check + new.sentence + format.series.number.din output.nonnull + pages set.period.dash.check + format.pages.book output + note set.period.dash.check + note output + isbn set.period.dash.check + issn set.period.dash.check + format.isbn.issn output + fin.entry +} + +%% geaendert 23/2/94 auch fuer Firmenschriften u."a. zu benutzen +FUNCTION {techreport} +{ output.bibitem + author empty$ + { format.editors "author and editor" output.check } + { format.authors format.editors output.nonnull } + if$ + set.colon.after + format.title "title" output.check + institution new.sentence.checka + institution empty$ + 'skip$ + { " / " institution * output.nonnull } + if$ + format.address.publisher.year output + number new.sentence.checka + format.tr.number.din "number" output.check +%% new.sentence + pages set.period.dash.check + format.pages.book output + note "note" output.check + isbn set.period.dash.check + issn set.period.dash.check + format.isbn.issn output + fin.entry +} + +FUNCTION {unpublished} {misc}%% author, title, note muessen sein! howpublished +%% %% entfaellt natuerlich +FUNCTION {default.type} { misc } + +MACRO {jan} {"Januar"} + +MACRO {feb} {"Februar"} + +MACRO {mar} {"M{\^^b a}rz"} +%% nach Bernd Raichle, Febr. 1999 + +MACRO {apr} {"April"} + +MACRO {mai} {"Mai"} + +MACRO {may} {"Mai"} + +MACRO {jun} {"Juni"} + +MACRO {jul} {"Juli"} + +MACRO {aug} {"August"} + +MACRO {sep} {"September"} + +MACRO {okt} {"Oktober"} + +MACRO {oct} {"Oktober"} + +MACRO {nov} {"November"} + +MACRO {dez} {"Dezember"} + +MACRO {dec} {"Dezember"} + +%% stillgelegte Beispiele fuer den Gebrauch von Kuerzeln (hier Zs-Titel). + +%%MACRO {acmcs} {"ACM Computing Surveys"} + +%%MACRO {acta} {"Acta Informatica"} + +%%MACRO {cacm} {"Communications of the ACM"} + +%%MACRO {ibmjrd} {"IBM Journal of Research and Development"} + +%%MACRO {ibmsj} {"IBM Systems Journal"} + +%%MACRO {ieeese} {"IEEE Transactions on Software Engineering"} + +%%MACRO {ieeetc} {"IEEE Transactions on Computers"} + +%%MACRO {ieeetcad} +%% {"IEEE Transactions on Computer-Aided Design of Integrated Circuits"} + +%%MACRO {ipl} {"Information Processing Letters"} + +%%MACRO {jacm} {"Journal of the ACM"} + +READ + +FUNCTION {sortify} +{ purify$ + "l" change.case$ +} + +INTEGERS { len } + +FUNCTION {chop.word} +{ 's := + 'len := + s #1 len substring$ = + { s len #1 + global.max$ substring$ } + 's + if$ +} + +INTEGERS { et.al.char.used } + +FUNCTION {initialize.et.al.char.used} +{ #0 'et.al.char.used := +} + +EXECUTE {initialize.et.al.char.used} + +FUNCTION {format.lab.names} +{ 's := + s num.names$ 'numnames := + numnames #1 > + { numnames #4 > + { #3 'namesleft := } + { numnames 'namesleft := } + if$ + #1 'nameptr := + "" + { namesleft #0 > } + { nameptr numnames = + { s nameptr "{ff }{vv }{ll}{ jj}" format.name$ "others" = +%% { "\," * %% kein besonderes Zeichen fuer "others" i. label + { "{\etalchar{+}}" * %% ein plus-Zeichen (+) fuer "others"! + #1 'et.al.char.used := + } +%% { s nameptr "{v{}}{l{}}" format.name$ * } + { s nameptr "{l{}}" format.name$ * } + if$ + } +%% { s nameptr "{v{}}{l{}}" format.name$ * } + { s nameptr "{l{}}" format.name$ * } + if$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ + numnames #4 > +%% { "\," * %% s. Bemerkung oben + { "{\etalchar{+}}" * + #1 'et.al.char.used := + } + 'skip$ + if$ + } +%% { s #1 "{v{}}{l{}}" format.name$ + { s #1 "{l{}}" format.name$ + duplicate$ text.length$ #2 < + { pop$ s #1 "{ll}" format.name$ #3 text.prefix$ } %% vgl. Anmerkung! + 'skip$ + if$ + } + if$ +} +%% Anmerkung, Lo 14/12/95: +%% wenn man in der letzten label-Bearbeitung #4 statt #3 setzt, dann werden +%% auch Umlaute oder á an 3. Stelle im Namen korrekt in das label genommen. +%% Tip: Aendere diese Zahl nur, wenn in einer Lit.-Liste der Umlautsonderfall +%% stoerend auffaellt. + +FUNCTION {author.key.label} +{ author empty$ + { key empty$ + { cite$ #1 #3 substring$ } + { key #3 text.prefix$ } + if$ + } + { author format.lab.names } + if$ +} + +FUNCTION {author.editor.key.label} +{ author empty$ + { editor empty$ + { key empty$ + { cite$ #1 #3 substring$ } + { key #3 text.prefix$ } + if$ + } + { editor format.lab.names } + if$ + } + { author format.lab.names } + if$ +} + +FUNCTION {author.key.organization.label} +{ author empty$ + { key empty$ + { organization empty$ + { cite$ #1 #3 substring$ } + { "The " #4 organization chop.word #3 text.prefix$ } + if$ + } + { key #3 text.prefix$ } + if$ + } + { author format.lab.names } + if$ +} +%% neu 19/5/99 damit eigene labels fuer Konferenzen erzeugt werden koennen, +%% darf man zusaetzlich auch ein key-Feld eingeben. Das produziert +%% dann vorrangig das label. +FUNCTION {editor.key.organization.label} +{ editor empty$ + { key empty$ + { organization empty$ + { cite$ #1 #3 substring$ } + { "The " #4 organization chop.word organization } %% Lo, 26/1/98 +%% { "The " #4 organization chop.word #3 text.prefix$ } + if$ + } + { key #5 text.prefix$ }%% man kann Laenge des key einstellen + if$ + } + { key empty$%% wenn key vh., dann macht er das label! Lo,18/5/99 + { editor format.lab.names } + { key #5 text.prefix$ } + if$ + } + if$ +} + +FUNCTION {calc.label} +{ type$ "book" = + type$ "inbook" = + or + 'author.editor.key.label + { type$ "proceedings" = + 'editor.key.organization.label + { type$ "manual" = + 'author.key.organization.label + 'author.key.label + if$ + } + if$ + } + if$ + duplicate$ + year field.or.null purify$ #-1 #2 substring$ + * + 'label := + year field.or.null purify$ #-1 #4 substring$ + * + sortify 'sort.label := +} + +FUNCTION {sort.format.names} +{ 's := + #1 'nameptr := + "" + s num.names$ 'numnames := + numnames 'namesleft := + { namesleft #0 > } + { nameptr #1 > + { " " * } + 'skip$ + if$ +% s nameptr "{vv{ } }{ll{ }}{ ff{ }}{ jj{ }}" format.name$ 't := +% +% Zeile geaendert, damit die Namenszusaetze wie von, de usw nach deutscher +% Norm richtig einsortiert werden. 27.10.94 Lueddecke +% + s nameptr "{ll{ }}{ ff{ }}{ vv{ }}{ jj{ }}" format.name$ 't := + nameptr numnames = t "others" = and + { "[u.~a.]" * } + %% { "et al" * }% Geschmackssache + { t sortify * } + if$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ +} + +FUNCTION {sort.format.title} +{ 't := + "A " #2 + "An " #3 + "Der " #4 + "Die " #4 + "Das " #4 + "Ein " #4 + "Eine " #5 + "The " #4 t chop.word + chop.word + chop.word + chop.word + chop.word + chop.word + chop.word + chop.word + sortify + #1 global.max$ substring$ +} + +FUNCTION {author.sort} +{ author empty$ + { key empty$ + { "to sort, need author or key in " cite$ * warning$ + "" + } + { key sortify } + if$ + } + { author sort.format.names } + if$ +} + +FUNCTION {author.editor.sort} +{ author empty$ + { editor empty$ + { key empty$ + { "to sort, need author, editor, or key in " cite$ * warning$ + "" + } + { key sortify } + if$ + } + { editor sort.format.names } + if$ + } + { author sort.format.names } + if$ +} + +FUNCTION {author.organization.sort} +{ author empty$ + { organization empty$ + { key empty$ + { "to sort, need author, organization, or key in " cite$ * warning$ + "" + } + { key sortify } + if$ + } + { "The " #4 organization chop.word sortify } + if$ + } + { author sort.format.names } + if$ +} + +FUNCTION {editor.organization.sort} +{ editor empty$ + { organization empty$ + { key empty$ + { "to sort, need editor, organization, or key in " cite$ * warning$ + "" + } + { key sortify } + if$ + } + { "The " #4 organization chop.word sortify } + if$ + } + { editor sort.format.names } + if$ +} + +FUNCTION {presort} +{ calc.label + sort.label + " " + * + type$ "book" = + type$ "inbook" = + or + 'author.editor.sort + { type$ "proceedings" = + 'editor.organization.sort + { type$ "manual" = + 'author.organization.sort + 'author.sort + if$ + } + if$ + } + if$ + * + " " + * + year field.or.null sortify + * + " " + * + title field.or.null + sort.format.title + * + #1 entry.max$ substring$ + 'sort.key$ := +} + +ITERATE {presort} + +SORT + +STRINGS { longest.label last.sort.label next.extra } + +INTEGERS { longest.label.width last.extra.num } + +FUNCTION {initialize.longest.label} +{ "" 'longest.label := + #0 int.to.chr$ 'last.sort.label := + "" 'next.extra := + #0 'longest.label.width := + #0 'last.extra.num := +} + +FUNCTION {forward.pass} +{ last.sort.label sort.label = + { last.extra.num #1 + 'last.extra.num := + last.extra.num int.to.chr$ 'extra.label := + } + { "a" chr.to.int$ 'last.extra.num := + "" 'extra.label := + sort.label 'last.sort.label := + } + if$ +} + +FUNCTION {reverse.pass} +{ next.extra "b" = + { "a" 'extra.label := } + 'skip$ + if$ + label extra.label * 'label := + label width$ longest.label.width > + { label 'longest.label := + label width$ 'longest.label.width := + } + 'skip$ + if$ + extra.label 'next.extra := +} + +EXECUTE {initialize.longest.label} + +ITERATE {forward.pass} + +REVERSE {reverse.pass} + +FUNCTION {begin.bib}%%lt. Original wiederhergestellt 4/1/96 +{ et.al.char.used + { "\newcommand{\etalchar}[1]{$^{#1}$}" write$ newline$ } + 'skip$ + if$ + preamble$ empty$ + 'skip$ + { preamble$ write$ newline$ } + if$ + "\begin{thebibliography}{" longest.label * "}" * write$ newline$ +} + +EXECUTE {begin.bib} + +EXECUTE {init.state.consts} + +ITERATE {call.type$} + +FUNCTION {end.bib} +{ newline$ + "\end{thebibliography}" write$ newline$ +} + +EXECUTE {end.bib} + +%% Ende von ALPHADIN.BST KFL, 23/11/99 diff --git a/isr-eclipse-plugin/TeX/natbib.cfg b/isr-eclipse-plugin/TeX/natbib.cfg new file mode 100644 index 0000000000000000000000000000000000000000..32ed930dba3820fe78ce364698598609633c5613 --- /dev/null +++ b/isr-eclipse-plugin/TeX/natbib.cfg @@ -0,0 +1,19 @@ +% NATBIB.CFG in Verbindung mit natbib.sty +% Lorenzen, 2006-01-02 +% diese Konfigurationsdatei wird zuletzt eingelesen und +% enth"alt die lokal gew"unschten Einstellungen f"ur den +% Bibliographie-- und Zitierstil + +\newcommand{\bibstyle@natdin}% + {\bibpunct{(}{)}{;}{a}{}{,~} + \gdef\NAT@biblabelnum##1{\textbf{##1}\\}} +%% nach dieser Definition wird das label (dinatlabel) fett geschrieben, dann Zeilenumbruch; +%% darunter der bibliographische Beleg + + +\bibstyle@natdin + +%% Einzug der Belege nach der Einordnungsmarke +\setlength{\bibhang}{7mm} + + diff --git a/isr-eclipse-plugin/TeX/natdin.bst b/isr-eclipse-plugin/TeX/natdin.bst new file mode 100644 index 0000000000000000000000000000000000000000..ca88f322608902e74461d9719895849cf322691f --- /dev/null +++ b/isr-eclipse-plugin/TeX/natdin.bst @@ -0,0 +1,2234 @@ +%% natdin.bst Vers. [3.1] 2006-01-02 mit PWD cite-multimode +%% +%% Aenderungen seit Vers. [3.0bx]: +%% a) Funktions-Zusaetze bei Autoren sind nun moeglich +%% b) Internetquellen ohne Zusatz "Online--Ressource" ! +%% c) verbesserte INPROCEEDINGS, PROCEEDINGS-Funktionen +%% d) neue TECHREPORT und MANUAL-Funktionen +%% e) neue format.pages.book-Funktion +%% f) neue format.online.lastchecked-Funktion +%% +%% +%% K.F.Lorenzen (Copyright 1994-2006) email: lorenzen.marxen@t-online.de +%% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +%% Mit diesem BibTex-style werden Literaturverzeichnisse nach dem deutschen +%% Standard DIN 1505, Teil 2 und 3 formatiert. Die label im Quellen-/ +%% Literaturverzeichnis sind vom Typ 'Verfasser - Jahr' und +%% entsprechen den Zitatformen im Text. Es koennen alle von +%% Patrick W. Daly im natbib-Paket implementierten Zitierbefehle +%% genutzt werden. Eine Kurzbeschreibung liegt als Datei natnotes.pdf zusammen +%% mit der im Aufbau befindlichen Beschreibung des natdin-Stils +%% unter der URL http://www.haw-hamburg.de/pers/Lorenzen/bibtex. +%% Eine Anleitung zur Anwendung der Norm DIN 1505 findet sich unter der +%% URL http://www.bui.haw-hamburg.de/pers/klaus.lorenzen/ASP/litverz.pdf +%% +%% Es werden nun auch Elektronische Online / Offline Ressourcen wie +%% Internetquellen, CD-ROM usw. verarbeitet. Dazu kommen spezielle +%% Publikationsformen wie Patente, Normen, Karten, Fernsehaufzeichnungen, +%% Gesetzesstellen, Spiele u.a. +% +%% NATDIN.BST muss zusammen mit NATBIB.STY von Patrick W. Daly und der in +%% dieser Verteilung modifizierten Konfiguration NATBIB.CFG aufgerufen +%% werden. NATDIN.BST ist vorzugsweise in den ...\bibtex\bst - Pfad zu +%% stellen. Die jeweils individuelle Konfiguration NATBIB.CFG wird am +%% besten in das Verzeichnis der LaTex-Quelle selbst gelegt. +%% +%% Eine Muster-Konfiguration wird auf Vorschlag von Helge Baumann eingefuegt: +% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +% NATBIB.CFG in Verbindung mit natbib.sty Lorenzen, 2005-05-31 +% diese Konfigurationsdatei wird zuletzt eingelesen und +% enthaelt die lokal gewuenschten Einstellungen fuer den +% Bibliographie-- und Zitierstil +% +% \newcommand{\bibstyle@natdin}% +% {\bibpunct{(}{)}{;}{a}{}{,~} +% \gdef\NAT@biblabelnum##1{\textbf{##1}\\}} %% \\ bewirkt Zeilenumbruch +% %% nach label-Ausgabe +% +% \bibstyle@natdin +% +% % Einzug der Belege nach der Einordnungsmarke +% \setlength{\bibhang}{7mm} +% +%% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +%% +%% Zur Gewaehrleistung der Allgemeingueltigkeit von bib-files gelten +%% in den DIN-styles mit einer einzigen Ausnahme die in der Tex-Literatur +%% veroeffentlichten originalen Definitionen und Regeln fuer die +%% Publikationstypen (entry-types) und die bibliographischen Felder (fields). +%% Die Ausnahme bezieht sich auf den entry-type PROCEEDINGS und das Feld +%% address, fuer das Oren Patashnik dort die Sonderbedeutung "Konferenzort" +%% gewaehlt hatte. In den DIN-Stilen behaelt address auch hier seine normale +%% Bedeutung als "Verlagsort" bei! +%% In einigen entry-types werden zu Gunsten bibliographischer Vollstaendigkeit +%% mehr optionale Felder verwendet als seinerzeit von Patashnik angegeben. +%% Treten "Schoenheitsfehler" im fertig gesetzten output auf, +%% lassen sich diese so gut wie immer durch eine veraenderte +%% Erfassung im bib-inputfile beseitigen. Oren Patashnik empfiehlt, die +%% Definition der Felder weit auszulegen. Last but not least koennen +%% Sie im output-file < *.bbl > noch letzte Hand zur Korrektur ansetzen. +%% Wegen der meist langen Internetadressen kann es zu "unschoenen" Luecken +%% im Belegtext kommen. Dann muss mit \underfull hbox.... gekaempft werden. +%% +%% Die Darstellung von Internetadressen wird durch das Zusatzpaket +%% url.sty ver 3.1, 15-Mar-2004 von Donald Arseneau erheblich verbessert und +%% wird sehr empfohlen. +%% +%% HYPERREF-Paket: wird dieses Paket zusaetzlich geladen, werden im output +%% aktivierbare externe (URLs usw.) und interne (Dokumentbezogene) Links +%% gesetzt. Sehr gute Zusammenarbeit mit PDFLaTex u.a. +% +%% WARN- UND FEHLERMELDUNGEN +%% Ursache von Warnmeldungen sind meistens ausgelassene Felder oder +%% Erfassungs-"Fehler". Letztere haengen teilweise mit den gegenueber US- +%% Gepflogenheiten andersartigen bibliographischen Regeln nach DIN 1505 +%% zusammen. Sie sind also in Wahrheit keine "Fehler" und duerfen fast immer +%% ignoriert werden. Dennoch pruefen Sie diese Warnungen, um heraus zu finden, +%% ob Publikationstyp (=entry-type) und "fields" eventuell unzulaessig +%% kombiniert worden sind. +%% Echte Fehler ("errors") duerften nur noch bei bibliographisch falscher +%% Erfassung auftreten. Pruefen Sie die Syntax, den entry-type und die fields. +%% Zu guter letzt: Qualitaetsmasstab ist einzig der DIN-konforme output! +%% +%% DANKSAGUNG +%% Hartmut Lueddecke, HAW Hamburg, hat viele Verbesserungsvorschlaege +%% in die frueheren Versionen eingebracht. Ihm danke ich herzlich. +%% Patrick W. Daly, dem Entwickler des Natbib-Stils, verdanke ich viele +%% Anregungen und den steten Ansporn, die DIN-Stile zu verbessern. +%% Helge Baumann hatte mit seiner Weiterentwicklung meines alten natdin.bst +%% zu dinat.bst (Vers. 2001) die volle Zitierkapazitaet des natbib-Pakets +%% eingefuehrt. Damit war ein deutlicher Zugewinn erreicht. Von ihm stammt +%% der in der vorliegenden natdin.bst-Version 3.0x neu eingefuehrte Befehl +%% \dinatlabel unter seinem von H. Baumann vergebenen Namen. +%% Viele an dieser Stelle ungenannt bleibende Anwender haben mich in +%% den vergangenen Jahren auf Fehler oder Verbesserungsmoeglichkeiten +%% aufmerksam gemacht und so diesen Stil mitentwickelt. Ihnen gilt mein +%% besonderer Dank. Ihr Feedback ist immer willkommen und eine Ermunterung. +%% +%% Klaus F. Lorenzen +%% +%% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +%% version 0.99c for BibTeX versions 0.99c or later, LaTeX2e version +%% Copyright (C) 1985, all rights reserved. +%% Copying of this file is authorized only if either +%% (1) you make absolutely no changes to your copy, including name, or +%% (2) if you do make changes, you name it something other than +%% natdin.bst, natbib.sty +%% This restriction helps ensure that all standard styles are identical. +%% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +%% +%% NEUE FELDER +%% Zur Erfassung von Internetquellen, E-mail u.a. gibt es folgende +%% neue Felder: doi, lastchecked (nach Gray), url, urn +%% Internetquellen (z.B. auch E-mail) werden vorzugsweise mit dem +%% BOOKLET-Typ erfasst. +%% Normen, Patente, Schutzrechte, Gesetzesstellen sind mit dem MISC-Typ +%% zu erfassen. +%% + + +ENTRY + { address %% Verlagsort (immer!) + author %% persoenlicher Urheber eines Werkes oder am Zustandekommen + %% beteiligte Personen(=Mitarbeiter, Uebersetzer, Redakteur u.a.) + booktitle %% a) Gesamttitel eines mehrbaendigen Werkes +% %% b) Titel des Sammelwerks, das einzelne selbstaendige +% %% Beitraege mit eigenem Titel enthaelt ->incollection + chapter %% Kapitel in einem Buch (Monographie) + doi %%% Digital Object Identifier ->article + edition %% a) Auflagevermerk +% %% b) bei selbst. elektron. Quellen == Version ->booklet + editor %% Persoenl.Herausgeber oder Koerperschaftlicher Herausgeber + howpublished %% beliebiger Verlegervermerk: veroeffentlicht "von wem, wo" + institution %% Institution, die e.verlagsfreie Veroeffentlichung betreibt + isbn %% Standardnr fuer Buecher + issn %% - " - : Zeitschriften u. Serien + journal %% Titel einer Zeitschrift + key %% Zusaetzlich vergebener Sortierschluessel, mitunter notwend. + lastchecked %% neues Feld fuer das Datum des Online-Abrufs +% %% einer Internetquelle (n. GRAY ) + month %% naehere Bestimmung des Erscheinungsjahres -> macro 's + note %% freies Eingabefeld fuer zusaetzliche Informationen z. Quelle + number %% Versch. Bedeutungen in Abhaengigkeit vom Eingabetyp: +% %% a) Bandnummer einer gezaehlten Reihe (series) +% %% b) Heftnummer einer Zeitschrift ->article +% %% c) Nummer eines Forschungsberichts ->techreport + organization %% a) Name der Organisation/des Organisators e. Tagung,Konferenz +% %% b) Name einer Firma/Gesellschaft, die ein ->manual herausgab + pages %% Umfangsangaben, meist Seitenzahlen + publisher %% Verlag + school %% Hochschule/Universitaet, die eine Dipl.-Arb./Dissertation veroeff. + series %% Titel e.Reihe, in der ein best. Buchtitel erschienen ist + title %% Titel einer (namentlich gekennzeichneten) Veroeffentlichung + type %% Zusatzfeld z.Kennzeichnung e.besonderen Publikationstyps + url %% neues Feld URL ( Uniform Resource Locator ): +% %% Serveradresse einer Internetquelle + urn %% neues Feld URN ( Uniform Resource Name ): +% %% Persistent Identifier einer Internetquelle + volume %% a) Zaehlung bei einem mehrbaendigen Werk ->book/->proceedings +% %% b) Jahrgang einer Zeitschrift ->article + year %% Erscheinungsjahr + } + {} + { label extra.label sort.label short.list dinat.label} + +%%%---------------------------------------------------------------------------- +% Einige Standardvorgaben, die vom Benutzer veraendert werden koennen. +%%%---------------------------------------------------------------------------- + +% Abkuerzung ("... und andere") bei Mehrverfasserquellen: + +FUNCTION { ua.etal } { " u.\,a." } %% evtl. auch in eckigen Klammern " [u.\,a.]" + +%% oder lateinisch: FUNCTION { ua.etal } { " et~al." } + +FUNCTION { und } { " und " } + +%% oder ausgeschrieben: FUNCTION { und } { " und " } + + +% Einige elektronische Medien erhalten nach DIN 1505 eine "Ergaenzende Angabe" +% zusaetzlich zum materiellen Typ, z.B. CD ROM oder DVD u.a.: + +FUNCTION { eress } { "Elektronische Ressource" } +%%%----------------------------------------------------------------------------------- + +INTEGERS { output.state before.all mid.sentence after.sentence after.block } + +INTEGERS { after.firstblock } + +INTEGERS { colon.after period.dash } + +INTEGERS { zahl lang } + +INTEGERS { len } + +INTEGERS { longest.label.width last.extra.num number.label } + +INTEGERS { nameptr namesleft numnames } + +INTEGERS { ptr collation collrest } + +STRINGS { longest.label last.label next.extra } + +STRINGS { h s t u v w } + +STRINGS { fkt } + +%%--------------------------- + +FUNCTION {init.state.consts} +{ #0 'before.all := + #1 'mid.sentence := + #2 'after.sentence := + #3 'after.block := + #4 'colon.after := + #5 'period.dash := + #6 'after.firstblock := +} + + + +FUNCTION {set.period.dash} %% Wenn ein ". - " die Satzteile trennen soll.! +{ output.state before.all = + 'skip$ + { period.dash 'output.state := } + if$ +} + + +FUNCTION {set.period.dash.check} +{ empty$ + 'skip$ + 'set.period.dash + if$ +} + +FUNCTION {set.colon.after} %%$$$ Wenn ein ": " d. Satzteile trennen soll! +{ output.state before.all = + 'skip$ + { colon.after 'output.state := } + if$ +} + +%% Wenn ein " " die Satzteile trennen soll.! +FUNCTION {new.sentence} +{ output.state before.all = + 'skip$ + { after.sentence 'output.state := } + if$ +} + +%% neu 17/2/94 Wenn ein ", " die Satzteile trennen soll.! +FUNCTION { part.of.sentence } +{ output.state before.all = + 'skip$ + { mid.sentence 'output.state := } + if$ +} + +FUNCTION {new.sentence.checka} +{ empty$ + 'skip$ + 'new.sentence + if$ +} + +FUNCTION {output.nonnull} +{ 's := + output.state after.block = + { add.period$ write$ + newline$ + "\newblock " write$ + } + { output.state before.all = + { write$ } + { output.state colon.after = + { ": " * write$ + newline$ + "\newblock " write$ + } + { output.state period.dash = + { ". -- " * write$ + newline$ + "\newblock " write$ + } + { output.state mid.sentence = + { ", " * write$ } + { output.state after.sentence = + { " " * write$ } + { output.state after.firstblock = + { add.period$ write$ + newline$ + "\newblock " write$ + } + { write$ + newline$ + "\newblock " write$ + } + if$ + } + if$ + } + if$ + } + if$ + } + if$ + } + if$ + after.block 'output.state := + } + if$ + s + } + +FUNCTION {output} +{ duplicate$ empty$ + 'pop$ + 'output.nonnull + if$ +} + +FUNCTION {output.check} +{ 't := + duplicate$ empty$ + { pop$ "empty " t * " in " * cite$ * warning$ } + 'output.nonnull + if$ +} + +FUNCTION {new.block} +{ output.state before.all = + 'skip$ + { after.block 'output.state := } + if$ +} + +FUNCTION {not} +{ { #0 } + { #1 } + if$ +} + +FUNCTION {and} +{ 'skip$ + { pop$ #0 } + if$ +} + +FUNCTION {or} +{ { pop$ #1 } + 'skip$ + if$ +} + +FUNCTION {format.date} +{ year duplicate$ empty$ + { "empty year in " cite$ * warning$ + pop$ "" } + 'skip$ + if$ + month empty$ + 'skip$ + { type$ "book" = + type$ "inbook" = + OR + 'skip$ + { month " " * swap$ * } + if$ + } + if$ +%% ohne Extrabuchstabe beim Erscheinungsjahr +} + +FUNCTION {format.edition.or.date} +{ edition empty$ year empty$ and + { "" } + { edition empty$ + { type empty$ NOT + { type #-1 #4 substring$ "mail" = + type #1 #4 substring$ "Mail" = + OR + { " gesendet: " "-- " type * swap$ * + format.date * + } + { "\,Version:\," + format.date * + } + if$ + } + { "\,Version:\," + format.date * + } + if$ + } + { year empty$ + { "\,Version:\," edition * } + { "\,Version:\," edition * ", " * + format.date * + } + if$ + } + if$ + } + if$ +} + +FUNCTION {format.online.lastcheck} +{ lastchecked empty$ + { url empty$ doi empty$ urn empty$ and and + { skip$ } + { "" output } + if$ + } + { url empty$ doi empty$ urn empty$ and and + { "there's a lastchecked date but no url, urn or doi in " + cite$ * warning$ + } + { part.of.sentence + lastchecked "Abruf: " swap$ * output + } + if$ + } + if$ +} + +FUNCTION {format.maillist.lastcheck} + { type empty$ NOT + { type #-1 #4 substring$ "mail" = + type #1 #4 substring$ "Mail" = + OR + { format.online.lastcheck } + 'skip$ + if$ + } + 'skip$ + if$ + } + +FUNCTION {format.doi} +{ doi empty$ + { "" } + { new.block "\url{http://dx.doi.org/" doi * "}" * + %% { new.block "\url{http://dx.medra.org/" doi * "}" * + } + if$ +} + +FUNCTION {format.url} +{ urn missing$ + { doi missing$ + { url empty$ + { "" } + { type empty$ NOT + { type #-1 #4 substring$ "mail" = + type #1 #4 substring$ "Mail" = + OR + { type$ "incollection" = + { "" } + { "\,Absenderadresse: \url{" url * "}" * } + if$ + } + { "\url{" url * "}" * }%% evtl. "URL" oder "<...>" + if$ + } + { "\url{" url * "}" * } %% evtl. "URL" oder "<...>" + if$ + } + if$ + } + { format.doi } + if$ + } + { "\url{http://nbn-resolving.de/urn/resolver.pl?urn=" urn * "}" * + } + if$ +} + +FUNCTION {format.maillist.url} + { url empty$ + { "" } + { type empty$ + { "" } + { type #-1 #4 substring$ "mail" = + type #1 #4 substring$ "Mail" = + OR + { "\url{" url * "}" * } + { "" } + if$ + } + if$ + } + if$ + } + + +FUNCTION {format.full.names} +{'s := + #1 'nameptr := + s num.names$ 'numnames := + numnames 'namesleft := + { namesleft #0 > } + { s nameptr + "{vv~}{ll}" format.name$ 't := + nameptr #1 > + { + namesleft #1 > + { ", " * t * } + { + numnames #2 > + { "," * } + 'skip$ + if$ + t "others" = + { ua.etal * } + { und * t * } + if$ + } + if$ + } + 't + if$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ +} + +FUNCTION {author.editor.full} +{ author empty$ + { editor empty$ + { "" } + { editor format.full.names } + if$ + } + { author format.full.names } + if$ +} + +FUNCTION {author.full} +{ author empty$ + { "" } + { author format.full.names } + if$ +} + +FUNCTION {editor.full} +{ editor empty$ + { "" } + { editor format.full.names } + if$ +} + +FUNCTION {make.full.names} +{ type$ "book" = + type$ "inbook" = + or + 'author.editor.full + { type$ "proceedings" = + 'editor.full + 'author.full + if$ + } + if$ +} + + +FUNCTION {output.bibitem} +{ newline$ + "\bibitem[" write$ + label write$ + ")" make.full.names duplicate$ short.list = + { pop$ } + { * } + if$ + "]{" * write$ + cite$ write$ + "}" write$ + newline$ + "\dinatlabel{" dinat.label * "} " * %% Zeilenumbruch steht in NATBIB.CFG! + write$ + "" + before.all 'output.state := +} + + +FUNCTION {fin.entry} +{ write$ + newline$ +} + +FUNCTION {field.or.null} +{ duplicate$ empty$ + { pop$ "" } + 'skip$ + if$ +} + +FUNCTION {emphasize} +{ duplicate$ empty$ + { pop$ "" } + { "\emph{" swap$ * "}" * } + if$ +} + +FUNCTION { capitalize } + { duplicate$ empty$ + { pop$ "" } + { "\textsc{" swap$ * "}" * } + if$ +} + +FUNCTION {article.in.journal} +{ duplicate$ empty$ + { pop$ "" } + { author missing$ title missing$ and + { emphasize } + { emphasize "{In: }" swap$ * } + if$ + } + if$ +} + +FUNCTION {format.names} +{ 's := + "" 'u := + #1 'nameptr := + s num.names$ 'numnames := + numnames 'namesleft := + { namesleft #0 > } + { + s nameptr "{ll}" format.name$ 't := + t capitalize 't := + s nameptr "{ jj}" format.name$ 'w := + s nameptr "{, ff}{ vv}{ jj}" format.name$ 'u := + u text.length$ 'lang := + #1 'zahl := + "" 'v := + { zahl lang < } + { u zahl #1 substring$ "~" = + { v "" = + { u #1 zahl #1 - substring$ 'v := } + 'skip$ + if$ + v u zahl #2 substring$ * "." * w * 'v := + } + 'skip$ + if$ + zahl #1 + 'zahl := } + while$ + v "" = + { u 'v := } + 'skip$ + if$ + t v * fkt * 't := + nameptr #1 > + { namesleft #1 > + { " ; " * t * } + { numnames #2 > + { " " * } + 'skip$ + if$ + t "\textsc{others}" = t "\textsc{others} (Hrsg.)" = or + { ua.etal * } + { " ; " * t * } + if$ + } + if$ %% Ende der namesleft-Pruefung + } + 't + if$ %% Ende der nameptr-Pruefung + + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ %% Ende von { namesleft #0 > } ganz oben + "" 'fkt := %% fkt wird zurueckgesetzt +} + +FUNCTION {format.authors} +{ author empty$ + { "" } + { author format.names } + if$ +} + +FUNCTION {format.editors} +{ editor empty$ + { author empty$ + { "empty author and editor in " cite$ * warning$ "" } + 'skip$ + if$ + } + { author empty$ + { " (Hrsg.)" 'fkt := + editor format.names + } + { " (Hrsg.)" 'fkt := + " ; " * editor format.names * + } + if$ + } + if$ + } + +%% 2005-11-11 +FUNCTION { format.authors.organization } +{ type$ "misc" = + { organization empty$ + { author empty$ + { "" } + { author format.names " (Erfinder)" * } + if$ + } + { author empty$ + { organization } + { author format.names " (Erfinder); " * + organization * " (Anmelder)" * + } + if$ + } + if$ + } + { type$ "manual" = + { organization empty$ + { format.authors } + { author empty$ + { organization capitalize " (Hrsg.)" * } + { author format.names } + if$ + } + if$ + } + 'skip$ + if$ + } + if$ +} + +FUNCTION { format.editors.organization } +{ organization empty$ + 'skip$ + { type$ "misc" = + { organization } + { * " ; " * organization " (Veranst.)" *} + if$ + } + if$ +} + +FUNCTION { format.tr.institution } +{ institution empty$ + 'skip$ + { institution capitalize } + if$ +} + +FUNCTION {format.ed.incoll} +{ editor empty$ + { "" } + { " (Hrsg.)" 'fkt := + editor format.names + format.editors.organization + } + if$ +} + + +FUNCTION {format.title} +{ title empty$ + { "" } + { title } %% Text so wie er dasteht im Feld title + if$ +} + +FUNCTION {format.number} +{ number empty$ + { "" } + { number " " * } %% Text so wie er im Feld number steht plus " " + if$ +} + +FUNCTION {format.digital.type} +{ type empty$ + { "" } + { type #-1 #4 substring$ "mail" = + type #1 #4 substring$ "Mail" = + OR + { "" } + { type } %% Typ einer digitalen Ressource in Form einer + %% "Ergaenzenden Angabe", so wie er dasteht; + %% Alternativ kann dieser Text auch in NOTE erfasst werden. + if$ + } + if$ +} + +FUNCTION {n.dashify} +{ 't := + "" + { t empty$ not } + { t #1 #1 substring$ "-" = + { t #1 #2 substring$ "--" = not + { "--" * + t #2 global.max$ substring$ 't := + } + { { t #1 #1 substring$ "-" = } + { "-" * + t #2 global.max$ substring$ 't := + } + while$ + } + if$ + } + { t #1 #1 substring$ * + t #2 global.max$ substring$ 't := + } + if$ + } + while$ +} + +%% Auflagenvermerke gibt man komplett, einschliesslich Abkuerzungen in +%% das Feld edition ein: ---> EDITION= { 3., erw. und verb. Aufl. } +%% oder fremdsprachlich: EDITION= { 2nd edition } + +FUNCTION {format.edition} +{ edition empty$ + { "" } + { edition } + if$ +} + +FUNCTION {format.version.url} +{ url empty$ doi empty$ urn empty$ and and + { type$ "techreport" = + { format.edition } + { "" } + if$ + } + { format.edition.or.date output format.url } + if$ +} + +FUNCTION {format.edition.or.version} +{ url empty$ doi empty$ urn empty$ and and + { format.edition } + { format.edition.or.date } + if$ +} + +FUNCTION {format.address.publisher.year} +{ publisher empty$ + { address empty$ + { year empty$ + { "" } + { year } + if$ + } + { "there's an address but no publisher in " cite$ * warning$ + address ", " * format.date * + } + if$ + } + { address empty$ + { year empty$ + { "neither address nor publication date in " cite$ * warning$ + publisher + } + { publisher ", " * format.date * } + if$ + } + { year empty$ + { address " : " * publisher * } + { address " : " * publisher * ", " * format.date * } + if$ + } + if$ + } + if$ +} + +FUNCTION {format.howpublished} +{ url missing$ urn missing$ doi missing$ AND AND + { howpublished empty$ + { address empty$ + { type empty$ + { "" } + { type #-1 #4 substring$ "mail" = + { "(gesendet: " new.sentence + format.date * ")" * + } + { "" } + if$ + } + if$ + format.date * + } + { address ", " * format.date * } + if$ + } + { address empty$ + { howpublished ", " * format.date * } + { address " : " * howpublished * ", " * format.date * } + if$ + } + if$ + } + { howpublished empty$ + { "" } + { howpublished } + if$ + } + if$ +} + +FUNCTION {format.btitle} +{ title emphasize +} + +FUNCTION {tie.or.space.connect} +{ duplicate$ text.length$ #3 < + { "~" } + { " " } + if$ + swap$ * * +} + +FUNCTION {format.btitle.vol} +{ number empty$ + { series empty$ + { volume empty$ + { title emphasize } + { title emphasize ". Bd." * volume tie.or.space.connect } + if$ + } + { volume empty$ + { title emphasize }%% ein Buch, das zusaetzl. SERIES=Reihentitel besitzt + %% jetzt kommt d. Fall des mehrbaendigen Werkes mit Gesamttitel=SERIES + %% Zaehlung=VOLUME und Bandtitel=TITLE; + { series emphasize ". Bd." * volume tie.or.space.connect + ": " * "{\emph{" * title * "}}" * } + if$ + } + if$%% series-test + } + { title emphasize }%% wenn number ex., dann immer title-Feld + if$%% Ende number-test +} + +FUNCTION {format.series.number.din} +{ volume empty$ + { number empty$ + { series empty$ + { "" } + { "(" series * ")" * } %% d. Seriennr koennte auch gleich hier + %% im SERIES-Feld miterfasst werden + if$ + } + { series empty$ + { "(" number tie.or.space.connect ")" * + "there's a number but no series in " cite$ * warning$ + } + { "(" series * number tie.or.space.connect ")" * } + if$ + } + if$ + } + { series empty$ + { "" } + { type$ "proceedings" = %% Sonderfall, es darf VOLUME und NUMBER ex. ! + type$ "inproceedings" = OR + { number empty$ + { "(" series * ")" * } + { "(" series * number tie.or.space.connect ")" * } + if$ + } + { "" }%% Ausstieg mit Nullstring, s. Kommentar + if$ + }%% bei gezaehlten Reihen MUSS die Reihennr. im Feld NUMBER stehen! + if$ %% wenn also d. Feld VOLUME nicht leer ist, dann liegt ausser bei + %% Typ PROCEEDINGS/INPROCEEDINGS falsche + } %% Erfassung vor und es erfolgt d. Ausstieg mit d. Nullstring! + if$ +} + +FUNCTION {format.tr.series.or.number} +{ number empty$ + { series empty$ + { "" } + { "(" series * ")" * } + if$ + } + { series empty$ + { "(" number * ")" * } + { "(" series * number tie.or.space.connect ")" * } + if$ + } + if$ + } + +FUNCTION {format.misc.series} +{ series empty$ + { "" } + { "(" series * ")" * } + if$ +} + +FUNCTION { format.doi.urn } +{ urn empty$ + { doi empty$ + { "" } + { "DOI" doi n.dashify tie.or.space.connect } + if$ + } + { "URN" urn n.dashify tie.or.space.connect } + if$ +} + +FUNCTION { format.isbn.issn } +{ isbn empty$ + { issn empty$ + { "" } + { "ISSN" issn n.dashify tie.or.space.connect } + if$ + } + { "ISBN" isbn n.dashify tie.or.space.connect } + if$ +} + +FUNCTION {format.pages} +{ pages empty$ + { "" } + { url empty$ + { "S." pages n.dashify tie.or.space.connect } + { pages } + if$ + } + if$ +} + +FUNCTION {format.pages.book} +{ pages empty$ + { "" } + { note empty$ isbn empty$ AND + { "" pages n.dashify tie.or.space.connect " S" * + add.period$ + } + { "" pages n.dashify tie.or.space.connect " S" * + } + if$ + } + if$ +} + +FUNCTION {format.pages.bkcollation} +{ pages empty$ + { "" } + { "" pages n.dashify tie.or.space.connect } + if$ +} + +FUNCTION {format.bkpages.collat.check} +{ 's := + #1 'ptr := + s text.length$ 'collation := + collation #1 = + { format.pages.book } + { + collation 'collrest := + { collrest #0 > } + { s ptr #2 substring$ 't := + t "S." = + { format.pages.bkcollation + #0 'collrest := } + { ptr #1 + 'ptr := + collrest #1 - 'collrest := + #1 collrest = + { format.pages.book } + { skip$ } + if$ + } + if$ + } + while$ + } + if$ +} + +FUNCTION {format.vol.year.num.pages} +{ volume field.or.null + year empty$ + { "there's no year in " cite$ * warning$ } + { " (" year * ")" * * } + if$ + month empty$ + 'skip$ + { ", " month * * } + if$ + number empty$ + 'skip$ + { ", Nr. " number * * } + if$ + pages empty$ + 'skip$ + { duplicate$ empty$ + { pop$ "" } + { title missing$ + { ", " pages format.bkpages.collat.check * *} + { ", " format.pages * *} + if$ + } + if$ + } + if$ +} + +FUNCTION {format.chapter.inbook} +{ duplicate$ empty$ + { pop$ "empty chapter in " cite$ * warning$ } + { type empty$ + { "\emph{Kapitel\/} " swap$ tie.or.space.connect } + { type " " * swap$ * }%% wenn keine bes. Abschnittsform gen. werden soll, + %% koennte e. kl. Zwischenraum gewaehlt werden, z.B. " \, " + if$ + } + if$ +} + +FUNCTION {format.chapter.pages} +{ chapter empty$ + 'format.pages + { type empty$ + { "Kapitel " } + { url empty$ + { type } + { "Kapitel " } + if$ + } + if$ + chapter tie.or.space.connect + pages empty$ + 'skip$ + { ", " * format.pages * } + if$ + } + if$ +} + +FUNCTION {format.in.ed.booktitle.din} +{ booktitle empty$ + { "" } + { editor empty$ + { volume empty$ + { "{In: }" booktitle emphasize * }%% n. Belieben fettes In: + { "{In: }" booktitle emphasize * %% - " - + " Bd." volume tie.or.space.connect * + } + if$ + } + { volume empty$ + { "{In: }" format.ed.incoll * ": " * booktitle emphasize * } + { "{In: }" format.ed.incoll * ": " * booktitle emphasize * + " Bd." volume tie.or.space.connect * + } + if$ + } + if$ + } + if$ +} + +FUNCTION {format.thesis.tr.type} +{ type empty$ + 'skip$ + { pop$ + type + } + if$ +} + +FUNCTION {format.article.crossref} +{ key empty$ + { journal empty$ + { "need key or journal for " cite$ * " to crossref " * crossref * + warning$ + "" + } + { "{In: }{\emph " journal * "}" * }%% n. Belieben fettes In: + if$ + } + { "{In: }" key * }%% s.o. fettes In: + if$ + " {\textbf{\citep{" * crossref * "}" * "}" * "}" * ", " * format.pages * +} + +FUNCTION {format.crossref.editor} +%vorher,Lue { editor #1 "{vv~}{ll}" format.name$ " (Hrsg.)" * + { editor #1 "{ll}" format.name$ " (Hrsg.)" * + editor num.names$ duplicate$ + #2 > + { pop$ ua.etal * } + { #2 < + 'skip$ + { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = + { ua.etal * } + { " ; " * editor #2 "{vv~}{ll}" format.name$ * " (Hrsg.)" * } + if$ + } + if$ + } + if$ +} + +FUNCTION {format.inbk.vol.title} +{ volume empty$ + { " In: " } + { title empty$ + { " In: Bd." volume tie.or.space.connect + " von " * + } + { "In: Bd." volume tie.or.space.connect ": " * title emphasize * + " (" * year * ") in " * + } + if$ + } + if$ + } + +FUNCTION {format.book.crossref} +{ type$ "inbook" = + { format.inbk.vol.title } + { volume empty$ + { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ + " " + } + { ". -- Bd." volume tie.or.space.connect + " von " * + } + if$ + } + if$ + editor empty$ + editor field.or.null author field.or.null = + or + { key empty$ + { series empty$ + { "need editor, key, or series for " cite$ * " to crossref " * + crossref * warning$ + "" * + } + { "" * }%% dadurch kommt nach der Band Nr. gleich das label 2/6/99 +%% { "{\emph{" * series * "}} {\textbf{siehe}} " * } + if$ + } + { key * } + if$ + } + { "" * } + if$ + "{\textbf{\citep{" * crossref * "}" * "}" * "}" * +} + +FUNCTION {format.incoll.inproc.crossref} +{ editor empty$ + editor field.or.null author field.or.null = + or + { key empty$ + { booktitle empty$ + { "need editor, key, or booktitle for " cite$ * " to crossref " * + crossref * warning$ + "" + } + { "{In: }{\emph " booktitle * "}" * }%% + if$ + } + { "{In: }" } + if$ + } + { "{In: }" } + if$ + "{\textbf{\citep{" * crossref * "}" * "}" * "}" * %% ", " * format.pages * +} + +FUNCTION {article} +{ output.bibitem + format.authors "author" output.check + set.colon.after + format.title "title" output.check + crossref missing$ + { journal article.in.journal output.nonnull + new.sentence + format.vol.year.num.pages output + format.url output + } + { format.article.crossref output.nonnull } + if$ + format.online.lastcheck + doi set.period.dash.check + urn set.period.dash.check + format.doi.urn output + issn set.period.dash.check + format.isbn.issn output + note set.period.dash.check + note output + fin.entry +} + +FUNCTION {book} +{ output.bibitem + author empty$ + { format.editors "author and editor" output.check } + { format.authors format.editors output.nonnull } + if$ + set.colon.after + crossref missing$ + { format.btitle.vol "title" output.check } + { format.btitle "title" output.check } + if$ + format.edition output + format.address.publisher.year "publisher" output.check + new.sentence + crossref missing$ + { format.series.number.din output } + { format.book.crossref output.nonnull } + if$ + pages empty$ + { skip$ } + { pages set.period.dash.check + pages format.bkpages.collat.check output + } + if$ + format.doi output + format.url output + new.block + isbn set.period.dash.check + format.isbn.issn output + note set.period.dash.check + note output + fin.entry +} + +FUNCTION {booklet} +{ output.bibitem + author empty$ + { format.editors "author and editor" output.check } + { format.authors format.editors output.nonnull } + if$ + set.colon.after + format.btitle "title" output.check + format.edition.or.version output + format.url output + format.online.lastcheck + format.howpublished output + series new.sentence.checka + format.series.number.din output + pages empty$ + { skip$ } + { pages set.period.dash.check + pages format.bkpages.collat.check output + } + if$ + type set.period.dash.check + format.digital.type output + doi set.period.dash.check + urn set.period.dash.check + format.doi.urn output + note set.period.dash.check + note output + format.isbn.issn output + fin.entry +} + +FUNCTION {inbook} +{ output.bibitem + chapter format.chapter.inbook output.nonnull + crossref missing$ + { author empty$ + { format.editors "\,{In:\,}" swap$ * "author and editor" output.check } + { format.authors "\,{In:\,}" swap$ * output.nonnull } + if$ + author empty$ editor empty$ AND + { before.all 'output.state := } + { set.colon.after } + if$ + format.btitle.vol "title" output.check + format.edition output + format.address.publisher.year "publisher" output.check + new.sentence + format.series.number.din output + isbn set.period.dash.check + format.isbn.issn output + } + { format.book.crossref output.nonnull + } + if$ + part.of.sentence + format.pages output + note set.period.dash.check + note output + fin.entry +} + +FUNCTION {incollection} +{ output.bibitem + format.authors "author" output.check + set.colon.after + format.title "title" output.check + format.version.url output + type empty$ NOT + { type #-1 #4 substring$ "mail" = + type #1 #4 substring$ "Mail" = + OR + 'skip$ + { format.online.lastcheck } + if$ + } + { format.online.lastcheck } + if$ + crossref missing$ + { format.in.ed.booktitle.din "booktitle" output.check + format.edition output + format.address.publisher.year "publisher" output.check + format.maillist.url output + format.maillist.lastcheck + new.sentence + format.series.number.din output + doi set.period.dash.check + urn set.period.dash.check + format.doi.urn output + isbn set.period.dash.check + issn set.period.dash.check + format.isbn.issn output + } + { format.incoll.inproc.crossref output.nonnull } + if$ + part.of.sentence + format.chapter.pages "pages" output.check + note set.period.dash.check + note output + fin.entry +} + +FUNCTION {inproceedings} +{ output.bibitem + format.authors "author" output.check + set.colon.after + format.title "title" output.check + crossref missing$ + { format.in.ed.booktitle.din "booktitle" output.check + address empty$ + { organization new.sentence.checka + organization output + part.of.sentence + format.address.publisher.year output + } + { format.address.publisher.year "publisher" output.check } + if$ + new.sentence + format.series.number.din output + isbn set.period.dash.check + issn set.period.dash.check + format.isbn.issn output + } + { format.incoll.inproc.crossref output.nonnull } + if$ + part.of.sentence + format.pages output + note set.period.dash.check + note output + fin.entry +} + +FUNCTION {conference} { inproceedings }%% nach Patashnik, wg US-Kompatibilitaet + +FUNCTION {manual} +{ output.bibitem + author empty$ + { organization empty$ + { title empty$ + 'skip$ + {format.btitle "title" output.check } + if$ + } + 'skip$ + if$ + } + 'skip$ + if$ + format.authors.organization output.nonnull + set.colon.after + format.btitle "title" output.check + format.edition "edition" output.check + author empty$ organization empty$ AND + { address "address" output.check + part.of.sentence + } + { organization empty$ + { address "address" output.check + part.of.sentence + } + { address ": " * organization * output + part.of.sentence + } + if$ + } + if$ + format.date output + number empty$ + 'skip$ + { "(" number * ") " * output } + if$ + pages empty$ + { skip$ } + { pages set.period.dash.check + pages format.bkpages.collat.check output + } + if$ + format.doi output + format.url output + format.online.lastcheck + note set.period.dash.check + note output + fin.entry +} + +%% Standard ist "Diplomarbeit", anderes mit TYPE="anderer Typ" erfassen! +%% z.B. TYPE={Hausarbeit}, TYPE={Diss.}, TYPE={Habil.}, TYPE={Magisterarb.} +FUNCTION {mastersthesis} +{ output.bibitem + format.authors "author" output.check + set.colon.after + format.btitle "title" output.check + address output + part.of.sentence + school "school" output.check + part.of.sentence + "Diplomarbeit" format.thesis.tr.type output.nonnull + part.of.sentence + format.date "year" output.check + format.url output + format.online.lastcheck + doi set.period.dash.check + urn set.period.dash.check + format.doi.urn output + pages empty$ + { skip$ } + { pages set.period.dash.check + pages format.bkpages.collat.check output + } + if$ + note set.period.dash.check + note output + fin.entry +} + +FUNCTION {phdthesis} %% {mastersthesis}% ist identisch bis auf Standardwert, s.o. +{ output.bibitem + format.authors "author" output.check + set.colon.after + format.btitle "title" output.check + address output + part.of.sentence + school "school" output.check + part.of.sentence + "Diss." format.thesis.tr.type output.nonnull % koennte auch `Dissertation' sein + part.of.sentence + format.date "year" output.check + format.url output + format.online.lastcheck + doi set.period.dash.check + urn set.period.dash.check + format.doi.urn output + pages empty$ + { skip$ } + { pages set.period.dash.check + pages format.bkpages.collat.check output + } + if$ + note set.period.dash.check + note output + fin.entry +} + + +%% Normen, Vornormen, Schutzrechte (Patente) werden hiermit erfasst; +%% E-mail, (auch Internetressourcen moeglich; besser --> booklet-Fkt!) +%% das type-Feld uebernimmt eine wichtige Steuerfunktion: +FUNCTION {misc} +{ output.bibitem + type missing$ not + { type duplicate$ #1 #4 substring$ "Norm" = + type #1 #4 substring$ "Vorn" = OR + { " " * + format.number * output + new.sentence + format.date output + title empty$ + { skip$ } + { add.period$ new.sentence } + if$ + format.btitle "title" output.check + note set.period.dash.check + note output + } + { duplicate$ #1 #6 substring$ "Schutz" = + { " " * format.number * output + new.sentence + "(" * format.date ")" * output + add.period$ new.sentence + format.authors.organization add.period$ output + note output + } + %% wenn irgendein anderer Typ eingetragen ist + { pop$ pop$ "" + title empty$ + { note empty$ + { url empty$ + { "there's no relevant field in " cite$ warning$ + pop$ "" + } + { format.url output }%%% + if$ + } + { note " " * output.nonnull } + if$ + } + { author empty$ + { editor empty$ + { organization empty$ + { skip$ } + { format.editors.organization output.nonnull + set.colon.after + } + if$ + } + { format.editors format.editors.organization + output.nonnull set.colon.after + } + if$ + } + { format.authors format.editors output.nonnull + set.colon.after + } + if$ + format.btitle output.nonnull + url empty$ + { format.edition output + format.howpublished output} + { format.howpublished output + format.edition.or.version output + format.url output + } + if$ + format.online.lastcheck + new.sentence + format.misc.series output + note set.period.dash.check + note output + } + if$ + } + if$ + } + if$ + } + %% wenn es keinen type gibt + { title empty$ + { note empty$ + { url empty$ + { "there's no relevant field in " cite$ warning$ + pop$ "" + } + { format.url output }%%% das waere e. reine URL + if$ + } + { note " " * output.nonnull + } + if$ + } + { author empty$ + { editor empty$ + { organization empty$ + 'skip$ + { format.editors.organization output.nonnull + set.colon.after + } + if$ + } + { format.editors format.editors.organization + output.nonnull set.colon.after + } + if$ + } + { format.authors format.editors output.nonnull + set.colon.after + } + if$ + format.btitle output.nonnull + url empty$ + { format.edition output + format.howpublished output} + { format.howpublished output + format.url output + format.edition.or.date output + format.online.lastcheck + } + if$ + new.sentence + format.misc.series output + note set.period.dash.check + note output + } + if$ + } + if$ + fin.entry +} + +FUNCTION {proceedings} +{ output.bibitem + editor empty$ + { organization empty$ + { "empty organization and editor in " cite$ * warning$ } + { organization " (Veranst.)" * output } + if$ + } + { format.editors format.editors.organization output.nonnull } + if$ + set.colon.after + format.btitle "title" output.check + volume empty$ + 'skip$ + { "{\textnormal{Bd.}}" volume tie.or.space.connect emphasize "volume" output.check } + if$ + format.address.publisher.year "publisher" output.check + new.sentence + format.series.number.din output.nonnull + pages empty$ + { skip$ } + { pages set.period.dash.check + pages format.bkpages.collat.check output + } + if$ + isbn set.period.dash.check + issn set.period.dash.check + format.isbn.issn output + note set.period.dash.check + note output + fin.entry +} + +FUNCTION {techreport} +{ output.bibitem + author empty$ + { format.editors "author and editor" output.check + format.tr.institution output.nonnull } + { format.authors format.editors output.nonnull } + if$ + set.colon.after + format.title "title" output.check + institution empty$ + 'skip$ + { author empty$ editor empty$ AND + 'skip$ + { institution new.sentence.checka + "/ " institution * output.nonnull + } + if$ + } + if$ + format.version.url output + format.online.lastcheck + format.address.publisher.year output + number new.sentence.checka + format.tr.series.or.number "number" output.check + "Forschungsbericht" format.thesis.tr.type set.period.dash.check + "Forschungsbericht" format.thesis.tr.type output + pages empty$ + { skip$ } + { pages set.period.dash.check + pages format.bkpages.collat.check output + } + if$ + isbn set.period.dash.check + issn set.period.dash.check + format.isbn.issn output + note set.period.dash.check + note "note" output.check + fin.entry +} + + +FUNCTION {unpublished} {misc}%% author, title, note muessen sein! howpublished +%% %% entfaellt natuerlich + +FUNCTION {default.type} { misc } + +MACRO {jan} {"Januar"} + +MACRO {feb} {"Februar"} + +MACRO {mar} {"M{\^^b a}rz"} + +MACRO {apr} {"April"} + +MACRO {mai} {"Mai"} + +MACRO {may} {"Mai"} + +MACRO {jun} {"Juni"} + +MACRO {jul} {"Juli"} + +MACRO {aug} {"August"} + +MACRO {sep} {"September"} + +MACRO {okt} {"Oktober"} + +MACRO {oct} {"Oktober"} + +MACRO {nov} {"November"} + +MACRO {dez} {"Dezember"} + +MACRO {dec} {"Dezember"} + +%%$$$ stillgelegte Beispiele fuer den Gebrauch von Kuerzeln (hier Zs-Titel). + +%%MACRO {acmcs} {"ACM Computing Surveys"} + +%%MACRO {acta} {"Acta Informatica"} + +READ + +FUNCTION {sortify} +{ purify$ + "l" change.case$ +} + +FUNCTION {chop.word} +{ 's := + 'len := + s #1 len substring$ = + { s len #1 + global.max$ substring$ } + 's + if$ +} + +FUNCTION {format.lab.names} +{ 's := + s #1 "{vv~}{ll}" format.name$ + s num.names$ duplicate$ + #2 > + { pop$ ua.etal * } + { #2 < + 'skip$ + { s #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = + { ua.etal * } + { und * s #2 "{vv~}{ll}" format.name$ * } + if$ + } + if$ + } + if$ +} + +FUNCTION {author.key.label} +{ author empty$ + { key empty$ + { cite$ #1 #3 substring$ } + 'key + if$ + } + { author format.lab.names } + if$ +} + +FUNCTION {author.editor.key.label} +{ author empty$ + { editor empty$ + { key empty$ + { cite$ #1 #3 substring$ } + 'key + if$ + } + { year empty$ + 'key + { editor format.lab.names } + if$ + } + if$ + } + { author format.lab.names } + if$ +} + +FUNCTION {author.key.organization.label} +{ author empty$ + { key empty$ + { organization empty$ + { cite$ #1 #3 substring$ } + { "The " #4 organization chop.word #3 text.prefix$ } + if$ + } + { key } + if$ + } + { author format.lab.names } + if$ +} + +FUNCTION {editor.key.organization.label} +{ editor empty$ + { key empty$ + { organization empty$ + { cite$ #1 #3 substring$ } + { "The " #4 organization chop.word #4 text.prefix$ } + if$ + } + { key } + if$ + } + { key empty$%% das key-feld soll zwangsweise das label machen! + { editor format.lab.names } + { key }%%das ganze label + if$ + } + if$ +} +FUNCTION {calc.short.authors} +{ type$ "book" = + type$ "booklet" = + type$ "inbook" = + or or + 'author.editor.key.label + { type$ "proceedings" = + 'editor.key.organization.label + { type$ "manual" = + 'author.key.organization.label + 'author.key.label + if$ + } + if$ + } + if$ + 'short.list := +} + +FUNCTION {calc.label} +{ calc.short.authors + short.list + "(" + * +%% year duplicate$ empty$ +%% short.list key field.or.null = or +%% { pop$ "" } +%% 'skip$ +%% if$ + year field.or.null purify$ #1 #4 substring$ + * + 'label := + short.list " " * + year field.or.null purify$ #1 #4 substring$ * 'dinat.label := +} + +FUNCTION {sort.format.names} +{ 's := + #1 'nameptr := + "" + s num.names$ 'numnames := + numnames 'namesleft := + { namesleft #0 > } + { nameptr #1 > + { " " * } + 'skip$ + if$ + s nameptr "{ll{ }}{ ff{ }}{ vv{ }}{ jj{ }}" format.name$ 't := + nameptr numnames = t "others" = and + { ua.etal * } + { t sortify * } + if$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ +} + +FUNCTION {sort.format.title} +{ 't := + "A " #2 + "An " #3 + "Der " #4 + "Die " #4 + "Das " #4 + "Ein " #4 + "Eine " #5 + "The " #4 t chop.word + chop.word + chop.word + chop.word + chop.word + chop.word + chop.word + chop.word + sortify + #1 global.max$ substring$ +} + +FUNCTION {author.sort} +{ author empty$ + { key empty$ + { "to sort, need author or key in " cite$ * warning$ + "" + } + { key sortify } + if$ + } + { author sort.format.names } + if$ +} + +FUNCTION {author.editor.sort} +{ author empty$ + { editor empty$ + { key empty$ + { "to sort, need author, editor, or key in " cite$ * warning$ + "" + } + { key sortify } + if$ + } + { editor sort.format.names } + if$ + } + { author sort.format.names } + if$ +} + +FUNCTION {author.organization.sort} +{ author empty$ + { organization empty$ + { key empty$ + { "to sort, need author, organization, or key in " cite$ * warning$ + "" + } + { key sortify } + if$ + } + { "The " #4 organization chop.word sortify } + if$ + } + { author sort.format.names } + if$ +} + +FUNCTION {editor.organization.sort.PWD}%% so war es in plainnat +{ editor empty$ + { organization empty$ + { key empty$ + { "to sort, need editor, organization, or key in " cite$ * warning$ + "" + } + { key sortify } + if$ + } + { "The " #4 organization chop.word sortify } + if$ + } + { editor sort.format.names } + if$ +} + +FUNCTION {editor.organization.sort}%%das key-Feld soll z. Sortieren ben. werden +{ key empty$ + { editor empty$ + { organization empty$ + { "to sort, need editor, organization, or key in " cite$ * warning$ + "" + } + { "The " #4 organization chop.word sortify } + if$ + } + { editor sort.format.names } + if$ + } + { key sortify } + if$ +} + +FUNCTION {presort} +{ calc.label + label sortify + " " + * + type$ "book" = + type$ "booklet" = + type$ "inbook" = + or or + 'author.editor.sort + { type$ "proceedings" = + 'editor.organization.sort + { type$ "manual" = + 'author.organization.sort + 'author.sort + if$ + } + if$ + } + if$ + " " + * + year field.or.null sortify + * + " " + * + title field.or.null + sort.format.title + * + #1 entry.max$ substring$ + 'sort.label := + sort.label * + #1 entry.max$ substring$ + 'sort.key$ := +} + +ITERATE {presort} + +SORT + +FUNCTION {initialize.longest.label} +{ "" 'longest.label := + #0 int.to.chr$ 'last.label := + "" 'next.extra := + #0 'longest.label.width := + #0 'last.extra.num := + #0 'number.label := +} + +FUNCTION {forward.pass} +{ last.label label = + { last.extra.num #1 + 'last.extra.num := + last.extra.num int.to.chr$ 'extra.label := + } + { "a" chr.to.int$ 'last.extra.num := + "" 'extra.label := + label 'last.label := + } + if$ + number.label #1 + 'number.label := +} + +FUNCTION {reverse.pass} +{ next.extra "b" = + { "a" 'extra.label := } + 'skip$ + if$ + extra.label 'next.extra := + extra.label + duplicate$ empty$ + 'skip$ + { "{\natexlab{" swap$ * "}}" * } + if$ + 'extra.label := + label extra.label * 'label := + dinat.label extra.label * 'dinat.label := +} + +EXECUTE {initialize.longest.label} + +ITERATE {forward.pass} + +REVERSE {reverse.pass} + +FUNCTION {bib.sort.order} +{ sort.label 'sort.key$ := +} + +ITERATE {bib.sort.order} + +SORT + +FUNCTION {begin.bib} +{ preamble$ empty$ + 'skip$ + { preamble$ write$ newline$ } + if$ + "\begin{thebibliography}{" number.label int.to.str$ * "}" * + write$ newline$ newline$ + "% this bibliography is generated by nd24.bst [3.0c2] from 2005-12-21" + write$ newline$ newline$ + "\providecommand{\natexlab}[1]{#1}" + write$ newline$ + "\providecommand{\url}[1]{\texttt{#1}}" + write$ newline$ + "\makeatletter" + write$ newline$ + "\newcommand{\dinatlabel}[1]%" + write$ newline$ + "{\ifNAT@numbers\else\NAT@biblabelnum{#1}\fi}" + write$ newline$ + "\makeatother" + write$ newline$ + "\expandafter\ifx\csname urlstyle\endcsname\relax" + write$ newline$ + " \providecommand{\doi}[1]{doi: #1}\else" + write$ newline$ + " \providecommand{\doi}{doi: \begingroup \urlstyle{rm}\Url}\fi" + write$ newline$ +} + +EXECUTE {begin.bib} + +EXECUTE {init.state.consts} + +ITERATE {call.type$} + +FUNCTION {end.bib} +{ newline$ + "\end{thebibliography}" write$ newline$ +} + +EXECUTE {end.bib} diff --git a/isr-eclipse-plugin/TeX/nomencl.ist b/isr-eclipse-plugin/TeX/nomencl.ist new file mode 100644 index 0000000000000000000000000000000000000000..a5b6b739983e44d09bd11ace0470182a664675e5 --- /dev/null +++ b/isr-eclipse-plugin/TeX/nomencl.ist @@ -0,0 +1,75 @@ +%% +%% This is file `nomencl.ist', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% nomencl.dtx (with options: `idxstyle') +%% +%% Copyright 1996 Boris Veytsman +%% Copyright 1999-2001 Bernd Schandl +%% www http://sarovar.org/projects/nomencl +%% +%% This file can be redistributed and/or modified under the terms +%% of the LaTeX Project Public License distributed from CTAN +%% archives in the directory macros/latex/base/lppl.txt; either +%% version 1.2 of the license, or (at your option) any later version. +%% +%% +%% Nomenclature style file for MAKEINDEX. +%% For nomencl v2.5 (and later) +%% +%% Formats glossary entries to show, e.g. nomenclature of equations. +%% +%% Written by Boris Veytsman boris@plmsc.psu.edu +%% Changed by Bernd Schandl schandl@gmx.net (starting 1999/02/20) +%% Changed by Lee Netherton ltn100@users.sourceforge.net +%% (starting 2005/03/31) +%% +%% Changes: +%% 2005/04/27. Updates to the documentation, including support for hyperref (LN) +%% 2005/04/20. Improvements to Italian option, and minor documentation +%% changes (LN) +%% 2005/03/31. Made more compatible with other glossary packages. (LN) +%% Added option to include nomenclature in TOC. (LN) +%% 1996/11/25. Change quote character to % (BV) +%% 1999/02/20. Removed setting of actual to its default value +%% Removed setting of quote to '%' to get its default '"' instead +%% Changed group_skip to do nothing; user should use \nomgroup +%% Changed spacing in gls file +%% +%% \CharacterTable +%% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z +%% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z +%% Digits \0\1\2\3\4\5\6\7\8\9 +%% Exclamation \! Double quote \" Hash (number) \# +%% Dollar \$ Percent \% Ampersand \& +%% Acute accent \' Left paren \( Right paren \) +%% Asterisk \* Plus \+ Comma \, +%% Minus \- Point \. Solidus \/ +%% Colon \: Semicolon \; Less than \< +%% Equals \= Greater than \> Question mark \? +%% Commercial at \@ Left bracket \[ Backslash \\ +%% Right bracket \] Circumflex \^ Underscore \_ +%% Grave accent \` Left brace \{ Vertical bar \| +%% Right brace \} Tilde \~} +%% +%% ---- for input file ---- +keyword "\\nomenclatureentry" +%% Germans might want to change this and delete the two %% +%% quote '"' +%% ---- for output file ---- +preamble "\\begin{thenomenclature} \n"% +postamble "\n\n\\end{thenomenclature}\n" group_skip "\n" +delim_0 "" +delim_1 "" +delim_2 "" +%% The next lines will produce some warnings when +%% running Makeindex as they try to cover two different +%% versions of the program: +lethead_prefix "\n \\nomgroup{" +lethead_suffix "}\n" +lethead_flag 1 +heading_prefix "\n \\nomgroup{" +heading_suffix "}\n" +headings_flag 1 diff --git a/isr-eclipse-plugin/TeX/symbols-a4.pdf b/isr-eclipse-plugin/TeX/symbols-a4.pdf new file mode 100644 index 0000000000000000000000000000000000000000..ae7de6ebbe285de5c23bfef43d6bba4e2983b4e9 Binary files /dev/null and b/isr-eclipse-plugin/TeX/symbols-a4.pdf differ diff --git a/isr-eclipse-plugin/build.properties b/isr-eclipse-plugin/build.properties new file mode 100644 index 0000000000000000000000000000000000000000..edc4c76f30736ef55f0cefdfca488808c7a67fc6 --- /dev/null +++ b/isr-eclipse-plugin/build.properties @@ -0,0 +1,9 @@ +source.isreditor.jar = src/ +output.isreditor.jar = bin/ +bin.includes = plugin.xml,\ + isreditor.jar,\ + icons/,\ + lib/ +src.includes = lib/xerces.jar,\ + src/IsrGrammarXmlDefinition.dtd +jars.compile.order = isreditor.jar diff --git a/isr-eclipse-plugin/contexts.xml b/isr-eclipse-plugin/contexts.xml new file mode 100644 index 0000000000000000000000000000000000000000..f40113517f6cea937993e9c2e85d416082a8dd39 --- /dev/null +++ b/isr-eclipse-plugin/contexts.xml @@ -0,0 +1,11 @@ +<contexts> + <context id="viewer" title="Isr-grammar-viewer"> + <topic href="/PLUGINS_ROOT/org.eclipse.platform.doc.isv/guide/ua_help_context.htm" label="Context-sensitive help"> + <enablement> + <with variable="platform"> + <test property="org.eclipse.core.runtime.isBundleInstalled" args="org.eclipse.platform.doc.isv"/> + </with> + </enablement> + </topic> + </context> +</contexts> diff --git a/isr-eclipse-plugin/icons/sample.gif b/isr-eclipse-plugin/icons/sample.gif new file mode 100644 index 0000000000000000000000000000000000000000..34fb3c9d8cb7d489681b7f7aee4bdcd7eaf53610 Binary files /dev/null and b/isr-eclipse-plugin/icons/sample.gif differ diff --git a/isr-eclipse-plugin/lib/xerces.jar b/isr-eclipse-plugin/lib/xerces.jar new file mode 100644 index 0000000000000000000000000000000000000000..ff0f8998f8740ed9d07355b12d7e947e5ee6f85c Binary files /dev/null and b/isr-eclipse-plugin/lib/xerces.jar differ diff --git a/isr-eclipse-plugin/lib/xom-1.2.8.jar b/isr-eclipse-plugin/lib/xom-1.2.8.jar new file mode 100644 index 0000000000000000000000000000000000000000..370d40c38efbbbb2ed76e6968b6cece8efe08d8e Binary files /dev/null and b/isr-eclipse-plugin/lib/xom-1.2.8.jar differ diff --git a/isr-eclipse-plugin/plugin.xml b/isr-eclipse-plugin/plugin.xml new file mode 100644 index 0000000000000000000000000000000000000000..78ebb7f359ff086a7cf618a5a166438c10b97cd9 --- /dev/null +++ b/isr-eclipse-plugin/plugin.xml @@ -0,0 +1,387 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?eclipse version="3.0"?> +<plugin> + <extension id="hterhors.editor.isr.editor" point="org.eclipse.ui.editors"> + + <editor id="hterhors.editor.ISREditor" name="ISR-Editor" + class="hterhors.editor.ISREditor" contributorClass="hterhors.editor.ISREditorContributor" + extensions="grm" icon="icons/sample.gif"> + </editor> + </extension> + + <extension id="problemmarker" name="Error Marker" + point="org.eclipse.core.resources.markers"> + <super type="org.eclipse.core.resources.marker" /> + <attribute name="severity" /> + <attribute name="message" /> + <attribute name="location" /> + <persistent value="true" /> + </extension> + + <extension point="org.eclipse.ui.popupMenus"> + + <objectContribution id="hterhors.editor.xmlconverter.converttoxmlaction.contribution" + nameFilter="*.grm" objectClass="org.eclipse.core.resources.IFile"> + <action id="hterhors.editor.xmlconverter.converttoxmlaction" + class="hterhors.editor.xmlconverter.ConvertToXMLAction" + definitionId="hterhors.editor.xmlconverter.converttoxmlaction.definition" + enablesFor="1" + icon="icons/sample.gif" label="Convert to XML" menubarPath="additions"> + </action> + </objectContribution> + </extension> + + <extension point="org.eclipse.ui.perspectives"> + <perspective id="hterhors.editor.perspective.IsrPerspective" + name="Isr Grammar" class="hterhors.editor.perspective.IsrPerspective" + icon="icons/sample.gif"> + </perspective> + </extension> + + <extension point="org.eclipse.ui.views"> + <category id="view" name="Isr-grammar-viewer"> + </category> + + <view id="hterhors.editor.zest.IsrGraphView" name="Isr-grammar-viewer" + category="view" class="hterhors.editor.zest.IsrGraphView" icon="icons/sample.gif"> + </view> + </extension> + + <extension point="org.eclipse.ui.perspectiveExtensions"> + + <perspectiveExtension targetID="org.eclipse.jdt.ui.JavaPerspective"> + + <view id="hterhors.editor.zest.IsrGraphView" ratio="0.9" + relationship="right" relative="org.eclipse.ui.editorss"> + </view> + </perspectiveExtension> + </extension> + + <!--extension point="org.eclipse.help.contexts"> + + <contexts file="contexts.xml"> + </contexts> + </extension--> + + <extension point="org.eclipse.ui.commands"> + + <category id="visualization.category" name="Isr visualization"> + </category> + + <command id="isr.graph.visualization" name="Update graph" + categoryId="visualization.category"> + </command> + </extension> + + <extension point="org.eclipse.ui.handlers"> + + <handler class="hterhors.editor.zest.UpdateGraphHandler" + commandId="isr.graph.visualization"> + </handler> + </extension> + + <extension point="org.eclipse.ui.bindings"> + + <key commandId="isr.graph.visualization" contextId="org.eclipse.ui.contexts.window" + schemeId="org.eclipse.ui.defaultAcceleratorConfiguration" sequence="M1+Shift+V"> + </key> + </extension> + <!-- GRID --> + <extension point="org.eclipse.ui.handlers"> + <handler class="hterhors.editor.zest.layouthandler.GridLayoutGraphHandler" + commandId="grid.graph"> + </handler> + </extension> + + <extension point="org.eclipse.ui.commands"> + + <category id="visualization.category" name="Isr visualization"> + </category> + <command id="grid.graph" name="Grid-Layout" + categoryId="visualization.category"> + </command> + </extension> + <!-- HORIZONTAL --> + <extension point="org.eclipse.ui.handlers"> + <handler class="hterhors.editor.zest.layouthandler.HorizontalTreeLayoutGraphHandler" + commandId="horizontal.tree.graph"> + </handler> + </extension> + + <extension point="org.eclipse.ui.commands"> + + <category id="visualization.category" name="Isr visualization"> + </category> + + <command id="horizontal.tree.graph" name="Horizontal-Tree-Layout" + categoryId="visualization.category"> + </command> + </extension> + <!-- RADIAL --> + <extension point="org.eclipse.ui.handlers"> + <handler class="hterhors.editor.zest.layouthandler.RadialLayoutGraphHandler" + commandId="radial.graph"> + </handler> + </extension> + +<extension point="org.eclipse.ui.commands"> + + <category id="visualization.category" name="Isr visualization"> + </category> + + <command id="radial.graph" name="Radial-Tree-Layout" + categoryId="visualization.category"> + </command> + </extension> + <!-- SPRING --> + <extension point="org.eclipse.ui.handlers"> + <handler class="hterhors.editor.zest.layouthandler.SpringLayoutGraphHandler" + commandId="spring.graph"> + </handler> + </extension> + +<extension point="org.eclipse.ui.commands"> + + <category id="visualization.category" name="Isr visualization"> + </category> + + <command id="spring.graph" name="Spring-Tree-Layout" + categoryId="visualization.category"> + </command> + </extension> + + <!-- TREE --> + <extension point="org.eclipse.ui.handlers"> + <handler class="hterhors.editor.zest.layouthandler.TreeLayoutGraphHandler" + commandId="tree.graph"> + </handler> + </extension> + +<extension point="org.eclipse.ui.commands"> + + <category id="visualization.category" name="Isr visualization"> + </category> + + <command id="tree.graph" name="Tree-Layout" + categoryId="visualization.category"> + </command> + </extension> + + <!-- VERTICAL --> + <extension point="org.eclipse.ui.handlers"> + <handler class="hterhors.editor.zest.layouthandler.VerticalLayoutGraphHandler" + commandId="vertical.graph"> + </handler> + </extension> + +<extension point="org.eclipse.ui.commands"> + + <category id="visualization.category" name="Isr visualization"> + </category> + + <command id="vertical.graph" name="Vertical-Tree-Layout" + categoryId="visualization.category"> + </command> + </extension> + +<!-- Parser --> + <extension point="org.eclipse.ui.commands"> + <category id="visualization.category" name="Parse sentences"> + </category> + + <command id="parse.sentences" name="Parse sentences" + categoryId="visualization.category"> + </command> + </extension> + + <extension point="org.eclipse.ui.handlers"> + + <handler class="hterhors.editor.sentenceparser.ParseSentenceHandler" + commandId="parse.sentences"> + </handler> + </extension> + + <extension point="org.eclipse.ui.bindings"> + + <key commandId="parse.sentences" contextId="org.eclipse.ui.contexts.window" + schemeId="org.eclipse.ui.defaultAcceleratorConfiguration" sequence="M1+Shift+P"> + </key> + </extension> + + + <!-- isr.info GENERAL --> + <extension point="org.eclipse.ui.commands"> + <category id="isr.info.category" name="General"> + </category> + + <command id="isr.general.info" name="General" + categoryId="isr.info.category"> + </command> + </extension> + + <extension point="org.eclipse.ui.handlers"> + + <handler class="hterhors.editor.info.InfoGeneralHandler" + commandId="isr.general.info"> + </handler> + </extension> + + <!-- isr.info EXAMPLE --> + <extension point="org.eclipse.ui.commands"> + <category id="isr.info.category" name="Example"> + </category> + + <command id="isr.example.info" name="Example" + categoryId="isr.info.category"> + </command> + </extension> + + <extension point="org.eclipse.ui.handlers"> + + <handler class="hterhors.editor.info.InfoExampleHandler" + commandId="isr.example.info"> + </handler> + </extension> + + <!-- isr.info SYNTAX --> + <extension point="org.eclipse.ui.commands"> + <category id="isr.info.category" name="Syntax"> + </category> + + <command id="isr.syntax.info" name="Syntax" + categoryId="isr.info.category"> + </command> + </extension> + + <extension point="org.eclipse.ui.handlers"> + + <handler class="hterhors.editor.info.InfoSyntaxHandler" + commandId="isr.syntax.info"> + </handler> + </extension> + + <extension point="org.eclipse.ui.menus"> + + <menuContribution locationURI="menu:org.eclipse.ui.main.menu?after=additions"> + + <menu id="isr.menu" label="Isr" mnemonic="I"> + + <menu id="isr.menu.infos" label="Info" mnemonic="I"> + <command id="isr.general.info.command" commandId="isr.general.info" + mnemonic="G"> + + </command> + <command id="isr.example.info.command" commandId="isr.example.info" + mnemonic="E"> + </command> + <command id="isr.syntax.info.command" commandId="isr.syntax.info" + mnemonic="S"> + </command> + </menu> + <command id="parse.sentences.command" commandId="parse.sentences" + mnemonic="P"> + </command> + <command id="update.graph.command" commandId="isr.graph.visualization" + mnemonic="U"> + </command> + <menu id="isr.menu.layouts" label="Graph layouts" mnemonic="L"> + <command id="horizontal.tree.graph.command" commandId="horizontal.tree.graph" + mnemonic="H"> + + </command> + <command id="radial.graph.command" commandId="radial.graph" + mnemonic="R"> + + </command> + <command id="spring.graph.command" commandId="spring.graph" + mnemonic="S"> + + </command> + <command id="tree.graph.command" commandId="tree.graph" + mnemonic="T"> + + </command> + <command id="vertical.graph.command" commandId="vertical.graph" + mnemonic="V"> + + </command> + <command id="grid.graph.command" commandId="grid.graph" + mnemonic="G"> + </command> + </menu> + <visibleWhen checkEnabled="false"> + + <with variable="selection"> + + <iterate ifEmpty="false" operator="or"> + + <!--or> + + <adapt type="org.eclipse.core.resources.IResource"> + + <or> + + <test property="org.eclipse.core.resources.extension" + value="grm"> + </test> + </or> + </adapt--> + + <with variable="activeEditorInput"> + + <adapt type="org.eclipse.core.resources.IResource"> + + <or> + + <test property="org.eclipse.core.resources.extension" + value="grm"> + </test> + </or> + </adapt> + </with> + <!--/or--> + </iterate> + </with> + </visibleWhen> + </menu> + </menuContribution> + + <menuContribution + locationURI="toolbar:org.eclipse.ui.main.toolbar?after=additions"> + + <toolbar id="isr.toolbars.update.graph"> + + <command id="isr.toolbar.update.graph.command" commandId="isr.graph.visualization" + icon="icons/sample.gif" tooltip="Update graph-visualization"> + + <visibleWhen checkEnabled="false"> + + <with variable="selection"> + + <iterate ifEmpty="false" operator="or"> + + <with variable="activeEditorInput"> + + <adapt type="org.eclipse.core.resources.IResource"> + <test property="org.eclipse.core.resources.extension" + value="grm"> + </test> + </adapt> + </with> + </iterate> + </with> + </visibleWhen> + </command> + </toolbar> + </menuContribution> + </extension> + + <extension point="org.eclipse.ui.workbench.texteditor.hyperlinkDetectors"> + + <hyperlinkDetector id="hterhors.editor.hyperlink.isrhyperlinkdetector" + name="IsrHyperLink" class="hterhors.editor.hyperlink.IsrHyperLinkDetector" + targetId="org.eclipse.ui.DefaultTextEditor"> + </hyperlinkDetector> + </extension> + +</plugin> \ No newline at end of file diff --git a/isr-eclipse-plugin/src/IsrGrammarXmlDefinition.dtd b/isr-eclipse-plugin/src/IsrGrammarXmlDefinition.dtd new file mode 100644 index 0000000000000000000000000000000000000000..5001f444e8c722ff1a41c5d18a5ae7fb4b29fa87 --- /dev/null +++ b/isr-eclipse-plugin/src/IsrGrammarXmlDefinition.dtd @@ -0,0 +1,15 @@ +<!ELEMENT ISR_GRAMMAR (Start,DeclarationNonTerminal*)> + +<!ELEMENT Start (Or?)*> +<!ATTLIST Start name CDATA #REQUIRED> + +<!ELEMENT Terminal EMPTY> +<!ATTLIST Terminal name CDATA #REQUIRED> + +<!ELEMENT NonTerminal EMPTY> +<!ATTLIST NonTerminal name CDATA #REQUIRED> + +<!ELEMENT Or (NonTerminal|Terminal)*> + +<!ELEMENT DeclarationNonTerminal (Or?)*> +<!ATTLIST DeclarationNonTerminal name CDATA #REQUIRED> diff --git a/isr-eclipse-plugin/src/gramar.dtd b/isr-eclipse-plugin/src/gramar.dtd new file mode 100644 index 0000000000000000000000000000000000000000..9507555b787d668b6d701d547bbf93b6095c7a65 --- /dev/null +++ b/isr-eclipse-plugin/src/gramar.dtd @@ -0,0 +1,86 @@ +<?xml version="1.0" encoding="ISO-8859-1"?> + +<!-- +SRGS XML Grammar Form DTD (20020524) + +Copyright 1998-2002 W3C (MIT, INRIA, Keio), All Rights Reserved. + +Permission to use, copy, modify and distribute the SRGS DTD and +its accompanying documentation for any purpose and without fee is +hereby granted in perpetuity, provided that the above copyright +notice and this paragraph appear in all copies. + +The copyright holders make no representation about the suitability +of the DTD for any purpose. It is provided "as is" without expressed +or implied warranty. +--> + +<!ENTITY % uri "CDATA"> +<!ENTITY % rule-expansion "#PCDATA | token | ruleref + | item | one-of | tag "> +<!ENTITY % grammar-header "( meta | metadata | lexicon )*"> +<!ENTITY % grammar-body "( rule )*"> + +<!ELEMENT ruleref EMPTY> +<!ATTLIST ruleref + uri %uri; #IMPLIED + type CDATA #IMPLIED + special (NULL | VOID | GARBAGE) #IMPLIED + xml:lang NMTOKEN #IMPLIED +> + +<!ELEMENT token (#PCDATA)> +<!ATTLIST token + xml:lang NMTOKEN #IMPLIED +> + +<!ELEMENT tag (#PCDATA)> + +<!ELEMENT one-of (item)+> +<!ATTLIST one-of + xml:lang NMTOKEN #IMPLIED +> + +<!ELEMENT item (%rule-expansion;)*> +<!ATTLIST item + repeat NMTOKEN #IMPLIED + repeat-prob NMTOKEN #IMPLIED + weight NMTOKEN #IMPLIED + xml:lang NMTOKEN #IMPLIED +> + +<!ELEMENT rule (%rule-expansion; | example)*> +<!ATTLIST rule + id ID #REQUIRED + scope (private | public) "private" +> + +<!ELEMENT example (#PCDATA)> + +<!ELEMENT lexicon EMPTY> +<!ATTLIST lexicon + uri %uri;#REQUIRED + type CDATA #IMPLIED +> + +<!ELEMENT meta EMPTY> +<!ATTLIST meta + name NMTOKEN #IMPLIED + content CDATA #REQUIRED + http-equiv NMTOKEN #IMPLIED +> + +<!ELEMENT metadata EMPTY> + +<!ELEMENT grammar (%grammar-header;, %grammar-body;)> +<!ATTLIST grammar + tag-format %uri; #IMPLIED + xml:base %uri; #IMPLIED + version NMTOKEN #REQUIRED + xml:lang NMTOKEN #IMPLIED + xmlns CDATA #REQUIRED + xmlns:xsi CDATA #IMPLIED + xsi:schemaLocation CDATA #IMPLIED + root IDREF #IMPLIED + mode (voice | dtmf) "voice" +> \ No newline at end of file diff --git a/isr-eclipse-plugin/src/hterhors/Activator.java b/isr-eclipse-plugin/src/hterhors/Activator.java new file mode 100644 index 0000000000000000000000000000000000000000..51840d13e66931eed0fe1ed6f2a5e7e2db6db711 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/Activator.java @@ -0,0 +1,82 @@ +package hterhors; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The main plugin class to be used in the desktop. + */ +public class Activator extends AbstractUIPlugin { + // The shared instance. + /** + * @uml.property name="plugin" + * @uml.associationEnd + */ + private static Activator plugin; + + // Resource bundle. + /** + * @uml.property name="resourceBundle" + */ + private ResourceBundle resourceBundle; + + /** + * The constructor. + */ + public Activator() { + super(); + plugin = this; + try { + resourceBundle = ResourceBundle + .getBundle("hterhors.EditorPluginResources"); + } catch (MissingResourceException x) { + resourceBundle = null; + } + } + + /** + * This method is called upon plug-in activation + */ + public void start(BundleContext context) throws Exception { + super.start(context); + } + + /** + * This method is called when the plug-in is stopped + */ + public void stop(BundleContext context) throws Exception { + super.stop(context); + } + + /** + * Returns the shared instance. + */ + public static Activator getDefault() { + return plugin; + } + + /** + * Returns the string from the plugin's resource bundle, or 'key' if not + * found. + */ + public static String getResourceString(String key) { + ResourceBundle bundle = Activator.getDefault() + .getResourceBundle(); + try { + return (bundle != null) ? bundle.getString(key) : key; + } catch (MissingResourceException e) { + return key; + } + } + + /** + * Returns the plugin's resource bundle, + * @uml.property name="resourceBundle" + */ + public ResourceBundle getResourceBundle() { + return resourceBundle; + } +} diff --git a/isr-eclipse-plugin/src/hterhors/EditorPluginResources.properties b/isr-eclipse-plugin/src/hterhors/EditorPluginResources.properties new file mode 100644 index 0000000000000000000000000000000000000000..a860a230b761271f38752a73fa3eb941c5c2d89c --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/EditorPluginResources.properties @@ -0,0 +1,19 @@ +ContentAssistProposal.label=Content Assists@Ctrl+SPACE +ContentAssistProposal.tooltip=Content Assist +ContentAssistProposal.image= +ContentAssistProposal.description=Content Assist + +ContentAssistTip.label=Content Tip@Ctrl+SHIFT+SPACE +ContentAssistTip.tooltip=Content Tip +ContentAssistTip.image= +ContentAssistTip.description=Content Tip + +ContentFormatProposal.label=Content Format@Ctrl+SHIFT+F +ContentFormatProposal.tooltip=Content Format +ContentFormatProposal.image= +ContentFormatProposal.description=Content Format + +ContentFormatTip.label=Content Tip@Ctrl+SHIFT+SPACE +ContentFormatTip.tooltip=Content Tip +ContentFormatTip.image= +ContentFormatTip.description=Content Tip diff --git a/isr-eclipse-plugin/src/hterhors/editor/ColorManager.java b/isr-eclipse-plugin/src/hterhors/editor/ColorManager.java new file mode 100644 index 0000000000000000000000000000000000000000..6693b3b34b9e69cf613c275a889b7d1ed1fc975b --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/ColorManager.java @@ -0,0 +1,34 @@ +package hterhors.editor; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; + +/** + * This class manages the + * @author Hendrik + * + */ +public class ColorManager { + + protected Map fColorTable = new HashMap(10); + + public void dispose() { + Iterator e = fColorTable.values().iterator(); + while (e.hasNext()) + ((Color) e.next()).dispose(); + } + + public Color getColor(RGB rgb) { + Color color = (Color) fColorTable.get(rgb); + if (color == null) { + color = new Color(Display.getCurrent(), rgb); + fColorTable.put(rgb, color); + } + return color; + } +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/DoubleClickStrategy.java b/isr-eclipse-plugin/src/hterhors/editor/DoubleClickStrategy.java new file mode 100644 index 0000000000000000000000000000000000000000..fcc5503a0ad407e29b2577ea1c6aeec02e781a3e --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/DoubleClickStrategy.java @@ -0,0 +1,87 @@ +package hterhors.editor; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextDoubleClickStrategy; +import org.eclipse.jface.text.ITextViewer; + +/** + * Implements the editors double click strategy. + * + * @author Hendrik + * + */ +public class DoubleClickStrategy implements ITextDoubleClickStrategy { + protected ITextViewer fText; + + @Override + public void doubleClicked(ITextViewer part) { + int pos = part.getSelectedRange().x; + + if (pos < 0) + return; + + fText = part; + + selectWord(pos); + } + + /** + * This method calculates the word which should be selected. + * + * @param caretPos + * the cursors current position + */ + protected void selectWord(int caretPos) { + + IDocument doc = fText.getDocument(); + int startPos, endPos; + + try { + + int pos = caretPos; + char c; + + while (pos >= 0) { + c = doc.getChar(pos); + if (!Character.isJavaIdentifierPart(c)) + break; + --pos; + } + + startPos = pos; + + pos = caretPos; + int length = doc.getLength(); + + while (pos < length) { + c = doc.getChar(pos); + if (!Character.isJavaIdentifierPart(c)) + break; + ++pos; + } + + endPos = pos; + selectRange(startPos, endPos); + return; + + } catch (BadLocationException x) { + } + + return; + } + + /** + * Triggers the selection. + * + * @param startPos + * startposition + * @param stopPos + * stopposition + */ + private void selectRange(int startPos, int stopPos) { + int offset = startPos + 1; + int length = stopPos - offset; + fText.setSelectedRange(offset, length); + } +} \ No newline at end of file diff --git a/isr-eclipse-plugin/src/hterhors/editor/IISRColorConstants.java b/isr-eclipse-plugin/src/hterhors/editor/IISRColorConstants.java new file mode 100644 index 0000000000000000000000000000000000000000..169544c89dbf6bb9e1acd4f76d5e381c48a224ed --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/IISRColorConstants.java @@ -0,0 +1,20 @@ +package hterhors.editor; + +import org.eclipse.swt.graphics.RGB; + +public interface IISRColorConstants { + RGB DEC_NON_TERMINAL = new RGB(128, 0, 128); + RGB NON_TERMINAL = new RGB(0, 0, 192); + RGB START = new RGB(225, 0, 255); + RGB DEFAULT = new RGB(0, 0, 0); + RGB OR = new RGB(8, 255, 8); + RGB NUMBER = new RGB(192, 192, 0); + RGB IGNORE = new RGB(200, 0, 0); + RGB JOKER = new RGB(192, 128, 128); + RGB DEC_NON_TERMINAL_GRAPH = new RGB(255, 64, 255); + RGB NON_TERMINAL_GRAPH = new RGB(128, 128, 255); + RGB START_GRAPH = new RGB(225, 128, 255); + RGB OR_GRAPH = new RGB(0, 255, 0); + RGB IGNORE_GRAPH = new RGB(255, 128, 128); + RGB JOKER_GRAPH = new RGB(255, 192, 192); +} \ No newline at end of file diff --git a/isr-eclipse-plugin/src/hterhors/editor/ISRContentAssistantDefaultProcessor.java b/isr-eclipse-plugin/src/hterhors/editor/ISRContentAssistantDefaultProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..ce8cfc8dfed48671c83992fbc1e44c87d6d4ddab --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/ISRContentAssistantDefaultProcessor.java @@ -0,0 +1,154 @@ +package hterhors.editor; + +import hterhors.editor.markers.IsrRuleValidator; + +import java.util.ArrayList; + +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.contentassist.CompletionProposal; +import org.eclipse.jface.text.contentassist.ICompletionProposal; +import org.eclipse.jface.text.contentassist.IContentAssistProcessor; +import org.eclipse.jface.text.contentassist.IContextInformation; +import org.eclipse.jface.text.contentassist.IContextInformationValidator; + +/** + * @author Hendrik + */ +class ISRContentAssistantDefaultProcessor implements IContentAssistProcessor { + private final IContextInformation[] NO_CONTEXTS = {}; + private final char[] PROPOSAL_ACTIVATION_CHARS = { 's', 'f', 'p', 'n', 'm', }; + private ICompletionProposal[] NO_COMPLETIONS = {}; + private int override = 0; + private String preSpace = ""; + protected static final String lineSeparator = System + .getProperty("line.separator"); + + /** + * Use this method to set the size for overriding by using content-assistant. + * @param override The size to be override. + * @uml.property name="override" + */ + public void setOverride(int override) { + this.override = override; + } + + @Override + public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, + int offset) { + try { + IDocument document = viewer.getDocument(); + ArrayList<CompletionProposal> result = new ArrayList<CompletionProposal>(); + if (!IsrRuleValidator.startSymbolExists(document.get())) { + result.add(new CompletionProposal( + preSpace + "$$S: ;" + lineSeparator, + offset, + override, + 5 + preSpace.length(), + null, + "New start-symbol", + null, + "The '$$S' symbol is the start symbol and must be included\n" + + "in the grammar. Additionally, the '$$SS' symbol is predefined and\n" + + "must not be used in the grammatic description. ")); + } + for (String nonterminal : IsrRuleValidator + .getMissingNontermDec(document.get())) { + result.add(new CompletionProposal(preSpace + "$" + nonterminal + + ": ;" + lineSeparator, offset, override, 3 + + nonterminal.length() + preSpace.length(), null, + nonterminal + " - Missing!", null, + "Add the missing nonterminal-declaration ($" + + nonterminal + ":) to the grammar.")); + } + result.add(new CompletionProposal( + preSpace + "$: ;" + lineSeparator, + offset, + override, + 1 + preSpace.length(), + null, + "New declaration", + null, + "\"NONTERMINAL\" symbols are defined equally as TERMINAL symbols but\n" + + "must have a '$' or '$$' prefix.\n" + + "Symbols with '$$' prefix are technical symbols which are describe\n" + + "at \"New technical-nonterminal-declaration\"\n." + + " The declaration ends with ':' and the whole rule ends with ending-symbol ';'.")); + result.add(new CompletionProposal(preSpace + "[] $: ;" + + lineSeparator, offset, override, 1 + preSpace.length(), + null, "Numbered Rule", null, + "This is the number of the rule. Its an optional information.")); + result.add(new CompletionProposal( + preSpace + "$$: ;" + lineSeparator, + offset, + override, + 2 + preSpace.length(), + null, + "New technical-nonterminal-declaration", + null, + "\"Technical symbols\" are nonterminal symbols of the grammar which\n" + + "are not relevant for the understanding process but restrict\n" + + "word sequences which are allowed by the grammar. They are marked\n" + + "in the symbol table so that a parser can use this information\n" + + "when generating the parsing output.")); + result.add(new CompletionProposal( + preSpace + "%IGNORE = ;" + lineSeparator, + offset, + override, + 10 + preSpace.length(), + null, + "New ignore-rule", + null, + "The \" IGNORE list\" is a list of terminal symbols defined in the\n" + + "lexicon. A parser can use this list in order to skip some\n" + + "of these words from the word sequence analysed by the parser.\n" + + "This may be useful when hesitations like \"er\" should be ignored.\n\n" + + "An ignore-rule starts with \"%IGNORE =\"\nfollowed by N terminal-symbols and\n" + + "is closed with closing-symbol \";\"\n\nExample:\n %IGNORE= eh ehm ah er;")); + result.add(new CompletionProposal( + preSpace + "%IGNORE = eh ehm er ah ahm ;" + lineSeparator, + offset, + override, + 29 + preSpace.length(), + null, + "Predefined ignore rule.", + null, + "Creates a predefined ignore rule using most used ignore words.\n" + + "The \" IGNORE list\" is a list of terminal symbols defined in the\n" + + "lexicon. A parser can use this list in order to skip some\n" + + "of these words from the word sequence analysed by the parser.\n" + + "This may be useful when hesitations like \"er\" should be ignored.")); + return (ICompletionProposal[]) result + .toArray(new ICompletionProposal[result.size()]); + } catch (Exception e) { + e.printStackTrace(); + return NO_COMPLETIONS; + } + } + + @Override + public IContextInformation[] computeContextInformation(ITextViewer viewer, + int offset) { + return NO_CONTEXTS; + } + + @Override + public char[] getCompletionProposalAutoActivationCharacters() { + return null; + } + + @Override + public char[] getContextInformationAutoActivationCharacters() { + return null; + } + + @Override + public IContextInformationValidator getContextInformationValidator() { + return null; + } + + @Override + public String getErrorMessage() { + return "ERR"; + } +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/ISRContentAssistantIgnoreRuleProcessor.java b/isr-eclipse-plugin/src/hterhors/editor/ISRContentAssistantIgnoreRuleProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..267e1a5d953449d70d119a213c2fdb62e8826c92 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/ISRContentAssistantIgnoreRuleProcessor.java @@ -0,0 +1,81 @@ +package hterhors.editor; + +import java.util.ArrayList; + +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.contentassist.CompletionProposal; +import org.eclipse.jface.text.contentassist.ICompletionProposal; +import org.eclipse.jface.text.contentassist.IContentAssistProcessor; +import org.eclipse.jface.text.contentassist.IContextInformation; +import org.eclipse.jface.text.contentassist.IContextInformationValidator; + +/** + * @author Hendrik + */ +class ISRContentAssistantIgnoreRuleProcessor implements IContentAssistProcessor { + private final IContextInformation[] NO_CONTEXTS = {}; + private ICompletionProposal[] NO_COMPLETIONS = {}; + private int override = 0; + private String preSpace = ""; + protected static final String lineSeparator = System + .getProperty("line.separator"); + + /** + * Use this method to set the size for overriding by using content-assistant. + * @param override The size to be override. + * @uml.property name="override" + */ + public void setOverride(int override) { + this.override = override; + } + + @Override + public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, + int offset) { + try { + ArrayList<CompletionProposal> result = new ArrayList<CompletionProposal>(); + + result.add(new CompletionProposal( + preSpace + "newTerminal ", + offset, + override, + preSpace.length(), + null, + "New terminal", + null, + "\"TERMINAL\" symbols are sequences of letters from the set [a-zA-Z_\\-\\\"0-9].\n" + + "They must be started by a letter from the subset [a-zA-Z_\\\"].")); + return (ICompletionProposal[]) result + .toArray(new ICompletionProposal[result.size()]); + } catch (Exception e) { + e.printStackTrace(); + return NO_COMPLETIONS; + } + } + + @Override + public IContextInformation[] computeContextInformation(ITextViewer viewer, + int offset) { + return NO_CONTEXTS; + } + + @Override + public char[] getCompletionProposalAutoActivationCharacters() { + return null; + } + + @Override + public char[] getContextInformationAutoActivationCharacters() { + return null; + } + + @Override + public IContextInformationValidator getContextInformationValidator() { + return null; + } + + @Override + public String getErrorMessage() { + return "ERR"; + } +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/ISRContentAssistantRuleProcessor.java b/isr-eclipse-plugin/src/hterhors/editor/ISRContentAssistantRuleProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..5343da1ee74b5e565759c3dfaddc411d0f2392a6 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/ISRContentAssistantRuleProcessor.java @@ -0,0 +1,133 @@ +package hterhors.editor; + +import hterhors.editor.markers.IsrRuleValidator; + +import java.util.ArrayList; + +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.contentassist.CompletionProposal; +import org.eclipse.jface.text.contentassist.ICompletionProposal; +import org.eclipse.jface.text.contentassist.IContentAssistProcessor; +import org.eclipse.jface.text.contentassist.IContextInformation; +import org.eclipse.jface.text.contentassist.IContextInformationValidator; + +/** + * @author Hendrik + */ +class ISRContentAssistantRuleProcessor implements IContentAssistProcessor { + private final IContextInformation[] NO_CONTEXTS = {}; + private ICompletionProposal[] NO_COMPLETIONS = {}; + private int override = 0; + private String preSpace = ""; + protected static final String lineSeparator = System + .getProperty("line.separator"); + /** + * Use this method to set the size for overriding by using content-assistant. + * @param override The size to be override. + * @uml.property name="override" + */ + public void setOverride(int override) { + this.override = override; + } + + @Override + public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, + int offset) { + try { + IDocument document = viewer.getDocument(); + ArrayList<CompletionProposal> result = new ArrayList<CompletionProposal>(); + for (String missing : IsrRuleValidator + .getUnusedNonterminals(document.get())) { + result.add(new CompletionProposal(preSpace + "$" + missing + + " ", offset, override, 2 + missing.length() + + preSpace.length(), null, missing + " - Unused!", + null, "Add the declared but not used nonterminal (" + + missing + ")to the rule.")); + } + result.add(new CompletionProposal(preSpace + "| ", offset, + override, 2 + preSpace.length(), null, "Or", null, + "Add the or-symbol to the rule.")); + result.add(new CompletionProposal(preSpace + "$ ", offset, + override, 1 + preSpace.length(), null, "Nonterminal", null, + "Add New nonterminal-symbol to the current rule.")); + result.add(new CompletionProposal( + preSpace + "!*", + offset, + override, + 2 + preSpace.length(), + null, + "New joker-symbol", + null, + "\"TERMINAL\" symbols are sequences of letters from the set [a-zA-Z_\\-\\\"0-9].\n" + + "They must be started by a letter from the subset [a-zA-Z_\\\"].\n" + + "The joker symbol is denoted by '!*'.\n\n" + + "The \" joker symbol\" is a special terminal symbol of the grammar which\n" + + "must not be defined in the lexicon.\n" + + "If the parser is called with a terminal symbol which is defined\n" + + "in the lexicon and the corresponding action table entry is empty\n" + + "it can use this joker symbol in order to get a defined parser\n" + + "action. The former terminal symbol has to be parsed afterwards.\n" + + "The joker symbol can be used in the grammar description in order\n" + + "to define such parser actions. It is handled in the same way\n" + + "as other terminal symbols defined in the lexicon but does not\n" + + "correspond to an input symbol. Therefore, it can be called\n" + + "a virtuell symbol. A special action 'VSHIFT' (virtual shift)\n" + + "is introduced when generating the action table.\n" + + "A parser used in a speech recognizer can add a penalty to the \n" + + "score of the word sequence when shifting the joker symbol. ")); + result.add(new CompletionProposal( + preSpace + "newTerminal ", + offset, + override, + preSpace.length(), + null, + "New terminal", + null, + "\"TERMINAL\" symbols are sequences of letters from the set [a-zA-Z_\\-\\\"0-9].\n" + + "They must be started by a letter from the subset [a-zA-Z_\\\"].\n" + + "The joker symbol is denoted by '!*'.")); + for (String nonterminalDec : IsrRuleValidator + .getNonterminalsDeclarations(document.get())) { + result.add(new CompletionProposal( + + preSpace + "$" + nonterminalDec + " ", offset, override, 2 + + nonterminalDec.length() + preSpace.length(), null, + nonterminalDec + " - Existing!", null, + "Add the existing nonterminal ($" + nonterminalDec + + ") to the rule.")); + } + return (ICompletionProposal[]) result + .toArray(new ICompletionProposal[result.size()]); + } catch (Exception e) { + e.printStackTrace(); + return NO_COMPLETIONS; + } + } + + @Override + public IContextInformation[] computeContextInformation(ITextViewer viewer, + int offset) { + return NO_CONTEXTS; + } + + @Override + public char[] getCompletionProposalAutoActivationCharacters() { + return null; + } + + @Override + public char[] getContextInformationAutoActivationCharacters() { + return null; + } + + @Override + public IContextInformationValidator getContextInformationValidator() { + return null; + } + + @Override + public String getErrorMessage() { + return "ERR"; + } +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/ISRDocumentProvider.java b/isr-eclipse-plugin/src/hterhors/editor/ISRDocumentProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..11c0244090a12a2ceb5b628cd89beb4797d004d1 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/ISRDocumentProvider.java @@ -0,0 +1,51 @@ +package hterhors.editor; + +import hterhors.editor.scanners.ISRPartitionScanner; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IDocumentPartitioner; +import org.eclipse.jface.text.rules.FastPartitioner; +import org.eclipse.ui.editors.text.FileDocumentProvider; + +public class ISRDocumentProvider extends FileDocumentProvider { + + @Override + protected IDocument createDocument(Object element) throws CoreException { + IDocument document = super.createDocument(element); + if (document != null) { + IDocumentPartitioner partitioner = new FastPartitioner( + new ISRPartitionScanner(), new String[] { + ISRPartitionScanner.ISR_IGNORE, + ISRPartitionScanner.ISR_RULE, + }); + partitioner.connect(document); + document.setDocumentPartitioner(partitioner); + } + return document; + } + + /** + * @uml.property name="iSRPartitionScanner" + * @uml.associationEnd inverse="iSRDocumentProvider:hterhors.editor.scanners.ISRPartitionScanner" + */ + private ISRPartitionScanner isrPartitionScanner; + + /** + * Getter of the property <tt>iSRPartitionScanner</tt> + * @return Returns the isrPartitionScanner. + * @uml.property name="iSRPartitionScanner" + */ + public ISRPartitionScanner getISRPartitionScanner() { + return isrPartitionScanner; + } + + /** + * Setter of the property <tt>iSRPartitionScanner</tt> + * @param iSRPartitionScanner The isrPartitionScanner to set. + * @uml.property name="iSRPartitionScanner" + */ + public void setISRPartitionScanner(ISRPartitionScanner isrPartitionScanner) { + this.isrPartitionScanner = isrPartitionScanner; + } +} \ No newline at end of file diff --git a/isr-eclipse-plugin/src/hterhors/editor/ISREditor.java b/isr-eclipse-plugin/src/hterhors/editor/ISREditor.java new file mode 100644 index 0000000000000000000000000000000000000000..cbacce4ef3181a4ce78c531abf841b8df64365fa --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/ISREditor.java @@ -0,0 +1,251 @@ +package hterhors.editor; + +import hterhors.Activator; +import hterhors.editor.markers.MarkerContainer; +import hterhors.editor.markers.MarkingErrorHandler; +import hterhors.editor.outline.EditorContentOutlinePage; + +import java.io.File; +import java.util.ResourceBundle; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IFileEditorInput; +import org.eclipse.ui.editors.text.TextEditor; +import org.eclipse.ui.texteditor.ContentAssistAction; +import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds; +import org.eclipse.ui.texteditor.TextOperationAction; +import org.eclipse.ui.views.contentoutline.IContentOutlinePage; + +/** + * The main editor. Manages the Plugins Editor. + * + * @author Hendrik + */ +public class ISREditor extends TextEditor { + + /** + * @uml.property name="colorManager" + * @uml.associationEnd + */ + private ColorManager colorManager; + /** + * @uml.property name="input" + */ + private IEditorInput input; + /** + * @uml.property name="outlinePage" + * @uml.associationEnd + */ + private EditorContentOutlinePage outlinePage; + + public ISREditor() { + super(); + new Activator(); + colorManager = new ColorManager(); + ISRDocumentProvider documentProvider = new ISRDocumentProvider(); + ISRSourceViewerConfiguration svc = new ISRSourceViewerConfiguration( + colorManager, this); + setSourceViewerConfiguration(svc); + setDocumentProvider(documentProvider); + // if (vT == null) { + new ValidateThread().start(); + // } + } + + // static ValidateThread vT = null; + // + // private ValidateThread getThread() { + // if (vT == null) { + // return vT = new ValidateThread(); + // } + // return vT; + // + // } + + /** + * This thread calls validateAndMark() every 500 millisec. to validate the + * current Grammar. For efficient the validating is triggered in case of + * dirty editor-content. + * + * @author Hendrik + * + */ + class ValidateThread extends Thread { + + @Override + public void run() { + + boolean isDirty = true; + super.run(); + while (true) { + try { + isDirty = ISREditor.this.getSite().getPage() + .getActiveEditor().isDirty() + && ISREditor.this.getSite().getPage() + .getActiveEditor().getTitle() == getInputFile() + .getName(); + } catch (NullPointerException e) { + } + try { + if (getInputDocument() != null && isDirty) + validateAndMark(); + sleep(500); + } catch (InterruptedException e) { + e.printStackTrace(); + + } + } + } + } + + @Override + public void dispose() { + colorManager.dispose(); + if (outlinePage != null) + outlinePage.setInput(null); + super.dispose(); + } + + @Override + protected void doSetInput(IEditorInput newInput) throws CoreException { + super.doSetInput(newInput); + this.input = newInput; + if (outlinePage != null) + outlinePage.setInput(input); + validateAndMark(); + } + + @Override + protected void editorSaved() { + super.editorSaved(); + if (outlinePage != null) + outlinePage.update(); + this.setInput(input); + } + + // ValidateThreadListener threadListener = new ValidateThreadListener(); + + public synchronized IDocument getInputDocument() { + try { + IDocument document = getDocumentProvider().getDocument(input); + return document; + } catch (NullPointerException e) { + return null; + } + // if (document != null) { + // document.addDocumentListener(new IDocumentListener() { + // + // @Override + // public void documentChanged(DocumentEvent event) { + // System.out.println("changed"); + // // threadListener.run = true; + // // threadListener.run(); + // } + // + // @Override + // public void documentAboutToBeChanged(DocumentEvent event) { + // System.out.println("changed2"); + // } + // }); + // } + } + + // class ValidateThreadListener extends Thread { + // + // boolean run = true; + // + // @Override + // public void run() { + // super.run(); + // while (run) { + // System.out.println(run); + // try { + // run = false; + // sleep(2000); + // } catch (InterruptedException e) { + // e.printStackTrace(); + // } + // System.out.println(run); + // if (getInputDocument() != null && ISREditor.this.isDirty()) { + // if (!run) { + // System.out.println("VALIDATE"); + // // validateAndMark(); + // } + // } + // } + // } + // } + + /** + * Triggers the validation of the current grammar. + * + */ + public synchronized void validateAndMark() { + if (getInputDocument() != null + && MarkerContainer.isDirty(getInputDocument().get())) { + MarkingErrorHandler markingErrorHandler = new MarkingErrorHandler( + getInputFile(), getInputDocument()); + markingErrorHandler.removeExistingMarker(); + markingErrorHandler.setCurrentMarker(); + } + } + + /** + * Returns the current input as an IFile object. + * + * @return File with the current grammar. + */ + protected synchronized IFile getInputFile() { + IFileEditorInput ife = (IFileEditorInput) input; + IFile file = ife.getFile(); + return file; + } + + /** + * Returns the current editor-input + * + * @return current editor-input. + * @uml.property name="input" + */ + public IEditorInput getInput() { + return input; + } + + @Override + protected void createActions() { + super.createActions(); + ResourceBundle bundle = Activator.getDefault().getResourceBundle(); + setAction("ContentFormatProposal", new TextOperationAction(bundle, + "ContentFormatProposal.", this, ISourceViewer.FORMAT)); + + Action action = new ContentAssistAction(bundle, + "ContentAssistProposal.", this); + String id = ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS; + action.setActionDefinitionId(id); + setAction("ContentAssistProposal", action); + markAsStateDependentAction("ContentAssistProposal", true); + + } + + @Override + public Object getAdapter(Class required) { + + if (IContentOutlinePage.class.equals(required)) { + if (outlinePage == null) { + outlinePage = new EditorContentOutlinePage(this); + if (getEditorInput() != null) + outlinePage.setInput(getEditorInput()); + } + return outlinePage; + } + + return super.getAdapter(required); + + } + +} \ No newline at end of file diff --git a/isr-eclipse-plugin/src/hterhors/editor/ISREditorContributor.java b/isr-eclipse-plugin/src/hterhors/editor/ISREditorContributor.java new file mode 100644 index 0000000000000000000000000000000000000000..31bdf96d4db80103a9168c7baf6013f8cac6ce68 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/ISREditorContributor.java @@ -0,0 +1,88 @@ +package hterhors.editor; + +import hterhors.Activator; + +import java.util.ResourceBundle; + +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.editors.text.TextEditorActionContributor; +import org.eclipse.ui.part.EditorActionBarContributor; +import org.eclipse.ui.texteditor.ITextEditor; +import org.eclipse.ui.texteditor.RetargetTextEditorAction; + +/** + * Manages the installation and deinstallation of actions for the editor. + */ +public class ISREditorContributor extends TextEditorActionContributor { + + protected RetargetTextEditorAction contentAssistProposal; + protected RetargetTextEditorAction contentAssistTip; + protected RetargetTextEditorAction formatProposal; + + /** + * Constructor for SQLEditorContributor. Creates a new contributor in the + * form of adding Content Assist, Conent Format and Assist tip menu items + */ + public ISREditorContributor() { + super(); + ResourceBundle bundle = Activator.getDefault() + .getResourceBundle(); + + contentAssistProposal = new RetargetTextEditorAction(bundle, + "ContentAssistProposal."); + formatProposal = new RetargetTextEditorAction(bundle, + "ContentFormatProposal."); + contentAssistTip = new RetargetTextEditorAction(bundle, + "ContentAssistTip."); + + } + + public void contributeToMenu(IMenuManager mm) { + super.contributeToMenu(mm); + IMenuManager editMenu = mm + .findMenuUsingPath(IWorkbenchActionConstants.M_EDIT); + if (editMenu != null) { + editMenu.add(new Separator()); + editMenu.add(contentAssistProposal); + editMenu.add(formatProposal); + editMenu.add(contentAssistTip); + } + } + + /** + * Sets the active editor to this contributor. This updates the actions to + * reflect the editor. + * + * @see EditorActionBarContributor#editorChanged + */ + public void setActiveEditor(IEditorPart part) { + + super.setActiveEditor(part); + + ITextEditor editor = null; + if (part instanceof ITextEditor) + editor = (ITextEditor) part; + + contentAssistProposal.setAction(getAction(editor, + "ContentAssistProposal")); + formatProposal.setAction(getAction(editor, "ContentFormatProposal")); + contentAssistTip.setAction(getAction(editor, "ContentAssistTip")); + + } + + /** + * + * Contributes to the toolbar. + * + * @see EditorActionBarContributor#contributeToToolBar + */ + public void contributeToToolBar(IToolBarManager tbm) { + super.contributeToToolBar(tbm); + tbm.add(new Separator()); + } + +} \ No newline at end of file diff --git a/isr-eclipse-plugin/src/hterhors/editor/ISRPartitioner.java b/isr-eclipse-plugin/src/hterhors/editor/ISRPartitioner.java new file mode 100644 index 0000000000000000000000000000000000000000..2c626bd1ac8ce7b6eaa4bfadc33554d029f4da1f --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/ISRPartitioner.java @@ -0,0 +1,57 @@ +/* + * Created on Oct 10, 2004 + */ +package hterhors.editor; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITypedRegion; +import org.eclipse.jface.text.rules.FastPartitioner; +import org.eclipse.jface.text.rules.IPartitionTokenScanner; + +/** + * Helper class for programmers. Use this class in ISRDocumentProvider instead + * of the FastPartitioner to display the partitions. + * + * @author Hendrik + * + */ +public class ISRPartitioner extends FastPartitioner { + + public ISRPartitioner(IPartitionTokenScanner scanner, + String[] legalContentTypes) { + super(scanner, legalContentTypes); + } + + public ITypedRegion[] computePartitioning(int offset, int length, + boolean includeZeroLengthPartitions) { + return super.computePartitioning(offset, length, + includeZeroLengthPartitions); + } + + public void connect(IDocument document, boolean delayInitialization) { + super.connect(document, delayInitialization); + printPartitions(document); + } + + public void printPartitions(IDocument document) { + StringBuffer buffer = new StringBuffer(); + + ITypedRegion[] partitions = computePartitioning(0, document.getLength()); + for (int i = 0; i < partitions.length; i++) { + try { + buffer.append("Partition type: " + partitions[i].getType() + + ", offset: " + partitions[i].getOffset() + + ", length: " + partitions[i].getLength()); + buffer.append("\n"); + buffer.append("Text:\n"); + buffer.append(document.get(partitions[i].getOffset(), + partitions[i].getLength())); + buffer.append("\n---------------------------\n\n\n"); + } catch (BadLocationException e) { + e.printStackTrace(); + } + } + System.out.print(buffer); + } +} \ No newline at end of file diff --git a/isr-eclipse-plugin/src/hterhors/editor/ISRSourceViewerConfiguration.java b/isr-eclipse-plugin/src/hterhors/editor/ISRSourceViewerConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..73b568a42ab4c9a14a356af72aa5e9872ecbb812 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/ISRSourceViewerConfiguration.java @@ -0,0 +1,194 @@ +package hterhors.editor; + +import hterhors.editor.format.DefaultFormattingStrategy; +import hterhors.editor.format.IgnoreFormattingStrategy; +import hterhors.editor.format.RuleFormattingStrategy; +import hterhors.editor.hoverinfos.GenerateHoverInfos; +import hterhors.editor.hoverinfos.IISRAnnontationHover; +import hterhors.editor.hyperlink.IsrHyperLinkDetector; +import hterhors.editor.scanners.ISRPartitionScanner; +import hterhors.editor.scanners.ISRSyntaxScanner; + +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextDoubleClickStrategy; +import org.eclipse.jface.text.ITextHover; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.text.TextAttribute; +import org.eclipse.jface.text.contentassist.ContentAssistEvent; +import org.eclipse.jface.text.contentassist.ContentAssistant; +import org.eclipse.jface.text.contentassist.ICompletionListener; +import org.eclipse.jface.text.contentassist.ICompletionProposal; +import org.eclipse.jface.text.contentassist.IContentAssistant; +import org.eclipse.jface.text.formatter.ContentFormatter; +import org.eclipse.jface.text.formatter.IContentFormatter; +import org.eclipse.jface.text.hyperlink.IHyperlinkDetector; +import org.eclipse.jface.text.presentation.IPresentationReconciler; +import org.eclipse.jface.text.presentation.PresentationReconciler; +import org.eclipse.jface.text.rules.DefaultDamagerRepairer; +import org.eclipse.jface.text.rules.Token; +import org.eclipse.jface.text.source.IAnnotationHover; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.text.source.SourceViewerConfiguration; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.texteditor.ITextEditor; + +/** + * @author Hendrik + */ +public class ISRSourceViewerConfiguration extends SourceViewerConfiguration { + + /** + * @uml.property name="doubleClickStrategy" + * @uml.associationEnd + */ + private DoubleClickStrategy doubleClickStrategy; + /** + * @uml.property name="scanner" + * @uml.associationEnd + */ + private ISRSyntaxScanner scanner; + /** + * @uml.property name="colorManager" + * @uml.associationEnd + */ + private ColorManager colorManager; + /** + * @uml.property name="editor" + * @uml.associationEnd + */ + private ISREditor editor; + + public ISRSourceViewerConfiguration(ColorManager colorManager, + ISREditor editor) { + this.colorManager = colorManager; + this.editor = editor; + } + + @Override + public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) { + return new String[] { IDocument.DEFAULT_CONTENT_TYPE, + ISRPartitionScanner.ISR_IGNORE, ISRPartitionScanner.ISR_RULE, }; + } + + @Override + public ITextDoubleClickStrategy getDoubleClickStrategy( + ISourceViewer sourceViewer, String contentType) { + if (doubleClickStrategy == null) + doubleClickStrategy = new DoubleClickStrategy(); + return doubleClickStrategy; + } + + /** + * Returns the ISRSyntaxScanner. If scanner is null it will be created. + * + * @return The current ISRSyntaxScanner + * + */ + private ISRSyntaxScanner getISRSyntaxScanner() { + if (scanner == null) { + scanner = new ISRSyntaxScanner(colorManager); + scanner.setDefaultReturnToken(new Token(new TextAttribute( + colorManager.getColor(IISRColorConstants.DEFAULT)))); + } + return scanner; + } + + @Override + public IPresentationReconciler getPresentationReconciler( + ISourceViewer sourceViewer) { + PresentationReconciler reconciler = new PresentationReconciler(); + DefaultDamagerRepairer dr = new DefaultDamagerRepairer( + getISRSyntaxScanner()); + reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE); + reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE); + + dr = new DefaultDamagerRepairer(getISRSyntaxScanner()); + reconciler.setDamager(dr, ISRPartitionScanner.ISR_IGNORE); + reconciler.setRepairer(dr, ISRPartitionScanner.ISR_IGNORE); + dr = new DefaultDamagerRepairer(getISRSyntaxScanner()); + reconciler.setDamager(dr, ISRPartitionScanner.ISR_RULE); + reconciler.setRepairer(dr, ISRPartitionScanner.ISR_RULE); + dr = new DefaultDamagerRepairer(getISRSyntaxScanner()); + return reconciler; + } + + @Override + public IContentAssistant getContentAssistant(ISourceViewer sv) { + ContentAssistant ca = new ContentAssistant(); + final ISRContentAssistantRuleProcessor carp = new ISRContentAssistantRuleProcessor(); + final ISRContentAssistantIgnoreRuleProcessor cairp = new ISRContentAssistantIgnoreRuleProcessor(); + final ISRContentAssistantDefaultProcessor cadp = new ISRContentAssistantDefaultProcessor(); + ca.setContentAssistProcessor(carp, ISRPartitionScanner.ISR_RULE); + ca.setContentAssistProcessor(cairp, ISRPartitionScanner.ISR_IGNORE); + ca.setContentAssistProcessor(cadp, IDocument.DEFAULT_CONTENT_TYPE); + ca.setInformationControlCreator(getInformationControlCreator(sv)); + + ca.addCompletionListener(new ICompletionListener() { + + @Override + public void selectionChanged(ICompletionProposal arg0, boolean arg1) { + } + + @Override + public void assistSessionStarted(ContentAssistEvent arg0) { + ((ISRContentAssistantRuleProcessor) carp) + .setOverride(getSelectedText(editor).length()); + ((ISRContentAssistantIgnoreRuleProcessor) cairp) + .setOverride(getSelectedText(editor).length()); + ((ISRContentAssistantDefaultProcessor) cadp) + .setOverride(getSelectedText(editor).length()); + + } + + @Override + public void assistSessionEnded(ContentAssistEvent arg0) { + } + }); + return ca; + } + + /** + * Returns the current selected text from a specified editor. + * + * @param editor + * The Editor from which the selection should take. + * @return The current Selection + */ + private String getSelectedText(ITextEditor editor) { + ISelection selection = editor.getSelectionProvider().getSelection(); + return ((ITextSelection) selection).getText(); + } + + @Override + public IHyperlinkDetector[] getHyperlinkDetectors(ISourceViewer sourceViewer) { + return new IHyperlinkDetector[] { new IsrHyperLinkDetector(editor) }; + } + + @Override + public IContentFormatter getContentFormatter(ISourceViewer sourceViewer) { + ContentFormatter formatter = new ContentFormatter(); + RuleFormattingStrategy ruleFormattingStrategy = new RuleFormattingStrategy(); + IgnoreFormattingStrategy ignoreFormattingStrategy = new IgnoreFormattingStrategy(); + DefaultFormattingStrategy defaultFormattingStrategy = new DefaultFormattingStrategy(); + formatter.setFormattingStrategy(defaultFormattingStrategy, + IDocument.DEFAULT_CONTENT_TYPE); + formatter.setFormattingStrategy(ignoreFormattingStrategy, + ISRPartitionScanner.ISR_IGNORE); + formatter.setFormattingStrategy(ruleFormattingStrategy, + ISRPartitionScanner.ISR_RULE); + return formatter; + } + + @Override + public ITextHover getTextHover(ISourceViewer sourceViewer, + String contentType) { + return new GenerateHoverInfos(sourceViewer, contentType); + } + + @Override + public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) { + super.getAnnotationHover(sourceViewer); + return new IISRAnnontationHover(); + } + +} \ No newline at end of file diff --git a/isr-eclipse-plugin/src/hterhors/editor/format/DefaultFormattingStrategy.java b/isr-eclipse-plugin/src/hterhors/editor/format/DefaultFormattingStrategy.java new file mode 100644 index 0000000000000000000000000000000000000000..c0dc5b43bad3d36587763aa76ade20569d86240b --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/format/DefaultFormattingStrategy.java @@ -0,0 +1,28 @@ +package hterhors.editor.format; + +import org.eclipse.jface.text.formatter.IFormattingStrategy; + +public class DefaultFormattingStrategy implements IFormattingStrategy { + + protected static final String lineSeparator = System + .getProperty("line.separator"); + + public DefaultFormattingStrategy() { + super(); + } + + public void formatterStarts(String initialIndentation) { + } + + public String format(String content, boolean isLineStart, + String indentation, int[] positions) { + content = content.replace(lineSeparator, " "); + content = content.replaceAll("\\s+", " "); + content = content.replace("\t", " "); + return content; + } + + public void formatterStops() { + } + +} \ No newline at end of file diff --git a/isr-eclipse-plugin/src/hterhors/editor/format/IgnoreFormattingStrategy.java b/isr-eclipse-plugin/src/hterhors/editor/format/IgnoreFormattingStrategy.java new file mode 100644 index 0000000000000000000000000000000000000000..94f35075df1f43d2fc456645a89ce8a485d37fb7 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/format/IgnoreFormattingStrategy.java @@ -0,0 +1,26 @@ +package hterhors.editor.format; + +import org.eclipse.jface.text.formatter.IFormattingStrategy; + +public class IgnoreFormattingStrategy implements IFormattingStrategy { + + protected static final String lineSeparator = System + .getProperty("line.separator"); + + public IgnoreFormattingStrategy() { + super(); + } + + public void formatterStarts(String initialIndentation) { + } + + public String format(String content, boolean isLineStart, + String indentation, int[] positions) { + return content.replace(lineSeparator, " ").replaceAll("\\s+", " ") + + lineSeparator + lineSeparator; + } + + public void formatterStops() { + } + +} \ No newline at end of file diff --git a/isr-eclipse-plugin/src/hterhors/editor/format/RuleFormattingStrategy.java b/isr-eclipse-plugin/src/hterhors/editor/format/RuleFormattingStrategy.java new file mode 100644 index 0000000000000000000000000000000000000000..975f94afb5378ed41faa5056c7351d1b28e0b31e --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/format/RuleFormattingStrategy.java @@ -0,0 +1,41 @@ +package hterhors.editor.format; + +import java.util.StringTokenizer; + +import org.eclipse.jface.text.formatter.IFormattingStrategy; + +public class RuleFormattingStrategy implements IFormattingStrategy { + + protected static final String lineSeparator = System + .getProperty("line.separator"); + + public RuleFormattingStrategy() { + super(); + } + + public void formatterStarts(String initialIndentation) { + } + + public String format(String content, boolean isLineStart, + String indentation, int[] positions) { + content = content.replace(lineSeparator, " "); + content = content.replaceAll("\\s+", " "); + content = content.replace("\t", " "); + StringTokenizer stringTokenizer = new StringTokenizer(content); + String space = ""; + if (stringTokenizer.hasMoreTokens()) { + String token = stringTokenizer.nextToken(); + for (int i = 0; i < token.length(); i++) { + space += " "; + } + } + content = content.replace("|", lineSeparator + space + "|"); + content = content.replace(";", ";" + lineSeparator + lineSeparator); + return content; + + } + + public void formatterStops() { + } + +} \ No newline at end of file diff --git a/isr-eclipse-plugin/src/hterhors/editor/helper/Word.java b/isr-eclipse-plugin/src/hterhors/editor/helper/Word.java new file mode 100644 index 0000000000000000000000000000000000000000..28d6d1a2a64438a64d82197b7cadd971d13b7b1a --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/helper/Word.java @@ -0,0 +1,103 @@ +package hterhors.editor.helper; + +/** + * @author Hendrik + */ +public class Word { + /** + * @uml.property name="beginningOffset" + */ + private int beginningOffset = 0; + /** + * @uml.property name="endOffset" + */ + private int endOffset = 0; + /** + * @uml.property name="word" + */ + private StringBuffer word = new StringBuffer(); + private String document; + private int offset; + /** + * @uml.property name="isNull" + */ + private boolean isNull; + + public Word(int offset, String document) { + this.offset = offset; + this.document = document; + calculate(); + } + + + + /** + * @return + * @uml.property name="isNull" + */ + public boolean isNull() { + return isNull; + } + + + /** + * @return + * @uml.property name="beginningOffset" + */ + public int getBeginningOffset() { + return offset - beginningOffset; + } + + /** + * @return + * @uml.property name="endOffset" + */ + public int getEndOffset() { + return offset + endOffset; + } + + /** + * @return + * @uml.property name="word" + */ + public String getWord() { + return word.toString(); + } + + private void calculate() { + char c = document.charAt(offset); + if (Character.isWhitespace(c) || offset == 0) { + isNull = true; + return; + } else { + word.append(c); + } + while (true) { + beginningOffset++; + if (offset - beginningOffset >= 0) { + c = document.charAt(offset - beginningOffset); + if (Character.isWhitespace(c)) { + break; + } else { + word.append(c); + } + } else { + break; + } + } + word = word.reverse(); + while (true) { + endOffset++; + if (offset + endOffset < document.length()) { + c = document.charAt(offset + endOffset); + if (Character.isWhitespace(c)) { + break; + } else { + word.append(c); + } + } else { + break; + } + } + } +} \ No newline at end of file diff --git a/isr-eclipse-plugin/src/hterhors/editor/hoverinfos/GenerateHoverInfos.java b/isr-eclipse-plugin/src/hterhors/editor/hoverinfos/GenerateHoverInfos.java new file mode 100644 index 0000000000000000000000000000000000000000..c5997e23ea7772cbf239105bf912e81c1fdcd302 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/hoverinfos/GenerateHoverInfos.java @@ -0,0 +1,82 @@ +package hterhors.editor.hoverinfos; + +import hterhors.editor.helper.Word; +import hterhors.editor.markers.MarkerContainer; +import hterhors.editor.markers.ISRValidationObject; +import hterhors.editor.markers.IsrRuleValidator; + +import java.util.StringTokenizer; + +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextHover; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.source.ISourceViewer; + +public class GenerateHoverInfos implements ITextHover { + + public GenerateHoverInfos(ISourceViewer sourceViewer, String contentType) { + } + + @Override + public String getHoverInfo(ITextViewer viewer, IRegion region) { + String document = viewer.getDocument().get(); + int regOff; + Word word = new Word(regOff = region.getOffset(), document); + if (word.isNull()) { + return null; + } + for (ISRValidationObject err : MarkerContainer.getErrors(document)) { + if (regOff >= err.getColumnStart() && regOff <= err.getColumnEnd()) { + return err.getErrorMessage(); + } + } + for (ISRValidationObject warn : MarkerContainer.getWarnings(document)) { + if (regOff >= warn.getColumnStart() + && regOff <= warn.getColumnEnd()) { + return warn.getErrorMessage(); + } + } + boolean isIndex = false; + if (word.getWord().matches(IsrRuleValidator.NON_TERMINAL + "(;?|:?)")) { + String text = word.getWord().replace(";", "").replace(":", ""); + int begin = document.indexOf(text); + do { + StringTokenizer stringTokenizer = new StringTokenizer( + document.substring(begin)); + while (stringTokenizer.hasMoreTokens()) { + String cT = stringTokenizer.nextToken(); + if (cT.matches(IsrRuleValidator.NON_TERMINAL_DECLARATION)) { + isIndex = true; + } else if (cT.matches(IsrRuleValidator.NON_TERMINAL) + && stringTokenizer.hasMoreTokens()) { + if (stringTokenizer.nextToken().matches( + IsrRuleValidator.C)) { + isIndex = true; + } + } + break; + } + if (isIndex) { + break; + } + } while ((begin = document.indexOf(text, begin + text.length())) != -1 + || !isIndex); + StringTokenizer hoverInfo; + hoverInfo = new StringTokenizer(document.substring(begin), ";", + true); + if (hoverInfo.hasMoreTokens()) { + return "\nDeclaration: \n\n " + hoverInfo.nextToken() + " ;\n"; + } else { + return null; + } + } + return null; + } + + @Override + public IRegion getHoverRegion(ITextViewer viewer, int offset) { + return new Region(offset, 20); + } + +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/hoverinfos/IISRAnnontationHover.java b/isr-eclipse-plugin/src/hterhors/editor/hoverinfos/IISRAnnontationHover.java new file mode 100644 index 0000000000000000000000000000000000000000..dbe7ad914355934bb888037d82fa9eab96ae5ee6 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/hoverinfos/IISRAnnontationHover.java @@ -0,0 +1,45 @@ +package hterhors.editor.hoverinfos; + +import java.util.Iterator; + +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.text.source.IAnnotationHover; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.ui.texteditor.MarkerAnnotation; + +public class IISRAnnontationHover implements IAnnotationHover { + + @Override + public String getHoverInfo(ISourceViewer sourceViewer, int i) { + StringBuffer out = new StringBuffer(); + boolean begin = true; + for (@SuppressWarnings("unchecked") + Iterator<MarkerAnnotation> iterator = (Iterator<MarkerAnnotation>) sourceViewer + .getAnnotationModel().getAnnotationIterator(); iterator + .hasNext();) { + try { + Object maO; + if ((maO = iterator.next()) instanceof MarkerAnnotation) { + MarkerAnnotation ma = (MarkerAnnotation) maO; + IMarker m = (IMarker) ma.getMarker(); + Integer line = Integer.valueOf((Integer) m + .getAttribute(IMarker.LINE_NUMBER)); + if (i+1 == line) { + if (!begin) { + out.append("\n"); + } + out.append((String) m.getAttribute(IMarker.MESSAGE)); + begin = false; + } + } + } catch (NumberFormatException e) { + e.printStackTrace(); + } catch (CoreException e) { + e.printStackTrace(); + } + + } + return out.toString(); + } +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/hyperlink/IsrHyperLinkDetector.java b/isr-eclipse-plugin/src/hterhors/editor/hyperlink/IsrHyperLinkDetector.java new file mode 100644 index 0000000000000000000000000000000000000000..012d3ee371994c8b91a69f9d485e9329ce8de402 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/hyperlink/IsrHyperLinkDetector.java @@ -0,0 +1,56 @@ +package hterhors.editor.hyperlink; + +import hterhors.editor.ISREditor; +import hterhors.editor.helper.Word; +import hterhors.editor.markers.IsrRuleValidator; + +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector; +import org.eclipse.jface.text.hyperlink.IHyperlink; +import org.eclipse.jface.text.hyperlink.IHyperlinkDetector; + + +/** + * @author Hendrik + */ +public class IsrHyperLinkDetector extends AbstractHyperlinkDetector implements IHyperlinkDetector { + + /** + * @uml.property name="editor" + * @uml.associationEnd + */ + private ISREditor editor; + + public IsrHyperLinkDetector() { + } + + public IsrHyperLinkDetector(ISREditor editor) { + this.editor = editor; + } + + public IHyperlink[] detectHyperlinks(ITextViewer textViewer, + IRegion region, boolean canShowMultipleHyperlinks) { + IDocument document = textViewer.getDocument(); + Word word = new Word(region.getOffset(), document.get()); + if (word.isNull() || !checkValidWord(word.getWord())) { + return null; + } + String text = word.getWord().replace(";", "").replaceAll(":",""); + if (word.getBeginningOffset() < 0 || word.getEndOffset() < 0 + || word.getBeginningOffset() == word.getEndOffset() + 1) { + return null; + } + IRegion reg = new Region(word.getBeginningOffset() + 1, text + .length()); + return new IHyperlink[] { new IsrHyperlink(reg, text, editor, + document) }; + } + + private boolean checkValidWord(String word) { + return word.matches(IsrRuleValidator.NON_TERMINAL + ";?"); + } + +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/hyperlink/IsrHyperlink.java b/isr-eclipse-plugin/src/hterhors/editor/hyperlink/IsrHyperlink.java new file mode 100644 index 0000000000000000000000000000000000000000..3ecf20720fd870bdc29c83eb3b8dfcf5dec99e25 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/hyperlink/IsrHyperlink.java @@ -0,0 +1,75 @@ +package hterhors.editor.hyperlink; + +import java.util.StringTokenizer; + +import hterhors.editor.ISREditor; +import hterhors.editor.markers.IsrRuleValidator; + +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.hyperlink.IHyperlink; + +/** + * Java element hyperlink. + * @since 3.1 + */ +public class IsrHyperlink implements IHyperlink { + + private String word; + private IRegion region; + /** + * @uml.property name="editor" + * @uml.associationEnd + */ + private ISREditor editor; + private String document; + + public IsrHyperlink(IRegion region, String text, ISREditor editor, + IDocument document) { + this.editor = editor; + this.region = region; + this.word = text; + this.document = document.get(); + } + + public IRegion getHyperlinkRegion() { + return region; + } + + public void open() { + boolean isIndex = false; + int begin = document.indexOf(word); + do { + StringTokenizer stringTokenizer = new StringTokenizer( + document.substring(begin)); + while (stringTokenizer.hasMoreTokens()) { + String cT = stringTokenizer.nextToken(); + if (cT.matches(IsrRuleValidator.NON_TERMINAL_DECLARATION)) { + isIndex = true; + } else if (cT.matches(IsrRuleValidator.NON_TERMINAL) + && stringTokenizer.hasMoreTokens()) { + if (stringTokenizer.nextToken().matches(IsrRuleValidator.C)) { + isIndex = true; + } + } + break; + } + if (isIndex) { + break; + } + } while ((begin = document.indexOf(word, begin + word.length())) != -1 + || !isIndex); + + editor.selectAndReveal(begin, word.length() + 1); + editor.setFocus(); + } + + public String getTypeLabel() { + return null; + } + + public String getHyperlinkText() { + return null; + } + +} \ No newline at end of file diff --git a/isr-eclipse-plugin/src/hterhors/editor/info/InfoExampleHandler.java b/isr-eclipse-plugin/src/hterhors/editor/info/InfoExampleHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..aff88dc458266ca02211ee47f08d50e514084ce4 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/info/InfoExampleHandler.java @@ -0,0 +1,34 @@ +package hterhors.editor.info; + +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.texteditor.ITextEditor; + +public class InfoExampleHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + ITextEditor textEditor = (ITextEditor) HandlerUtil + .getActiveEditor(event); + IEditorInput input = HandlerUtil.getActiveEditorInput(event); + Shell shell = HandlerUtil.getActiveShell(event); + + MessageBox mb = new MessageBox(shell, SWT.SMOOTH); + mb.setText("General infos"); + mb.setMessage(InfoStringGetter.infoStringGetter(getClass(),"/resources/info_example.txt")); + mb.open(); + return null; + } +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/info/InfoFunctionalityHandler.java b/isr-eclipse-plugin/src/hterhors/editor/info/InfoFunctionalityHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..5687d9d25c380fc0ad6ffd5bfcd1369ec3ac17bf --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/info/InfoFunctionalityHandler.java @@ -0,0 +1,22 @@ +package hterhors.editor.info; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.handlers.HandlerUtil; + +public class InfoFunctionalityHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + Shell shell = HandlerUtil.getActiveShell(event); + MessageBox mb = new MessageBox(shell, SWT.SMOOTH); + mb.setText("Functionality infos"); + mb.setMessage(InfoStringGetter.infoStringGetter(getClass(),"/resources/info_functionality.txt")); + mb.open(); + return null; + } +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/info/InfoGeneralHandler.java b/isr-eclipse-plugin/src/hterhors/editor/info/InfoGeneralHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..70778fbcd32ea1d1b779e6e2f6badaec1241a015 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/info/InfoGeneralHandler.java @@ -0,0 +1,28 @@ +package hterhors.editor.info; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.texteditor.ITextEditor; + +public class InfoGeneralHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + ITextEditor textEditor = (ITextEditor) HandlerUtil + .getActiveEditor(event); + IEditorInput input = HandlerUtil.getActiveEditorInput(event); + Shell shell = HandlerUtil.getActiveShell(event); + + MessageBox mb = new MessageBox(shell, SWT.SMOOTH); + mb.setText("General infos"); + mb.setMessage(InfoStringGetter.infoStringGetter(getClass(),"/resources/info_general.txt")); + mb.open(); + return null; + } +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/info/InfoStringGetter.java b/isr-eclipse-plugin/src/hterhors/editor/info/InfoStringGetter.java new file mode 100644 index 0000000000000000000000000000000000000000..cf61a160b1751d7d6254a35ff16cf5e70deb877f --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/info/InfoStringGetter.java @@ -0,0 +1,38 @@ +package hterhors.editor.info; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +import org.eclipse.core.commands.AbstractHandler; + +public class InfoStringGetter { + + public static String infoStringGetter( + Class<? extends AbstractHandler> class1,String path) { + StringBuffer info = new StringBuffer(); + String tmp; + InputStreamReader reader = null; + BufferedReader d = null; + try { + InputStream bis = null; + bis = class1.getResource(path) + .openStream(); + reader = new InputStreamReader(bis); + d = new BufferedReader(reader); + while ((tmp = d.readLine()) != null) + info.append(tmp + "\n"); + + } catch (IOException e1) { + return "An error has accrued!\n Missing resources could be the trigger."; + } finally { + try { + if (d != null) + d.close(); + } catch (IOException e) { + } + } + return info.toString(); + } +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/info/InfoSyntaxHandler.java b/isr-eclipse-plugin/src/hterhors/editor/info/InfoSyntaxHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..95e5e9d1b1d788b3aa67abff187012675f82e0d8 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/info/InfoSyntaxHandler.java @@ -0,0 +1,29 @@ +package hterhors.editor.info; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.texteditor.ITextEditor; + +public class InfoSyntaxHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + ITextEditor textEditor = (ITextEditor) HandlerUtil + .getActiveEditor(event); + IEditorInput input = HandlerUtil.getActiveEditorInput(event); + Shell shell = HandlerUtil.getActiveShell(event); + + MessageBox mb = new MessageBox(shell, SWT.SMOOTH); + mb.setText("General infos"); + mb.setMessage(InfoStringGetter.infoStringGetter(getClass(),"/resources/info_syntax.txt")); + mb.open(); + return null; + } + +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/markers/EISRType.java b/isr-eclipse-plugin/src/hterhors/editor/markers/EISRType.java new file mode 100644 index 0000000000000000000000000000000000000000..a14040a4265f988f4e7595724f726d506951839d --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/markers/EISRType.java @@ -0,0 +1,58 @@ +package hterhors.editor.markers; + +/** + * @author Hendrik + */ +public enum EISRType { + + /** + * @uml.property name="sTART" + * @uml.associationEnd + */ + START, /** + * @uml.property name="dECLARATION_NON_TERMINAL" + * @uml.associationEnd + */ + DECLARATION_NON_TERMINAL, /** + * @uml.property name="oR" + * @uml.associationEnd + */ + OR, /** + * @uml.property name="tERMINAL" + * @uml.associationEnd + */ + TERMINAL, /** + * @uml.property name="nON_TERMINAL" + * @uml.associationEnd + */ + NON_TERMINAL, /** + * @uml.property name="nONTERMINAL_END" + * @uml.associationEnd + */ + NONTERMINAL_END, /** + * @uml.property name="tECHNICAL_NON_TERMINAL_END" + * @uml.associationEnd + */ + TECHNICAL_NON_TERMINAL_END, /** + * @uml.property name="tERMINAL_END" + * @uml.associationEnd + */ + TERMINAL_END, /** + * @uml.property name="tECHNICAL_DECLARATION_NON_TERMINAL" + * @uml.associationEnd + */ + TECHNICAL_DECLARATION_NON_TERMINAL, /** + * @uml.property name="tECHNICAL_NON_TERMINAL" + * @uml.associationEnd + */ + TECHNICAL_NON_TERMINAL, /** + * @uml.property name="jOKER_TERMINAL_END" + * @uml.associationEnd + */ + JOKER_TERMINAL_END, /** + * @uml.property name="jOKER_TERMINAL" + * @uml.associationEnd + */ + JOKER_TERMINAL; + +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/markers/ISRValidationObject.java b/isr-eclipse-plugin/src/hterhors/editor/markers/ISRValidationObject.java new file mode 100644 index 0000000000000000000000000000000000000000..84bf2e24932d08cbe108cd54669604fd6a92d123 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/markers/ISRValidationObject.java @@ -0,0 +1,93 @@ +package hterhors.editor.markers; + +/** + * @author Hendrik + */ +public class ISRValidationObject { + /** + * @uml.property name="errorMessage" + */ + private String errorMessage; + /** + * @uml.property name="lineNumber" + */ + private int lineNumber; + /** + * @uml.property name="columnStart" + */ + private int columnStart; + /** + * @uml.property name="columnEnd" + */ + private int columnEnd; + /** + * @uml.property name="type" + * @uml.associationEnd + */ + private EValidType type; + + public ISRValidationObject(String errorMessage, int lineNumber, + int columnStart, int columnEnd, EValidType type) { + this.errorMessage = errorMessage; + this.lineNumber = lineNumber; + this.columnStart = columnStart; + this.columnEnd = columnEnd; + this.type = type; + } + + /** + * @return + * @uml.property name="errorMessage" + */ + public String getErrorMessage() { + return errorMessage; + } + + /** + * @return + * @uml.property name="lineNumber" + */ + public int getLineNumber() { + return lineNumber; + } + + /** + * @return + * @uml.property name="columnStart" + */ + public int getColumnStart() { + return columnStart; + } + + /** + * @return + * @uml.property name="columnEnd" + */ + public int getColumnEnd() { + return columnEnd; + } + + public String toString() { + StringBuffer buf = new StringBuffer(); + buf.append(type + " on ").append(" line ").append(lineNumber) + .append(", column starts ").append(columnStart) + .append(", column ends ").append(columnEnd).append(": ") + .append(errorMessage).append("\n"); + return buf.toString(); + } + + /** + * @author Hendrik + */ + enum EValidType { + /** + * @uml.property name="error" + * @uml.associationEnd + */ + Error, /** + * @uml.property name="warning" + * @uml.associationEnd + */ + Warning; + } +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/markers/IsrRuleValidator.java b/isr-eclipse-plugin/src/hterhors/editor/markers/IsrRuleValidator.java new file mode 100644 index 0000000000000000000000000000000000000000..c830cf9e2d70b01e87d8e6b0461c30c99cd336ce --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/markers/IsrRuleValidator.java @@ -0,0 +1,595 @@ +package hterhors.editor.markers; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; + +public class IsrRuleValidator { + + public static final String TERMINAL = "([a-zA-Z_\\\"][a-zA-Z_\\-\\\"0-9]*)"; + public static final String IGNORE = "%IGNORE"; + public static final String PRE_START_SYMBOL = "\\$\\$S"; + public static final String NON_TERMINAL_DECLARATION = "(\\${1,2}[a-zA-Z_\\\"][a-zA-Z_\\-\\\"0-9]*:)"; + public static final String NON_TERMINAL = "(\\${1,2}[a-zA-Z_\\\"][a-zA-Z_\\-\\\"0-9]*)"; + public static final String C = ":"; + public static final String E = ";"; + public static final String NUMBER = "\\[-?[0-9]+\\]"; + public static final String WRONG_NUMBER = "\\[.+\\]|\\[.+|.+\\]"; + public static final String O = "(\\|)"; + private static final String S = "(\\$\\$S)"; + private static final String N = "(\\${1,2}[a-zA-Z_\\\"][a-zA-Z_\\-\\\"0-9]*)"; + private static final String J = "((!\\*)|([a-zA-Z_\\\"][a-zA-Z_\\-\\\"0-9]*))"; + private static final String J_T_N = J + "|" + N; + private static final String JE_TE_NE = "(" + J + ";)|(" + N + ";)"; + static List<ISRValidationObject> errors = new ArrayList<ISRValidationObject>(); + static List<ISRValidationObject> warnings = new ArrayList<ISRValidationObject>(); + protected static final String lineSeparator = System + .getProperty("line.separator"); + + private static IDocument doc; + + public static List<ISRValidationObject> parseErrors(String isrGrammar) { + errors = new ArrayList<ISRValidationObject>(); + warnings = new ArrayList<ISRValidationObject>(); + doc = new Document(isrGrammar); + multipleDeclarations(isrGrammar); + checkValidStartSymbol(isrGrammar); + // checkWellSpelled(isrGrammar); + hasAllNonTerminalsDeclared(isrGrammar); + checkSyntax(isrGrammar); + return errors; + } + + public static List<ISRValidationObject> parseWarnings(String isrGrammar) { + warnUnusedNonterminalDeclaration(isrGrammar); + warnSameNamedNTAndT(isrGrammar); + return warnings; + } + + private static void warnSameNamedNTAndT(String isrGrammar) { + final List<Pair> nonTerminals = new ArrayList<Pair>(); + final List<Pair> terminals = new ArrayList<Pair>(); + prepareNonAndTerminals(isrGrammar, nonTerminals, terminals); + for (Pair pair : terminals) { + if (nonTerminals.remove(pair)) { + addWarning( + "Terminal has same name like an existing noterminal! Rename token ", + pair.integer, pair.string); + } + } + } + + private static int lastFullLine = 0; + + private static List<StringTokenizer> partition(String isrGrammar) { + final List<StringTokenizer> partList = new ArrayList<StringTokenizer>(); + for (final String iterable_element : isrGrammar.split(lineSeparator)) { + partList.add(new StringTokenizer(iterable_element)); + + } + lastFullLine = partList.size(); + for (StringTokenizer stringTokenizer : partList) { + if (stringTokenizer.countTokens() == 0) { + lastFullLine--; + } else { + break; + } + } + return partList; + } + + private static void multipleDeclarations(String isrGrammar) { + final List<Pair> nonTerminals = new ArrayList<Pair>(); + final List<StringTokenizer> partList = partition(isrGrammar); + String preToken = null; + StringTokenizer stringTokenizer; + for (int i = 0; i < partList.size(); i++) { + stringTokenizer = partList.get(i); + while (stringTokenizer.hasMoreTokens()) { + if (preToken == null) { + preToken = stringTokenizer.nextToken(); + } + String nextToken; + if (preToken.matches(NON_TERMINAL) + && !preToken.matches(PRE_START_SYMBOL) + && stringTokenizer.hasMoreTokens()) { + nextToken = stringTokenizer.nextToken(); + if (nextToken.equals(C)) { + if (nonTerminals.contains(new Pair( + getAttributeName(preToken), 0))) { + addError( + "Multiple entry for non-terminal-declaration", + i, preToken); + } else { + nonTerminals.add(new Pair( + getAttributeName(preToken), 0)); + } + preToken = null; + } else { + preToken = nextToken; + } + } else if (preToken.matches(NON_TERMINAL_DECLARATION) + && !preToken.matches(PRE_START_SYMBOL + C)) { + if (nonTerminals.contains(new Pair( + getAttributeName(preToken), 0))) { + addError("Multiple entry for non-terminal-declaration", + i, preToken); + } else { + nonTerminals + .add(new Pair(getAttributeName(preToken), 0)); + } + preToken = null; + } else { + preToken = null; + } + } + } + } + + private static void checkValidStartSymbol(String isrGrammar) { + final List<StringTokenizer> partList = partition(isrGrammar); + String preToken = null; + int countStartSymbol = 0; + StringTokenizer stringTokenizer; + for (int i = 0; i < partList.size(); i++) { + stringTokenizer = partList.get(i); + while (stringTokenizer.hasMoreTokens()) { + if (preToken == null) { + preToken = stringTokenizer.nextToken(); + } + String nextToken; + if (preToken.matches(PRE_START_SYMBOL + "S:?")) { + addError("Illigal declaration for nonterminal", i, preToken); + preToken = null; + } else if (preToken.matches(PRE_START_SYMBOL) + && stringTokenizer.hasMoreTokens()) { + nextToken = stringTokenizer.nextToken(); + if (nextToken.equals(C)) { + if (countStartSymbol >= 1) { + addError("Multiple entry for start-symbol", i, + preToken); + } else { + countStartSymbol++; + } + preToken = null; + } else { + preToken = nextToken; + } + } else if (preToken.matches(PRE_START_SYMBOL + C)) { + if (countStartSymbol >= 1) { + addError("Multiple entry for start-symbol", i, preToken); + } else { + countStartSymbol++; + } + preToken = null; + } else { + preToken = null; + } + } + } + if (countStartSymbol == 0) { + addError("Missing start-symbol ", 0, "$$S:"); + } + } + + private static void addError(String message, int i, String token) { + int offsetStart = exctractOffset(i, token); + errors.add(new ISRValidationObject(message + " \"" + + getAttributeName(token) + "\"!", i, offsetStart, offsetStart + + token.length(), ISRValidationObject.EValidType.Error)); + } + + private static void hasAllNonTerminalsDeclared(String isrGrammar) { + final List<Pair> nonTerminals = new ArrayList<Pair>(); + final List<Pair> decNonTerminals = new ArrayList<Pair>(); + prepareNonTerminals(isrGrammar, nonTerminals, decNonTerminals); + for (Pair pair : nonTerminals) { + if (!decNonTerminals.remove(pair)) { + addError("Missing Non-Terminal-Declaration for element", + pair.integer, pair.string); + } + } + } + + static class Pair { + String string; + int integer; + + public Pair(String name, int integer) { + super(); + this.string = name; + this.integer = integer; + } + + @Override + public boolean equals(Object arg0) { + return string.equals(((Pair) (arg0)).string); + } + + @Override + public String toString() { + return "Pair [string=" + string + ", integer=" + integer + "]"; + } + + } + + private static void warnUnusedNonterminalDeclaration(String isrGrammar) { + final List<Pair> nonTerminals = new ArrayList<Pair>(); + final List<Pair> decNonTerminals = new ArrayList<Pair>(); + prepareNonTerminals(isrGrammar, nonTerminals, decNonTerminals); + for (Pair pair : decNonTerminals) { + if (!nonTerminals.remove(pair)) { + if (!pair.string.equals("SS")) { + addWarning("Unused Non-Terminal-Declaration for element", + pair.integer, pair.string); + } + } + } + } + + private static void addWarning(String message, int i, String token) { + int offsetStart = exctractOffset(i, token); + warnings.add(new ISRValidationObject(message + "\"" + token + "\"!", i, + offsetStart, offsetStart + token.length(), + ISRValidationObject.EValidType.Warning)); + } + + private static void prepareNonTerminals(String isrGrammar, + List<Pair> nonTerminals, List<Pair> decNonTerminals) { + String preToken = null; + final List<StringTokenizer> partList = partition(isrGrammar); + StringTokenizer stringTokenizer; + for (int i = 0; i < partList.size(); i++) { + stringTokenizer = partList.get(i); + while (stringTokenizer.hasMoreElements()) { + if (preToken == null) { + preToken = stringTokenizer.nextToken(); + } + if (preToken.matches(NON_TERMINAL_DECLARATION) + && !preToken.matches(PRE_START_SYMBOL + C)) { + String nt = getAttributeName(preToken); + if (!decNonTerminals.contains(new Pair(nt, 0))) { + decNonTerminals.add(new Pair(nt, i)); + } + preToken = null; + } else if (preToken.matches(NON_TERMINAL) + && !preToken.matches(PRE_START_SYMBOL)) { + if (stringTokenizer.hasMoreTokens()) { + String nextToken = stringTokenizer.nextToken(); + String nt = getAttributeName(preToken); + if (nextToken.equals(C)) { + if (!decNonTerminals.contains(new Pair(nt, 0))) { + decNonTerminals.add(new Pair(nt, i)); + } + preToken = null; + } else { + if (!nonTerminals.contains(new Pair(nt, 0))) { + nonTerminals.add(new Pair(nt, i)); + } + preToken = nextToken; + } + } + } else if (preToken.matches(NON_TERMINAL + ";")) { + String nt = getAttributeName(preToken); + if (!nonTerminals.contains(new Pair(nt, 0))) { + nonTerminals.add(new Pair(nt, i)); + } + preToken = null; + } else { + preToken = null; + } + } + } + } + + private static void prepareNonAndTerminals(String isrGrammar, + List<Pair> nonTerminals, List<Pair> terminals) { + String preToken = null; + final List<StringTokenizer> partList = partition(isrGrammar); + StringTokenizer stringTokenizer; + for (int i = 0; i < partList.size(); i++) { + stringTokenizer = partList.get(i); + while (stringTokenizer.hasMoreElements()) { + preToken = stringTokenizer.nextToken(); + if (preToken.matches(TERMINAL + ";?")) { + String nt = getAttributeName(preToken); + if (!terminals.contains(new Pair(nt, 0))) { + terminals.add(new Pair(nt, i)); + } + } else if (preToken.matches(NON_TERMINAL + ";?")) { + String nt = getAttributeName(preToken); + if (!nonTerminals.contains(new Pair(nt, 0))) { + nonTerminals.add(new Pair(nt, i)); + } + } + } + } + } + + private static void checkSyntax(String isrGrammar) { + final List<StringTokenizer> partList = partition(isrGrammar); + StringTokenizer stringTokenizer; + String preToken = null; + boolean afterEnd = true; + List<Integer> ruleNumbers = new ArrayList<Integer>(); + for (int i = 0; i < partList.size(); i++) { + stringTokenizer = partList.get(i); + while (stringTokenizer.hasMoreElements()) { + if (preToken == null) { + preToken = stringTokenizer.nextToken(); + } + String nextToken; + if ((preToken.matches(IGNORE + "=")) + || (preToken.matches(IGNORE) + && stringTokenizer.hasMoreElements() && stringTokenizer + .nextToken().matches("="))) { + afterEnd = false; + do { + if (!stringTokenizer.hasMoreTokens()) { + i++; + stringTokenizer = partList.get(i); + } else { + nextToken = stringTokenizer.nextToken(); + if (nextToken.matches(TERMINAL)) { + } else if (nextToken.matches(TERMINAL + ";|" + E)) { + preToken = nextToken; + break; + } else { + addError("Syntax error on", i, nextToken); + } + preToken = nextToken; + } + } while (true); + } else if (preToken.matches(S)) { + afterEnd = false; + if (stringTokenizer.hasMoreTokens()) { + if ((nextToken = stringTokenizer.nextToken()) + .matches(C)) { + } else { + addError("Colon expected after", i, preToken); + } + preToken = nextToken; + } else { + preToken = null; + } + } else if (preToken.matches(S + C)) { + afterEnd = false; + if (stringTokenizer.hasMoreTokens()) { + if ((nextToken = stringTokenizer.nextToken()) + .matches(J_T_N + "|" + JE_TE_NE)) { + } else { + addError("Syntax error after \"" + preToken + + "\" on token", i, nextToken); + } + preToken = nextToken; + } else { + preToken = null; + } + } else if (afterEnd && preToken.matches(N)) { + afterEnd = false; + if (stringTokenizer.hasMoreTokens()) { + if ((nextToken = stringTokenizer.nextToken()) + .matches(C)) { + } else { + addError("Colon expected after", i, preToken); + } + preToken = nextToken; + } else { + preToken = null; + } + } else if (preToken.matches(N)) { + afterEnd = false; + if (stringTokenizer.hasMoreTokens()) { + if ((nextToken = stringTokenizer.nextToken()) + .matches(J_T_N + "|" + JE_TE_NE + "|" + E + + "|\\|")) { + } else { + addError("Syntax error on", i, nextToken); + } + preToken = nextToken; + } else { + preToken = null; + } + } else if (preToken.matches(N + C)) { + afterEnd = false; + if (stringTokenizer.hasMoreTokens()) { + if ((nextToken = stringTokenizer.nextToken()) + .matches(J_T_N + "|" + JE_TE_NE)) { + afterEnd = false; + } else { + addError("Syntax error after \"" + preToken + + "\" on token", i, nextToken); + } + preToken = nextToken; + } else { + preToken = null; + } + } else if (preToken.matches(C)) { + afterEnd = false; + if (stringTokenizer.hasMoreTokens()) { + if ((nextToken = stringTokenizer.nextToken()) + .matches(J_T_N + "|" + JE_TE_NE)) { + } else { + addError("Syntax error after \"" + preToken + + "\" on token", i, nextToken); + } + preToken = nextToken; + } else { + preToken = null; + } + } else if (preToken.matches(J_T_N)) { + afterEnd = false; + if (stringTokenizer.hasMoreTokens()) { + if ((nextToken = stringTokenizer.nextToken()) + .matches(J_T_N + "|" + JE_TE_NE + "|" + E + "|" + + O)) { + } else { + addError("Syntax error after \"" + preToken + + "\" on token", i, nextToken); + } + preToken = nextToken; + } else { + preToken = null; + } + } else if (preToken.matches(O)) { + afterEnd = false; + if (stringTokenizer.hasMoreTokens()) { + if ((nextToken = stringTokenizer.nextToken()) + .matches(J_T_N + "|" + JE_TE_NE + "|" + E)) { + } else { + addError("Syntax error after \"" + preToken + + "\" on token", i, nextToken); + } + preToken = nextToken; + } else { + preToken = null; + } + } else if (preToken.matches(JE_TE_NE + "|" + E + "|" + NUMBER)) { + afterEnd = true; + if (stringTokenizer.hasMoreTokens()) { + if ((nextToken = stringTokenizer.nextToken()).matches(S + + "|" + N + "|" + S + C + "|" + N + C + "|" + + NUMBER + "|" + IGNORE)) { + if (nextToken.matches(NUMBER)) { + String x = nextToken.substring(1, + nextToken.length() - 1); + Integer number = Integer.valueOf(x); + if(ruleNumbers.contains(number)){ + addError("Multiple rule-number on token", i, + nextToken); + }else{ + ruleNumbers.add(number); + } + } + } else { + if (nextToken.matches(WRONG_NUMBER)) { + addError("Not a valid rule-number: ", i, + nextToken); + } else { + addError("New rule expected on token", i, + nextToken); + } + } + preToken = nextToken; + } else { + preToken = null; + } + } else { + // addError("Element not well spelled", i, preToken); + preToken = null; + } + } + if (preToken != null && i == (partList.size() - 1) + && !preToken.matches(JE_TE_NE + "|" + E)) { + afterEnd = true; + addError("Valid end-symbol missing. Syntax error on token", + lastFullLine - 1, preToken); + } + } + } + + private static int exctractOffset(int i, String string) { + int x = 0; + try { + IRegion region = doc.getLineInformation(i); + String line = doc.get(region.getOffset(), region.getLength()); + x += region.getOffset(); + x += line.indexOf(string); + } catch (BadLocationException e) { + e.printStackTrace(); + } + return x; + } + + private static String getAttributeName(String token) { + if (token.length() != 1) { + return token.replace("$", "").replace("$$", "").replace(":", "") + .replace("!*", "").replace(";", ""); + } + return token; + } + + public static List<String> getNonterminalsDeclarations(String isrGrammar) { + final List<Pair> nonTerminals = new ArrayList<Pair>(); + final List<Pair> decNonTerminals = new ArrayList<Pair>(); + prepareNonTerminals(isrGrammar, nonTerminals, decNonTerminals); + List<String> returnvalue = new ArrayList<String>(); + for (Pair pair : decNonTerminals) { + if (nonTerminals.remove(pair)) { + returnvalue.add(pair.string); + } + } + return returnvalue; + } + + public static List<String> getNonterminals(String isrGrammar) { + final List<Pair> nonTerminals = new ArrayList<Pair>(); + final List<Pair> decNonTerminals = new ArrayList<Pair>(); + prepareNonTerminals(isrGrammar, nonTerminals, decNonTerminals); + List<String> returnvalue = new ArrayList<String>(); + for (Pair pair : nonTerminals) { + returnvalue.add(pair.string); + } + return returnvalue; + } + + public static List<String> getUnusedNonterminals(String isrGrammar) { + final List<Pair> nonTerminals = new ArrayList<Pair>(); + final List<Pair> decNonTerminals = new ArrayList<Pair>(); + prepareNonTerminals(isrGrammar, nonTerminals, decNonTerminals); + List<String> returnvalue = new ArrayList<String>(); + for (Pair pair : decNonTerminals) { + if (!nonTerminals.remove(pair)) { + returnvalue.add(pair.string); + } + } + return returnvalue; + } + + public static List<String> getMissingNontermDec(String isrGrammar) { + final List<Pair> nonTerminals = new ArrayList<Pair>(); + final List<Pair> decNonTerminals = new ArrayList<Pair>(); + prepareNonTerminals(isrGrammar, nonTerminals, decNonTerminals); + List<String> returnvalue = new ArrayList<String>(); + for (Pair pair : nonTerminals) { + if (!decNonTerminals.remove(pair)) { + returnvalue.add(pair.string); + } + } + return returnvalue; + } + + public static boolean startSymbolExists(String isrGrammar) { + final List<StringTokenizer> partList = partition(isrGrammar); + String preToken = null; + StringTokenizer stringTokenizer; + for (int i = 0; i < partList.size(); i++) { + stringTokenizer = partList.get(i); + while (stringTokenizer.hasMoreTokens()) { + if (preToken == null) { + preToken = stringTokenizer.nextToken(); + } + String nextToken; + if (preToken.matches(PRE_START_SYMBOL) + && stringTokenizer.hasMoreTokens()) { + nextToken = stringTokenizer.nextToken(); + if (nextToken.equals(C)) { + return true; + } else { + preToken = nextToken; + } + } else if (preToken.matches(PRE_START_SYMBOL + C)) { + return true; + } else { + preToken = null; + } + } + } + return false; + } +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/markers/MarkerContainer.java b/isr-eclipse-plugin/src/hterhors/editor/markers/MarkerContainer.java new file mode 100644 index 0000000000000000000000000000000000000000..1cfd6b64acbcb754434e08cf887f243813e5661e --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/markers/MarkerContainer.java @@ -0,0 +1,38 @@ +package hterhors.editor.markers; + +import java.util.List; + +public class MarkerContainer { + + private static List<ISRValidationObject> errors = null; + private static List<ISRValidationObject> warnings = null; + private static int hashCode = 0; + + private static void calcErrAndWarn(String document) { + isDirty(document); + errors = IsrRuleValidator.parseErrors(document); + warnings = IsrRuleValidator.parseWarnings(document); + + } + + public synchronized static boolean isDirty(String document) { + int tmp = document.hashCode(); + if (tmp == hashCode) { + return false; + } else { + hashCode = tmp; + return true; + } + } + + public static List<ISRValidationObject> getErrors(String document) { + calcErrAndWarn(document); + return errors; + } + + public static List<ISRValidationObject> getWarnings(String document) { + calcErrAndWarn(document); + return warnings; + } + +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/markers/MarkingErrorHandler.java b/isr-eclipse-plugin/src/hterhors/editor/markers/MarkingErrorHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..cd4c29aa1af761d470453f2e94467be188c68915 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/markers/MarkingErrorHandler.java @@ -0,0 +1,86 @@ +package hterhors.editor.markers; + +import java.util.List; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.text.IDocument; + +/** + * @author Hendrik + */ +public class MarkingErrorHandler { + + private IFile file; + private IDocument document; + + public MarkingErrorHandler(IFile file, IDocument document) { + super(); + + this.file = file; + this.document = document; + } + + /** + * @param document + * @uml.property name="document" + */ + public void setDocument(IDocument document) { + this.document = document; + } + + public synchronized void removeExistingMarker() { + try { + file.deleteMarkers(IMarker.PROBLEM, true, IResource.DEPTH_ZERO); + } catch (CoreException e1) { + e1.printStackTrace(); + } + } + + public synchronized void setCurrentMarker() { + final List<ISRValidationObject> warns = MarkerContainer + .getWarnings(document.get()); + final List<ISRValidationObject> errs = MarkerContainer + .getErrors(document.get()); + /* + * Avoid ConcurrentModificationException + */ + final ISRValidationObject[] warnsArray; + warnsArray = warns.toArray(new ISRValidationObject[warns.size()]); + final ISRValidationObject[] errsArray; + errsArray = errs.toArray(new ISRValidationObject[errs.size()]); + + for (final ISRValidationObject warn : warnsArray) { + try { + final IMarker marker; + marker = file.createMarker(IMarker.PROBLEM); + marker.setAttribute(IMarker.LINE_NUMBER, + warn.getLineNumber() + 1); + marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_WARNING); + marker.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_NORMAL); + marker.setAttribute(IMarker.MESSAGE, warn.getErrorMessage()); + marker.setAttribute(IMarker.CHAR_START, warn.getColumnStart()); + marker.setAttribute(IMarker.CHAR_END, warn.getColumnEnd()); + } catch (CoreException e) { + e.printStackTrace(); + } + } + for (final ISRValidationObject error : errsArray) { + try { + final IMarker marker; + marker = file.createMarker(IMarker.PROBLEM); + marker.setAttribute(IMarker.LINE_NUMBER, + error.getLineNumber() + 1); + marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR); + marker.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_HIGH); + marker.setAttribute(IMarker.MESSAGE, error.getErrorMessage()); + marker.setAttribute(IMarker.CHAR_START, error.getColumnStart()); + marker.setAttribute(IMarker.CHAR_END, error.getColumnEnd()); + } catch (CoreException e) { + e.printStackTrace(); + } + } + } +} \ No newline at end of file diff --git a/isr-eclipse-plugin/src/hterhors/editor/outline/EditorContentOutlinePage.java b/isr-eclipse-plugin/src/hterhors/editor/outline/EditorContentOutlinePage.java new file mode 100644 index 0000000000000000000000000000000000000000..9e514285ed590f9e4f4ef6b47c3ff297af0a961a --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/outline/EditorContentOutlinePage.java @@ -0,0 +1,93 @@ +package hterhors.editor.outline; + +import hterhors.editor.xml.XMLElement; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.texteditor.ITextEditor; +import org.eclipse.ui.views.contentoutline.ContentOutlinePage; + + +/** + * @author Hendrik + */ +public class EditorContentOutlinePage extends ContentOutlinePage { + + private ITextEditor editor; + private IEditorInput input; + /** + * @uml.property name="outlineContentProvider" + * @uml.associationEnd + */ + private OutlineContentProvider outlineContentProvider; + /** + * @uml.property name="outlineLabelProvider" + * @uml.associationEnd + */ + private OutlineLabelProvider outlineLabelProvider; + + public EditorContentOutlinePage(ITextEditor editor) { + super(); + this.editor = editor; + } + + public void createControl(Composite parent) { + + super.createControl(parent); + TreeViewer viewer = getTreeViewer(); + outlineContentProvider = new OutlineContentProvider( + editor.getDocumentProvider()); + viewer.setContentProvider(outlineContentProvider); + + outlineLabelProvider = new OutlineLabelProvider(); + viewer.setLabelProvider(outlineLabelProvider); + viewer.addSelectionChangedListener(this); + + if (input != null) + viewer.setInput(input); + } + + public void setInput(Object input) { + this.input = (IEditorInput) input; + update(); + } + + public void selectionChanged(SelectionChangedEvent event) { + super.selectionChanged(event); + ISelection selection = event.getSelection(); + if (selection.isEmpty()) + editor.resetHighlightRange(); + else { + XMLElement element = (XMLElement) ((IStructuredSelection) selection) + .getFirstElement(); + + int start = element.getPosition().getOffset(); + int length = element.getPosition().getLength(); + try { + editor.setHighlightRange(start, length, true); + } catch (IllegalArgumentException x) { + editor.resetHighlightRange(); + } + } + } + + public void update() { + TreeViewer viewer = getTreeViewer(); + + if (viewer != null) { + Control control = viewer.getControl(); + if (control != null && !control.isDisposed()) { + control.setRedraw(false); + viewer.setInput(input); + viewer.expandAll(); + control.setRedraw(true); + } + } + } + +} \ No newline at end of file diff --git a/isr-eclipse-plugin/src/hterhors/editor/outline/OutlineContentHandler.java b/isr-eclipse-plugin/src/hterhors/editor/outline/OutlineContentHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..6ac39ccd095a7c8a1bfcd28779b445ef1817883f --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/outline/OutlineContentHandler.java @@ -0,0 +1,149 @@ +package hterhors.editor.outline; + +import hterhors.editor.xml.RootElement; +import hterhors.editor.xml.XMLAttribute; +import hterhors.editor.xml.XMLElement; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.BadPositionCategoryException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.Position; +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + + +/** + * @author Hendrik + */ +public class OutlineContentHandler extends DefaultHandler implements + ContentHandler { + + /** + * @uml.property name="dtdTree" + * @uml.associationEnd + */ + private RootElement dtdTree; + + /** + * @uml.property name="dtdElement" + * @uml.associationEnd + */ + private XMLElement dtdElement; + + private Locator locator; + + private IDocument document; + + private String positionCategory; + + public OutlineContentHandler() { + super(); + } + + public void setDocumentLocator(Locator locator) { + this.locator = locator; + } + + public void startElement(String namespace, String localname, String qName, + Attributes attributes) throws SAXException { + + int lineNumber = locator.getLineNumber() - 1; + XMLElement element = new XMLElement(localname); + + int startPosition = getOffsetFromLine(lineNumber); + Position position = new Position(startPosition); + + addPosition(position); + element.setPosition(position); + + if (dtdTree == null) { + this.dtdTree = new RootElement(); + this.dtdTree.setRootElement(element); + } + + if (attributes != null) { + int attributeLength = attributes.getLength(); + for (int i = 0; i < attributeLength; i++) { + String value = attributes.getValue(i); + + String localName = attributes.getLocalName(i); + + element.addChildAttribute(new XMLAttribute(localName, value)); + } + } + + if (dtdElement != null) + dtdElement.addChildElement(element); + + dtdElement = element; + + } + + public void endElement(String namespace, String localname, String qName) + throws SAXException { + + int lineNumber = locator.getLineNumber(); + int endPosition = getOffsetFromLine(lineNumber); + + if (dtdElement != null) { + + Position position = dtdElement.getPosition(); + int length = endPosition - position.getOffset(); + position.setLength(length); + + dtdElement = dtdElement.getParent(); + + } + } + + private void addPosition(Position position) { + try { + document.addPosition(positionCategory, position); + } catch (BadLocationException e) { + e.printStackTrace(); + } catch (BadPositionCategoryException e) { + e.printStackTrace(); + } + } + + public void endDocument() throws SAXException { + super.endDocument(); + } + + private int getOffsetFromLine(int lineNumber) { + int offset = 0; + try { + offset = document.getLineOffset(lineNumber); + } catch (BadLocationException e) { + try { + offset = document.getLineOffset(lineNumber - 1); + } catch (BadLocationException e1) { + } + } + return offset; + } + + public XMLElement getRootElement() { + return dtdTree.getRootElement(); + } + + /** + * @param document + * @uml.property name="document" + */ + public void setDocument(IDocument document) { + this.document = document; + } + + /** + * @param positionCategory + * @uml.property name="positionCategory" + */ + public void setPositionCategory(String positionCategory) { + this.positionCategory = positionCategory; + } + +} \ No newline at end of file diff --git a/isr-eclipse-plugin/src/hterhors/editor/outline/OutlineContentProvider.java b/isr-eclipse-plugin/src/hterhors/editor/outline/OutlineContentProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..58fe6552b8a0ea1346fa3ef20a6494cae0b2d226 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/outline/OutlineContentProvider.java @@ -0,0 +1,137 @@ +package hterhors.editor.outline; + +import hterhors.editor.xml.XMLElement; +import hterhors.editor.xml.XMLParser; +import hterhors.editor.xmlconverter.IsrFileToXmlFileUsingXOM; + +import java.util.List; + +import org.eclipse.jface.text.BadPositionCategoryException; +import org.eclipse.jface.text.DefaultPositionUpdater; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IPositionUpdater; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.texteditor.IDocumentProvider; +import org.xml.sax.helpers.LocatorImpl; + +/** + * @author Hendrik + */ +public class OutlineContentProvider implements ITreeContentProvider { + + /** + * @uml.property name="root" + * @uml.associationEnd + */ + private XMLElement root = null; + private IEditorInput input; + private IDocumentProvider documentProvider; + + protected final static String TAG_POSITIONS = "__tag_positions"; + protected IPositionUpdater positionUpdater = new DefaultPositionUpdater( + TAG_POSITIONS); + + public OutlineContentProvider(IDocumentProvider provider) { + super(); + this.documentProvider = provider; + } + + public Object[] getChildren(Object parentElement) { + if (parentElement == input) { + if (root == null) + return new Object[0]; + List childrenDTDElements = root.getChildrenDTDElements(); + if (childrenDTDElements != null) + return childrenDTDElements.toArray(); + } else { + XMLElement parent = (XMLElement) parentElement; + List childrenDTDElements = parent.getChildrenDTDElements(); + if (childrenDTDElements != null) + return childrenDTDElements.toArray(); + } + return new Object[0]; + } + + public Object getParent(Object element) { + if (element instanceof XMLElement) + return ((XMLElement) element).getParent(); + return null; + } + + public boolean hasChildren(Object element) { + if (element == input) + return true; + else { + return ((XMLElement) element).getChildrenDTDElements().size() > 0; + } + } + + public Object[] getElements(Object inputElement) { + if (root == null) + return new Object[0]; + List childrenDTDElements = root.getChildrenDTDElements(); + if (childrenDTDElements != null) + return childrenDTDElements.toArray(); + return new Object[0]; + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + + if (oldInput != null) { + IsrFileToXmlFileUsingXOM converter = new IsrFileToXmlFileUsingXOM( + true); + IDocument xmlDoc = converter.convertFile(documentProvider + .getDocument(oldInput)); + if (xmlDoc != null) { + try { + xmlDoc.removePositionCategory(TAG_POSITIONS); + } catch (BadPositionCategoryException x) { + } + xmlDoc.removePositionUpdater(positionUpdater); + } + } + input = (IEditorInput) newInput; + if (newInput != null) { + IsrFileToXmlFileUsingXOM converter = new IsrFileToXmlFileUsingXOM( + true); + IDocument xmlDoc = converter.convertFile(documentProvider + .getDocument(newInput)); + if (xmlDoc != null) { + xmlDoc.addPositionCategory(TAG_POSITIONS); + xmlDoc.addPositionUpdater(positionUpdater); + XMLElement rootElement = parseRootElement(xmlDoc); + if (rootElement != null) { + root = rootElement; + } + } + } + } + + private XMLElement parseRootElement(IDocument document) { + String text = document.get(); + XMLElement tagPositions = parseRootElements(text, document); + return tagPositions; + } + + private XMLElement parseRootElements(String text, IDocument document) { + try { + XMLParser xmlParser = new XMLParser(); + OutlineContentHandler contentHandler = new OutlineContentHandler(); + contentHandler.setDocument(document); + contentHandler.setPositionCategory(TAG_POSITIONS); + contentHandler.setDocumentLocator(new LocatorImpl()); + xmlParser.setContentHandler(contentHandler); + xmlParser.doParse(text); + XMLElement root = contentHandler.getRootElement(); + return root; + } catch (Exception e) { + return null; + } + } + +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/outline/OutlineLabelProvider.java b/isr-eclipse-plugin/src/hterhors/editor/outline/OutlineLabelProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..b04a05ff5e78ea5af2c0c57ece1efdf70f7429e5 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/outline/OutlineLabelProvider.java @@ -0,0 +1,52 @@ +package hterhors.editor.outline; + +import hterhors.editor.xml.XMLElement; + +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.swt.graphics.Image; + +public class OutlineLabelProvider implements ILabelProvider { + + public OutlineLabelProvider() { + super(); + } + + public Image getImage(Object element) { + return null; + } + + public String getText(Object element) { + if (element instanceof XMLElement) { + XMLElement dtdElement = (XMLElement) element; + String textToShow = dtdElement.getName(); + String nameAttribute = dtdElement.getAttributeValue("id"); + if (nameAttribute != null) { + if (textToShow.equals("token")) { + textToShow = nameAttribute; + } else if (textToShow.equals("one-of") + || textToShow.equals("item")) { + } else { + textToShow += " id =\"" + nameAttribute + "\""; + } + } + return textToShow; + } + return null; + } + + public void dispose() { + } + + public boolean isLabelProperty(Object element, String property) { + return false; + } + + public void removeListener(ILabelProviderListener listener) { + } + + @Override + public void addListener(ILabelProviderListener arg0) { + } + +} \ No newline at end of file diff --git a/isr-eclipse-plugin/src/hterhors/editor/perspective/IsrPerspective.java b/isr-eclipse-plugin/src/hterhors/editor/perspective/IsrPerspective.java new file mode 100644 index 0000000000000000000000000000000000000000..b40ca81bd819d83087f2fda0c7628991cc6536b5 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/perspective/IsrPerspective.java @@ -0,0 +1,24 @@ +package hterhors.editor.perspective; + +import org.eclipse.ui.IFolderLayout; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; + +public class IsrPerspective implements IPerspectiveFactory { + + @Override + public void createInitialLayout(IPageLayout layout) { + String editorArea = layout.getEditorArea(); + + IFolderLayout topLeft = layout.createFolder("topLeft", + IPageLayout.LEFT, 0.25f, editorArea); + topLeft.addView(IPageLayout.ID_PROJECT_EXPLORER); + + IFolderLayout bottomLeft = layout.createFolder("bottomLeft", + IPageLayout.BOTTOM, 0.50f, "topLeft"); + bottomLeft.addView(IPageLayout.ID_PROBLEM_VIEW); + + layout.addView(IPageLayout.ID_OUTLINE, IPageLayout.RIGHT, 0.85f, + editorArea); + } +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/scanners/ISRPartitionScanner.java b/isr-eclipse-plugin/src/hterhors/editor/scanners/ISRPartitionScanner.java new file mode 100644 index 0000000000000000000000000000000000000000..632f04935cc72483b5071164fcbde79aa97dad7a --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/scanners/ISRPartitionScanner.java @@ -0,0 +1,56 @@ +package hterhors.editor.scanners; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.text.rules.IPredicateRule; +import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.MultiLineRule; +import org.eclipse.jface.text.rules.RuleBasedPartitionScanner; +import org.eclipse.jface.text.rules.Token; +import hterhors.editor.ISRDocumentProvider; + +public class ISRPartitionScanner extends RuleBasedPartitionScanner { + + public final static String ISR_RULE = "isr_rule"; +// public final static String ISR_START = "isr_start"; + public final static String ISR_IGNORE = "isr_ignore"; + + public ISRPartitionScanner() { + + IToken isr_rule = new Token(ISR_RULE); +// IToken isr_start = new Token(ISR_START); + IToken isr_ignore = new Token(ISR_IGNORE); + + List<IPredicateRule> rules = new ArrayList<IPredicateRule>(); +// rules.add(new MultiLineRule("$$S :", ";", isr_start)); + rules.add(new MultiLineRule("$", ";", isr_rule)); + rules.add(new MultiLineRule("%IGNORE = ", ";", isr_ignore)); + + setPredicateRules(rules.toArray(new IPredicateRule[rules.size()])); + } + + /** + * @uml.property name="iSRDocumentProvider" + * @uml.associationEnd inverse="iSRPartitionScanner:hterhors.editor.ISRDocumentProvider" + */ + private ISRDocumentProvider isrDocumentProvider = new hterhors.editor.ISRDocumentProvider(); + + /** + * Getter of the property <tt>iSRDocumentProvider</tt> + * @return Returns the isrDocumentProvider. + * @uml.property name="iSRDocumentProvider" + */ + public ISRDocumentProvider getISRDocumentProvider() { + return isrDocumentProvider; + } + + /** + * Setter of the property <tt>iSRDocumentProvider</tt> + * @param iSRDocumentProvider The isrDocumentProvider to set. + * @uml.property name="iSRDocumentProvider" + */ + public void setISRDocumentProvider(ISRDocumentProvider isrDocumentProvider) { + this.isrDocumentProvider = isrDocumentProvider; + } +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/scanners/ISRSyntaxScanner.java b/isr-eclipse-plugin/src/hterhors/editor/scanners/ISRSyntaxScanner.java new file mode 100644 index 0000000000000000000000000000000000000000..0197d9179c248f39be091a5df6ed11850a600910 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/scanners/ISRSyntaxScanner.java @@ -0,0 +1,70 @@ +package hterhors.editor.scanners; + +import hterhors.editor.ColorManager; +import hterhors.editor.IISRColorConstants; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.text.TextAttribute; +import org.eclipse.jface.text.rules.IRule; +import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.MultiLineRule; +import org.eclipse.jface.text.rules.RuleBasedScanner; +import org.eclipse.jface.text.rules.Token; + + +public class ISRSyntaxScanner extends RuleBasedScanner { + + public ISRSyntaxScanner(ColorManager manager) { + IToken decNonTerminals = new Token(new TextAttribute( + manager.getColor(IISRColorConstants.DEC_NON_TERMINAL))); + IToken start = new Token(new TextAttribute( + manager.getColor(IISRColorConstants.START))); + IToken number = new Token(new TextAttribute( + manager.getColor(IISRColorConstants.NUMBER))); + IToken nonTerminal = new Token(new TextAttribute( + manager.getColor(IISRColorConstants.NON_TERMINAL))); + IToken or = new Token(new TextAttribute( + manager.getColor(IISRColorConstants.OR))); + IToken ignore = new Token(new TextAttribute( + manager.getColor(IISRColorConstants.IGNORE))); + IToken joker = new Token(new TextAttribute( + manager.getColor(IISRColorConstants.JOKER))); + List<IRule> ruleList = new ArrayList<IRule>(); + ruleList.add(new MultiLineRule("$$S", ":", start)); + ruleList.add(new MultiLineRule("%IGNORE", ";", ignore)); + ruleList.add(new MultiLineRule("$$S:", " ", start)); + ruleList.add(new MultiLineRule("$", ":", decNonTerminals)); + ruleList.add(new MultiLineRule("$$", ":", decNonTerminals)); + ruleList.add(new MultiLineRule("!", "*", joker)); + ruleList.add(new MultiLineRule("!", "*\n", joker)); + ruleList.add(new MultiLineRule("!", "*\t", joker)); + ruleList.add(new MultiLineRule("!", "*\r", joker)); + ruleList.add(new MultiLineRule("!", "*\b", joker)); + ruleList.add(new MultiLineRule("!", "*\f", joker)); + ruleList.add(new MultiLineRule("!", "*;", joker)); + ruleList.add(new MultiLineRule("$", " ", nonTerminal)); + ruleList.add(new MultiLineRule("$", "\n", nonTerminal)); + ruleList.add(new MultiLineRule("$", "\t", nonTerminal)); + ruleList.add(new MultiLineRule("$", "\r", nonTerminal)); + ruleList.add(new MultiLineRule("$", "\b", nonTerminal)); + ruleList.add(new MultiLineRule("$", "\f", nonTerminal)); + ruleList.add(new MultiLineRule("$", ";", nonTerminal)); + ruleList.add(new MultiLineRule("$$", " ", nonTerminal)); + ruleList.add(new MultiLineRule("$$", "\n", nonTerminal)); + ruleList.add(new MultiLineRule("$$", "\t", nonTerminal)); + ruleList.add(new MultiLineRule("$$", "\r", nonTerminal)); + ruleList.add(new MultiLineRule("$$", "\b", nonTerminal)); + ruleList.add(new MultiLineRule("$$", "\f", nonTerminal)); + ruleList.add(new MultiLineRule("$$", ";", nonTerminal)); + ruleList.add(new MultiLineRule("|", " ", or)); + ruleList.add(new MultiLineRule("|", "\n", or)); + ruleList.add(new MultiLineRule("|", "\t", or)); + ruleList.add(new MultiLineRule("|", "\r", or)); + ruleList.add(new MultiLineRule("|", "\b", or)); + ruleList.add(new MultiLineRule("|", "\f", or)); + ruleList.add(new MultiLineRule("[", "]", number)); + setRules(ruleList.toArray(new IRule[ruleList.size()])); + } +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/sentenceparser/ParseSentenceHandler.java b/isr-eclipse-plugin/src/hterhors/editor/sentenceparser/ParseSentenceHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..e0141790e52c7e71929f3145ea1f33cf8afc8f84 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/sentenceparser/ParseSentenceHandler.java @@ -0,0 +1,290 @@ +package hterhors.editor.sentenceparser; + +import hterhors.editor.markers.IsrRuleValidator; +import hterhors.editor.sentenceparser.grammar.Grammar; +import hterhors.editor.sentenceparser.grammar.GrammarParser; +import hterhors.editor.sentenceparser.grammar.GrammarParser.ParseException; +import hterhors.editor.sentenceparser.grammar.Tree; +import hterhors.editor.sentenceparser.grammar.TreeFrame; +import hterhors.editor.sentenceparser.grammar.TreeParser; +import hterhors.editor.zest.SentenceGraphBuilder; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.jface.dialogs.IInputValidator; +import org.eclipse.jface.dialogs.InputDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.texteditor.ITextEditor; + + +/** + * @author Hendrik + */ +public class ParseSentenceHandler extends AbstractHandler { + + /** + * @uml.property name="parser" + * @uml.associationEnd + */ + private TreeParser parser = null; + private String result; + private String defaultString = "Example sentence,Another example"; + /** + * @uml.property name="tree_frame" + * @uml.associationEnd + */ + private TreeFrame tree_frame; + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + result = ""; + ITextEditor textEditor = (ITextEditor) HandlerUtil + .getActiveEditor(event); + IEditorInput input = HandlerUtil.getActiveEditorInput(event); + String grm = textEditor.getDocumentProvider().getDocument(input).get(); + + Shell shell = HandlerUtil.getActiveShell(event); + InputDialog dialog = new InputDialog(shell, "Sentence validator!", + "Enter the sentences to be tested, seperated with commas!", + defaultString, new IInputValidator() { + @Override + public String isValid(String sentences) { + String x = sentences.replaceAll("\\.*\\?*", ""); + if (x.matches("((" + IsrRuleValidator.TERMINAL + + " ?)+,?)+")) { + return null; + } else { + return "Wrong syntax! Sentences must look like e.g.: \"Hello Tobi\" to validate \"Hello Tobi\".\n Multiple sentences must be seperated with commas e.g.: \"Hello Tobi,Go to the kitchen\"!"; + } + } + }); + + if (dialog.open() == IStatus.OK) { + String value = defaultString = dialog.getValue(); + MessageBox pmb = new MessageBox(shell, SWT.ICON_QUESTION | SWT.YES + | SWT.NO); + pmb.setText("Show Syntax-tree"); + pmb.setMessage("Do you want to display the syntax-trees-graph of the valid given sentences?\n !!ATTENTION: Each sentence will become his own window.!!"); + int val = pmb.open(); + boolean show; + switch (val) { + case SWT.YES: + show = true; + break; + default: + show = false; + break; + } + try { + if (doParse(parseToCFG(grm), getSentences(value), show)) { + MessageBox mb = new MessageBox(shell, SWT.ICON_WORKING); + mb.setText("Result"); + mb.setMessage(result + + "\nEvery sentence is valid against the given grammar!"); + mb.open(); + } else { + MessageBox mb = new MessageBox(shell, SWT.ICON_WARNING); + mb.setText("Result"); + mb.setMessage(result + + "\nOne or more sentences are not valid against the given grammar!"); + mb.open(); + } + } catch (ParseException e) { + MessageBox mb = new MessageBox(shell, SWT.ICON_ERROR); + mb.setText("Result"); + mb.setMessage("An error has accrued, may be the grammar is invalid!"); + mb.open(); + } + } + return null; + } + + private String[] getSentences(String value) { + String[] split = value.split(","); + String[] returnValue = new String[split.length]; + for (int i = 0; i < split.length; i++) { + returnValue[i] = split[i]; + } + return returnValue; + } + + public boolean doParse(String grm, String[] sentences, boolean show) + throws ParseException { + Grammar g = getGrammar(grm); + if (g == null) + throw new GrammarParser.ParseException(); + boolean alright = true; + SentenceGraphBuilder.clearInput(); + for (int index = 0; index < sentences.length; index++) { + tree_frame = new TreeFrame(); + StringTokenizer toks = new StringTokenizer( + removeIgnores(sentences[index].toLowerCase())); + Grammar.Atom[] text = new Grammar.Atom[toks.countTokens()]; + boolean text_ok = true; + for (int i = 0; toks.hasMoreTokens(); i++) { + text[i] = g.getAtom(toks.nextToken()); + if (text[i] == null) + text_ok = false; + } + Tree t = null; + if (text_ok) { + parser = new TreeParser(g); + t = parser.parse(text); + } + if (t == null) { + result += "FAILED!\n -> \"" + sentences[index] + "\"\n\n"; + alright = false; + } else { + result += "OK!\n -> \"" + sentences[index] + "\"\n\n"; + if (show) { + // TreeBuilder x = new TreeBuilder(); + // x.setTree(t, sentences[index]); + tree_frame.setTree(t, sentences[index]); + tree_frame.setVisible(true); + } + } + } + return alright; + } + + private String removeIgnores(String sentence) { + for (String string : ignores) { + sentence = sentence.replaceAll(" " + string + " ", " "); + } + return sentence; + } + + private Grammar getGrammar(String grm) { + try { + return GrammarParser.parse(grm); + } catch (GrammarParser.ParseException e) { + e.printStackTrace(); + return null; + } + } + + private String parseToCFG(String grm) { + getIgnoreTerminals(grm); + StringTokenizer stringTokenizer = new StringTokenizer(grm); + String chomskyGrm = ""; + String start = ""; + boolean isStart = false; + String token = ""; + boolean nextToken = true; + while (stringTokenizer.hasMoreTokens()) { + if (nextToken) { + token = stringTokenizer.nextToken(); + } + nextToken = true; + if (token.matches(IsrRuleValidator.PRE_START_SYMBOL + ":?")) { + start += "S -> "; + isStart = true; + } else if (token.matches(IsrRuleValidator.O)) { + if (isStart) { + start += token + " "; + } else { + chomskyGrm += token + " "; + } + + } else if (token.matches(IsrRuleValidator.E)) { + if (isStart) { + start += "\n"; + } else { + chomskyGrm += "\n"; + } + + } else if (token.matches("(!\\*)?" + IsrRuleValidator.TERMINAL)) { + if (isStart) { + start += getAttributeName(token).toLowerCase() + " "; + } else { + chomskyGrm += getAttributeName(token).toLowerCase() + " "; + } + + } else if (token.matches("(!\\*)?" + IsrRuleValidator.TERMINAL + + ";")) { + if (isStart) { + start += getAttributeName(token).toLowerCase() + "\n"; + } else { + chomskyGrm += getAttributeName(token).toLowerCase() + "\n"; + } + } else if (token.matches(IsrRuleValidator.NON_TERMINAL_DECLARATION)) { + isStart = false; + chomskyGrm += getAttributeName(token).toUpperCase() + " -> "; + } else if (token.matches(IsrRuleValidator.NON_TERMINAL + ";")) { + if (isStart) { + start += getAttributeName(token).toUpperCase() + "\n"; + } else { + chomskyGrm += getAttributeName(token).toUpperCase() + "\n"; + } + + } else if (stringTokenizer.hasMoreTokens() + && token.matches(IsrRuleValidator.NON_TERMINAL)) { + String oldToken = token; + nextToken = false; + if ((token = stringTokenizer.nextToken()) + .matches(IsrRuleValidator.C)) { + isStart = false; + chomskyGrm += getAttributeName(oldToken).toUpperCase() + + " -> "; + } else { + if (isStart) { + start += getAttributeName(oldToken).toUpperCase() + " "; + } else { + chomskyGrm += getAttributeName(oldToken).toUpperCase() + + " "; + } + + } + } else if (token.matches("%IGNORE")) { + isStart = false; + while (stringTokenizer.hasMoreTokens()) { + if (stringTokenizer.nextToken().matches( + IsrRuleValidator.E + "|" + + IsrRuleValidator.TERMINAL + + IsrRuleValidator.E)) { + break; + } + } + } + } + return start + chomskyGrm; + } + + private List<String> ignores = new ArrayList<String>(); + + private void getIgnoreTerminals(String grm) { + StringTokenizer stringTokenizer = new StringTokenizer(grm); + String token; + while (stringTokenizer.hasMoreTokens()) { + token = stringTokenizer.nextToken(); + if (token.matches("%IGNORE")) { + String nextToken; + while (stringTokenizer.hasMoreTokens()) { + if ((nextToken = stringTokenizer.nextToken()) + .matches(IsrRuleValidator.E + "|" + + IsrRuleValidator.TERMINAL + + IsrRuleValidator.E)) { + break; + } else if (nextToken.matches(IsrRuleValidator.TERMINAL)) { + ignores.add(nextToken); + } + } + } + } + } + + private String getAttributeName(String token) { + return token.replace("$", "").replace("$$", "").replace(":", "") + .replace("!*", "").replace(";", ""); + } +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/sentenceparser/grammar/Grammar.java b/isr-eclipse-plugin/src/hterhors/editor/sentenceparser/grammar/Grammar.java new file mode 100644 index 0000000000000000000000000000000000000000..8572125e0a39bc6a7ff2439eb6e178ab6c67ee0d --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/sentenceparser/grammar/Grammar.java @@ -0,0 +1,225 @@ +/* Copyright (c) 2003, Carl Burch. License information is located in the + * edu.csbsju.socs.grammar.Main source code and at + * www.cburch.com/proj/grammar/. */ + +package hterhors.editor.sentenceparser.grammar; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.HashMap; +import java.util.HashSet; + +/** + * @author Hendrik + */ +public class Grammar { + private static int last_alloc = 0; + + /** + * @author Hendrik + */ + public static class Element { + /** + * @uml.property name="name" + */ + private String name; + + private Element() { + this.name = "temp" + last_alloc; + last_alloc++; + } + + private Element(String name) { + this.name = name; + } + + /** + * @return + * @uml.property name="name" + */ + public String getName() { + return name; + } + + public String toString() { + return name; + } + } + + public static class Symbol extends Element { + public Symbol() { + super(); + } + + public Symbol(String name) { + super(name); + } + } + + public static class Atom extends Element { + public Atom() { + super(); + } + + public Atom(String name) { + super(name); + } + } + + /** + * @author Hendrik + */ + public static class Rule { + /** + * @uml.property name="lhs" + * @uml.associationEnd + */ + private Symbol lhs; + /** + * @uml.property name="rhs" + * @uml.associationEnd multiplicity="(0 -1)" + */ + private Element[] rhs; + + public Rule(Symbol lhs, Element[] rhs) { + this.lhs = lhs; + this.rhs = rhs; + } + + public Symbol getLeftSide() { + return lhs; + } + + public Element[] getRightSide() { + return rhs; + } + + public String toString() { + StringBuffer ret = new StringBuffer(); + ret.append(lhs + " ->"); + for (int i = 0; i < rhs.length; i++) { + ret.append(" " + rhs[i]); + } + return ret.toString(); + } + + } + + /** + * @uml.property name="root" + * @uml.associationEnd + */ + private Symbol root = null; + /** + * @uml.property name="symbols" + */ + private HashSet symbols = new HashSet(); + /** + * @uml.property name="atoms" + */ + private HashMap atoms = new HashMap(); + /** + * @uml.property name="rules" + */ + private HashSet rules = new HashSet(); + private HashMap rule_map = new HashMap(); + + public Grammar() { + } + + /** + * @param root + * @uml.property name="root" + */ + public void setRoot(Symbol root) { + this.root = root; + symbols.add(root); + } + + public void addRule(Symbol lhs, Element[] rhs) { + add(new Rule(lhs, rhs)); + } + + public void add(Rule rule) { + Collection c = getRules(rule.lhs); + if (c == null) { + c = new ArrayList(); + rule_map.put(rule.lhs, c); + } + c.add(rule); + rules.add(rule); + + symbols.add(rule.lhs); + for (int i = 0; i < rule.rhs.length; i++) { + Element e = rule.rhs[i]; + if (e instanceof Symbol) + symbols.add(e); + else + atoms.put(e.getName(), e); + } + } + + /** + * @return + * @uml.property name="root" + */ + public Symbol getRoot() { + return root; + } + + public Collection getRules(Symbol lhs) { + return (Collection) rule_map.get(lhs); + } + + /** + * @return + * @uml.property name="rules" + */ + public Collection getRules() { + return rules; + } + + /** + * @return + * @uml.property name="symbols" + */ + public Collection getSymbols() { + return symbols; + } + + /** + * @return + * @uml.property name="atoms" + */ + public Collection getAtoms() { + return atoms.values(); + } + + public Collection getLeftSideSymbols() { + return rule_map.keySet(); + } + + public Atom getAtom(String name) { + return (Atom) atoms.get(name); + } + + public void print(java.io.PrintStream out) { + Iterator it = rule_map.keySet().iterator(); + while (it.hasNext()) { + Grammar.Symbol sym = (Grammar.Symbol) it.next(); + boolean first = true; + Iterator it2 = getRules(sym).iterator(); + while (it2.hasNext()) { + Rule rule = (Rule) it2.next(); + out.print(first ? (sym + " ->") : " |"); + first = false; + Grammar.Element[] rhs = rule.getRightSide(); + for (int i = 0; i < rhs.length; i++) { + out.print(" " + rhs[i]); + } + out.println(); + } + } + } +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/sentenceparser/grammar/GrammarParser.java b/isr-eclipse-plugin/src/hterhors/editor/sentenceparser/grammar/GrammarParser.java new file mode 100644 index 0000000000000000000000000000000000000000..a2eb48a34647cb5d76cd5571462c4b0ba52d9a48 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/sentenceparser/grammar/GrammarParser.java @@ -0,0 +1,149 @@ +/* Copyright (c) 2003, Carl Burch. License information is located in the + * edu.csbsju.socs.grammar.Main source code and at + * www.cburch.com/proj/grammar/. */ + +package hterhors.editor.sentenceparser.grammar; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.StringTokenizer; + +public class GrammarParser { + public static class ParseException extends Exception { + public ParseException() { + super(); + } + } + + public static Grammar parse(String text) throws ParseException { + Grammar ret = new Grammar(); + + StringTokenizer lines = new StringTokenizer(text, "\n"); + Grammar.Symbol cur_sym = null; + Grammar.Symbol eps = new Grammar.Symbol("-"); + HashMap map = new HashMap(); // names mapped to Elements + map.put("-", eps); + HashMap usage = new HashMap(); // Elements mapped to line #'s + ArrayList sequence = new ArrayList(); + int line_num = 0; + while (lines.hasMoreTokens()) { + ++line_num; + String line = lines.nextToken(); + int comment = line.indexOf('#'); + if (comment >= 0) + line = line.substring(0, comment); + + StringTokenizer toks = new StringTokenizer(line); + while (toks.hasMoreTokens()) { + String tok = toks.nextToken(); + System.out.println(sequence); + if (tok.equals("->")) { + if (sequence.size() == 0) { + throw new ParseException(); + } + Object last_obj = sequence.remove(sequence.size() - 1); + System.out.println(last_obj); + // if (!(last_obj instanceof Grammar.Symbol)) { + // throw new ParseException(); + // } + Grammar.Symbol last = (Grammar.Symbol) last_obj; + if (cur_sym == null) { + if (sequence.size() > 0) { + throw new ParseException(); + } + ret.setRoot(last); + } else { + addRule(ret, cur_sym, sequence, line_num, eps); + sequence.clear(); + } + cur_sym = last; + } else if (tok.equals("|")) { + if (cur_sym == null) { + throw new ParseException(); + } + addRule(ret, cur_sym, sequence, line_num, eps); + sequence.clear(); + } else { + Grammar.Element e = (Grammar.Element) map.get(tok); + if (e == null) { + // verify token is valid + boolean ok = true; + boolean is_sym = true; + for (int i = 0; ok && i < tok.length(); i++) { + char c = tok.charAt(i); + if (c != '_') { + if (!Character.isDigit(c) + && !Character.isLetter(c)) { + // ok = false; + } + if (!Character.isUpperCase(c)) { + is_sym = false; + } + } + } + + if (!ok) { + throw new ParseException(); + } + + if (is_sym) + e = new Grammar.Symbol(tok); + else + e = new Grammar.Atom(tok); + map.put(tok, e); + usage.put(e, new Integer(line_num)); + } + sequence.add(e); + } + } + } + addRule(ret, cur_sym, sequence, line_num, eps); + + // confirm that all symbols used are defined + if (!ret.getLeftSideSymbols().containsAll(ret.getSymbols())) { + Iterator it = ret.getSymbols().iterator(); + while (it.hasNext()) { + Grammar.Symbol sym = (Grammar.Symbol) it.next(); + if (ret.getRules(sym) == null) { + Integer line = (Integer) usage.get(sym); + throw new ParseException(); + } + } + } + if (ret.getRoot() == null) { + throw new ParseException(); + } + Collection root_rules = ret.getRules(ret.getRoot()); + if (root_rules == null || root_rules.size() == 0) { + throw new ParseException(); + } + return ret; + } + + private static void addRule(Grammar ret, Grammar.Symbol lhs, ArrayList rhs, + int line_num, Grammar.Symbol eps) throws ParseException { + if (rhs.contains(eps)) { + // if epsilon is in sequence, make sure it is + // alone, and remove it. + if (rhs.size() > 1) { + throw new ParseException(); + } + ret.addRule(lhs, new Grammar.Element[] {}); + } else { + ret.addRule(lhs, toElements(rhs)); + } + } + + private static Grammar.Element[] toElements(ArrayList l) { + Grammar.Element[] ret = new Grammar.Element[l.size()]; + int i = 0; + Iterator it = l.iterator(); + while (it.hasNext()) { + ret[i] = (Grammar.Element) it.next(); + i++; + } + return ret; + } +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/sentenceparser/grammar/Tree.java b/isr-eclipse-plugin/src/hterhors/editor/sentenceparser/grammar/Tree.java new file mode 100644 index 0000000000000000000000000000000000000000..3b004e052204389990bebd36e28e4ec38c153ea2 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/sentenceparser/grammar/Tree.java @@ -0,0 +1,77 @@ +package hterhors.editor.sentenceparser.grammar; + +/* Copyright (c) 2003, Carl Burch. License information is located in the + * edu.csbsju.socs.grammar.Main source code and at + * www.cburch.com/proj/grammar/. */ + +/** + * @author Hendrik + */ +public class Tree { + /** + * @uml.property name="null_children" + * @uml.associationEnd multiplicity="(0 -1)" + */ + private static final Tree[] null_children = {}; + + /** + * @uml.property name="data" + */ + private Object data; + /** + * @uml.property name="children" + * @uml.associationEnd multiplicity="(0 -1)" + */ + private Tree[] children; + private boolean is_leaf = false; + + protected Tree(Object data) { + this(data, null_children); + this.is_leaf = true; + } + + protected Tree(Object data, Tree[] children) { + this.data = data; + this.children = children; + } + + /** + * @return + * @uml.property name="data" + */ + public Object getData() { + return data; + } + + /** + * @param data + * @uml.property name="data" + */ + public void setData(Object data) { + this.data = data; + } + + public Tree getChild(int which) { + return children[which]; + } + + /** + * @return + * @uml.property name="children" + */ + public Tree[] getChildren() { + return children; + } + + public boolean isLeaf() { + return is_leaf; + } + + public static Tree createNode(Object data, Tree[] children) { + return new Tree(data, children); + } + + public static Tree createLeaf(Object data) { + return new Tree(data); + } +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/sentenceparser/grammar/TreeBuilder.java b/isr-eclipse-plugin/src/hterhors/editor/sentenceparser/grammar/TreeBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..59c687578ff266220be342b03b177a1d0dd53a82 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/sentenceparser/grammar/TreeBuilder.java @@ -0,0 +1,72 @@ +package hterhors.editor.sentenceparser.grammar; + +/* Copyright (c) 2003, Carl Burch. License information is located in the + * edu.csbsju.socs.grammar.Main source code and at + * www.cburch.com/proj/grammar/. */ + +import hterhors.editor.zest.SentenceGraphBuilder; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.font.LineMetrics; +import java.util.ArrayList; +import java.util.Iterator; + +import javax.swing.JPanel; + +/** + * @author Hendrik + */ +public class TreeBuilder { + + /** + * @uml.property name="tree" + * @uml.associationEnd + */ + private Tree tree = null; + private ArrayList tree_data = new ArrayList(); + + public TreeBuilder() { + } + + public void setTree(Tree value, String sentence) { + if (value == null) + value = new Tree("\"" + sentence + "\" is not in grammar!"); + this.tree = value; + this.tree_data = null; + tree_data = new ArrayList(); + autoArrangeSub(value); + SentenceGraphBuilder.addInput(tree_data, null); + } + + private TreeData autoArrangeSub(Tree t) { + Tree[] children = t.getChildren(); + + TreeData child = null; + + if (children.length == 0) { + } else { + TreeData last = null; + for (int i = 0; i < children.length; i++) { + TreeData data = autoArrangeSub(children[i]); + if (last == null) + child = data; + else + last.sibling = data; + last = data; + } + } + + TreeData ret = new TreeData(t); + ret.child = child; + for (TreeData n = child; n != null; n = n.sibling) { + n.parent = ret; + } + tree_data.add(ret); + return ret; + } +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/sentenceparser/grammar/TreeData.java b/isr-eclipse-plugin/src/hterhors/editor/sentenceparser/grammar/TreeData.java new file mode 100644 index 0000000000000000000000000000000000000000..ffbe87246517b4c8570c23d6e3f72fdbd29f3217 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/sentenceparser/grammar/TreeData.java @@ -0,0 +1,32 @@ +package hterhors.editor.sentenceparser.grammar; + +/** + * @author Hendrik + */ +public class TreeData { + + /** + * @uml.property name="data" + * @uml.associationEnd + */ + public Tree data; + /** + * @uml.property name="parent" + * @uml.associationEnd + */ + public TreeData parent = null; + /** + * @uml.property name="child" + * @uml.associationEnd + */ + public TreeData child = null; + /** + * @uml.property name="sibling" + * @uml.associationEnd + */ + public TreeData sibling = null; + + TreeData(Tree data) { + this.data = data; + } +} \ No newline at end of file diff --git a/isr-eclipse-plugin/src/hterhors/editor/sentenceparser/grammar/TreeFrame.java b/isr-eclipse-plugin/src/hterhors/editor/sentenceparser/grammar/TreeFrame.java new file mode 100644 index 0000000000000000000000000000000000000000..422ef55ac7073ec68d77895fe8e40fbb1f484565 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/sentenceparser/grammar/TreeFrame.java @@ -0,0 +1,94 @@ +package hterhors.editor.sentenceparser.grammar; + +/* Copyright (c) 2003, Carl Burch. License information is located in the + * edu.csbsju.socs.grammar.Main source code and at + * www.cburch.com/proj/grammar/. */ + +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JScrollPane; + +/** + * @author Hendrik + */ +public class TreeFrame extends JFrame { + private class FileMenu extends JMenu implements ActionListener { + private JMenuItem close = new JMenuItem(); + + private FileMenu() { + add(close); + close.addActionListener(this); + } + + private void renewStrings() { + this.setText("Menu"); + close.setText("Close"); + } + + public void actionPerformed(ActionEvent e) { + Object src = e.getSource(); + if (src == close) + TreeFrame.this.dispose(); + } + + } + + private class WindowCloser extends WindowAdapter { + public void windowClosing(WindowEvent e) { + TreeFrame.this.dispose(); + } + } + + /** + * @uml.property name="file_menu" + * @uml.associationEnd + */ + private FileMenu file_menu = new FileMenu(); + /** + * @uml.property name="panel" + * @uml.associationEnd + */ + private TreePanel panel = new TreePanel(); + private JFileChooser chooser = new JFileChooser("."); + private JScrollPane panel_scroll; + + public TreeFrame() { + addWindowListener(new WindowCloser()); + + JMenuBar menubar = new JMenuBar(); + menubar.add(file_menu); + setJMenuBar(menubar); + + panel_scroll = new JScrollPane(panel); + getContentPane().add(panel_scroll, BorderLayout.CENTER); + } + + public void renewStrings(String title) { + this.setTitle(title); + file_menu.renewStrings(); + pack(); + + JFileChooser newch = new JFileChooser(); + java.io.File f = chooser.getCurrentDirectory(); + if (f != null) + newch.setCurrentDirectory(f); + f = chooser.getSelectedFile(); + if (f != null) + newch.setSelectedFile(f); + chooser = newch; + } + + public void setTree(Tree t, String sentence) { + panel.setTree(t, sentence); + renewStrings(sentence); + } +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/sentenceparser/grammar/TreePanel.java b/isr-eclipse-plugin/src/hterhors/editor/sentenceparser/grammar/TreePanel.java new file mode 100644 index 0000000000000000000000000000000000000000..d0358d10c7e70907c1daa426434d168526b23063 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/sentenceparser/grammar/TreePanel.java @@ -0,0 +1,280 @@ +package hterhors.editor.sentenceparser.grammar; + +/* Copyright (c) 2003, Carl Burch. License information is located in the + * edu.csbsju.socs.grammar.Main source code and at + * www.cburch.com/proj/grammar/. */ + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.font.LineMetrics; +import java.util.ArrayList; +import java.util.Iterator; + +import javax.swing.JPanel; + +/** + * @author Hendrik + */ +public class TreePanel extends JPanel { + private static final int VERT_GAP = 35; + private static final int HORZ_GAP = 5; + private static final int LABEL_BORDER = 2; + private static final int BORDER = 20; + private static final int NO_CHILD_X = 3; + + /** + * @author Hendrik + */ + private static class TreeData { + int x; // x-coordinate of label's center + int y; + int label_width; + int label_height; + int label_top_offs; + int label_base_offs; + /** + * @uml.property name="data" + * @uml.associationEnd + */ + Tree data; + /** + * @uml.property name="parent" + * @uml.associationEnd + */ + TreeData parent = null; + /** + * @uml.property name="child" + * @uml.associationEnd + */ + TreeData child = null; + /** + * @uml.property name="sibling" + * @uml.associationEnd + */ + TreeData sibling = null; + + int width; // these are for during the auto-arrange only + int height; + + TreeData(Tree data, int x, int y, int label_width, int label_height, + int label_top_offs, int label_base_offs, int width, int height) { + this.data = data; + this.x = x; + this.y = y; + this.label_width = label_width; + this.label_height = label_height; + this.label_top_offs = label_top_offs; + this.label_base_offs = label_base_offs; + this.width = width; + this.height = height; + } + } + + /** + * @uml.property name="tree" + * @uml.associationEnd + */ + private Tree tree = null; + private Font font = new Font("Dialog", Font.PLAIN, 12); + private ArrayList tree_data = new ArrayList(); + + public TreePanel() { + this(null,null); + } + + public TreePanel(Tree tree, String sentence) { + setBackground(Color.white); + if (tree != null) + setTree(tree,sentence); + setPreferredSize(new Dimension(200, 200)); + } + + public void setTree(Tree value, String sentence) { + if (value == null) + value = new Tree("\"" + sentence + "\" is not in grammar!"); + this.tree = value; + this.tree_data = null; + autoArrange(); + } + + public Image getImage() { + Graphics g = getGraphics(); + if (tree == null || g == null) + return null; + if (tree_data == null) + autoArrange(g); + if (tree_data == null) + return null; + + Dimension dims = getPreferredSize(); + int width = (int) Math.ceil(dims.getWidth()); + int height = (int) Math.ceil(dims.getHeight()); + Image ret = createImage(width, height); + g = ret.getGraphics(); + if (g == null) + return null; + g.setColor(Color.white); + g.fillRect(0, 0, width, height); + doPaint(g, BORDER, BORDER); + return ret; + } + + public void paintComponent(Graphics g) { + super.paintComponent(g); + + if (tree == null) + return; + if (tree_data == null) + autoArrange(g); + if (tree_data == null) + return; + + Dimension size = getSize(); + Dimension pref = getPreferredSize(); + int x_offs = BORDER + Math.max(0, (size.width - pref.width) / 2); + int y_offs = BORDER + Math.max(0, (size.height - pref.height) / 2); + doPaint(g, x_offs, y_offs); + } + + private void doPaint(Graphics g, int x_offs, int y_offs) { + // draw connecting lines + g.setColor(Color.gray); + Iterator it = tree_data.iterator(); + while (it.hasNext()) { + TreeData nd = (TreeData) it.next(); + + // draw line to parent + TreeData pd = nd.parent; + if (pd != null) { + g.drawLine(x_offs + nd.x, y_offs + nd.y, x_offs + pd.x, y_offs + + pd.y); + } + + // if appropriate, draw X marking non-leaf with no children + Tree[] nch = nd.data.getChildren(); + if (nch == null || nch.length == 0) { + if (!nd.data.isLeaf()) { + int endx = x_offs + nd.x; + int endy = y_offs + nd.y + VERT_GAP / 2; + g.drawLine(x_offs + nd.x, y_offs + nd.y, endx, endy); + g.drawLine(endx - NO_CHILD_X, endy - NO_CHILD_X, endx + + NO_CHILD_X, endy + NO_CHILD_X); + g.drawLine(endx - NO_CHILD_X, endy + NO_CHILD_X, endx + + NO_CHILD_X, endy - NO_CHILD_X); + } + } + } + + // draw labels + g.setFont(font); + it = tree_data.iterator(); + while (it.hasNext()) { + TreeData nd = (TreeData) it.next(); + + int x = x_offs + nd.x - nd.label_width / 2; + int y = y_offs + nd.y + nd.label_top_offs; + g.setColor(Color.white); + g.fillRect(x - LABEL_BORDER, y - LABEL_BORDER, nd.label_width + 2 + * LABEL_BORDER, nd.label_height + 2 * LABEL_BORDER); + y = y_offs + nd.y + nd.label_base_offs; + g.setColor(Color.white); + g.setColor(Color.blue); + g.drawString(nd.data.getData().toString(), x, y); + } + + } + + public void autoArrange() { + autoArrange(getGraphics()); + repaint(); + } + + private void autoArrange(Graphics g) { + if (g == null) + return; + FontMetrics fm = g.getFontMetrics(); + if (fm == null) + return; + + tree_data = new ArrayList(); + g.setFont(font); + TreeData data = autoArrangeSub(tree, 0, 0, fm, g); + setPreferredSize(new Dimension(data.width + 2 * BORDER, data.height + 2 + * BORDER)); + invalidate(); + } + + private TreeData autoArrangeSub(Tree t, int x, int y, FontMetrics fm, + Graphics g) { + Tree[] children = t.getChildren(); + + LineMetrics lm = fm.getLineMetrics(t.getData().toString(), g); + int label_width = fm.stringWidth(t.getData().toString()); + int label_height = (int) Math.ceil(lm.getAscent() + lm.getDescent()); + int label_x = x + label_width / 2; + int label_y = y + fm.getAscent() / 2; + int label_base_offs = (y + fm.getAscent()) - label_y; + int label_top_offs = (int) Math.round((label_y + label_base_offs - lm + .getAscent()) - label_y); + int width = label_width; + int height = label_height; + TreeData child = null; + + if (children.length == 0) { + if (!t.isLeaf()) { + height = Math.max(height, VERT_GAP / 2 + NO_CHILD_X); + width = Math.max(width, 2 * NO_CHILD_X); + } + } else { + int xpos = x; + y += VERT_GAP; + int max_height = 0; + TreeData last = null; + for (int i = 0; i < children.length; i++) { + TreeData data = autoArrangeSub(children[i], xpos, y, fm, g); + if (last == null) + child = data; + else + last.sibling = data; + last = data; + xpos += data.width + HORZ_GAP; + max_height = Math.max(max_height, data.height); + } + xpos -= HORZ_GAP; + int center = (child.x + last.x) / 2; + if (center >= label_x) { + label_x = center; + } else { // label is wider than children + int offs = label_x - center; + for (TreeData n = child; n != null; n = n.sibling) { + translateTree(n, offs, 0); + } + xpos += offs; + } + width = Math.max(label_x + label_width / 2 - x, xpos - x); + height = Math.max(label_height, VERT_GAP + max_height); + } + + TreeData ret = new TreeData(t, label_x, label_y, label_width, + label_height, label_top_offs, label_base_offs, width, height); + ret.child = child; + for (TreeData n = child; n != null; n = n.sibling) { + n.parent = ret; + } + tree_data.add(ret); + return ret; + } + + private void translateTree(TreeData t, int x_offs, int y_offs) { + t.x += x_offs; + t.y += y_offs; + for (TreeData n = t.child; n != null; n = n.sibling) { + translateTree(n, x_offs, y_offs); + } + } + +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/sentenceparser/grammar/TreeParser.java b/isr-eclipse-plugin/src/hterhors/editor/sentenceparser/grammar/TreeParser.java new file mode 100644 index 0000000000000000000000000000000000000000..7a7df030380c4306f02bc646a89a0e3047154807 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/sentenceparser/grammar/TreeParser.java @@ -0,0 +1,628 @@ +package hterhors.editor.sentenceparser.grammar; + +/* Copyright (c) 2003, Carl Burch. License information is located in the + * edu.csbsju.socs.grammar.Main source code and at + * www.cburch.com/proj/grammar/. */ + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +/** + * @author Hendrik + */ +public class TreeParser { + private static class FinalTree extends Tree { + public FinalTree(Object data) { super(data); } + public FinalTree(Object data, Tree[] children) { + super(data, children); + } + } + /** + * @author Hendrik + */ + private static class SymbolTree { + /** + * @uml.property name="sym" + * @uml.associationEnd + */ + Grammar.Element sym; + /** + * @uml.property name="tree" + * @uml.associationEnd + */ + Tree tree; + + SymbolTree(Grammar.Element sym, Tree tree) { + this.sym = sym; + this.tree = tree; + } + public int hashCode() { return sym.hashCode(); } + public boolean equals(Object other) { + return sym.equals(((SymbolTree) other).sym); + } + public String toString() { return sym.toString(); } + } + /** + * @author Hendrik + */ + private static class Single { + /** + * @uml.property name="lhs" + * @uml.associationEnd + */ + Grammar.Symbol lhs; + /** + * @uml.property name="a" + * @uml.associationEnd + */ + Grammar.Atom a; + + Single(Grammar.Symbol lhs, Grammar.Atom a) { + this.lhs = lhs; + this.a = a; + } + } + /** + * @author Hendrik + */ + private static class Dual { + /** + * @uml.property name="lhs" + * @uml.associationEnd + */ + SymbolTree lhs; + /** + * @uml.property name="a" + * @uml.associationEnd + */ + Grammar.Symbol a; + /** + * @uml.property name="b" + * @uml.associationEnd + */ + Grammar.Symbol b; + + Dual(SymbolTree lhs, Grammar.Symbol a, Grammar.Symbol b) { + this.lhs = lhs; + this.a = a; + this.b = b; + } + } + + /** + * @uml.property name="base" + * @uml.associationEnd + */ + private Grammar base; + private HashMap singles = new HashMap(); + private HashMap duals = new HashMap(); + private HashMap final_orig_rules = new HashMap(); + /** + * @uml.property name="null_parse" + * @uml.associationEnd + */ + private Tree null_parse = null; + + public TreeParser(Grammar g) { + base = g; + HashMap orig_rules = new HashMap(); + g = computeNoEpsilons(g, orig_rules); + g = computeNoUselessSymbols(g, orig_rules); + g = computeNoUnit(g, orig_rules); + this.final_orig_rules = orig_rules; + computeChomsky(g); + } + + private void printRuleMap(HashMap orig_rules) { + Iterator it = orig_rules.entrySet().iterator(); + while(it.hasNext()) { + Map.Entry e = (Map.Entry) it.next(); + Tree t = (Tree) e.getValue(); + System.err.print(e.getKey() + " : " + t.getData() + + " /"); + Tree[] children = t.getChildren(); + for(int i = 0; i < children.length; i++) { + System.err.print(" " + children[i].getData()); + } + System.err.println(); + } + } + + private Grammar computeNoUselessSymbols(Grammar g, + HashMap orig_rules) { + // determine which symbols terminate in some string + // (cf. page 89, Hopcroft and Ullman) + HashSet terminating = new HashSet(); + boolean changed = true; + while(changed) { + changed = false; + Iterator it = g.getRules().iterator(); + while(it.hasNext()) { + Grammar.Rule rule = (Grammar.Rule) it.next(); + Grammar.Symbol lhs = rule.getLeftSide(); + if(terminating.contains(lhs)) continue; + if(allSymsInSet(rule.getRightSide(), terminating)) { + terminating.add(lhs); + changed = true; + } + } + } + + // compute grammar (rules in base with all symbols terminating) + Grammar ret = new Grammar(); + ret.setRoot(g.getRoot()); + Iterator it = g.getRules().iterator(); + while(it.hasNext()) { + Grammar.Rule rule = (Grammar.Rule) it.next(); + if(allSymsInSet(rule.getRightSide(), terminating)) { + ret.add(rule); + } else { + orig_rules.remove(rule); + } + } + return ret; + } + private boolean allSymsInSet(Grammar.Element[] rhs, Set query) { + for(int i = 0; i < rhs.length; i++) { + if(rhs[i] instanceof Grammar.Symbol + && !query.contains(rhs[i])) { + return false; + } + } + return true; + } + + // orig rules should be empty HashMap + private Grammar computeNoEpsilons(Grammar g, HashMap orig_rules) { + // determine nullability + HashMap nullable = new HashMap(); + boolean changed = true; + while(changed) { + changed = false; + Iterator it = g.getRules().iterator(); + while(it.hasNext()) { + Grammar.Rule rule = (Grammar.Rule) it.next(); + Grammar.Symbol lhs = rule.getLeftSide(); + if(nullable.get(lhs) != null) continue; + Grammar.Element[] rhs = rule.getRightSide(); + boolean can_null = true; + for(int i = 0; can_null && i < rhs.length; i++) { + can_null = rhs[i] instanceof Grammar.Symbol + && nullable.get(rhs[i]) != null; + } + if(can_null) { + Tree tree = treeFor(rule, nullable); + nullable.put(lhs, + new FinalTree(tree.getData(), tree.getChildren())); + changed = true; + } + } + } + + // determine tree for null sentence + null_parse = (Tree) nullable.get(g.getRoot()); + + // compute return grammar + Grammar ret = new Grammar(); + ret.setRoot(g.getRoot()); + Iterator it = g.getRules().iterator(); + while(it.hasNext()) { + Grammar.Rule rule = (Grammar.Rule) it.next(); + Grammar.Symbol lhs = rule.getLeftSide(); + Grammar.Element[] rhs = rule.getRightSide(); + Tree[] known = new Tree[rhs.length]; + addNonNullRules(new AddNonNullData(ret, lhs, rhs, known, + nullable, orig_rules), 0); + } + return ret; + } + private Tree treeFor(Grammar.Rule rule, HashMap tree_map) { + Grammar.Element[] rhs = rule.getRightSide(); + Tree[] children = new Tree[rhs.length]; + for(int i = 0; i < children.length; i++) { + if(rhs[i] instanceof Grammar.Symbol && tree_map != null) { + children[i] = (Tree) tree_map.get(rhs[i]); + } else { + children[i] = Tree.createLeaf(rhs[i]); + } + } + return Tree.createNode(rule.getLeftSide(), children); + } + /* + private Tree treeFor(Grammar.Symbol sym, HashMap rule_map) { + Grammar.Rule rule = (Grammar.Rule) rule_map.get(sym); + Grammar.Element[] rhs = rule.getRightSide(); + Tree[] child = new Tree[rhs.length]; + for(int i = 0; i < child.length; i++) { + if(rhs[i] instanceof Grammar.Symbol) { + child[i] = treeFor((Grammar.Symbol) rhs[i], rule_map); + } else { + child[i] = Tree.createLeaf(child[i]); + } + } + return Tree.createNode(sym, child); + } + */ + /** + * @author Hendrik + */ + private static class AddNonNullData { + /** + * @uml.property name="dest" + * @uml.associationEnd + */ + Grammar dest; + /** + * @uml.property name="lhs" + * @uml.associationEnd + */ + Grammar.Symbol lhs; + /** + * @uml.property name="rhs" + * @uml.associationEnd multiplicity="(0 -1)" + */ + Grammar.Element[] rhs; + int pos; + /** + * @uml.property name="known" + * @uml.associationEnd multiplicity="(0 -1)" + */ + Tree[] known; + HashMap nullable; + HashMap orig_rules; + AddNonNullData(Grammar dest, Grammar.Symbol lhs, + Grammar.Element[] rhs, Tree[] known, + HashMap nullable, HashMap orig_rules) { + this.dest = dest; + this.lhs = lhs; + this.rhs = rhs; + this.pos = pos; + this.known = known; + this.nullable = nullable; + this.orig_rules = orig_rules; + } + } + private void addNonNullRules(AddNonNullData data, int pos) { + if(pos == data.rhs.length) { + Tree[] children = new Tree[data.rhs.length]; + int len = 0; + for(int i = 0; i < data.rhs.length; i++) { + if(data.known[i] == null) { + children[i] = Tree.createLeaf(data.rhs[i]); + ++len; + } else { + children[i] = data.known[i]; + } + } + if(len != 0) { + Grammar.Element[] new_rhs = new Grammar.Element[len]; + int j = 0; + for(int i = 0; i < data.rhs.length; i++) { + if(data.known[i] == null) new_rhs[j++] = data.rhs[i]; + } + Grammar.Rule r = new Grammar.Rule(data.lhs, new_rhs); + data.dest.add(r); + data.orig_rules.put(r, Tree.createNode(data.lhs, children)); + } + } else { + Tree null_tree = (Tree) data.nullable.get(data.rhs[pos]); + if(null_tree != null) { + data.known[pos] = null_tree; + addNonNullRules(data, pos + 1); + data.known[pos] = null; + addNonNullRules(data, pos + 1); + } else { + int j = pos + 1; + while(j < data.rhs.length + && data.nullable.get(data.rhs[j]) == null) { + ++j; + } + addNonNullRules(data, j); + } + } + } + + // g must have no useless symbols or epsilon-productions + private Grammar computeNoUnit(Grammar g, HashMap rule_orig) { + // divide rules into unit productions and others + HashMap goesto = new HashMap(); + Grammar ret = new Grammar(); + ret.setRoot(g.getRoot()); + Iterator it = g.getRules().iterator(); + while(it.hasNext()) { + Grammar.Rule rule = (Grammar.Rule) it.next(); + Grammar.Element[] rhs = rule.getRightSide(); + if(rhs.length == 1 && rhs[0] instanceof Grammar.Symbol) { + Grammar.Symbol lhs = rule.getLeftSide(); + Grammar.Symbol a = (Grammar.Symbol) rhs[0]; + HashSet dest = (HashSet) goesto.get(lhs); + if(dest == null) { + dest = new HashSet(); + goesto.put(lhs, dest); + } + Tree t = (Tree) rule_orig.get(rule); + if(t == null) t = treeFor(rule, null); + else rule_orig.remove(rule); + dest.add(new SymbolTree(a, t)); + } else { + ret.add(rule); + } + } + + // compute closure of unit productions + boolean changed = true; + while(changed) { + changed = false; + it = goesto.entrySet().iterator(); + while(it.hasNext()) { + Map.Entry entry = (Map.Entry) it.next(); + Grammar.Symbol a = (Grammar.Symbol) entry.getKey(); + Collection bs = (Collection) entry.getValue(); + Collection bs_toadd = new java.util.LinkedList(); + Iterator it2 = bs.iterator(); + while(it2.hasNext()) { + SymbolTree b = (SymbolTree) it2.next(); + Collection cs = (Collection) goesto.get(b.sym); + if(cs != null) { + Iterator it3 = cs.iterator(); + while(it3.hasNext()) { + SymbolTree c = (SymbolTree) it3.next(); + if(!bs.contains(c)) { + bs_toadd.add(new SymbolTree(c.sym, + treeJoin(b.tree, c.tree))); + changed = true; + } + } + } + } + bs.addAll(bs_toadd); + } + } + + // add non-unit productions within closure + it = goesto.entrySet().iterator(); + while(it.hasNext()) { + Map.Entry entry = (Map.Entry) it.next(); + Grammar.Symbol a = (Grammar.Symbol) entry.getKey(); + Collection bs = (Collection) entry.getValue(); + Iterator it2 = bs.iterator(); + while(it2.hasNext()) { + SymbolTree b = (SymbolTree) it2.next(); + Iterator it3 = g.getRules((Grammar.Symbol) b.sym).iterator(); + while(it3.hasNext()) { + Grammar.Rule rule = (Grammar.Rule) it3.next(); + Grammar.Element[] rhs = rule.getRightSide(); + if(rhs.length != 1 + || !(rhs[0] instanceof Grammar.Symbol)) { + Grammar.Rule r = new Grammar.Rule(a, rhs); + ret.add(r); + + Tree t = (Tree) rule_orig.get(rule); + if(t == null) t = treeFor(rule, null); + rule_orig.put(r, treeJoin(b.tree, t)); + } + } + } + } + + return ret; + } + private Tree treeJoin(Tree a, Tree b) { + if(a == null) return null; + if(a.getData() == b.getData()) return b; + Tree[] children = a.getChildren(); + for(int i = 0; i < children.length; i++) { + Tree lower = treeJoin(children[i], b); + if(lower != null) { + Tree[] new_children = new Tree[children.length]; + System.arraycopy(children, 0, new_children, 0, + children.length); + new_children[i] = lower; + return Tree.createNode(a.getData(), new_children); + } + } + return null; + } + + // g must have no useless symbols, epsilon-productions, or unit + // productions + private void computeChomsky(Grammar g) { + HashMap smap = new HashMap(); + /* + Collection atoms = g.getAtoms(); + Iterator it = atoms.iterator(); + while(it.hasNext()) { + Grammar.Atom a = (Grammar.Atom) it.next(); + Grammar.Symbol s = new Grammar.Symbol(); + Tree t = Tree.createNode(s, new Tree[] { new Tree(a) }); + + HashMap syms_mapping = new HashMap(); + syms_mapping.put(s, t); + singles.put(a, syms_mapping); + smap.put(a, s); + } + */ + + Iterator it = g.getRules().iterator(); + while(it.hasNext()) { + Grammar.Rule rule = (Grammar.Rule) it.next(); + Grammar.Symbol lhs = rule.getLeftSide(); + Grammar.Element[] rhs = rule.getRightSide(); + if(rhs.length == 1) { + Tree map = (Tree) final_orig_rules.get(rule); + if(map == null) map = treeFor(rule, null); + Tree t = Tree.createNode(new SymbolTree(lhs, map), new Tree[] { + Tree.createLeaf(new SymbolTree(rhs[0], null)) + }); + getSingles(rhs[0]).put(lhs, t); + } else { + Tree t = (Tree) final_orig_rules.get(rule); + for(int i = rhs.length - 1; i >= 2; i--) { + Grammar.Symbol a = new Grammar.Symbol(); + addDual(lhs, a, symFor(rhs[i], smap), t); + t = null; + lhs = a; + } + Grammar.Symbol a = symFor(rhs[0], smap); + addDual(lhs, a, symFor(rhs[1], smap), t); + } + } + } + private HashMap getSingles(Grammar.Element e) { + HashMap ret = (HashMap) singles.get(e); + if(ret == null) { + ret = new HashMap(); + singles.put(e, ret); + } + return ret; + } + private Grammar.Symbol symFor(Grammar.Element e, HashMap smap) { + if(e instanceof Grammar.Symbol) return (Grammar.Symbol) e; + Grammar.Symbol ret = (Grammar.Symbol) smap.get(e); + if(ret == null) { + ret = new Grammar.Symbol(); + getSingles(e).put(ret, + Tree.createNode(new SymbolTree(ret, Tree.createLeaf(e)), new Tree[] { + Tree.createLeaf(new SymbolTree(e, null)) + })); + smap.put(e, ret); + } + return ret; + } + private void addDual(Grammar.Symbol lhs, Grammar.Symbol a, + Grammar.Symbol b, Tree t) { + HashSet a_map = (HashSet) duals.get(a); + if(a_map == null) { + a_map = new HashSet(); + duals.put(a, a_map); + } + a_map.add(new Dual(new SymbolTree(lhs, t), a, b)); + } + + private void printChomsky() { + Iterator it = singles.entrySet().iterator(); + while(it.hasNext()) { + Map.Entry entry = (Map.Entry) it.next(); + Iterator it2 = ((HashMap) entry.getValue()).keySet().iterator(); + while(it2.hasNext()) { + System.err.println(it2.next() + " -> " + + entry.getKey()); + } + } + it = duals.values().iterator(); + while(it.hasNext()) { + HashSet entry = (HashSet) it.next(); + Iterator it2 = entry.iterator(); + while(it2.hasNext()) { + Dual d = (Dual) it2.next(); + System.err.println(d.lhs + " -> " + d.a + " " + d.b); + } + } + } + + public Tree parse(Grammar.Atom[] x) { + if(x == null || x.length == 0) return null_parse; + + // CYK algorithm: V[i][j] represents all symbols that can + // derive x[i..i+j] (inclusive of x[i+j]). + int n = x.length; + Map[][] V = new Map[n][n]; + for(int i = 0; i < x.length; i++) { + V[i][0] = (Map) singles.get(x[i]); + } + for(int j = 1; j < n; j++) { + for(int i = 0; i + j < n; i++) { + V[i][j] = new HashMap(); + for(int k = 0; k < j; k++) { // [i..i+k] and [i+k+1..i+j] + if(V[i][k] == null) continue; + Collection entries = V[i][k].entrySet(); + Iterator it = entries.iterator(); + while(it.hasNext()) { + Map.Entry ae = (Map.Entry) it.next(); + Grammar.Symbol a = (Grammar.Symbol) ae.getKey(); + HashSet a_duals = (HashSet) duals.get(a); + if(a_duals == null) continue; + Iterator it2 = a_duals.iterator(); + while(it2.hasNext()) { + Dual dual = (Dual) it2.next(); + Object bt = V[i + k + 1][j - k - 1].get(dual.b); + if(bt != null) { + Tree all_t = Tree.createNode(dual.lhs, + new Tree[] { (Tree) ae.getValue(), + (Tree) bt }); + V[i][j].put(dual.lhs.sym, all_t); + } + } + } + } + } + } + + // now translate tree back base grammar + Tree chtree = (Tree) V[0][n - 1].get(base.getRoot()); + if(chtree == null) return null; + ArrayList subtrees = translateTree(chtree); + if(subtrees.size() != 1) { + throw new RuntimeException("unexpected bonus subtrees"); + } + return (Tree) subtrees.get(0); + } + private void printTree(Tree chtree, int depth) { + SymbolTree root = (SymbolTree) chtree.getData(); + Tree[] children = chtree.getChildren(); + for(int i = 0; i < depth; i++) System.err.print(" "); + System.err.print(root.sym); + if(root.tree != null) { + System.err.print(" (" + root.tree.getData() + + " " + root.tree.getChildren().length + ")"); + } + System.err.println(); + for(int i = 0; i < children.length; i++) { + printTree(children[i], depth + 1); + } + } + private ArrayList translateTree(Tree n) { + SymbolTree root = (SymbolTree) n.getData(); + Tree[] children = n.getChildren(); + ArrayList ret = new ArrayList(); + if(root.tree instanceof FinalTree) { + ret.add(root.tree); + } else { + for(int i = 0; i < children.length; i++) { + ret.addAll(translateTree(children[i])); + } + if(root.tree != null) { + Tree t = joinTree(root.tree, ret); + ret.add(0, t); + } + } + return ret; + } + private Tree joinTree(Tree base, ArrayList leaves) { + Tree[] children = base.getChildren(); + if(base instanceof FinalTree) { + return base; + } else if(children.length == 0) { + if(leaves.size() > 0) { + Tree leaf = (Tree) leaves.get(0); + if(base.getData() == leaf.getData()) { + leaves.remove(0); // consume leaf + return leaf; + } + } + return base; + } else { + Tree[] newch = new Tree[children.length]; + for(int i = 0; i < children.length; i++) { + newch[i] = joinTree(children[i], leaves); + } + return Tree.createNode(base.getData(), newch); + } + } + +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/xml/RootElement.java b/isr-eclipse-plugin/src/hterhors/editor/xml/RootElement.java new file mode 100644 index 0000000000000000000000000000000000000000..59ea63bce09056f4f2c13945dde669bd410175d5 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/xml/RootElement.java @@ -0,0 +1,29 @@ +package hterhors.editor.xml; + +/** + * @author Hendrik + */ +public class RootElement { + + /** + * @uml.property name="rootElement" + * @uml.associationEnd + */ + private XMLElement rootElement; + + /** + * @return + * @uml.property name="rootElement" + */ + public XMLElement getRootElement() { + return rootElement; + } + + /** + * @param rootElement + * @uml.property name="rootElement" + */ + public void setRootElement(XMLElement rootElement) { + this.rootElement = rootElement; + } +} \ No newline at end of file diff --git a/isr-eclipse-plugin/src/hterhors/editor/xml/XMLAttribute.java b/isr-eclipse-plugin/src/hterhors/editor/xml/XMLAttribute.java new file mode 100644 index 0000000000000000000000000000000000000000..ba45687ba303d3511f4e96fc8bcc9b80256cc55f --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/xml/XMLAttribute.java @@ -0,0 +1,43 @@ +package hterhors.editor.xml; + +/** + * @author Hendrik + */ +public class XMLAttribute { + + /** + * @uml.property name="name" + */ + private String name; + /** + * @uml.property name="value" + */ + private String value; + + public XMLAttribute(String name) { + super(); + this.name = name; + } + + public XMLAttribute(String name, String value) { + super(); + this.name = name; + this.value = value; + } + + /** + * @return + * @uml.property name="name" + */ + public String getName() { + return name; + } + + /** + * @return + * @uml.property name="value" + */ + public String getValue() { + return value; + } +} \ No newline at end of file diff --git a/isr-eclipse-plugin/src/hterhors/editor/xml/XMLElement.java b/isr-eclipse-plugin/src/hterhors/editor/xml/XMLElement.java new file mode 100644 index 0000000000000000000000000000000000000000..13b16243c4f8bb8851b90b205757bc20e3f24bc9 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/xml/XMLElement.java @@ -0,0 +1,104 @@ +package hterhors.editor.xml; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.jface.text.Position; + +/** + * @author Hendrik + */ +public class XMLElement { + + private List elementChildren = new ArrayList(); + private List attributeChildren = new ArrayList(); + + /** + * @uml.property name="name" + */ + private String name; + /** + * @uml.property name="parent" + * @uml.associationEnd + */ + private XMLElement parent; + /** + * @uml.property name="position" + */ + private Position position; + + public XMLElement(String name) { + super(); + this.name = name; + } + + public List getChildrenDTDElements() { + return elementChildren; + } + + public XMLElement addChildElement(XMLElement element) { + elementChildren.add(element); + element.setParent(this); + return this; + } + + /** + * @param element + * @uml.property name="parent" + */ + public void setParent(XMLElement element) { + this.parent = element; + } + + /** + * @return + * @uml.property name="parent" + */ + public XMLElement getParent() { + return parent; + } + + public XMLElement addChildAttribute(XMLAttribute attribute) { + attributeChildren.add(attribute); + return this; + } + + /** + * @return + * @uml.property name="name" + */ + public String getName() { + return name; + } + + public String getAttributeValue(String localName) { + for (Iterator iter = attributeChildren.iterator(); iter.hasNext();) { + XMLAttribute attribute = (XMLAttribute) iter.next(); + if (attribute.getName().equals(localName)) + return attribute.getValue(); + } + return null; + } + + public void clear() { + elementChildren.clear(); + attributeChildren.clear(); + } + + /** + * @param position + * @uml.property name="position" + */ + public void setPosition(Position position) { + this.position = position; + } + + /** + * @return + * @uml.property name="position" + */ + public Position getPosition() { + return position; + } +} \ No newline at end of file diff --git a/isr-eclipse-plugin/src/hterhors/editor/xml/XMLParser.java b/isr-eclipse-plugin/src/hterhors/editor/xml/XMLParser.java new file mode 100644 index 0000000000000000000000000000000000000000..d8eb231116ea37923bd41a60e108f77a95ce5ee9 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/xml/XMLParser.java @@ -0,0 +1,52 @@ +package hterhors.editor.xml; + +import java.io.StringReader; + +import org.apache.xerces.parsers.SAXParser; +import org.xml.sax.ContentHandler; +import org.xml.sax.ErrorHandler; +import org.xml.sax.InputSource; +import org.xml.sax.XMLReader; + +/** + * @author Hendrik + */ +public class XMLParser { + + private ErrorHandler errorHandler; + private ContentHandler contentHandler; + + /** + * @param errorHandler + * @uml.property name="errorHandler" + */ + public void setErrorHandler(ErrorHandler errorHandler) { + this.errorHandler = errorHandler; + } + + /** + * @param contentHandler + * @uml.property name="contentHandler" + */ + public void setContentHandler(ContentHandler contentHandler) { + this.contentHandler = contentHandler; + } + + public static final String VALIDATION_FEATURE = "http://xml.org/sax/features/validation"; + + public void doParse(String xmlText) throws RuntimeException { + + InputSource inputSource = new InputSource(new StringReader(xmlText)); + try { + XMLReader reader = new SAXParser(); + reader.setErrorHandler(errorHandler); + reader.setContentHandler(contentHandler); + reader.setFeature(VALIDATION_FEATURE, true); + reader.parse(inputSource); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + + } +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/xmlconverter/ConvertToXMLAction.java b/isr-eclipse-plugin/src/hterhors/editor/xmlconverter/ConvertToXMLAction.java new file mode 100644 index 0000000000000000000000000000000000000000..503dc6228cf9f86ae916a3b30c24af6bc3ad88f7 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/xmlconverter/ConvertToXMLAction.java @@ -0,0 +1,151 @@ +package hterhors.editor.xmlconverter; + +import hterhors.editor.ISREditor; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.QualifiedName; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.DirectoryDialog; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IActionDelegate; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IFileEditorInput; +import org.eclipse.ui.IObjectActionDelegate; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.handlers.HandlerUtil; + +public class ConvertToXMLAction implements IObjectActionDelegate { + + private Shell shell; + + /** + * Constructor for Action1. + */ + public ConvertToXMLAction() { + super(); + } + + /** + * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart) + */ + public void setActivePart(IAction action, IWorkbenchPart targetPart) { + shell = targetPart.getSite().getShell(); + } + + /** + * @see IActionDelegate#run(IAction) + */ + public void run(IAction action) { + ISREditor textEditor = (ISREditor) PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage().getActiveEditor(); + IDocument doc = textEditor.getInputDocument(); + if (doc != null) { + createOutput(shell, extractResource(textEditor), doc.get()); + } else { + MessageBox pmb = new MessageBox(shell, SWT.ICON_ERROR | SWT.OK); + pmb.setText("An error has accrued!"); + pmb.setMessage("Please try again!"); + pmb.open(); + } + } + + /** + * @see IActionDelegate#selectionChanged(IAction, ISelection) + */ + public void selectionChanged(IAction action, ISelection selection) { + } + + private QualifiedName path = new QualifiedName("xml", "path"); + + private IResource extractResource(IEditorPart editor) { + // ISelection sel = HandlerUtil.getActiveMenuSelection(event); + // IStructuredSelection selection = (IStructuredSelection) sel; + IEditorInput input = editor.getEditorInput(); + if (!(input instanceof IFileEditorInput)) + return null; + return ((IFileEditorInput) input).getFile(); + } + + private void createOutput(Shell shell, IResource resource, String text) { + String directory; + boolean newDirectory = true; + directory = getPersistentProperty(resource, path); + + if (directory != null && directory.length() > 0) { + newDirectory = !(MessageDialog.openQuestion( + shell, + "Question", + "Use the previous output directory?" + + System.getProperty("line.separator") + + System.getProperty("line.separator") + + "Attention homonymous file " + + System.getProperty("line.separator") + + "will be override automatically!")); + } + if (newDirectory) { + DirectoryDialog fileDialog = new DirectoryDialog(shell); + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + File workspaceDirectory = workspace.getRoot().getLocation() + .toFile(); + fileDialog.setFilterPath(workspaceDirectory.getAbsolutePath()); + directory = fileDialog.open(); + + } + if (directory != null && directory.length() > 0) { + setPersistentProperty(resource, path, directory); + write(directory, text, resource.getName()); + } + } + + private String getPersistentProperty(IResource res, QualifiedName qn) { + try { + return res.getPersistentProperty(qn); + } catch (CoreException e) { + return ""; + } + } + + private void setPersistentProperty(IResource res, QualifiedName qn, + String value) { + try { + res.setPersistentProperty(qn, value); + } catch (CoreException e) { + e.printStackTrace(); + } + } + + private void write(String dir, String text, String name) { + IsrFileToXmlFileUsingXOM converter = new IsrFileToXmlFileUsingXOM(); + try { + String n; + try { + n = name.split("\\.")[0]; + } catch (ArrayIndexOutOfBoundsException e) { + n = name; + } + String xmlFile = dir + "\\" + n + ".xml"; + FileWriter output = new FileWriter(xmlFile); + BufferedWriter writer = new BufferedWriter(output); + writer.write(converter.convertText(text)); + writer.flush(); + } catch (IOException e) { + e.printStackTrace(); + } + + } +} \ No newline at end of file diff --git a/isr-eclipse-plugin/src/hterhors/editor/xmlconverter/CopyOfConvertToXMLHandler.java b/isr-eclipse-plugin/src/hterhors/editor/xmlconverter/CopyOfConvertToXMLHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..bce72d5ea8b3d1063a41024d3d68a9b023ff9bfb --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/xmlconverter/CopyOfConvertToXMLHandler.java @@ -0,0 +1,105 @@ +package hterhors.editor.xmlconverter; +//package hterhors.editor.xmlconverter; +// +//import java.io.BufferedWriter; +//import java.io.File; +//import java.io.FileWriter; +//import java.io.IOException; +// +//import org.eclipse.core.commands.AbstractHandler; +//import org.eclipse.core.commands.ExecutionEvent; +//import org.eclipse.core.commands.ExecutionException; +//import org.eclipse.core.resources.IResource; +//import org.eclipse.core.resources.IWorkspace; +//import org.eclipse.core.resources.ResourcesPlugin; +//import org.eclipse.core.runtime.CoreException; +//import org.eclipse.core.runtime.QualifiedName; +//import org.eclipse.jface.dialogs.MessageDialog; +//import org.eclipse.swt.widgets.DirectoryDialog; +//import org.eclipse.swt.widgets.Shell; +//import org.eclipse.ui.IEditorInput; +//import org.eclipse.ui.IEditorPart; +//import org.eclipse.ui.IFileEditorInput; +//import org.eclipse.ui.contexts.IContextActivation; +//import org.eclipse.ui.contexts.IContextService; +//import org.eclipse.ui.handlers.HandlerUtil; +//import org.eclipse.ui.texteditor.ITextEditor; +// +//public class CopyOfConvertToXMLHandler extends AbstractHandler { +// private QualifiedName path = new QualifiedName("xml", "path"); +// +// @Override +// public Object execute(ExecutionEvent event) throws ExecutionException { +// ITextEditor textEditor = (ITextEditor) HandlerUtil +// .getActiveEditor(event); +// HandlerUtil.getActiveWorkbenchWindow(event).getActivePage(); +// IEditorInput input = HandlerUtil.getActiveEditorInput(event); +// Shell shell = HandlerUtil.getActiveShell(event); +// IResource inputResource = extractResource(textEditor); +// createOutput(shell, inputResource, textEditor.getDocumentProvider() +// .getDocument(input).get()); +// return null; +// } +// +// private IResource extractResource(IEditorPart editor) { +// IEditorInput input = editor.getEditorInput(); +// if (!(input instanceof IFileEditorInput)) +// return null; +// return ((IFileEditorInput) input).getFile(); +// } +// +// private void createOutput(Shell shell, IResource resource, String text) { +// String directory; +// boolean newDirectory = true; +// directory = getPersistentProperty(resource, path); +// +// if (directory != null && directory.length() > 0) { +// newDirectory = !(MessageDialog.openQuestion(shell, "Question", +// "Use the previous output directory?")); +// } +// if (newDirectory) { +// DirectoryDialog fileDialog = new DirectoryDialog(shell); +// IWorkspace workspace = ResourcesPlugin.getWorkspace(); +// File workspaceDirectory = workspace.getRoot().getLocation() +// .toFile(); +// fileDialog.setFilterPath(workspaceDirectory.getAbsolutePath()); +// directory = fileDialog.open(); +// +// } +// if (directory != null && directory.length() > 0) { +// setPersistentProperty(resource, path, directory); +// write(directory, text, resource.getName()); +// } +// } +// +// private String getPersistentProperty(IResource res, QualifiedName qn) { +// try { +// return res.getPersistentProperty(qn); +// } catch (CoreException e) { +// return ""; +// } +// } +// +// private void setPersistentProperty(IResource res, QualifiedName qn, +// String value) { +// try { +// res.setPersistentProperty(qn, value); +// } catch (CoreException e) { +// e.printStackTrace(); +// } +// } +// +// private void write(String dir, String text, String name) { +// IsrFileToXmlFile converter = new IsrFileToXmlFile(); +// try { +// String htmlFile = dir + "\\" + name + ".xml"; +// FileWriter output = new FileWriter(htmlFile); +// BufferedWriter writer = new BufferedWriter(output); +// writer.write(converter.convertText(text)); +// writer.flush(); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// +// } +//} \ No newline at end of file diff --git a/isr-eclipse-plugin/src/hterhors/editor/xmlconverter/IsrFileToXmlFileUsingXOM.java b/isr-eclipse-plugin/src/hterhors/editor/xmlconverter/IsrFileToXmlFileUsingXOM.java new file mode 100644 index 0000000000000000000000000000000000000000..fd064a94fa9e7985c9fbde35f2505d8fbc4c58d7 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/xmlconverter/IsrFileToXmlFileUsingXOM.java @@ -0,0 +1,201 @@ +package hterhors.editor.xmlconverter; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +import nu.xom.*; + +import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.IDocument; + +public class IsrFileToXmlFileUsingXOM { + + private static final String TERMINAL = "([a-zA-Z_\\\"][a-zA-Z_\\-\\\"0-9]*)"; + private static final String IGNORE = "%IGNORE"; + private static final String C = ":"; + private static final String E = ";"; + private static final String O = "(\\|)"; + private static final String S = "(\\$\\$S)"; + private static final String N = "(\\${1,2}[a-zA-Z_\\\"][a-zA-Z_\\-\\\"0-9]*)"; + private static final String J_T = "((!\\*)?([a-zA-Z_\\\"][a-zA-Z_\\-\\\"0-9]*))"; + private static final String J_T_N = J_T + "|" + N; + private static final String JE_TE_NE = "(" + J_T + ";)|(" + N + ";)"; + + private List<String> ignores = new ArrayList<String>(); + + private String xmlString = "<!DOCTYPE world SYSTEM \"IsrGrammarXmlDefinition.dtd\">\n\n<ISR_GRAMMAR>\n"; + private boolean addIgnore = true; + private Element ignore_one_of; + private Element root = new Element("grammar"); + private boolean forContentOutline = false; + + public IsrFileToXmlFileUsingXOM(boolean forContentOutline) { + this.forContentOutline = forContentOutline; + } + + public IsrFileToXmlFileUsingXOM() { + } + + public String convertText(String isrGrammar) { + if (isrGrammar != null) { + write(new StringTokenizer(isrGrammar)); + } + // root.setBaseURI("http://www.w3.org/2001/06/grammar"); + // ("version", "1.0"); + root.addAttribute(new Attribute("version", "1.0")); + root.addAttribute(new Attribute("root", "S")); + root.addAttribute(new Attribute("mode", "voice")); +// root.addAttribute(new Attribute("xmlns", +// "http://www.w3.org/2001/06/grammar/")); + // +// root.addNamespaceDeclaration("xmlns", +// "http://www.w3.org/2001/06/grammar/"); + // root.addNamespaceDeclaration("xmlns:xsi", + // "http://www.w3.org/2001/XMLSchema-instance"); + // root.addNamespaceDeclaration("xsi:schemaLocation", + // "http://www.w3.org/2001/06/grammar\n" + // + "http://www.w3.org/TR/speech-grammar/grammar.xsd"); + // root.addNamespaceDeclaration("xml:lange", "en-US"); + // root.addNamespaceDeclaration("mode", "voice"); + // root.addNamespaceDeclaration("root", "Start"); + nu.xom.Document doc = new nu.xom.Document(root); + String result = doc.toXML(); + return result; + } + + public IDocument convertFile(IDocument document) { + return new Document(convertText(document.get())); + } + + void write(StringTokenizer stringTokenizer) { + try { + String token; + while (stringTokenizer.hasMoreElements()) { + token = stringTokenizer.nextToken(); + if ((token.matches(IGNORE + "=")) + || (token.matches(IGNORE) + && stringTokenizer.hasMoreElements() && stringTokenizer + .nextToken().matches("="))) { + if (addIgnore) { + addIgnore = false; + Element ignore = new Element("rule"); + ignore.addAttribute(new Attribute("id", "Ignore")); + ignore.appendChild(ignore_one_of = new Element("one-of")); + root.appendChild(ignore); + } + do { + String element = stringTokenizer.nextToken(); + if (!element.matches(TERMINAL + ";|" + E)) { + if (element.matches(TERMINAL)) { + if (!ignores.contains(element)) { + ignores.add(getAttributeName(element)); + } + } + } + if (element.matches(TERMINAL + ";|" + E)) { + if (!getAttributeName(element).isEmpty() + && !ignores.contains(element)) { + ignores.add(getAttributeName(element)); + } + break; + } + } while (stringTokenizer.hasMoreTokens()); + } else if (token.matches(S + C) + || (token.matches(S) + && stringTokenizer.hasMoreElements() && stringTokenizer + .nextToken().matches(C))) { + Element start = new Element("rule"); + start.addAttribute(new Attribute("id", "Start")); + root.appendChild(start); + Element oneOf = new Element("one-of"); + Element item; + oneOf.appendChild(item = new Element("item")); + start.appendChild(oneOf); + do { + String element = stringTokenizer.nextToken(); + if (!element.matches(E)) { + if (element.matches(N + ";?")) { + Element nt = new Element("ruleref"); + nt.addAttribute(new Attribute("uri", "#" + + getAttributeName(element))); + item.appendChild(nt); + } else if (element.matches(TERMINAL + ";?")) { + item.appendChild(getAttributeName(element) + + " "); + } + } + if (element.matches(O)) { + oneOf.appendChild(item = new Element("item")); + } + if (element.matches(JE_TE_NE + "|" + E)) { + break; + } + } while (stringTokenizer.hasMoreTokens()); + } else if (token.matches(N + C) + || (token.matches(N) + && stringTokenizer.hasMoreElements() && stringTokenizer + .nextToken().matches(C))) { + Element start = new Element("rule"); + start.addAttribute(new Attribute("id", + getAttributeName(token))); + root.appendChild(start); + Element oneOf = new Element("one-of"); + Element item; + oneOf.appendChild(item = new Element("item")); + start.appendChild(oneOf); + do { + String element = stringTokenizer.nextToken(); + if (element.matches(O)) { + oneOf.appendChild(item = new Element("item")); + } else if (!element.matches(E)) { + if (element.matches(N + ";?")) { + Element nt = new Element("ruleref"); + if (forContentOutline) { + nt.addAttribute(new Attribute("id", + getAttributeName(element))); + } else { + nt.addAttribute(new Attribute("uri", "#" + + getAttributeName(element))); + } + item.appendChild(nt); + } else if (element.matches(TERMINAL + ";?")) { + if (forContentOutline) { + Element t = new Element("token"); + t.addAttribute(new Attribute("id", + getAttributeName(element))); + item.appendChild(t); + } else { + item.appendChild(getAttributeName(element) + + " "); + } + } + } + if (element.matches(JE_TE_NE + "|" + E)) { + break; + } + } while (stringTokenizer.hasMoreTokens()); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + Element item; + for (String ignore : ignores) { + ignore_one_of.appendChild(item = new Element("item")); + if (forContentOutline) { + Element t = new Element("token"); + t.addAttribute(new Attribute("id", getAttributeName(ignore))); + item.appendChild(t); + } else { + item.appendChild(getAttributeName(ignore)); + } + } + } + + private String getAttributeName(String token) { + return token.replace("$", "").replace("$$", "").replace(":", "") + .replace("!*", "").replace(";", ""); + } + +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/zest/ELayouts.java b/isr-eclipse-plugin/src/hterhors/editor/zest/ELayouts.java new file mode 100644 index 0000000000000000000000000000000000000000..a2a10954c9d2ea532bd775118d8fbf30c0b27362 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/zest/ELayouts.java @@ -0,0 +1,32 @@ +package hterhors.editor.zest; + +/** + * @author Hendrik + */ +public enum ELayouts { + /** + * @uml.property name="treeLayoutAlgorithm" + * @uml.associationEnd + */ + TreeLayoutAlgorithm, /** + * @uml.property name="horizontalTreeLayoutAlgorithm" + * @uml.associationEnd + */ + HorizontalTreeLayoutAlgorithm, /** + * @uml.property name="radialLayoutAlgorithm" + * @uml.associationEnd + */ + RadialLayoutAlgorithm, /** + * @uml.property name="gridLayoutAlgorithm" + * @uml.associationEnd + */ + GridLayoutAlgorithm, /** + * @uml.property name="verticalLayoutAlgorithm" + * @uml.associationEnd + */ + VerticalLayoutAlgorithm, /** + * @uml.property name="springLayoutAlgorithm" + * @uml.associationEnd + */ + SpringLayoutAlgorithm; +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/zest/IsrGraphBuilder.java b/isr-eclipse-plugin/src/hterhors/editor/zest/IsrGraphBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..051b591ac1f4b67892877e4afab9e389deb6e5be --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/zest/IsrGraphBuilder.java @@ -0,0 +1,301 @@ +package hterhors.editor.zest; + +import hterhors.editor.IISRColorConstants; +import hterhors.editor.markers.IsrRuleValidator; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.zest.core.widgets.Graph; +import org.eclipse.zest.core.widgets.GraphConnection; +import org.eclipse.zest.core.widgets.GraphNode; +import org.eclipse.zest.core.widgets.ZestStyles; +import org.eclipse.zest.layouts.LayoutAlgorithm; +import org.eclipse.zest.layouts.LayoutStyles; +import org.eclipse.zest.layouts.algorithms.CompositeLayoutAlgorithm; +import org.eclipse.zest.layouts.algorithms.GridLayoutAlgorithm; +import org.eclipse.zest.layouts.algorithms.HorizontalShift; +import org.eclipse.zest.layouts.algorithms.HorizontalTreeLayoutAlgorithm; +import org.eclipse.zest.layouts.algorithms.RadialLayoutAlgorithm; +import org.eclipse.zest.layouts.algorithms.SpringLayoutAlgorithm; +import org.eclipse.zest.layouts.algorithms.TreeLayoutAlgorithm; +import org.eclipse.zest.layouts.algorithms.VerticalLayoutAlgorithm; + +/** + * @author Hendrik + */ +public class IsrGraphBuilder { + + private static String isrGrammar; + + public static void getGraph(Composite parent) { + if (isrGrammar != null) { + Device device = parent.getDisplay().getSystemColor(SWT.COLOR_GREEN) + .getDevice(); + List<String> graphNodes = new ArrayList<String>(); + final Graph graph = new Graph(parent, SWT.NONE); + StringTokenizer ruleToken = new StringTokenizer(isrGrammar, ";", + false); + boolean isIgnoreRule; + boolean isEmptyRule; + while (ruleToken.hasMoreTokens()) { + isIgnoreRule = false; + isEmptyRule = false; + GraphNode currentStartNode = null; + GraphNode lastNode = null; + String ruleText = ruleToken.nextToken(); + if (!ruleText.trim().isEmpty()) { + lastNode = new GraphNode(graph, SWT.NONE, ";"); + lastNode.setBackgroundColor(new Color(device, 230, 230, 230)); + } else { + isEmptyRule = true; + } + StringTokenizer orRulePartToken = new StringTokenizer(ruleText, + "|", false); + while (orRulePartToken.hasMoreTokens()) { + StringTokenizer wordToken = new StringTokenizer( + orRulePartToken.nextToken()); + int tokenCount = wordToken.countTokens(); + graphNodes.clear(); + String tmp; + while (wordToken.hasMoreTokens()) { + if ((tmp = wordToken.nextToken()).matches(":|=")) { + } else { + if (tmp.charAt(0) == '%') { + tmp = tmp.replace("=", ""); + graphNodes.add(tmp + "="); + isIgnoreRule = true; + } else if (tmp.charAt(0) == '$') { + if (tmp.contains(":")) { + tmp = tmp.replace(":", ""); + graphNodes.add(tmp + ":"); + } else { + graphNodes.add(tmp); + } + } else { + graphNodes.add(tmp); + } + } + } + GraphNode gn1 = null; + GraphNode gn2 = null; + for (int i = 0; i < graphNodes.size(); i++) { + if (isIgnoreRule) { + if (gn1 == null) { + gn1 = new GraphNode(graph, SWT.NONE, + graphNodes.get(i)); + currentStartNode = gn1; + currentStartNode + .setBackgroundColor(new Color(device, + IISRColorConstants.IGNORE_GRAPH)); + } else { + try { + gn2 = new GraphNode(graph, SWT.NONE, + graphNodes.get(i + 1)); + gn2.setBackgroundColor(new Color(device, + 255, 200, 200)); + GraphConnection gc = new GraphConnection( + graph, + ZestStyles.CONNECTIONS_DIRECTED, + currentStartNode, gn2); + gc.setLineColor(new Color(device, + IISRColorConstants.OR)); + new GraphConnection(graph, + ZestStyles.CONNECTIONS_DIRECTED, + gn2, lastNode); + } catch (IndexOutOfBoundsException e) { + } + } + } else { + if (gn2 == null) { + gn1 = new GraphNode(graph, SWT.NONE, + graphNodes.get(i)); + if (graphNodes.get(i).matches( + IsrRuleValidator.TERMINAL + ";?")) { + gn1.setBackgroundColor(new Color(device, + 255, 255, 255)); + } else if (graphNodes.get(i).matches( + "(!\\*)" + IsrRuleValidator.TERMINAL + + ";?")) { + gn1.setBackgroundColor(new Color(device, + 255, 255, 255)); + } else { + if (graphNodes.get(i).matches( + IsrRuleValidator.PRE_START_SYMBOL + + ":?")) { + gn1.setBackgroundColor(new Color( + device, + IISRColorConstants.START_GRAPH)); + } else if (graphNodes.get(i).matches( + IsrRuleValidator.IGNORE + "=?")) { + gn1.setBackgroundColor(new Color( + device, + IISRColorConstants.IGNORE_GRAPH)); + } else { + gn1.setBackgroundColor(new Color( + device, + IISRColorConstants.DEC_NON_TERMINAL_GRAPH)); + } + } + if (currentStartNode == null) { + currentStartNode = gn1; + } else { + GraphConnection gc = new GraphConnection( + graph, + ZestStyles.CONNECTIONS_DIRECTED, + currentStartNode, gn1); + gc.setLineColor(new Color(device, + IISRColorConstants.OR_GRAPH)); + } + } else { + gn1 = gn2; + setColor(device, graphNodes.get(i), gn1); + } + try { + gn2 = new GraphNode(graph, SWT.NONE, + graphNodes.get(i + 1)); + setColor(device, graphNodes.get(i), gn2); + } catch (IndexOutOfBoundsException e) { + gn2 = lastNode; + } + if (gn2 != null) { + GraphConnection gc = new GraphConnection(graph, + ZestStyles.CONNECTIONS_DIRECTED, gn1, + gn2); + if (gn1 == currentStartNode + && orRulePartToken.countTokens() == 1) { + gc.setLineColor(new Color(device, + IISRColorConstants.OR_GRAPH)); + } + } + } + } + + if (tokenCount == 0 && !isEmptyRule) { + GraphConnection gc = new GraphConnection(graph, + ZestStyles.CONNECTIONS_DIRECTED, + currentStartNode, lastNode); + gc.setLineColor(new Color(device, + IISRColorConstants.OR_GRAPH)); + } + } + } + + switch (layout) { + case TreeLayoutAlgorithm: + graph.setLayoutAlgorithm( + new CompositeLayoutAlgorithm( + LayoutStyles.NO_LAYOUT_NODE_RESIZING, + new LayoutAlgorithm[] { + new TreeLayoutAlgorithm( + LayoutStyles.NO_LAYOUT_NODE_RESIZING), + new HorizontalShift( + LayoutStyles.NO_LAYOUT_NODE_RESIZING) }), + true); + break; + case HorizontalTreeLayoutAlgorithm: + graph.setLayoutAlgorithm( + new CompositeLayoutAlgorithm( + LayoutStyles.NO_LAYOUT_NODE_RESIZING, + new LayoutAlgorithm[] { + new HorizontalTreeLayoutAlgorithm( + LayoutStyles.NO_LAYOUT_NODE_RESIZING), + new HorizontalShift( + LayoutStyles.NO_LAYOUT_NODE_RESIZING) }), + true); + break; + case RadialLayoutAlgorithm: + graph.setLayoutAlgorithm( + new CompositeLayoutAlgorithm( + LayoutStyles.NO_LAYOUT_NODE_RESIZING, + new LayoutAlgorithm[] { + new RadialLayoutAlgorithm( + LayoutStyles.NO_LAYOUT_NODE_RESIZING), + new HorizontalShift( + LayoutStyles.NO_LAYOUT_NODE_RESIZING) }), + true); + break; + case GridLayoutAlgorithm: + graph.setLayoutAlgorithm( + new CompositeLayoutAlgorithm( + LayoutStyles.NO_LAYOUT_NODE_RESIZING, + new LayoutAlgorithm[] { + new GridLayoutAlgorithm( + LayoutStyles.NO_LAYOUT_NODE_RESIZING), + new HorizontalShift( + LayoutStyles.NO_LAYOUT_NODE_RESIZING) }), + true); + break; + case VerticalLayoutAlgorithm: + graph.setLayoutAlgorithm( + new CompositeLayoutAlgorithm( + LayoutStyles.NO_LAYOUT_NODE_RESIZING, + new LayoutAlgorithm[] { + new VerticalLayoutAlgorithm( + LayoutStyles.NO_LAYOUT_NODE_RESIZING), + new HorizontalShift( + LayoutStyles.NO_LAYOUT_NODE_RESIZING) }), + true); + break; + case SpringLayoutAlgorithm: + graph.setLayoutAlgorithm( + new CompositeLayoutAlgorithm( + LayoutStyles.NO_LAYOUT_NODE_RESIZING, + new LayoutAlgorithm[] { + new SpringLayoutAlgorithm( + LayoutStyles.NO_LAYOUT_NODE_RESIZING), + new HorizontalShift( + LayoutStyles.NO_LAYOUT_NODE_RESIZING) }), + true); + break; + default: + graph.setLayoutAlgorithm( + new CompositeLayoutAlgorithm( + LayoutStyles.NO_LAYOUT_NODE_RESIZING, + new LayoutAlgorithm[] { + new HorizontalTreeLayoutAlgorithm( + LayoutStyles.NO_LAYOUT_NODE_RESIZING), + new HorizontalShift( + LayoutStyles.NO_LAYOUT_NODE_RESIZING) }), + true); + } + } + } + + private static void setColor(Device device, String nodeText, GraphNode node) { + if (nodeText.matches(IsrRuleValidator.NON_TERMINAL + ";?")) { + node.setBackgroundColor(new Color(device, + IISRColorConstants.NON_TERMINAL_GRAPH)); + } else if (nodeText.matches(IsrRuleValidator.IGNORE + "=?")) { + node.setBackgroundColor(new Color(device, + IISRColorConstants.IGNORE_GRAPH)); + } else if (nodeText + .matches("(!\\*)" + IsrRuleValidator.TERMINAL + ";?")) { + node.setBackgroundColor(new Color(device, + IISRColorConstants.IGNORE_GRAPH)); + } else { + node.setBackgroundColor(new Color(device, 255, 255, 255)); + } + } + + /** + * @uml.property name="layout" + * @uml.associationEnd + */ + private static ELayouts layout = ELayouts.HorizontalTreeLayoutAlgorithm; + + public static void setInput(String isrGrammar, ELayouts l) { + IsrGraphBuilder.isrGrammar = remNumbers(isrGrammar); + if (l != null) + layout = l; + } + + private static String remNumbers(String isrGrammar2) { + return isrGrammar2.replaceAll(IsrRuleValidator.NUMBER, ""); + } +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/zest/IsrGraphView.java b/isr-eclipse-plugin/src/hterhors/editor/zest/IsrGraphView.java new file mode 100644 index 0000000000000000000000000000000000000000..d832140183a82f2b11f8796b2e146c63bd8f98dd --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/zest/IsrGraphView.java @@ -0,0 +1,24 @@ +package hterhors.editor.zest; + +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.part.ViewPart; + +public class IsrGraphView extends ViewPart { + public static final String ID = "hterhors.editor.zest.IsrGraphView"; + + Composite parent; + + public void createPartControl(Composite composite) { + this.parent = composite; +// SentenceGraphBuilder.getGraph(composite); + IsrGraphBuilder.getGraph(composite); + + } + + /** + * Passing the focus request to the viewer's control. + */ + + public void setFocus() { + } +} \ No newline at end of file diff --git a/isr-eclipse-plugin/src/hterhors/editor/zest/SentenceGraphBuilder.java b/isr-eclipse-plugin/src/hterhors/editor/zest/SentenceGraphBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..75ef3738c2eb4619b102675c4536453a5c749fd2 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/zest/SentenceGraphBuilder.java @@ -0,0 +1,230 @@ +package hterhors.editor.zest; + +import hterhors.editor.IISRColorConstants; +import hterhors.editor.sentenceparser.grammar.TreeData; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.zest.core.widgets.Graph; +import org.eclipse.zest.core.widgets.GraphConnection; +import org.eclipse.zest.core.widgets.GraphNode; +import org.eclipse.zest.core.widgets.ZestStyles; +import org.eclipse.zest.layouts.LayoutAlgorithm; +import org.eclipse.zest.layouts.LayoutStyles; +import org.eclipse.zest.layouts.algorithms.CompositeLayoutAlgorithm; +import org.eclipse.zest.layouts.algorithms.GridLayoutAlgorithm; +import org.eclipse.zest.layouts.algorithms.HorizontalShift; +import org.eclipse.zest.layouts.algorithms.HorizontalTreeLayoutAlgorithm; +import org.eclipse.zest.layouts.algorithms.RadialLayoutAlgorithm; +import org.eclipse.zest.layouts.algorithms.SpringLayoutAlgorithm; +import org.eclipse.zest.layouts.algorithms.TreeLayoutAlgorithm; +import org.eclipse.zest.layouts.algorithms.VerticalLayoutAlgorithm; + +/** + * Buggy wegen recursion + * @author Hendrik + */ +public class SentenceGraphBuilder { + + private static List<ArrayList<TreeData>> treeDatas = new ArrayList<ArrayList<TreeData>>(); + + public static void getGraph(Composite parent) { + if (treeDatas != null) { + for (ArrayList<TreeData> treeData : treeDatas) { + gns.clear(); + if (treeData != null) { + Device device = parent.getDisplay() + .getSystemColor(SWT.COLOR_GREEN).getDevice(); + final Graph graph = new Graph(parent, SWT.NONE); + GraphNode parentNode = null; + Iterator<TreeData> it = treeData.iterator(); + while (it.hasNext()) { + if (it.next().parent == null) { + parentNode = new GraphNode(graph, SWT.NONE, "$$S"); + break; + } + } + parentNode.setBackgroundColor(new Color(device, + IISRColorConstants.START_GRAPH)); + it = treeData.iterator(); + while (it.hasNext()) { + TreeData nd = it.next(); + TreeData pd; + if (nd.data.isLeaf()) { + GraphNode ndNode = new GraphNode(graph, SWT.NONE, + nd.data.getData().toString()); + add(ndNode); + GraphNode pdNode = null; + while (true) { + pd = nd.parent; + if (pd != null) { + if (pd.parent != null) { + pdNode = getndNod(graph, pd.data + .getData().toString()); + add(pdNode); + if (!pd.data.isLeaf()) { + pdNode.setBackgroundColor(new Color( + device, + IISRColorConstants.NON_TERMINAL_GRAPH)); + } + new GraphConnection( + graph, + ZestStyles.CONNECTIONS_DIRECTED, + pdNode, ndNode); + } else { + new GraphConnection( + graph, + ZestStyles.CONNECTIONS_DIRECTED, + parentNode, ndNode); + } + nd = pd; + ndNode = pdNode; + } else { + break; + } + } + } + } + + switch (layout) { + case TreeLayoutAlgorithm: + graph.setLayoutAlgorithm( + new CompositeLayoutAlgorithm( + LayoutStyles.NO_LAYOUT_NODE_RESIZING, + new LayoutAlgorithm[] { + new TreeLayoutAlgorithm( + LayoutStyles.NO_LAYOUT_NODE_RESIZING), + new HorizontalShift( + LayoutStyles.NO_LAYOUT_NODE_RESIZING) }), + true); + break; + case HorizontalTreeLayoutAlgorithm: + graph.setLayoutAlgorithm( + new CompositeLayoutAlgorithm( + LayoutStyles.NO_LAYOUT_NODE_RESIZING, + new LayoutAlgorithm[] { + new HorizontalTreeLayoutAlgorithm( + LayoutStyles.NO_LAYOUT_NODE_RESIZING), + new HorizontalShift( + LayoutStyles.NO_LAYOUT_NODE_RESIZING) }), + true); + break; + case RadialLayoutAlgorithm: + graph.setLayoutAlgorithm( + new CompositeLayoutAlgorithm( + LayoutStyles.NO_LAYOUT_NODE_RESIZING, + new LayoutAlgorithm[] { + new RadialLayoutAlgorithm( + LayoutStyles.NO_LAYOUT_NODE_RESIZING), + new HorizontalShift( + LayoutStyles.NO_LAYOUT_NODE_RESIZING) }), + true); + break; + case GridLayoutAlgorithm: + graph.setLayoutAlgorithm( + new CompositeLayoutAlgorithm( + LayoutStyles.NO_LAYOUT_NODE_RESIZING, + new LayoutAlgorithm[] { + new GridLayoutAlgorithm( + LayoutStyles.NO_LAYOUT_NODE_RESIZING), + new HorizontalShift( + LayoutStyles.NO_LAYOUT_NODE_RESIZING) }), + true); + break; + case VerticalLayoutAlgorithm: + graph.setLayoutAlgorithm( + new CompositeLayoutAlgorithm( + LayoutStyles.NO_LAYOUT_NODE_RESIZING, + new LayoutAlgorithm[] { + new VerticalLayoutAlgorithm( + LayoutStyles.NO_LAYOUT_NODE_RESIZING), + new HorizontalShift( + LayoutStyles.NO_LAYOUT_NODE_RESIZING) }), + true); + break; + case SpringLayoutAlgorithm: + graph.setLayoutAlgorithm( + new CompositeLayoutAlgorithm( + LayoutStyles.NO_LAYOUT_NODE_RESIZING, + new LayoutAlgorithm[] { + new SpringLayoutAlgorithm( + LayoutStyles.NO_LAYOUT_NODE_RESIZING), + new HorizontalShift( + LayoutStyles.NO_LAYOUT_NODE_RESIZING) }), + true); + break; + default: + graph.setLayoutAlgorithm( + new CompositeLayoutAlgorithm( + LayoutStyles.NO_LAYOUT_NODE_RESIZING, + new LayoutAlgorithm[] { + new HorizontalTreeLayoutAlgorithm( + LayoutStyles.NO_LAYOUT_NODE_RESIZING), + new HorizontalShift( + LayoutStyles.NO_LAYOUT_NODE_RESIZING) }), + true); + } + } + } + } + } + + private static GraphNode getndNod(Graph graph, String ndNodeText) { + int index; + if ((index = contains(ndNodeText)) == -1) + return new GraphNode(graph, SWT.NONE, ndNodeText); + return gns.get(index); + } + + static List<GraphNode> gns = new ArrayList<GraphNode>(); + + private static void add(GraphNode ndNode) { + if (contains(ndNode) == null) { + gns.add(ndNode); + } + } + + private static GraphNode contains(GraphNode ndNode) { + if (ndNode.getText().equals(ndNode.getText().toUpperCase())) { + for (int i = 0; i < gns.size(); i++) { + if (gns.get(i).getText().equals(ndNode.getText())) { + return ndNode; + } + } + } + return null; + } + + private static int contains(String ndNodeText) { + if (ndNodeText.equals(ndNodeText.toUpperCase())) { + for (int i = 0; i < gns.size(); i++) { + if (gns.get(i).getText().equals(ndNodeText)) { + return i; + } + } + } + return -1; + } + + /** + * @uml.property name="layout" + * @uml.associationEnd + */ + private static ELayouts layout = ELayouts.HorizontalTreeLayoutAlgorithm; + + public static void addInput(ArrayList<TreeData> tree_data, ELayouts l) { + SentenceGraphBuilder.treeDatas.add(tree_data); + if (l != null) + layout = l; + } + + public static void clearInput() { + SentenceGraphBuilder.treeDatas.clear(); + } +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/zest/SetGraphSettingsHandler.java b/isr-eclipse-plugin/src/hterhors/editor/zest/SetGraphSettingsHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..ac65501d63a0835f29471f53d5b0c53fb63de25e --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/zest/SetGraphSettingsHandler.java @@ -0,0 +1,104 @@ +package hterhors.editor.zest; + +import hterhors.editor.markers.IsrRuleValidator; + +import java.util.StringTokenizer; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.texteditor.ITextEditor; + +/** + * @author Hendrik + */ +public class SetGraphSettingsHandler extends AbstractHandler { + /** + * @uml.property name="layout" + * @uml.associationEnd + */ + public static ELayouts layout; + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + generateInput(event); + IWorkbenchPage page = HandlerUtil.getActiveWorkbenchWindow(event) + .getActivePage(); + IViewPart findView = (IViewPart) page + .findView("hterhors.editor.zest.IsrGraphView"); + page.hideView(findView); + try { + page.showView("hterhors.editor.zest.IsrGraphView"); + } catch (PartInitException e) { + } + return null; + } + + /** + * @param l + * @uml.property name="layout" + */ + public void setLayout(ELayouts l) { + layout = l; + } + + private void generateInput(ExecutionEvent event) { + ITextEditor textEditor = (ITextEditor) HandlerUtil + .getActiveEditor(event); + IEditorInput input = HandlerUtil.getActiveEditorInput(event); + ITextSelection selection = (ITextSelection) textEditor.getEditorSite() + .getSelectionProvider().getSelection(); + if (selection.getText().trim().isEmpty()) { + IsrGraphBuilder.setInput(textEditor.getDocumentProvider() + .getDocument(input).get(), layout); + } else { + if (testSelectionIsARule(selection.getText().trim())) { + IsrGraphBuilder.setInput(selection.getText(), layout); + } else { + Shell shell = (Shell) HandlerUtil.getActiveShell(event); + MessageBox pmb = new MessageBox(shell, SWT.ICON_ERROR | SWT.OK); + pmb.setText("Unvalid selection"); + pmb.setMessage("The selection you did, was not a valid construct and cannot be displayed!"); + pmb.open(); + } + } + } + + private boolean testSelectionIsARule(String selection) { + StringTokenizer tokenizer = new StringTokenizer(selection); + String preToken = tokenizer.nextToken(); + if (selection.trim().endsWith(";")) { + if ((preToken.matches(IsrRuleValidator.IGNORE + "=")) + || (preToken.matches(IsrRuleValidator.IGNORE) + && tokenizer.hasMoreElements() && tokenizer + .nextToken().matches("="))) { + return true; + } else if (((preToken.matches(IsrRuleValidator.NUMBER) && tokenizer + .hasMoreElements()) && (((preToken = tokenizer.nextToken()) + .matches(IsrRuleValidator.NON_TERMINAL + ":")) || (preToken + .matches(IsrRuleValidator.NON_TERMINAL) + && tokenizer.hasMoreElements() && tokenizer.nextToken() + .matches(":")))) + || ((preToken.matches(IsrRuleValidator.NON_TERMINAL + ":")) || (preToken + .matches(IsrRuleValidator.NON_TERMINAL) + && tokenizer.hasMoreElements() && tokenizer + .nextToken().matches(":")))) { + return true; + } else { + return false; + } + } else { + return false; + } + } + +} diff --git a/isr-eclipse-plugin/src/hterhors/editor/zest/UpdateGraphHandler.java b/isr-eclipse-plugin/src/hterhors/editor/zest/UpdateGraphHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..3b31fe058a00aa304177af6b4e8f302fe646119c --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/zest/UpdateGraphHandler.java @@ -0,0 +1,12 @@ +package hterhors.editor.zest; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; + +public class UpdateGraphHandler extends SetGraphSettingsHandler { + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + setLayout(null); + return super.execute(event); + } +} \ No newline at end of file diff --git a/isr-eclipse-plugin/src/hterhors/editor/zest/layouthandler/GridLayoutGraphHandler.java b/isr-eclipse-plugin/src/hterhors/editor/zest/layouthandler/GridLayoutGraphHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..361872d2972d2f03821b3c9ad4462036187f4c4c --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/zest/layouthandler/GridLayoutGraphHandler.java @@ -0,0 +1,16 @@ +package hterhors.editor.zest.layouthandler; + + +import hterhors.editor.zest.ELayouts; +import hterhors.editor.zest.SetGraphSettingsHandler; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; + +public class GridLayoutGraphHandler extends SetGraphSettingsHandler { + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + setLayout(ELayouts.GridLayoutAlgorithm); + return super.execute(event); + } +} \ No newline at end of file diff --git a/isr-eclipse-plugin/src/hterhors/editor/zest/layouthandler/HorizontalTreeLayoutGraphHandler.java b/isr-eclipse-plugin/src/hterhors/editor/zest/layouthandler/HorizontalTreeLayoutGraphHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..fa12a08f8ae4f14a001690c77f2bcbd1c8939351 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/zest/layouthandler/HorizontalTreeLayoutGraphHandler.java @@ -0,0 +1,19 @@ +package hterhors.editor.zest.layouthandler; + + +import hterhors.editor.zest.ELayouts; +import hterhors.editor.zest.SetGraphSettingsHandler; +import hterhors.editor.zest.UpdateGraphHandler; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; + +public class HorizontalTreeLayoutGraphHandler extends SetGraphSettingsHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + UpdateGraphHandler.layout = ELayouts.HorizontalTreeLayoutAlgorithm; + return super.execute(event); + } + +} \ No newline at end of file diff --git a/isr-eclipse-plugin/src/hterhors/editor/zest/layouthandler/RadialLayoutGraphHandler.java b/isr-eclipse-plugin/src/hterhors/editor/zest/layouthandler/RadialLayoutGraphHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..cf7ed05cba2d30a55b89cf2778b2817075c87ebc --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/zest/layouthandler/RadialLayoutGraphHandler.java @@ -0,0 +1,19 @@ +package hterhors.editor.zest.layouthandler; + + +import hterhors.editor.zest.ELayouts; +import hterhors.editor.zest.SetGraphSettingsHandler; +import hterhors.editor.zest.UpdateGraphHandler; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; + +public class RadialLayoutGraphHandler extends SetGraphSettingsHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + UpdateGraphHandler.layout = ELayouts.RadialLayoutAlgorithm; + return super.execute(event); + } + +} \ No newline at end of file diff --git a/isr-eclipse-plugin/src/hterhors/editor/zest/layouthandler/SpringLayoutGraphHandler.java b/isr-eclipse-plugin/src/hterhors/editor/zest/layouthandler/SpringLayoutGraphHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..931f575928c9effdacd1a3471aac48a723183f9d --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/zest/layouthandler/SpringLayoutGraphHandler.java @@ -0,0 +1,16 @@ +package hterhors.editor.zest.layouthandler; + + +import hterhors.editor.zest.ELayouts; +import hterhors.editor.zest.SetGraphSettingsHandler; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; + +public class SpringLayoutGraphHandler extends SetGraphSettingsHandler { + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + setLayout(ELayouts.SpringLayoutAlgorithm); + return super.execute(event); + } +} \ No newline at end of file diff --git a/isr-eclipse-plugin/src/hterhors/editor/zest/layouthandler/TreeLayoutGraphHandler.java b/isr-eclipse-plugin/src/hterhors/editor/zest/layouthandler/TreeLayoutGraphHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..3ac029ba1304d0448edcb6e7f37efe934c9fb17a --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/zest/layouthandler/TreeLayoutGraphHandler.java @@ -0,0 +1,17 @@ +package hterhors.editor.zest.layouthandler; + + +import hterhors.editor.zest.ELayouts; +import hterhors.editor.zest.SetGraphSettingsHandler; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; + +public class TreeLayoutGraphHandler extends SetGraphSettingsHandler { + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + setLayout(ELayouts.TreeLayoutAlgorithm); + return super.execute(event); + } +} + diff --git a/isr-eclipse-plugin/src/hterhors/editor/zest/layouthandler/VerticalLayoutGraphHandler.java b/isr-eclipse-plugin/src/hterhors/editor/zest/layouthandler/VerticalLayoutGraphHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..daa2a282483527b6d3c858cd7247f7204bf1e9d8 --- /dev/null +++ b/isr-eclipse-plugin/src/hterhors/editor/zest/layouthandler/VerticalLayoutGraphHandler.java @@ -0,0 +1,17 @@ +package hterhors.editor.zest.layouthandler; + + +import hterhors.editor.zest.ELayouts; +import hterhors.editor.zest.SetGraphSettingsHandler; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; + +public class VerticalLayoutGraphHandler extends SetGraphSettingsHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + setLayout(ELayouts.VerticalLayoutAlgorithm); + return super.execute(event); + } +} \ No newline at end of file diff --git a/isr-eclipse-plugin/src/resources/info_example.txt b/isr-eclipse-plugin/src/resources/info_example.txt new file mode 100644 index 0000000000000000000000000000000000000000..09c705d7f6d5a8820ab5396b09f349dfb3f1dbf8 --- /dev/null +++ b/isr-eclipse-plugin/src/resources/info_example.txt @@ -0,0 +1,17 @@ + Grm_def 4grm "Sven Wachsmuth & Gernot A. Fink" - "ESMERALDA-Manual" + +This is an example grammar describing a time constituent: +$TIME : $DAY $TIME_CIRCA $TIME_PRECISE ; +$DAY : today ; +$TIME_CIRCA : in the morning | ; +$TIME_PRECISE : at $TIME_HOUR oclock | at $TIME_HOUR point $TIME_MIN | ; +$TIME_HOUR : one | two | three ; +$TIME_MIN : zero | fifteen | thirty ; +$$S : $TIME ; + +Some word sequences defined by the grammar are: + +today in the morning +today in the morning at three oclock +today at one point thirty +today diff --git a/isr-eclipse-plugin/src/resources/info_functionality.txt b/isr-eclipse-plugin/src/resources/info_functionality.txt new file mode 100644 index 0000000000000000000000000000000000000000..f31a4d4deb646aebaca61f7c2525f0107e5f4718 --- /dev/null +++ b/isr-eclipse-plugin/src/resources/info_functionality.txt @@ -0,0 +1,14 @@ +This info describes the implemented functionalities! + +Implemented by Hendrik ter Horst (hterhors@techfak.uni-bielefeld.de) + +*Syntax-highliting +*Live Errorhandler +*Automatic check of the wordproblem and create syntax trees (Strg+shift+P) +*Autoformatting (Strg+Shift+F) +*Hover-Info(hold the mouse pointer over a faulty rule-element or over a nonterminal) +*Hyperlinks(Strg+Klick) on a nonterminal > jumps to his declaration +*visualization of the rules. Select a rule and press shortcut(Strg+Shift+V) > . (beta...) +*Content Assitent (Strg+Leertaste) > invokes a wizard to quickly create rule-elements +*Outline-Page(beta) shows a rough outline of the grammar according to the W3C standard for speech recognition grammars +*Menu item (ISR) for more help and examples, and advanced virtualization features(beta). \ No newline at end of file diff --git a/isr-eclipse-plugin/src/resources/info_general.txt b/isr-eclipse-plugin/src/resources/info_general.txt new file mode 100644 index 0000000000000000000000000000000000000000..fc2c5bf880fecf788cc721f1020ba17561f2f236 --- /dev/null +++ b/isr-eclipse-plugin/src/resources/info_general.txt @@ -0,0 +1,14 @@ + Grm_def 4grm "Sven Wachsmuth & Gernot A. Fink" - "ESMERALDA-Manual" + +The grammar library provides methods for using a context free grammar +in conjunction with an incremental partial parser as a language model +for a statistical recognizer. + +The grammar library provides functions which generate a LR(1) parse-table +from a grammar definition. The terminal symbols used in the +grammar must be defined in a separated lexicon. + +For more informations take a look at Esmeralda-man-page! +"/vol/esmeralda/man/man4/grm_def.4" + +Call "-M /vol/esmeralda/man grm_def" \ No newline at end of file diff --git a/isr-eclipse-plugin/src/resources/info_syntax.txt b/isr-eclipse-plugin/src/resources/info_syntax.txt new file mode 100644 index 0000000000000000000000000000000000000000..0f36bff46ba08656287ffbd0db5c658129049823 --- /dev/null +++ b/isr-eclipse-plugin/src/resources/info_syntax.txt @@ -0,0 +1,11 @@ + Grm_def 4grm "Sven Wachsmuth & Gernot A. Fink" - "ESMERALDA-Manual" + +The following text describes the syntax of the grammatic description +GRAMMAR used in the grm-library. Firstly the EBNF is presented: + +GRAMMAR = { (IGN_LIST | [ "[" RULE_NUM "]" ] RULE) } . +IGN_LIST = "%IGNORE" "=" { TERMINAL } ";" . +RULE_NUM = NUMBER . +RULE = NONTERMINAL ":" BODY { "|" BODY } ";" . +BODY = { SYMBOL } . +SYMBOL = NONTERMINAL | TERMINAL . \ No newline at end of file