I am extending an existing open-source project, which already has a very advanced Lexer/Parser/TreeParser in ANTLR. I would like to adhere to the current directory structure, so I created my own directory where I would like to put my new (already written) grammar files. They are importing these three original grammar files and to compile the code, I can use java org.antlr.Tool, where I can specify one directory to search for imported grammars with -lib option argument.
My problem is that these three original imported grammar files have some imports themselves and again in different directory. To illustrate (inheritance/importing going to top):
Abstract syntax directory: lexer parser tree parser
Original syntax directory: lexer parser tree parser
My new syntax directory: lexer parser tree parser
This is the hierarchy. The trouble I am encountering is how to specify "Abstract syntax directory" and also "Original syntax directory" at once with the -lib option on the command line for the ANTLR tool (or any other solution which would allow me to compile my grammar importing the original one with the given directories structure).
I tried -lib directory1 directory2, that just appears to ignore the directory2 (and then tries to compile it, which it cannot, because it is a directory, not an ANTLR grammar). I tried specifying "-lib directory1 -lib directory2", the "-lib directory2" just overwrites the "-lib directory1" then.
It is what I believe a fairly basic need to specify multiple directories to search in, in any more complicated system of grammars, therefore I am sure I missed something. I just cannot google anything useful out.
IF you need any more details, I am happy to provide them, it is my master thesis extending an open source project, so I do not need to keep anything secret. :) If it is not possible, I can live without it, but would really like to keep the consistency of the original project.
Looking at the source of the org.antlr.Tool class:
else if (args[i].equals("-lib")) {
if (i + 1 >= args.length) {
System.err.println("missing library directory with -lib option; ignoring");
}
else {
i++;
libDirectory = args[i];
if (libDirectory.endsWith("/") || libDirectory.endsWith("\\")) {
libDirectory = libDirectory.substring(0,libDirectory.length()-1);
}
File outDir = new File(libDirectory);
if (!outDir.exists()) {
ErrorManager.error(ErrorManager.MSG_DIR_NOT_FOUND,libDirectory);
libDirectory = ".";
}
}
}
it appears just one -lib directory is being read.
I'm assuming your (implied) question is hereby answered (that it is not possible to point to more than 1 -lib directory).
Related
I remember that there's a ".txt" file which allows to define link/compile-time arguments, but I've forgotten it's name.
I tried to google for answer.
The text file is called compile_flags.txt.
It's discussed at https://clangd.llvm.org/installation#compile_flagstxt.
Note that there are some shortcomings of compile_flags.txt compared to the more common way of configuring a project for use with clang-based tooling, compile_commands.json; most notably, clangd won't index your project with compile_flags.txt.
For example, in my main.scm file I have (load "util.scm"). util.scm is a file in the same folder as main.scm. Both files are located in ~/documents/myproject/.
Now when I'm in this directory, and I run $ chez-scheme main.scm everything works fine. However, if I'm in my home directory and run $chez-scheme documents/myproject/main.scm it complains, not being able to find the file util.scm. I suppose this is the case because the current directory was my relevant home directory, and as such util.scm is indeed not there, it is actually in documents/myproject/. That being said, I'm used (in other languages) to the functionality of looking these paths up relative to the file containing the instruction to import, and I'd like to have that here as well. I've tried prefixing it by ./ or defining the file as a libary and doing (import (util)) but none of it works outside of documents/myproject/. Is there any way to get this to work as I intend it to?
I assume this is Chez-Scheme-specific. If not I'd prefer an answer that is implementation-neutral.
load is kind of awkward in R5RS since the report states that system interfaces are off topic in the report, but they include load which is a half hearted solution. The report does not say if the load is relative to the current directory or the file the load form originates from so in order to be portable I guess you are required to run your script from the current directory and have your loaded file relative to both.
Since Chez Scheme implements R6RS load is not really the right form to use. R6RS removed load in favor of libraries. You should make your file a library and consult how to install it. In some systems that is just placing the files in the right path, adding library location in configuration or running install script. How one uses the library is the same in all implementations, by using import.
According to Chez documentation you can pass --libdirs to it to give it one or more paths to consider for loading libraries. You can see the paths it scans by evaluating (library-directories)
There are several different ways to accomplish what (I think) you are trying to do, but eventually they all boil down to letting Chez know where to look for things. When given relative paths, include and load use the source-directories parameter to search for the requested file. Libraries have their path automatically prepended to source-directories while they are being loaded or compiled, so if your main.scm were a library definition then it would find util.scm as you expect.
However, it sounds like main.scm isn't a library, it's a top-level program. Unfortunately, Chez doesn't have a command line option to set the source-directories like it does for library directories. That leaves you with a bit less flexibility. Any of the following will work:
Make util.scm a library and invoke Chez with the --libdirs option to let it know where to look for libraries.
Set source-directories and load main.scm from inside the REPL rather than from the command line.
Write a wrapper shell script that does the above by echoing the commands into scheme so you don't have to type it yourself. (Only suitable if you don't also need to then type into the scheme session).
Write a wrapper shell script that cds into your project directory before running scheme (and presumably cds back to the original directory when it's done).
Hi im new to programming, how do i import a .txt file? My code cant find the file, is there any specific directory it has to be put into?
My code:
object Zettel01 extends App {
import scala.io.Source
object Suchtest {
val gesch = Source.fromFile("DieUnendlicheGeschichte.txt").getLines()
for (w <- gesch) println(w)
}
}
I have tried different code but the problem is always the same, i cant find the .txt file...
Thanks in advance for any help
Flurry1337
Every Scala program that you run on your computer is ultimately a java process. This process will have a "working directory", just as every process on your computer does. By default, the working directory is the working directory of the process that started it, that is, the current directory of the shell or command-line interpreter at the time when you started your program.
Now, that means it is important to know how exactly you start your program. If you are using a command line and start your program in the fashion of java MyCoolProgram, then the current directory of the shell will become the working directory of the program. If you use an IDE like Eclipse or IntelliJ IDEA, those typically use the project folder of your IDE project as the working directory of the process that they start.
There is a simple way to find it out quickly: You can always print out the result of new java.io.File(".").getAbsolutePath(). This will print the full path to the working directory. For example, you can write a little Scala program like this:
object PrintWorkingDirectory extends App {
println(new java.io.File(".").getAbsolutePath())
}
and start it. On the console, you should find the full path of the program's working directory. If you put a file named "DieUnendlicheGeschichte.txt" in this directory, your program will find that file under exactly that file name.
Of course, you don't have to dump all your files into that one directory. You can make subdirectories in order to organize your files better. For example, you might put your file in a path like "resources/text/DieUnendlicheGeschichte.txt".
Finally, I would like to point out that there is also a different way to associate resource files with your program, and to load them. The idea is that you put the code (class files) as well as resources like texts, images, CSV files, XML files and the like into one big file. This would be a JAR file. You can then use ClassLoader to access resources inside the JAR file by a URL.
Explaining that process in detail is out of scope for this question; this is just dropping a couple of buzzwords that you (or other readers) can search for in case they want to look up a more elaborated process.
System.getProperty("user.dir") also tells you the working directory.
I'm generating developer documentation using Doxygen. It's parsing all of the files correctly, but the output is generating duplicate entries in the member function list and class diagram.
Any ideas?
I had this exact problem, and found that I had accidentally specified a build folder in the INPUT line due to RECURSIVE being on, e.g.,
Example file structure:
./
MyLibrarySources/
Libs/
build/
Doxyfile:
INPUT = ./ MyLibrarySources/ ...
RECURSIVE = YES
This caused Doxygen to parse the headers from two different locations: once from MyLibrarySources/, and once from build/, producing duplicate members and other odd results.
The easy solution is to add your build directory to the EXCLUDE line, e.g.:
EXCLUDE = "build"
This makes Doxygen not parse the same header files in two different locations. And yes, in-source build directories are usually a bad idea, place them elsewhere. In my case, command-line builds not issued from my IDE went there by default.
Edit note: I had incorrectly believed that the source files were being parsed twice because of the double-specification in the INPUT line. This is not the case. Doxygen is smart about this and will not parse the same physical file twice 👍.
I have a src/templates/ directory full of mustache templates. How would I combine and minify the contents of those, so they're available for use in my CoffeeScript app?
I'm already following the directions at https://github.com/jashkenas/coffee-script/wiki/%5BHowTo%5D-Compiling-and-Setting-Up-Build-Tools for combining and minifying my CoffeeScript src into js.
First off, I'll assume that your templates are being exported to the global object (e.g. each one does window.userpane = rather than just userpane =). That's the most important thing. If you're doing that, and you're concatenating and compiling successfully, then the only thing left is to have automatic minification after each concatenation.
Short answer: There's no good tool for this yet. Your best option is to extend your existing Cakefile with a line like
fs.watchFile 'concatenated.js', ->
exec 'uglifyjs concatenated.js'
(To install UglifyJS, run npm install uglify-js.)
Now, this won't solve the problem of ensuring that your scripts are concatenated in a sensible order. (For instance, if you have window.templates = {} in file A and templates.userpane = in file B, then it's very important that file A be concatenated before file B.) For that, you should keep an eye on Sprockets, which lets you indicate at the top of each JS file what its dependencies are, then combine them in an order that respects those dependencies. The creator of Sprockets, Sam Stephenson, is an active member of the CoffeeScript community, and first-class support for CoffeeScript in Sprockets is coming in Sprockets 2 (repo here).
Update: Here's a Cake task to do the actual reading and concatenating of everything in the template directory:
templateJs = ''
files = fs.readdirSync 'template'
for file in files
contents = fs.readFileSync file, 'utf8'
name = file.replace /\..*/, '' # remove extension
templateJs += "window.#{name} = '#{contents}';"
Then prepend your concatenated JS with templateJs. Note that this assumes that there are no single quotes (') in the template. Either put backslashes in front of them or consistently use double quotes.