Parser Class осуществляет /Синтаксический Разбор X++. При помощи этого класса можно узнать структуру кода, определить где находятся определения методов, операторы присваивания и другие синтакические конструкции
Если вам нужен /Лексический Разбор — используйте Scanner Class
Перед чтением этой статьи рекомендуется изучить
БНФ грамматику X++
Основной сценарий использования следующий:
Поле этого вызываются методы обработки событий в порядке обнаружения этих событий
Методы можно разделить на несколько категорий
Когда вызываются методы разбора (parseXXX) разбирает исходик, который ему передали в конструкторе и вызывает методы обрабтки событий в тот момент когда он обнаруживает ошибку или использование правила грамматики языка. Если метод обнаруживает ошитбку, он возвращает -1 иначе — 0
Существует три метода разбора:
Вы можете перекрывать методы обработки событий чтобы узнавать о событиях
Методы правил вызываются когда парсер обаруживает что код соответствует какому-нибудь правилу грамматики языка. Каждый метод требует несколько объектов в качестве аргуметов и возвращает объект.
Вот, например, как выглядит объявления метода ttsstmt_begin, который вызывается когда разборщик находит ttsbegin; в исходном тексте:
protected Object ttsstmt_begin(Object _ttsbegin_sym, Object _semicolon_sym)
Назначение параметров-объектов полностью определяется тем, кто реализует подкласс.
Каждый параметр соответствует части правила и может быть null или равняется результатом ранее вызванного метода-правила.
Вот, например метод-правило для присваивания:
protected Object asgstmt(Object _lval_fld, Object _assign, Object _if_expr)
это соответствует следующему правилу
Что означеает «присваивание это lval (lval_fld) за которым следует знак присваивания (assign), за которым следует выражение (if_expr)". Если мы посмотрим в БНФ, что такое assign, мы видим следующее:
Что можно перевести как «assign может быть '=', '+=', '-='". Это правило отображается в Parser Class как метод:
protected Object assign(Object _asg_sym)
Но т.к. в Parser Class нет метода для '=', '+=', '-=', он передает null в качетстве значения параметра _asg_sym, а конкретный символ можно извлечь из стека:
Object assign(Object _p1)
{
// get concrete assign symbol, wrap it to object and return it
return new SysAnyType(this.name(0));
}
В качестве примера рассмотрим следующий код
ParserClass parser=new NewParserClass('void test(){a=b;}');
parser.parseFunction();
protected void error(int _errorcode, str _token, int _line, int _col)
метод вызывается когда в исходнике обнаруживается ошибка
Эти методы можно вызывать при обработке методов-событий для того, чтобы получить информацию о состоянии парсера. Каждый такой метод требует одного параметра — номер значения во внутреннем стеке разборщика. Каждый номер соответствует параметру метода-правила. Например, для правила
protected Object asgstmt(Object _lval_fld, Object _assign, Object _if_expr)
Этод метод возвращает идентификатор по номеру значения
Возвращает номер строки, в которой начинается часть правила.
Возвращает номер символа в строке. Для второй и далее строк отнимите 1 от возвращаемого дначения чтобы получить настоящий номер строки (возможно, ошибка)
Позволяет визуализировать структуру кода