Haskell parser and pretty printer for the java language.
Simple compilation unit parser:
parser compilationUnit "import java.util.*; public class MyClass {}"
or from a file:
ast <- parser compilationUnit `fmap` readFile "myClass.java"
Java parser and printer for haskell
License: Other
The last release on Hackage is from 2018. Is this project still maintained?
import java.util.List;
import java.util.ArrayList;
public abstract class F {
private List<Long> l = new ArrayList<>();
}
Fails as
("F.java",(line 5, column 15):
unexpected Op_LThan)
The MethodRefs are defined to be identifiers. However, Java allows to use this
as the class of the method reference.
This works:
parser Language.Java.Parser.exp "MyClass::myMethod"
> Right (MethodRef (Ident "MyClass") (Ident "myMethod"))
This also:
parser Language.Java.Parser.exp "otherInstance::myMethod"
> Right (MethodRef (Ident "otherInstance") (Ident "myMethod"))
This does not:
parser Language.Java.Parser.exp "this::myMethod"
> Right This
Regards
Johannes
When trying to run the parser over the Java file:
https://github.com/datastax/java-driver/blob/3.0/driver-core/src/test/java/com/datastax/driver/core/utils/CassandraVersion.java
One gets the error:
unexpected KW_Interface
Do you expect to support annotations soon?
Thanks a lot for this great package!
The dependency syb( http://hackage.haskell.org/package/syb-0.3.7 ) is missing in .cabal file.
It's used in Parser module (and possibly in somewhere else).
I'm trying to parse test files in test/
folder, but both testFile
and parser compilationUnit
calls throws parse errors. Are those tests broken ? Or otherwise how can I parse them ?
This parses ok:
class Something {
void a() {
Object a = new Object().a();
}
}
While parsing of this fails:
class Something {
void a() {
new Object().a();
}
}
*Main> fmap (parser compilationUnit) $ readFile "/home/elk/work/haskell/java-language/fails/Fail01.java"
Left (line 4, column 19):
unexpected Period
Expected result: second example should parse too, as it perfectly correct expression in java.
This code fails to parse:
public class Test {
public void test() {
i = 0;
for (i=1; ; ) {
}
}
}
The exception is:
Left (line 5, column 15):
unexpected Op_Equal
The expression in a condition is not being properly parsed.
For example,
if (bar() != null && foo() > 0)
Is being parsed as:
if ((bar() != null && foo()) > 0)
tests/Tests.hs:10:1:
Warning: The import of `Test.QuickCheck.Test' is redundant
except perhaps to import instances from `Test.QuickCheck.Test'
To import instances alone, use: import Test.QuickCheck.Test()
Linking dist/build/test-java-parse/test-java-parse ...
Running 1 test suites...
Test suite test-java-parse: RUNNING...
parsing unit good:
miscMath2: [Failed]
failure parse error: (line 3, column 19):
unexpected Op_LThan
rawTypes: [OK]
typeVarMembers: [OK]
miscMath3: [Failed]
failure parse error: (line 3, column 14):
unexpected Op_LThan
miscMath4: [Failed]
failure parse error: (line 3, column 19):
unexpected Op_LThan
test: [OK]
abstract: [OK]
miscMath: [Failed]
failure parse error: (line 32, column 14):
unexpected Op_LThan
miscMath5: [OK]
parsing unit bad:
empty: [OK]
syntax: [OK]
parsing.generating==id: [OK, passed 100 tests]
Properties Test Cases Total
Passed 1 7 8
Failed 0 4 4
Total 1 11 12
Test suite test-java-parse: FAIL
Test suite logged to: dist/test/language-java-0.2.4-test-java-parse.log
0 of 1 test suites (0 of 1 test cases) passed.
Failed to install language-java-0.2.4
cabal: Error: some packages failed to install:
language-java-0.2.4 failed during the tests phase. The exception was:
This pattern shows up e.g. in morphia: http://mongodb.github.io/morphia/1.3/guides/indexing/
would it make sense to add a case to https://hackage.haskell.org/package/language-java-0.2.8/docs/Language-Java-Syntax.html#t:ElementValue of EVAnnArray? seems less messy than parametrizing the VarInit type, but I haven't looked much into it - let me know and I can take a swing at fixing this myself.
The pretty printer doesn't take operator fixity into account. For example
prettyPrint $ BinOp (Lit (Int 1)) Sub (BinOp (Lit (Int 2)) Sub (Lit (Int 3)))
outputs "1 - 2 - 3"
, but it should be "1 - (2 - 3)"
.
Deeply, extraneously-nested values in parenthesis alike below experience poor performance when nested more than 10 deep.
public class Test {
public void _nestedParens() {
return ((((((((((((((((4))))))))))))))));
}
}
Above: x is the number of parenthesis sets, and t is the time for parsing in seconds.
Prelude Language.Java.Parser> parser stmt "x[1][2] = 1;"
Left (line 1, column 9):
unexpected Op_Equal
cpphs doesn't seem to be used, but as it is LGPL licensed as a library, this would
make a statically linked language-java LGPL licensed. Can this dependency
be dropped?
At least some documentation on how to parse files, strings etc. would be great.
I'm sure if anybody tried to use it, i. e. to construct AST programmatically, he can prove that it is hard, painful.
Stmt
and BlockStmt
data Ident = Ident String
. I understand it is supposed for "type safety", but generally design of this module allows to construct illegal Java source very easily (it could do better on this, though, but anyway this is not a priority for this module, because we anyway are going to compile Java source and java compiler will tell us we generated something wrong), so this is a highly doubtful goal.The result of the two above points, if I want to generate a trivial statement like int a = 0;
, I should write
import Language.Java.Syntax as J
J.LocalVars [] (J.PrimType J.IntT)
[J.VarDecl (J.VarId $ J.Ident "a") $ Just $ J.InitExp (J.Lit (J.Int 0))]
MethodCall
data type. It's MethodCall
, PrimaryMethodCall
, SuperMethodCall
, ClassMethodCall
and TypeMethodCall
(I especially like the last two ones) should be ImplicitlyTargetedMethodCall
(or NotTargetedMethodCall
), ExpressionTargetedMethodCall
, UnqualifiedSuperMethodCall
, QualifiedSuperMethodCall
, TypeTargetedMethodCall
. You may say the names are too long, but it raises the question if we actually need all five different constructors? See the point 1.data ForInit = ForLocalVars [Modifier] Type [VarDecl]
| ForInitExps [Exp]
I don't understand the defference between these two constructors. There is no documentation. Previously, looking at pretty-printing definition helped me in such cases, but now I see
instance Pretty ForInit where
prettyPrec p (ForLocalVars mods t vds) =
hsep $ map (prettyPrec p) mods ++
prettyPrec p t: punctuate comma (map (prettyPrec p) vds)
prettyPrec p (ForInitExps es) =
hsep $ punctuate comma (map (prettyPrec p) es)
(BTW. Why we have additional intermediate BasicFor (Maybe ForInit) ...
, If I can construct just ForInitExps []
?)
Hello,
I noticed that it doesn't seem to be possible to get the source position information once a file has been parsed into an AST. I think this is extremely useful information for a lot of applications. If you have an idea on how to best implement it, I would be glad to work on it and submit a pull request.
For now I have forked language-java and added a SourcePos field to Name and Ident, and it is "good enough" for me. I'm not sure the column numbers are completely accurate though.
Here is the diff for what I have hacked up so far:
karshan/language-java@vincenthz:master...master
language-java/Language/Java$ ghc -fwarn-incomplete-patterns Pretty.hs
[1 of 1] Compiling Language.Java.Pretty ( Pretty.hs, Pretty.o )
Pretty.hs:129:1: Warning: Tab character
Pretty.hs:138:1: Warning: Tab character
Pretty.hs:286:3: Warning:
Pattern match(es) are non-exhaustive
In an equation for ‘prettyPrec’:
Patterns not matched:
_ (Lambda _ _)
_ (MethodRef _ _)
I am currently writing something using language-java. Would it be possible to do a new bugfix release with the changes from last year? I am using the pretty printer, but the code crashes because if incomplete patterns, which are fixed in this change:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.