Groovy оценка строк в DSL

Я пытаюсь написать BASIC-подобный DSL с использованием Groovy, и я нахожусь на очень ранней стадии. У меня есть короткий скрипт (не обращайте внимания на пакет, я со временем его уберу):

package Binsic
PRINT "Hello World"

и этот класс:

package Binsic

abstract class BinsicInterpreter extends Script {

static def textArea

static def setTextArea(def window)
{
    textArea = window
}

def PRINT(def param) {
    textArea.append param
}

}

называется таким образом:

def engine = new BinsicEngine()
BinsicInterpreter.setTextArea(engine.binsicWindow.screenZX)
def conf = new CompilerConfiguration()
conf.setScriptBaseClass("BinsicInterpreter")
def shell = new GroovyShell(conf)
shell.evaluate(new File("./src/Binsic/test.bas"))

(BinsicEngine просто устанавливает TextArea в данный момент)

Этот код не работает...

org.codehaus.groovy.control.MultipleCompilationErrorsException: ошибка запуска: /Users/adrian/Documents/workspace-sts-2.9.1.RELEASE/BINSIC/src/Binsic/test.bas: 3: неожиданный токен: Hello World @ строка 3 , столбец 7. ПЕЧАТЬ «Hello World» ^

1 ошибка

Но если я изменю оператор на PRINT ("Hello World"), он сработает...

Точно так же я могу заставить PRINT this работать (т.е. он печатает ссылку на память для этого), если я настрою код PRINT для обработки не строк. Но никаких скобок не требуется.

Почему версия без скобок не работает? И как я могу это исправить?


person adrianmcmenamin    schedule 03.06.2012    source источник
comment
Между прочим, сейчас (и, возможно, навсегда) я собираюсь обойти это, написав класс препроцессора, который будет преобразовывать входной сценарий во что-то, что Groovy может удобно обрабатывать. См. github.com/mcmenaminadrian/BINSIC.   -  person adrianmcmenamin    schedule 04.06.2012


Ответы (2)


Проблема заключается в прописной PRINT или любой прописной первой букве (например, Print).

В Groovy опускание скобок — это синтаксический сахар, обеспечивающий лучшую поддержку DSL. У компилятора будет набор правил, когда это разрешено, а когда нет.

В моих тестах

def Print(String arg) {
    println arg
}
def a = Print "Hello World"

работает, пока

def Print(String arg) {
    println arg
}
Print "Hello World"

терпит неудачу, как вы обнаружили. Я предлагаю поднять это как проблему на http://groovy.codehaus.org/.

person Paul Marrington    schedule 04.06.2012
comment
Спасибо, я внесу это в список пользователей Groovy как потенциальную ошибку/особенность языка. - person adrianmcmenamin; 04.06.2012

Кажется, это как-то связано с тем, что метод PRINT используется в верхнем регистре. Измените его с «PRINT» на «foo», и все заработает. Измените его на «FOO», и это не сработает.

person GreyBeardedGeek    schedule 04.06.2012