1

Я использую генератор парсера под названием CUP. Мне предоставили грамматику (спецификацию CUP) и этот фрагмент кода поддержки (Expr.java) для определений классов.Как происходит вызов функций val() и rep() в этом коде (для них нет определения)?

В спецификации CUP, грамматические постановки имеют смысловое действие, связанное с ними, как это:

expr ::= expr:e1 PLUS expr:e2 
{: RESULT = new OpExpr(e1,e2,sym.PLUS); :}; 

Определение класса является чем-то вроде этого:

package java_cup.output; 
abstract class Expr { 

    protected static String symbols[] = new String[12]; 

    . 
    . 
    . 

    public abstract Integer val(); 

    public abstract String rep(); 

} 

Там есть класс выражений Integer

class IntExpr extends Expr{ 

    Integer intExpr; 

    public IntExpr(Integer e) { intExpr = e; } 

    public Integer val() { return intExpr; } 

    public String rep() { return "Integer{"+intExpr.toString()+"}"; } 

} 

И тогда есть классы вроде:

class ParaExpr extends Expr { 

    Expr paraExpr; 

    public ParaExpr(Expr e) { paraExpr = e; } 

    public Integer val() { return paraExpr.val(); } 

    public String rep() { return "ParaExpr{("+paraExpr.rep()+")}"; } 

} 

По сути, мой вопрос заключается в следующем: Там нет определения даны для функции респ() класса Expr (потому что он является абстрактным). Тогда что делает эта функция? paraExpr.rep()

Когда я создаю проект, построить синтаксический анализатор и и разобрать строку ввода, он создает AST и печатает его, как это:

ParaExpr {(IntExpr {(1)} + IntExpr {(2)})}

ответ

0

Ничего, это абстрактный метод, поэтому его реализация не имеет. но вы уже это знали.

Вы не будете иметь экземпляр Expr, когда вы звоните paraExpr.rep(), paraExp будет подкласс Expr, один, который делает реализовать rep() .e.g. IntExpr

+0

Итак, вы говорите, что paraExpr (который расширяет Expr, который является абстрактным) ищет определение функции там, но не находит каких-либо, смотрит на классы-братья для определения функции? –

+1

Почти. IntExpr является подклассом Expr. paraExpr - это переменная, которая указывает на объект, который является _at наименьшим значением Expr, но может быть подклассом. Когда вы вызываете метод объекта, он начинается с подкласса (в этом случае IntExpr) и работает до иерархии классов до тех пор, пока не найдет реализацию. Здесь, поскольку IntExpr реализовал rep(), ему больше не нужно искать нигде. – deanWombourne