2013-07-12 1 views
0

Я работал с JavaCC, чтобы собрать грамматику парсера для своего рода программы «сценарий изображения», которую я написал на Java. Программа принимает ряд скриптовых команд, которые в значительной степени отображаются прямо на java.awt.Graphics метод вызова, обрабатывает их напрямую и выводит изображение в файл. Я использую JavaCC для создания парсера для этого, потому что я хочу начать добавлять более сложные конструкции (например, цикл или функции).
Прямо сейчас, я использую JJTree для создания ввода как AST. В любом случае, я получаю предупреждение от JavaCC (JJTree в порядке с файлом .jjt):
Предупреждение: конфликт выбора в (...) * построить по строке 320, столбец 9. Расширение вложенное в конструкцию и расширение после у конструкции есть общие префиксы, один из которых «+»
Рассмотрите возможность использования 2-го или более для вложенного расширения.

Поскольку грамматика источника в «PicParse.jjt», я думаю, что это мешающая конструкция из этого файла:JavaCC: конфликт выбора в расширении звезды

(
    MulTerm() 
    (//line 320 in the file, column 9 starts at open parens 
     "+" 
     MulTerm() 
     {jjtThis.setName("+");} 
    | 
     "-" 
     MulTerm() 
     {jjtThis.setName("-");} 
    )* 
)#Plus(>1) 

Наконец, в то время как я наткнулся this, заменив оператор звезды ('* ') с оператором вопросительной метки ('? ') ничего не сделал, чтобы удалить предупреждение.
В конечном счете, я хочу, чтобы иметь возможность использовать это производственное правило (правило MulTerm() идентично этому правилу («AddTerm()»)), так что он сохраняет оператор, который согласован в любом выборе, который позволит мне различать добавление и вычитание, причем только один тип узла для представления каждого.

ответ

1

Исправлено! Проблема была не в моем слагаемом в конце концов, но в моей одноместный правилу:

(
    <OPAR> Expr() <CPAR> 
| 
    ((t=<PLUS> 
    | t=<MINUS>) Expr()) #Unary 
| 
    Integer() 
| 
    Float() 
| 
    Double() 
) 
{ if(t != null) jjtThis.setName(t.image); } 

рекурсия, вызванная вторым выбором (Expr() -> AddTerm() -> MulTerm() -> Одинарный() -> Expr()) был за предупреждением. Я решил эту проблему путем перемещения второго выбора в отдельное правило производства, которое только рекурсивно обратно унарный:

void PrimaryExpr() #PrimaryExpr(>1) : 
{ Token t=null; } 
{ 
    t=<PLUS> 
    Unary() 
    {if(t != null) jjtThis.setName(t.image);} 
| 
    t=<MINUS> 
    Unary() 
    {if(t != null) jjtThis.setName(t.image);} 
} 
+0

Только незначительное предложение: Включите имена на Унарное и PrimaryExpr. Также обратите внимание, что с вашей фиксированной грамматикой -a/b будет анализироваться как (-a)/b, а не - (a/b). Это довольно распространено в языках программирования, но не всегда, что ожидают пользователи. –