Инструменты пользователя

Инструменты сайта


axapta:класс:parserclass



Описание

ParserClass осуществляет СинтаксическийРазбор XPlusPlus. При помощи этого класса можно узнать структуру кода, определить где находятся определения методов, операторы присваивания и другие синтакические конструкции

Если вам нужен ЛексическийРазбор – используйте ScannerClass

Перед чтением этой статьи рекомендуется изучить http://msdn.microsoft.com/library/en-us/Axapta/Appendix_about_EBNF/LANG_X++grammar.asp ~X++

toc

Возможные сферы применения

  • job для автоматизации вставки вызовов протоколирования работы программы

Использование

Основной сценарий использования следующий:

  • создайте подкласс ParserClass
  • перекройте методы обработки событий
  • создайте экземпляр вашего подкласса, передав исходник для разбора в качестве параметра конструктора
  • вызовите один из методов parseXXX

Поле этого вызываются методы обработки событий в порядке обнаружения этих событий

Методы

Методы можно разделить на несколько категорий

Методы разбора

Когда вызываются методы разбора (parseXXX) разбирает исходик, который ему передали в конструкторе и вызывает методы обрабтки событий в тот момент когда он обнаруживает ошибку или использование правила грамматики языка. Если метод обнаруживает ошитбку, он возвращает -1 иначе – 0

Существует три метода разбора:

  • parseClass – разбор class declaration
  • parseExpr - разбор выражения ~X++
  • parseFunction - разбирает метод (но не конструктор 'new' – эту пролему пока неизвестно как решать)

Методы обработки событий

Вы можете перекрывать методы обработки событий чтобы узнавать о событиях

Методы правил

Методы правил вызываются когда парсер обаруживает что код соответствует какому-нибудь правилу грамматики языка. Каждый метод требует несколько объектов в качестве аргуметов и возвращает объект.

Вот, например, как выглядит объявления метода 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)

это соответствует следующему правилу

   asg_stmt ::= lval_fld assign if_expr

Что означеает «присваивание это lval (lval_fld) за которым следует знак присваивания (assign), за которым следует выражение (if_expr)». Если мы посмотрим в БНФ, что такое «assign», мы видим следующее:

  ASSIGN ::= =
  ASSIGN ::= +=
  ASSIGN ::= -=

Что можно перевести как «assign может быть '=', '+=', '-='». Это правило отображается в ParserClass как метод:

  protected Object assign(Object _asg_sym)

Но т.к. в ParserClass нет метода для '=', '+=', '-=', он передает 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();

при разборе исходного текста, разборщик находит символ '=' после чего, он вызывает метод 'assign', идет дальше, обнаруживает конек конструкции присваивания и вызывает метод asgstmt передавая в качестве параметра _assign значение ранее вызванного метода 'assign'.

метод Error

  protected void error(int _errorcode, str _token, int _line, int _col)

метод вызывается когда в исходнике обнаруживается ошибка

Моетоды для получения состояния

Эти методы можно вызывать при обработке методов-событий для того, чтобы получить информацию о состоянии парсера. Каждый такой метод требует одного параметра – номер значения во внутреннем стеке разборщика. Каждый номер соответствует параметру метода-правила. Например, для правила

protected Object asgstmt(Object _lval_fld, Object _assign, Object _if_expr)

последнему параметру будет соответствовать номер 0, первому – -3, второму – -2

name

Этод метод возвращает идентификатор по номеру значения

startLine

Возвращает номер строки, в которой начинается часть правила.

startingCol

Возвращает номер символа в строке. Для второй и далее строк отнимите 1 от возвращаемого дначения чтобы получить настоящий номер строки (возможно, ошибка)

Примеры

  • GenerateParmMethodsExtension – расширение IDE которое извлекает из класса структуру его полей и позволяет генерировать методы parm для этого класса

[[KOAN | ]]

скачать [[http://www.axaptapedia.com/images/6/6c/Koan.zip]] 

KoanShot

Позволяет визуализировать структуру кода

axapta/класс/parserclass.txt · Последнее изменение: 2018/04/13 22:43 (внешнее изменение)