LoginSignup
3
3

More than 5 years have passed since last update.

ParboiledをGroovyから使おうとしてできなかった話。

Last updated at Posted at 2013-01-12

JavaにPegDownというmarkdown変換用ライブラリがあって、Parboiledはそれで使っているパーサジェネレータ。
同じ人が開発している。

parboiled
https://github.com/sirthias/parboiled/wiki

ドキュメントがしっかりあり、構文も短くて良いと思ったので、Simple Java Example のページを見ながらgroovyで書いて試そうとした。
Groovy Version: 2.0.6 JVM: 1.6.0_37 Vendor: Apple Inc. OS: Mac OS X

import org.parboiled.BaseParser
import org.parboiled.Rule
import org.parboiled.annotations.BuildParseTree
import org.parboiled.Parboiled
import org.parboiled.support.ParsingResult
import org.parboiled.parserunners.ReportingParseRunner
import org.parboiled.support.ParseTreeUtils
@Grab('org.parboiled:parboiled-java:latest.release')

@BuildParseTree 
class CalculatorParser extends BaseParser {
    Rule Expression() {
        Sequence( Term(), ZeroOrMore(AnyOf("+-"), Term()) )
    }
    Rule Term() {
        Sequence( Factor(), ZeroOrMore(AnyOf("*/"), Factor() ) )
    }
    Rule Factor() {
        FirstOf( Number(), Sequence('(', Expression(), ')' ) )
    }
    Rule Number() {
        OneOrMore(CharRange('0', '9'))
    }
}

String input = "1+2"
CalculatorParser parser = Parboiled.createParser(CalculatorParser.class)
ParsingResult result = ReportingParseRunner.run(parser.Expression(), input)
String parseTreePrintOut = ParseTreeUtils.printNodeTree(result)
println parseTreePrintOut

が、なんかエラーが出て動かない。

Caught: java.lang.RuntimeException: Error creating extended parser class: Class not found
java.lang.RuntimeException: Error creating extended parser class: Class not found
    at org.parboiled.Parboiled.createParser(Parboiled.java:58)
    at test.run(test.groovy:27)
Caused by: java.io.IOException: Class not found
    at org.objectweb.asm.ClassReader.a(Unknown Source)
    at org.objectweb.asm.ClassReader.<init>(Unknown Source)
    at org.parboiled.transform.AsmUtils.createClassReader(AsmUtils.java:56)
    at org.parboiled.transform.ClassNodeInitializer.process(ClassNodeInitializer.java:62)
    at org.parboiled.transform.ParserTransformer.extendParserClass(ParserTransformer.java:44)
    at org.parboiled.transform.ParserTransformer.transformParser(ParserTransformer.java:38)
    at org.parboiled.Parboiled.createParser(Parboiled.java:54)
    ... 1 more

納得いかなかったので、Parboiledのソースを落として調べた。
org.parboiled.transform.AsmUtils の、line 51

...
    public static ClassReader createClassReader(Class<?> clazz) throws IOException {
        checkArgNotNull(clazz, "clazz");
        String classFilename = clazz.getName().replace('.', '/') + ".class"; //<- line51 ここ!
        InputStream inputStream = clazz.getClassLoader().getResourceAsStream(classFilename);
        if (inputStream == null) {
            inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(classFilename);
        }
        return new ClassReader(inputStream);
    }
...

ここで、クラス名から.classファイルを探し出し、ASMでバイトコードを読み出してるみたい。
.groovyファイルひとつで試してるから、当然 .classファイルはできていない。
だから使えなかったのか。そうかー。

groovyで気軽に使えるパーサライブラリが欲しいなぁ。

3
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3