JavaRush /Блоги Java /Random-TG /Ифодаҳои муқаррарӣ дар Java, Қисми 5

Ифодаҳои муқаррарӣ дар Java, Қисми 5

Дар гурӯҳ нашр шудааст
Мо ба таваҷҷуҳи шумо тарҷумаи дастури мухтасарро оид ба ибораҳои муқаррарӣ дар Java пешкаш мекунем, ки аз ҷониби Ҷефф Фризен барои вебсайти javaworld навишта шудааст. Барои осонии хондан, мо мақоларо ба чанд қисм тақсим кардем. Ин қисми ниҳоӣ аст. Ифодаҳои муқаррарӣ дар Java, Қисми 5 - 1Ифодаҳои муқаррарӣ дар Java, Қисми 1 Ифодаҳои муқаррарӣ дар Java, Қисми 2 Ифодаҳои муқаррарӣ дар Java, Қисми 3 Ифодаҳои муқаррарӣ дар Java, Қисми 4

Истифодаи ибораҳои муқаррарӣ барои таҳлor лексикӣ

Истифодаи боз ҳам муфидтари ифодаҳои муқаррарӣ китобхонаи codeи такрористеъмолшаванда барои анҷом додани таҳлor лексикӣ, ҷузъи асосии ҳама гуна компилятор ё ассемблер мебошад. Дар ин ҳолат ҷараёни вуруди аломатҳо ба ҷараёни баромади аломатҳо - номҳои пайдарпайии аломатҳое, ки маънои умумӣ доранд, гурӯҳбандӣ карда мешаванд. Масалан, дар ҷараёни вуруд ба пайдарпайии аломатҳои c, o, , u, , n, , , t, , , , e, r, , , , , , , , пешпо хӯрда, таҳлилгари лексикӣ метавонад токен ID(идентификатор) барорад. Пайдарҳамии аломатҳои ба аломат мувофиқро лексема меноманд.
Бештар дар бораи маркерҳо ва лексемаҳо
Токенҳо ба монанди ID метавонанд пайдарпайии бисёр аломатҳоро мувофиқат кунанд. Дар мавриди ин гуна аломатҳо, аломати воқеии мувофиқи токен низ ба компилятор, ассемблер ё утorтаи дигаре лозим аст, ки таҳлor лексикиро талаб мекунад. Барои нишонаҳо, ки як пайдарпаии мушаххаси аломатҳоро намояндагӣ мекунанд, ба монанди аломати PLUSтанҳо ба аломат мувофиқ +, аломати воқеӣ талаб карда намешавад, зеро он метавонад бо нишона [бегона] муайян карда шавад.
Ибораҳои муқаррарӣ нисбат ба таҳлилгарони лексикии давлатӣ, ки бояд дастӣ навишта шаванд ва умуман дубора истифода намешаванд, хеле самараноктаранд. Намунаи таҳлилгари лексикии ба ифодаи муқаррарӣ асосёфта JLex аст , генератори лексикии забони Java мебошад, ки ифодаҳои муқаррариро барои муайян кардани қоидаҳо барои тақсим кардани ҷараёни додаҳои воридотӣ ба аломатҳо истифода мебарад. Мисоли дигар Лексан аст.

Бо Лексан шинос шудан

Lexan китобхонаи Java-и такрорӣ барои таҳлor лексикӣ мебошад. Он ба codeи силсилаи постҳои блоги Навиштани таҳлилгар дар Java дар вебсайти Cogito Learning асос ёфтааст . Китобхона аз синфҳои зерин иборат аст, ки дар бастаи ca.javajeff.lexanрамзи зеркашишавандаи ин мақола дохил карда шудаанд:
  • Lexan: таҳлилгари лексикӣ;
  • LexanException: истисно партофташуда дар созандаи синфLexan;
  • LexException: истисно партофта мешавад, агар синтаксиси нодуруст ҳангоми таҳлor лексикӣ ошкор шавад;
  • Token: ном бо атрибути ифодаи муқаррарӣ;
  • TokLex: ҷуфти нишона / нишона.
Конструктор Lexan(java.lang.Class tokensClass)анализатори нави лексикиро месозад. Он як далелро дар шакли an objectи синфӣ, java.lang.Classки ба навъи синфи доимии мувофиқ аст , талаб мекунад static Token. Бо истифода аз Reflection API, созанда ҳамаи константаҳоро Tokenба массиви арзишҳо мехонад Token[]. Агар Tokenдоимӣ вуҷуд надошта бошад, истисно партофта мешавад LexanException. Ифодаҳои муқаррарӣ дар Java, Қисми 5 - 2Синф Lexanинчунин ду усули зеринро пешниҳод мекунад:
  • Усул рӯйхати ин лексерро бармегардонад;List getTokLexes() Token
  • Метод void lex(String str)Таҳлor лексикии сатри вурудро [бо натиҷаи ҷойгиршуда] дар рӯйхати арзишҳои навъи TokLex. Агар аломате дучор шавад, ки ба ягон намунаи массив мувофиқат накунад Token[], истисно партофта мешавад LexException.
Синф LexanExceptionусул надорад; он усули меросиро барои баргардонидани паёми истисно истифода мебарад getMessage(). Баръакси ин, синф LexExceptionусулҳои зеринро пешниҳод мекунад:
  • Усул int getBadCharIndex()мавқеъи аломатеро бармегардонад, ки ба ягон намунаи нишонгузор мувофиқат намекунад.
  • Усул String getText()матнеро, ки ҳангоми тавлиди истисно таҳлил шуда буд, бармегардонад.
Синф Tokenусули toString()баргардонидани номи маркерро бекор мекунад. Он инчунин усулеро пешниҳод мекунад String getPattern(), ки атрибути ифодаи муқаррарии нишонаро бармегардонад. Синф TokLexусулеро пешниҳод мекунад Token getToken(), ки аломати худро бармегардонад. Он инчунин усулеро пешниҳод мекунад String getLexeme(), ки нишонаи худро бармегардонад.

Намоиш аз китобхонаи Лексан

Барои нишон додани он, ки китобхона чӣ гуна кор мекунад, Lexanман ариза навиштам LexanDemo. Он аз синфҳои LexanDemo, BinTokens, MathTokensва NoTokens. Рамзи сарчашмаи барнома LexanDemoдар Рӯйхати 2 нишон дода шудааст. Рӯйхати 2. Намоиши китобхонаи Lexan дар амал
import ca.javajeff.lexan.Lexan;
import ca.javajeff.lexan.LexanException;
import ca.javajeff.lexan.LexException;
import ca.javajeff.lexan.TokLex;

public final class LexanDemo
{
   public static void main(String[] args)
   {
      lex(MathTokens.class, " sin(x) * (1 + var_12) ");
      lex(BinTokens.class, " 1 0 1 0 1");
      lex(BinTokens.class, "110");
      lex(BinTokens.class, "1 20");
      lex(NoTokens.class, "");
   }

   private static void lex(Class tokensClass, String text)
   {
      try
      {
         Lexan lexan = new Lexan(tokensClass);
         lexan.lex(text);
         for (TokLex tokLex: lexan.getTokLexes())
            System.out.printf("%s: %s%n", tokLex.getToken(),
                              tokLex.getLexeme());
      }
      catch (LexanException le)
      {
         System.err.println(le.getMessage());
      }
      catch (LexException le)
      {
         System.err.println(le.getText());
         for (int i = 0; i < le.getBadCharIndex(); i++)
            System.err.print("-");
         System.err.println("^");
         System.err.println(le.getMessage());
      }
      System.out.println();
   }
}
Усули main()дар Рӯйхати 2 як утorтаро lex()барои нишон додани таҳлor лексикӣ бо истифода аз Lexan даъват мекунад. Ҳар як занг ба ин усул ба синфи нишонаҳо дар an object Classва сатр барои таҳлил дода мешавад. Усули lex()аввал an objectи синфро Lexanтавассути интиқол додани an object Classба созандаи синф эҷод мекунад Lexan. Ва он гоҳ он усули lex()синфро Lexanдар ин сатр даъват мекунад. Агар таҳлor лексикӣ муваффақ бошад, усули синф барои баргардонидани рӯйхати an objectҳо TokLexдаъват карда мешавад . Барои ҳар яке аз ин an objectҳо усули синфии он барои баргардонидани нишона ва усули синфи он барои баргардонидани нишон даъват карда мешавад. Ҳарду арзишҳо ба баромади стандартӣ чоп карда мешаванд. Агар таҳлor лексикӣ ноком шавад, яке аз истисноҳо ё партофта мешавад ва мувофиқи он кор карда мешавад . Барои мухтасар, биёед танҳо синферо, ки ин барномаро ташкил медиҳад, баррасӣ кунем . Рӯйхати 3 рамзи сарчашмаи онро нишон медиҳад. Листинг 3. Тавсифи маҷмӯи аломатҳо барои забони хурди математикӣgetTokLexes()LexangetToken()TokLexgetLexeme()LexanExceptionLexExceptionMathTokens
import ca.javajeff.lexan.Token;

public final class MathTokens
{
   public final static Token FUNC = new Token("FUNC", "sin|cos|exp|ln|sqrt");
   public final static Token LPAREN = new Token("LPAREN", "\\(");
   public final static Token RPAREN = new Token("RPAREN", "\\)");
   public final static Token PLUSMIN = new Token("PLUSMIN", "[+-]");
   public final static Token TIMESDIV = new Token("TIMESDIV", "[*/]");
   public final static Token CARET = new Token("CARET", "\\^");
   public final static Token INTEGER = new Token("INTEGER", "[0-9]+");
   public final static Token ID = new Token("ID", "[a-zA-Z][a-zA-Z0-9_]*");
}
Рӯйхати 3 нишон медиҳад, ки синф MathTokensпайдарпайии доимии навъи Token. Ба ҳар яки онҳо арзиши an object дода мешавад Token. Созандаи ин an object сатрро мегирад, ки номи маркер аст ва дар якҷоягӣ бо ифодаи муқаррарӣ, ки ҳамаи сатрҳои аломатҳои марбут ба ин маркерро тавсиф мекунад. Барои возењ шудан, матлуб аст, ки номи сатри маркер бо номи доимї якхела бошад, аммо ин шарт нест. Ифодаҳои муқаррарӣ дар Java, Қисми 5 - 3Мавқеи доимӣ Tokenдар рӯйхати маркерҳо муҳим аст. Собитҳое, ки дар рӯйхат болотар ҷойгир шудаанд, Tokenнисбат ба онҳое, ки дар поён ҷойгиранд, бартарӣ доранд. Масалан, ҳангоми дучор шудан , Лексан ба ҷои , sinаломатро интихоб мекунад . Агар маркер пеш аз маркер мебуд , он интихоб мешуд. FUNCIDIDFUNC

Тартиб додан ва иҷро кардани барномаи LexanDemo

Рамзи зеркашишавандаи ин мақола бойгониеро дар бар мегирад lexan.zip, ки дорои ҳамаи файлҳои тақсимоти Lexan мебошад. Ин бойгониро кушоед ва ба зеркаталоги demosдиректорияи реша равед lexan. Агар шумо Windows-ро истифода баред, фармони зеринро иҷро кунед, то файлҳои рамзи ибтидоии барномаро тартиб диҳед:
javac -cp ..\library\lexan.jar *.java
Агар компиляция бомуваффақият бошад, фармони зеринро иҷро кунед, то барномаи намоиширо иҷро кунед:
java -cp ..\library\lexan.jar;. LexanDemo
Шумо бояд натиҷаҳои зеринро бинед:
FUNC: sin
LPAREN: (
ID: x
RPAREN: )
TIMESDIV: *
LPAREN: (
INTEGER: 1
PLUSMIN: +
ID: var_12
RPAREN: )
ONE: 1
ZERO: 0
ONE: 1
ZERO: 0
ONE: 1
ONE: 1
ONE: 1
ZERO: 0
1 20
--^
Неожиданный символ во входном тексте: 20
Паём Неожиданный символ во входном тексте: 20дар натиҷаи партофта шудани истисно LexanExceptionаз сабаби он, ки синф як доимиро бо арзиш ҳамчун ифодаи муқаррарӣ BinTokensэълон намекунад . Дар хотир доред, ки коркардкунандаи истисно мавқеи аломати номуносибро, ки аз таҳлor лексикии матн гирифта шудааст, мебарорад. Паёми гумшудаи нишонаҳо натиҷаи партофта шудани истисно аст, зеро дар синф ягон доимӣ эълон нашудааст . Token2LexExceptionNoTokensToken

Дар паси парда

Lexanсинфи Lexan-ро ҳамчун муҳаррики худ истифода мебарад. Татбиқи ин синфро дар Рӯйхати 4 дида бароед ва саҳми ибораҳои муқаррариро дар истифодаи дубораи муҳаррик қайд кунед. Листинг 4. Сохтани меъмории анализатори лексики дар асоси иборахои мукаррари
package ca.javajeff.lexan;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;

/**
 *  Лексический анализатор. Этот класс можно использовать для
 *  преобразования входного потока символов в выходной поток маркеров.
 *
 *  @Author Джефф Фризен
 */

public final class Lexan
{
   private List tokLexes;

   private Token[] values;

   /**
    *  Инициализируем лексический анализатор набором an objectов Token.
    *
    *  @параметры tokensClass – an object Class класса, содержащего
    *       набор an objectов Token
    *
    *  @генерирует исключение LexanException в случае невозможности
    *       формирования an object Lexan, возможно, из-за отсутствия an objectов
    *       Token в классе
    */

   public Lexan(Class tokensClass) throws LexanException
   {
      try
      {
         tokLexes = new ArrayList<>();
         List _values = new ArrayList<>();
         Field[] fields = tokensClass.getDeclaredFields();
         for (Field field: fields)
            if (field.getType().getName().equals("ca.javajeff.lexan.Token"))
               _values.add((Token) field.get(null));
         values = _values.toArray(new Token[0]);
         if (values.length == 0)
            throw new LexanException("маркеры отсутствуют");
      }
      catch (IllegalAccessException iae)
      {
         throw new LexanException(iae.getMessage());
      }

   /**
    * Получаем список TokLex'ов этого лексического анализатора.
    *
    *  @возвращает список TokLex'ов
    */

   public List getTokLexes()
   {
      return tokLexes;
   }

   /** * Выполняет лексический анализ входной строки [с помещением * результата] в список TokLex'ов. * * @параметры str – строка, подвергаемая лексическому анализу * * @генерирует исключение LexException: во входных данных обнаружен * неожиданный символ */

   public void lex(String str) throws LexException
   {
      String s = new String(str).trim(); // удалить ведущие пробелы
      int index = (str.length() - s.length());
      tokLexes.clear();
      while (!s.equals(""))
      {
         boolean match = false;
         for (int i = 0; i < values.length; i++)
         {
            Token token = values[i];
            Matcher m = token.getPattern().matcher(s);
            if (m.find())
            {
               match = true;
               tokLexes.add(new TokLex(token, m.group().trim()));
               String t = s;
               s = m.replaceFirst("").trim(); // удалить ведущие пробелы
               index += (t.length() - s.length());
               break;
            }
         }
         if (!match)
            throw new LexException("Неожиданный символ во входном тексте: "
                                    + s, str, index);
      }
   }
}
Рамзи усул lex()ба codeе асос ёфтааст, ки дар пости блоги "Навиштани таҳлилгар дар Java: Генератори аломат" дар вебсайти Cogito Learning оварда шудааст. Барои гирифтани маълумоти бештар дар бораи он, ки Lexan Regex API-ро барои тартиб додани code истифода мебарад, ин мақоларо хонед. Ифодаҳои муқаррарӣ дар Java, Қисми 5 - 4

Хулоса

Ифодаҳои муқаррарӣ як воситаи муфид мебошанд, ки метавонанд барои ҳар як таҳиякунанда муфид бошанд. API-и Regex аз забони барномасозии Java истифодаи онҳоро дар барномаҳо ва китобхонаҳо осон мекунад. Акнун, ки шумо аллакай фаҳмиши асосии ифодаҳои муқаррарӣ ва ин API-ро доред, ба ҳуҷҷатҳои SDK нигаред, java.util.regexто дар бораи ифодаҳои муқаррарӣ ва усулҳои иловагии Regex API маълумоти бештар гиред.
Шарҳҳо
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION