Commits (27)
variables:
GIT_SUBMODULE_STRATEGY: recursive
stages:
- build
- test
- ragdoc_build
- ragdoc_view
- publish
before_script:
- export GRADLE_USER_HOME=`pwd`/.gradle
cache:
paths:
- .gradle/wrapper
- .gradle/caches
build:
image: openjdk:8
stage: build
script:
- ./gradlew --console=plain --no-daemon assemble
artifacts:
paths:
- "src/gen"
expire_in: 1 week
test:
image: openjdk:8
stage: test
script:
- ./gradlew --console=plain --no-daemon test
artifacts:
reports:
junit: build/test-results/test/**/TEST-*.xml
ragdoc_build:
image:
name: "git-st.inf.tu-dresden.de:4567/jastadd/ragdoc-builder"
entrypoint: [""]
stage: ragdoc_build
needs:
- build
script:
- JAVA_FILES=$(find src/ -name '*.java')
- /ragdoc-builder/start-builder.sh -excludeGenerated -d data/ $JAVA_FILES
only:
- master
artifacts:
paths:
- "data/"
ragdoc_view:
image:
name: "git-st.inf.tu-dresden.de:4567/jastadd/ragdoc-view:relations"
entrypoint: [""]
stage: ragdoc_view
needs:
- ragdoc_build
script:
- DATA_DIR=$(pwd -P)/data
- mkdir -p pages/docs/ragdoc
- OUTPUT_DIR=$(pwd -P)/pages/docs/ragdoc
- cd /ragdoc-view/src/ && rm -rf data && ln -s $DATA_DIR
- /ragdoc-view/build-view.sh --output-path=$OUTPUT_DIR
only:
- master
artifacts:
paths:
- "pages/docs/ragdoc"
pages:
image: python:3.8-buster
stage: publish
needs:
- ragdoc_view
- test
before_script:
- pip install -U mkdocs mkdocs-macros-plugin mkdocs-git-revision-date-localized-plugin
script:
- cd pages && mkdocs build
only:
- master
artifacts:
paths:
- public
[submodule "src/main/jastadd/mustache"]
path = src/main/jastadd/mustache
url = ../mustache.git
plugins {
id 'java-library'
id 'application'
id 'org.jastadd'
id 'java'
id 'idea'
id 'java-test-fixtures'
}
ext {
mainClassName = 'org.jastadd.relast.compiler.RelastSourceToSourceCompiler'
}
apply plugin: 'java'
apply plugin: 'jastadd'
apply plugin: 'application'
apply plugin: "idea"
// set the main class name for `gradle run`
application.mainClassName = "${mainClassName}"
sourceCompatibility = 1.8
mainClassName = 'org.jastadd.relast.compiler.RelastSourceToSourceCompiler'
targetCompatibility = 1.8
repositories {
jcenter()
mavenCentral()
}
buildscript {
repositories.jcenter()
dependencies {
classpath 'org.jastadd:jastaddgradle:1.13.3'
sourceSets {
model {
java {
srcDir "src/gen/java"
}
}
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.4.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.4.0'
testCompile 'org.assertj:assertj-core:3.12.1'
compile 'org.jastadd:jastadd:2.3.4'
runtime 'org.jastadd:jastadd:2.3.4'
compile group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11'
task modelJar(type: Jar) {
group = "build"
archiveBaseName = 'model'
archiveVersion = ''
from sourceSets.model.output
}
sourceSets {
main {
java.srcDir "src/gen/java"
java.srcDir "buildSrc/gen/java"
}
artifacts {
archives modelJar
}
test {
useJUnitPlatform()
dependencies {
maxHeapSize = '1G'
modelImplementation group: 'org.jastadd', name: 'jastadd', version: '2.3.5'
modelImplementation group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11'
implementation files(modelJar.archiveFile.get())
api group: 'org.jastadd', name: 'jastadd', version: '2.3.5'
api group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11'
implementation group: 'com.github.jknack', name: 'handlebars', version: '4.2.0'
implementation group: 'org.yaml', name: 'snakeyaml', version: '1.27'
// test
testRuntimeClasspath files(modelJar.archiveFile.get())
// test fixtures
testFixturesApi group: 'org.slf4j', name: 'slf4j-jdk14', version: '1.7.30'
testFixturesApi group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.7.0'
testFixturesApi group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.7.0'
testFixturesApi group: 'org.assertj', name: 'assertj-core', version: '3.18.0'
testFixturesApi group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.12.0-rc1'
testFixturesApi group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.12.0-rc1'
testFixturesApi group: 'commons-io', name: 'commons-io', version: '2.8.0'
}
def versionFile = 'src/main/resources/preprocessor.properties'
def versionProps = new Properties()
try {
file(versionFile).withInputStream { stream -> versionProps.load(stream) }
version = versionProps['version']
} catch (e) {
// this happens, if either the properties file is not present, or cannot be read from
throw new GradleException("File ${versionFile} not found or unreadable. Aborting.", e)
}
jar {
manifest {
attributes "Main-Class": 'org.jastadd.relast.compiler.RelastSourceToSourceCompiler'
attributes "Main-Class": "${mainClassName}"
}
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}
test {
useJUnitPlatform()
maxHeapSize = '1G'
}
// Input and output files for relast
def relastInputFiles = [
"src/main/jastadd/RelAst.relast",
"src/main/jastadd/mustache/Mustache.relast"
]
def relastOutputFiles = [
"src/gen/jastadd/RelAst.ast",
"src/gen/jastadd/RelAst.jadd",
"src/gen/jastadd/RelAstRefResolver.jadd",
"src/gen/jastadd/RelAstResolverStubs.jrag"
]
task relast(type: JavaExec) {
classpath = files("libs/relast.jar")
group = 'Build'
main = "-jar"
doFirst {
delete "src/gen/jastadd/*.ast"
delete "src/gen/jastadd/RelAst.jadd"
delete "src/gen/jastadd/RelAstRefResolver.jadd"
delete "src/gen/jastadd/RelAstResolverStubs.jrag"
mkdir "src/gen/jastadd/"
delete relastOutputFiles
mkdir "src/gen/jastadd/"
}
args = [
"libs/relast.jar",
"./src/main/jastadd/RelAst.relast",
"--listClass=java.util.ArrayList",
"--jastAddList=JastAddList",
"--useJastAddNames",
"--file",
"--resolverHelper",
"--grammarName=./src/gen/jastadd/RelAst"
]
inputs.files file("../libs/relast.jar"),
file("src/main/jastadd/RelAst.relast")
outputs.files file("./src/gen/jastadd/RelAst.ast"),
file("src/gen/jastadd/RelAst.jadd"),
file("src/gen/jastadd/RelAstRefResolver.jadd"),
file('src/gen/jastadd/RelAstResolverStubs.jrag')
] + relastInputFiles
inputs.files relastInputFiles
outputs.files relastOutputFiles
}
jastadd {
configureModuleBuild()
modules {
//noinspection GroovyAssignabilityCheck
module("RelAst") {
java {
basedir "."
include "src/main/**/*.java"
include "src/gen/**/*.java"
}
module("Preprocessor") {
jastadd {
basedir "."
include "src/main/jastadd/**/*.ast"
include "src/main/jastadd/**/*.jadd"
include "src/main/jastadd/**/*.jrag"
......@@ -105,10 +141,10 @@ jastadd {
}
scanner {
include "src/main/jastadd/scanner/Header.flex", [-4]
include "src/main/jastadd/scanner/Preamble.flex", [-3]
include "src/main/jastadd/scanner/Macros.flex", [-2]
include "src/main/jastadd/scanner/RulesPreamble.flex", [-1]
include "src/main/jastadd/scanner/Header.flex", [-4]
include "src/main/jastadd/scanner/Preamble.flex", [-3]
include "src/main/jastadd/scanner/Macros.flex", [-2]
include "src/main/jastadd/scanner/RulesPreamble.flex", [-1]
include "src/main/jastadd/scanner/Keywords.flex", [0]
include "src/main/jastadd/scanner/Symbols.flex", [1]
include "src/main/jastadd/scanner/RulesPostamble.flex", [2]
......@@ -122,8 +158,8 @@ jastadd {
}
cleanGen.doFirst {
delete "src/gen/java/org"
delete "src/gen-res/BuildInfo.properties"
delete "src/gen"
delete "src/gen-res"
}
preprocessParser.doFirst {
......@@ -132,7 +168,7 @@ jastadd {
}
module = "RelAst"
module = "Preprocessor"
astPackage = 'org.jastadd.relast.ast'
......@@ -149,3 +185,11 @@ jastadd {
}
generateAst.dependsOn relast
clean.dependsOn(cleanGen)
modelJar.dependsOn(generateAst, modelClasses)
modelClasses.dependsOn(generateAst)
compileJava.dependsOn(modelJar)
jar.dependsOn(modelJar)
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
No preview for this file type
/docs/ragdoc/
{% block footer %}
<p>{% if config.copyright %}
<small>{{ config.copyright }}<br></small>
{% endif %}
<hr>
Built with <a href="https://www.mkdocs.org/">MkDocs</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
{% if page and page.meta and page.meta.git_revision_date_localized %}
<small><br><i>Last updated {{ page.meta.git_revision_date_localized }}</i></small>
{% endif %}
</p>
{% endblock %}
# Relational RAGs Preprocessor Documentation
The [Relational RAGs Preprocessor](https://git-st.inf.tu-dresden.de/jastadd/relast-preprocessor) is a framework to create custom preprocessors for [JastAdd](http://jastadd.org) and JastAdd-based [Relational RAGs](http://www.relational-rags.eu).
# Creating a Preprocessor
## Project Structure
The *gradle* build system is required to use the preprocessor.
It is recommended to use the same version of gradle as the preprocessor does internally, which currently is 6.7.
To create a new preprocessor, follow the following steps:
1. Create a new gradle project
2. Include this repository as a submodule in the directory `relast.preprocessor`
- copy the contents of this repository into this directory; this can be done using a git submodule
- in your `settings.gradle` add a dependency to it:
```groovy
include 'relast.preprocessor'
```
3. Adapt the `build.gradle` file of your project to use the subproject; this step is described in the next section
## Constructing a Gradle Build File
The preprocessor and its test infrastructure are included as project dependencies.
```groovy
dependencies {
implementation project(':relast.preprocessor')
testImplementation testFixtures(project(":relast.preprocessor"))
}
```
Next, the RelAST preprocessor must be called using files provided by the framework and potentially other extensions of the RelAST gramamr DSL.
```groovy
// Input and output files for relast
def relastInputFiles = [
"relast.preprocessor/src/main/jastadd/RelAst.relast",
"relast.preprocessor/src/main/jastadd/mustache/Mustache.relast"
// add more files here
]
def relastOutputFiles = [
"src/gen/jastadd/RelAst.ast",
"src/gen/jastadd/RelAst.jadd",
"src/gen/jastadd/RelAstRefResolver.jadd",
"src/gen/jastadd/RelAstResolverStubs.jrag"
]
task relast(type: JavaExec) {
classpath = files("relast.preprocessor/libs/relast.jar")
group = 'Build'
doFirst {
delete relastOutputFiles
mkdir "src/gen/jastadd/"
}
args = [
"--listClass=java.util.ArrayList",
"--jastAddList=JastAddList",
"--useJastAddNames",
"--file",
"--resolverHelper",
"--grammarName=./src/gen/jastadd/RelAst"
] + relastInputFiles
inputs.files relastInputFiles
outputs.files relastOutputFiles
}
```
Finally, JastAdd must be configured to use the correct files.
Note that the scanner includes are split into several files to allow for an extensible lexical analysis.
```groovy
jastadd {
configureModuleBuild()
modules {
//noinspection GroovyAssignabilityCheck
module("Preprocessor") {
jastadd {
basedir "."
include "relast.preprocessor/src/main/jastadd/**/*.ast"
include "relast.preprocessor/src/main/jastadd/**/*.jadd"
include "relast.preprocessor/src/main/jastadd/**/*.jrag"
include "src/main/jastadd/**/*.ast"
include "src/main/jastadd/**/*.jadd"
include "src/main/jastadd/**/*.jrag"
include "src/gen/jastadd/**/*.ast"
include "src/gen/jastadd/**/*.jadd"
include "src/gen/jastadd/**/*.jrag"
}
scanner {
include "relast.preprocessor/src/main/jastadd/scanner/Header.flex", [-4]
include "relast.preprocessor/src/main/jastadd/scanner/Preamble.flex", [-3]
include "relast.preprocessor/src/main/jastadd/scanner/Macros.flex", [-2]
include "relast.preprocessor/src/main/jastadd/scanner/RulesPreamble.flex", [-1]
include "relast.preprocessor/src/main/jastadd/scanner/Keywords.flex", [ 0]
include "relast.preprocessor/src/main/jastadd/scanner/Symbols.flex", [ 1]
include "relast.preprocessor/src/main/jastadd/scanner/RulesPostamble.flex", [ 2]
}
parser {
include "relast.preprocessor/src/main/jastadd/parser/Preamble.parser"
include "relast.preprocessor/src/main/jastadd/parser/RelAst.parser"
}
}
}
cleanGen.doFirst {
delete "src/gen"
delete "src/gen-res"
}
preprocessParser.doFirst {
args += ["--no-beaver-symbol"]
}
module = "Preprocessor"
astPackage = 'org.jastadd.relast.ast'
parser.name = 'RelAstParser'
genDir = 'src/gen/java'
buildInfoDir = 'src/gen-res'
scanner.genDir = "src/gen/java/org/jastadd/relast/scanner"
parser.genDir = "src/gen/java/org/jastadd/relast/parser"
jastaddOptions = ["--lineColumnNumbers", "--List=JastAddList", "--safeLazy", "--visitCheck=true", "--rewrite=cnta", "--cache=all"]
}
```
## Writing Tests
The preprocessor provides a test framework based on on JUnit 5.
This framework can be used to write acceptance tests, comparing input and output of runs of the constructed preprocessor.
Hereby, no java code has to be written - only a simple configuration file and some input and expected data have to be provided.
### Test Class
Create a new class inheriting from `RelAstProcessorTestBase` and set the `mainClass` field to the correct class.
```java
import org.jastadd.relast.tests.RelAstProcessorTestBase;
import org.junit.jupiter.api.BeforeAll;
public class MyPreprocessorTest extends RelAstProcessorTestBase {
@BeforeAll
static void init() {
mainClass = Main.class;
}
}
```
### Test DSL
Tests are described by a config file. Each directory in `src/main/resources` containing a `config.yaml` is assumed to contain test data.
A test configuration must contain a list of objects containing the following properties:
| Name | Type | Required | Default Value | Description |
| -------------- | --------------------- | -------- | ------------- | ---------------------------------------------------- |
| | | | | |
| `name` | string | yes | -- | name of the test case |
| `args` | list of strings | yes | -- | arguments passed to the preprocessor |
| `fail` | boolean | no | `false` | is the test a negative test |
| | | | | |
| `in` | string | no | `"in"` | directory containing input data |
| `out` | string | no | `"out"` | directory the output is written to |
| `expected` | string | no | `"expected"` | directory containing expected data |
| | | | | |
| `compare` | boolean | no | `false` | should `out` and `expected` directories be compared? |
| | | | | |
| `out-contains` | list of strings | no | empty list | string that must be contained in the `stdout` stream |
| `err-contains` | list of strings | no | empty list | string that must be contained in the `stderr` stream |
| `out-matches` | list of regex strings | no | empty list | regular expression the `stdout` stream must match |
| `err-matches` | list of regex strings | no | empty list | regular expression the `stderr` stream must match |
| | | | | |
Example:
```yaml
- name: "SimpleInheritance (null)"
compare: true
out: "null/out"
expected: "null/expected"
args:
- "--inputBaseDir=in"
- "--outputBaseDir=null/out"
- "--printYaml"
- "--errorHandling=null"
- "Example.relast"
- name: "SimpleInheritance (wrong exception)"
fail: true
err-matches:
- "(?s).*Invalid.*"
err-contains:
- "Invalid argument 'not.a.Class' for parameter 'errorHandling': Class not found (name must be qualified)."
args:
- "--inputBaseDir=in"
- "--outputBaseDir=out/does_not_matter_will_fail"
- "--errorHandling=not.a.Class"
- "Example.relast"
```
site_name: Relational RAGs Preprocessor Documentation
nav:
- using.md
- API documentation: ragdoc/index.html
theme:
name: readthedocs
custom_dir: custom_theme/
plugins:
- search
- git-revision-date-localized:
type: datetime
timezone: Europe/Berlin
locale: en
fallback_to_build_date: True
- macros
repo_url: https://git-st.inf.tu-dresden.de/jastadd/relast-preprocessor
site_dir: ../public
pluginManagement {
plugins {
id 'org.jastadd' version '1.13.3'
}
}
aspect Navigation {
/** Tests if Comment is a WhitespaceComment.
* @return 'true' if this is a WhitespaceComment, otherwise 'false'
*/
syn boolean Comment.isWhitespaceComment() = false;
eq WhitespaceComment.isWhitespaceComment() = true;
/** Tests if Comment is a SingleLineComment.
* @return 'true' if this is a SingleLineComment, otherwise 'false'
*/
syn boolean Comment.isSingleLineComment() = false;
eq SingleLineComment.isSingleLineComment() = true;
/** Tests if Comment is a MultiLineComment.
* @return 'true' if this is a MultiLineComment, otherwise 'false'
*/
syn boolean Comment.isMultiLineComment() = false;
eq MultiLineComment.isMultiLineComment() = true;
/** Tests if Comment is a DocComment.
* @return 'true' if this is a DocComment, otherwise 'false'
*/
syn boolean Comment.isDocComment() = false;
eq DocComment.isDocComment() = true;
/** Tests if DirectedRelation is a LeftDirectedRelation.
* @return 'true' if this is a LeftDirectedRelation, otherwise 'false'
*/
syn boolean DirectedRelation.isLeftDirectedRelation() = false;
eq LeftDirectedRelation.isLeftDirectedRelation() = true;
/** Tests if DirectedRelation is a RightDirectedRelation.
* @return 'true' if this is a RightDirectedRelation, otherwise 'false'
*/
syn boolean DirectedRelation.isRightDirectedRelation() = false;
eq RightDirectedRelation.isRightDirectedRelation() = true;
/** Tests if TypeComponent is a NormalComponent.
* @return 'true' if this is a NormalComponent, otherwise 'false'
*/
syn boolean TypeComponent.isNormalComponent() = false;
eq NormalComponent.isNormalComponent() = true;
/** Tests if TypeComponent is a ListComponent.
* @return 'true' if this is a ListComponent, otherwise 'false'
*/
syn boolean TypeComponent.isListComponent() = false;
eq ListComponent.isListComponent() = true;
/** Tests if TypeComponent is a OptComponent.
* @return 'true' if this is a OptComponent, otherwise 'false'
*/
syn boolean TypeComponent.isOptComponent() = false;
eq OptComponent.isOptComponent() = true;
/** Tests if Grammar is a GrammarFile.
* @return 'true' if this is a GrammarFile, otherwise 'false'
*/
syn boolean Grammar.isGrammarFile() = false;
eq GrammarFile.isGrammarFile() = true;
/** Tests if NavigableRole is a NormalRole.
* @return 'true' if this is a NormalRole, otherwise 'false'
*/
syn boolean NavigableRole.isNormalRole() = false;
eq NormalRole.isNormalRole() = true;
/** Tests if NavigableRole is a ListRole.
* @return 'true' if this is a ListRole, otherwise 'false'
*/
syn boolean NavigableRole.isListRole() = false;
eq ListRole.isListRole() = true;
/** Tests if NavigableRole is a OptRole.
* @return 'true' if this is a OptRole, otherwise 'false'
*/
syn boolean NavigableRole.isOptRole() = false;
eq OptRole.isOptRole() = true;
/** Tests if Component is a TypeComponent.
* @return 'true' if this is a TypeComponent, otherwise 'false'
*/
syn boolean Component.isTypeComponent() = false;
eq TypeComponent.isTypeComponent() = true;
/** Tests if Component is a TokenComponent.
* @return 'true' if this is a TokenComponent, otherwise 'false'
*/
syn boolean Component.isTokenComponent() = false;
eq TokenComponent.isTokenComponent() = true;
/** Tests if JavaTypeUse is a SimpleJavaTypeUse.
* @return 'true' if this is a SimpleJavaTypeUse, otherwise 'false'
*/
syn boolean JavaTypeUse.isSimpleJavaTypeUse() = false;
eq SimpleJavaTypeUse.isSimpleJavaTypeUse() = true;
/** Tests if JavaTypeUse is a ParameterizedJavaTypeUse.
* @return 'true' if this is a ParameterizedJavaTypeUse, otherwise 'false'
*/
syn boolean JavaTypeUse.isParameterizedJavaTypeUse() = false;
eq ParameterizedJavaTypeUse.isParameterizedJavaTypeUse() = true;
/** Tests if Relation is a DirectedRelation.
* @return 'true' if this is a DirectedRelation, otherwise 'false'
*/
syn boolean Relation.isDirectedRelation() = false;
eq DirectedRelation.isDirectedRelation() = true;
/** Tests if Relation is a BidirectionalRelation.
* @return 'true' if this is a BidirectionalRelation, otherwise 'false'
*/
syn boolean Relation.isBidirectionalRelation() = false;
eq BidirectionalRelation.isBidirectionalRelation() = true;
/** Tests if Role is a NavigableRole.
* @return 'true' if this is a NavigableRole, otherwise 'false'
*/
syn boolean Role.isNavigableRole() = false;
eq NavigableRole.isNavigableRole() = true;
/** Tests if Role is a UnnamedRole.
* @return 'true' if this is a UnnamedRole, otherwise 'false'
*/
syn boolean Role.isUnnamedRole() = false;
eq UnnamedRole.isUnnamedRole() = true;
/** Tests if Declaration is a EmptyDeclaration.
* @return 'true' if this is a EmptyDeclaration, otherwise 'false'
*/
syn boolean Declaration.isEmptyDeclaration() = false;
eq EmptyDeclaration.isEmptyDeclaration() = true;
/** Tests if Declaration is a TypeDecl.
* @return 'true' if this is a TypeDecl, otherwise 'false'
*/
syn boolean Declaration.isTypeDecl() = false;
eq TypeDecl.isTypeDecl() = true;
/** Tests if Declaration is a Relation.
* @return 'true' if this is a Relation, otherwise 'false'
*/
syn boolean Declaration.isRelation() = false;
eq Relation.isRelation() = true;
/** casts a Comment into a WhitespaceComment if possible.
* @return 'this' cast to a WhitespaceComment or 'null'
*/
syn WhitespaceComment Comment.asWhitespaceComment();
eq Comment.asWhitespaceComment() = null;
eq WhitespaceComment.asWhitespaceComment() = this;
/** casts a Comment into a SingleLineComment if possible.
* @return 'this' cast to a SingleLineComment or 'null'
*/
syn SingleLineComment Comment.asSingleLineComment();
eq Comment.asSingleLineComment() = null;
eq SingleLineComment.asSingleLineComment() = this;
/** casts a Comment into a MultiLineComment if possible.
* @return 'this' cast to a MultiLineComment or 'null'
*/
syn MultiLineComment Comment.asMultiLineComment();
eq Comment.asMultiLineComment() = null;
eq MultiLineComment.asMultiLineComment() = this;
/** casts a Comment into a DocComment if possible.
* @return 'this' cast to a DocComment or 'null'
*/
syn DocComment Comment.asDocComment();
eq Comment.asDocComment() = null;
eq DocComment.asDocComment() = this;
/** casts a DirectedRelation into a LeftDirectedRelation if possible.
* @return 'this' cast to a LeftDirectedRelation or 'null'
*/
syn LeftDirectedRelation DirectedRelation.asLeftDirectedRelation();
eq DirectedRelation.asLeftDirectedRelation() = null;
eq LeftDirectedRelation.asLeftDirectedRelation() = this;
/** casts a DirectedRelation into a RightDirectedRelation if possible.
* @return 'this' cast to a RightDirectedRelation or 'null'
*/
syn RightDirectedRelation DirectedRelation.asRightDirectedRelation();
eq DirectedRelation.asRightDirectedRelation() = null;
eq RightDirectedRelation.asRightDirectedRelation() = this;
/** casts a TypeComponent into a NormalComponent if possible.
* @return 'this' cast to a NormalComponent or 'null'
*/
syn NormalComponent TypeComponent.asNormalComponent();
eq TypeComponent.asNormalComponent() = null;
eq NormalComponent.asNormalComponent() = this;
/** casts a TypeComponent into a ListComponent if possible.
* @return 'this' cast to a ListComponent or 'null'
*/
syn ListComponent TypeComponent.asListComponent();
eq TypeComponent.asListComponent() = null;
eq ListComponent.asListComponent() = this;
/** casts a TypeComponent into a OptComponent if possible.
* @return 'this' cast to a OptComponent or 'null'
*/
syn OptComponent TypeComponent.asOptComponent();
eq TypeComponent.asOptComponent() = null;
eq OptComponent.asOptComponent() = this;
/** casts a Grammar into a GrammarFile if possible.
* @return 'this' cast to a GrammarFile or 'null'
*/
syn GrammarFile Grammar.asGrammarFile();
eq Grammar.asGrammarFile() = null;
eq GrammarFile.asGrammarFile() = this;
/** casts a NavigableRole into a NormalRole if possible.
* @return 'this' cast to a NormalRole or 'null'
*/
syn NormalRole NavigableRole.asNormalRole();
eq NavigableRole.asNormalRole() = null;
eq NormalRole.asNormalRole() = this;
/** casts a NavigableRole into a ListRole if possible.
* @return 'this' cast to a ListRole or 'null'
*/
syn ListRole NavigableRole.asListRole();
eq NavigableRole.asListRole() = null;
eq ListRole.asListRole() = this;
/** casts a NavigableRole into a OptRole if possible.
* @return 'this' cast to a OptRole or 'null'
*/
syn OptRole NavigableRole.asOptRole();
eq NavigableRole.asOptRole() = null;
eq OptRole.asOptRole() = this;
/** casts a Component into a TypeComponent if possible.
* @return 'this' cast to a TypeComponent or 'null'
*/
syn TypeComponent Component.asTypeComponent();
eq Component.asTypeComponent() = null;
eq TypeComponent.asTypeComponent() = this;
/** casts a Component into a TokenComponent if possible.
* @return 'this' cast to a TokenComponent or 'null'
*/
syn TokenComponent Component.asTokenComponent();
eq Component.asTokenComponent() = null;
eq TokenComponent.asTokenComponent() = this;
/** casts a JavaTypeUse into a SimpleJavaTypeUse if possible.
* @return 'this' cast to a SimpleJavaTypeUse or 'null'
*/
syn SimpleJavaTypeUse JavaTypeUse.asSimpleJavaTypeUse();
eq JavaTypeUse.asSimpleJavaTypeUse() = null;
eq SimpleJavaTypeUse.asSimpleJavaTypeUse() = this;
/** casts a JavaTypeUse into a ParameterizedJavaTypeUse if possible.
* @return 'this' cast to a ParameterizedJavaTypeUse or 'null'
*/
syn ParameterizedJavaTypeUse JavaTypeUse.asParameterizedJavaTypeUse();
eq JavaTypeUse.asParameterizedJavaTypeUse() = null;
eq ParameterizedJavaTypeUse.asParameterizedJavaTypeUse() = this;
/** casts a Relation into a DirectedRelation if possible.
* @return 'this' cast to a DirectedRelation or 'null'
*/
syn DirectedRelation Relation.asDirectedRelation();
eq Relation.asDirectedRelation() = null;
eq DirectedRelation.asDirectedRelation() = this;
/** casts a Relation into a BidirectionalRelation if possible.
* @return 'this' cast to a BidirectionalRelation or 'null'
*/
syn BidirectionalRelation Relation.asBidirectionalRelation();
eq Relation.asBidirectionalRelation() = null;
eq BidirectionalRelation.asBidirectionalRelation() = this;
/** casts a Role into a NavigableRole if possible.
* @return 'this' cast to a NavigableRole or 'null'
*/
syn NavigableRole Role.asNavigableRole();
eq Role.asNavigableRole() = null;
eq NavigableRole.asNavigableRole() = this;
/** casts a Role into a UnnamedRole if possible.
* @return 'this' cast to a UnnamedRole or 'null'
*/
syn UnnamedRole Role.asUnnamedRole();
eq Role.asUnnamedRole() = null;
eq UnnamedRole.asUnnamedRole() = this;
/** casts a Declaration into a EmptyDeclaration if possible.
* @return 'this' cast to a EmptyDeclaration or 'null'
*/
syn EmptyDeclaration Declaration.asEmptyDeclaration();
eq Declaration.asEmptyDeclaration() = null;
eq EmptyDeclaration.asEmptyDeclaration() = this;
/** casts a Declaration into a TypeDecl if possible.
* @return 'this' cast to a TypeDecl or 'null'
*/
syn TypeDecl Declaration.asTypeDecl();
eq Declaration.asTypeDecl() = null;
eq TypeDecl.asTypeDecl() = this;
/** casts a Declaration into a Relation if possible.
* @return 'this' cast to a Relation or 'null'
*/
syn Relation Declaration.asRelation();
eq Declaration.asRelation() = null;
eq Relation.asRelation() = this;
}
......@@ -2,6 +2,8 @@ aspect Navigation {
// --- program ---
inh Program ASTNode.program();
eq Grammar.getChild().program() = null;
eq GrammarFile.getChild().program() = program();
eq Program.getChild().program() = this;
// --- typeDecls ---
......@@ -28,66 +30,10 @@ aspect Navigation {
// --- containedFile ---
inh GrammarFile ASTNode.containedFile();
eq Grammar.getChild().containedFile() = null;
eq Program.getChild().containedFile() = null;
eq GrammarFile.getChild().containedFile() = this;
// --- containedFileName ---
inh String ASTNode.containedFileName();
eq GrammarFile.getChild().containedFileName() = getFileName();
// --- isTokenComponent ---
syn boolean Component.isTokenComponent() = false;
eq TokenComponent.isTokenComponent() = true;
// --- asTokenComponent ---
syn TokenComponent Component.asTokenComponent() = null;
eq TokenComponent.asTokenComponent() = this;
// --- isTypeDecl (should be in preprocessor) ---
syn boolean Declaration.isTypeDecl() = false;
eq TypeDecl.isTypeDecl() = true;
// --- asTypeDecl (should be in preprocessor) ---
syn TypeDecl Declaration.asTypeDecl() = null;
eq TypeDecl.asTypeDecl() = this;
// --- isTypeComponent (should be in preprocessor) ---
syn boolean Component.isTypeComponent() = false;
eq TypeComponent.isTypeComponent() = true;
// --- asTypeComponent (should be in preprocessor) ---
syn TypeComponent Component.asTypeComponent() = null;
eq TypeComponent.asTypeComponent() = this;
// --- isNormalComponent (should be in preprocessor) ---
syn boolean Component.isNormalComponent() = false;
eq NormalComponent.isNormalComponent() = true;
// --- asNormalComponent (should be in preprocessor) ---
syn NormalComponent Component.asNormalComponent() = null;
eq NormalComponent.asNormalComponent() = this;
// --- isListComponent (should be in preprocessor) ---
syn boolean Component.isListComponent() = false;
eq ListComponent.isListComponent() = true;
// --- asListComponent (should be in preprocessor) ---
syn ListComponent Component.asListComponent() = null;
eq ListComponent.asListComponent() = this;
// --- isDirectedRelation (should be in preprocessor) ---
syn boolean Relation.isDirectedRelation() = false;
eq DirectedRelation.isDirectedRelation() = true;
// --- asDirectedRelation (should be in preprocessor) ---
syn DirectedRelation Relation.asDirectedRelation() = null;
eq DirectedRelation.asDirectedRelation() = this;
// --- asBidirectionalRelation (should be in preprocessor) ---
syn BidirectionalRelation Relation.asBidirectionalRelation() = null;
eq BidirectionalRelation.asBidirectionalRelation() = this;
// --- isListRole (should be in preprocessor) ---
syn boolean Role.isListRole() = false;
eq ListRole.isListRole() = true;
syn String ASTNode.containedFileName() = containedFile().getFileName();
}
......@@ -43,14 +43,16 @@ aspect BackendAbstractGrammar {
if (getAbstract()) {
b.append("abstract ");
}
b.append(getName()).append(" ");
b.append(getName());
if (hasSuperType()) {
b.append(": ").append(getSuperType().getName()).append(" ");
b.append(" : ").append(getSuperType().getName());
}
b.append("::=");
for (Component component : getComponentList()) {
b.append(" ");
component.generateAbstractGrammar(b);
if (getNumComponent() > 0) {
b.append(" ::=");
for (Component component : getComponentList()) {
b.append(" ");
component.generateAbstractGrammar(b);
}
}
b.append(";");
super.generateAbstractGrammar(b);
......@@ -62,8 +64,7 @@ aspect BackendAbstractGrammar {
if (getNTA()) {
b.append("/");
}
if (!getName().equals("")) {
if (!getName().equals("") && !getName().equals(getTypeDecl().getName())) {
b.append(getName()).append(":");
}
b.append(getTypeDecl().getName());
......@@ -76,8 +77,7 @@ aspect BackendAbstractGrammar {
if (getNTA()) {
b.append("/");
}
if (!getName().equals("")) {
if (!getName().equals("") && !getName().equals(getTypeDecl().getName())) {
b.append(getName()).append(":");
}
b.append(getTypeDecl().getName()).append("*");
......@@ -91,7 +91,7 @@ aspect BackendAbstractGrammar {
b.append("/");
}
b.append("[");
if (!getName().equals("")) {
if (!getName().equals("") && !getName().equals(getTypeDecl().getName())) {
b.append(getName()).append(":");
}
b.append(getTypeDecl().getName()).append("]");
......@@ -187,7 +187,7 @@ aspect BackendAbstractGrammar {
}
public void SingleLineComment.generateAbstractGrammar(StringBuilder b) {
b.append("//").append(getText()).append("\n");
b.append("//").append(getText());
}
public void MultiLineComment.generateAbstractGrammar(StringBuilder b) {
......
Subproject commit c10bed0d03e3fa18b8133ce1de48de7646899615
GrammarFile goal
= comment_list.c {: return new EmptyDeclaration(c); :}
| grammar_file
= comment_list.c grammar_file.f {: f.getDeclarationList().insertChild(new EmptyDeclaration(c), 0); return f; :}
;
GrammarFile grammar_file
......@@ -16,8 +15,8 @@ Declaration declaration
// this method would be create by the JAstAddParser from a usage of
// 'comment+' in a rule, but only for the standard list class 'List'.
JastAddList comment_list
= comment.n {: return new JastAddList().add(n); :}
| comment_list.l comment.n {: return l.add(n); :}
= comment.c comment_list.l {: l.insertChild(c, 0); return l; :}
| /* epsilon */ {: return new JastAddList(); :}
;
Comment comment
......
<YYINITIAL,DECLARATION> {
<YYINITIAL,COMMENT,DECLARATION> {
"abstract" { yybegin(DECLARATION); return sym(Terminals.ABSTRACT); }
"rel" { yybegin(DECLARATION); return sym(Terminals.RELATION); }
}
<YYINITIAL,DECLARATION> {
<YYINITIAL,COMMENT,DECLARATION> {
{ID} { yybegin(DECLARATION); return sym(Terminals.ID); }
[^] { throw new ScannerError((yyline+1) +"," + (yycolumn+1) + ": Illegal character <"+yytext()+">"); }
}
<YYINITIAL,DECLARATION,COMMENT> {
<YYINITIAL,COMMENT,DECLARATION> {
<<EOF>> { return sym(Terminals.EOF); }
}
[^] { throw new ScannerError((yyline+1) +"," + (yycolumn+1) + ": Illegal character <"+yytext()+">"); }
}
\ No newline at end of file
<YYINITIAL,DECLARATION> {
<YYINITIAL,COMMENT,DECLARATION> {
";" { yybegin(COMMENT); return sym(Terminals.SCOL); }
":" { yybegin(DECLARATION); return sym(Terminals.COL); }
"::=" { yybegin(DECLARATION); return sym(Terminals.ASSIGN); }
......