தமிழ்

கம்பைலர் வடிவமைப்பின் முதல் கட்டமான லெக்சிகல் பகுப்பாய்வு பற்றிய ஆழமான ஆய்வு. டோக்கன்கள், லெக்சீம்கள், ரெகுலர் எக்ஸ்பிரஷன்கள், ஃபைனைட் ஆட்டோமேட்டா மற்றும் அவற்றின் நடைமுறைப் பயன்பாடுகளைப் பற்றி அறிந்து கொள்ளுங்கள்.

கம்பைலர் வடிவமைப்பு: லெக்சிகல் பகுப்பாய்வு அடிப்படைகள்

கம்பைலர் வடிவமைப்பு என்பது கணினி அறிவியலின் ஒரு வசீகரமான மற்றும் முக்கியமான துறையாகும், இது நவீன மென்பொருள் மேம்பாட்டின் பெரும்பகுதியை ஆதரிக்கிறது. கம்பைலர் என்பது மனிதர்களால் படிக்கக்கூடிய மூலக் குறியீட்டிற்கும் இயந்திரத்தால் இயக்கக்கூடிய வழிமுறைகளுக்கும் இடையேயான ஒரு பாலம். இந்தக் கட்டுரை, தொகுத்தல் செயல்பாட்டின் ஆரம்ப கட்டமான லெக்சிகல் பகுப்பாய்வின் அடிப்படைகளை ஆராயும். அதன் நோக்கம், முக்கிய கருத்துக்கள் மற்றும் உலகெங்கிலும் உள்ள ஆர்வமுள்ள கம்பைலர் வடிவமைப்பாளர்கள் மற்றும் மென்பொருள் பொறியாளர்களுக்கான நடைமுறை தாக்கங்களை நாங்கள் ஆராய்வோம்.

லெக்சிகல் பகுப்பாய்வு என்றால் என்ன?

லெக்சிகல் பகுப்பாய்வு, ஸ்கேனிங் அல்லது டோக்கனைசிங் என்றும் அழைக்கப்படுகிறது, இது ஒரு கம்பைலரின் முதல் கட்டமாகும். அதன் முதன்மை செயல்பாடு மூலக் குறியீட்டை எழுத்துக்களின் ஒரு தொடராகப் படித்து, அவற்றை லெக்சீம்கள் எனப்படும் அர்த்தமுள்ள வரிசைகளாக தொகுப்பதாகும். ஒவ்வொரு லெக்சீமும் அதன் பங்கின் அடிப்படையில் வகைப்படுத்தப்பட்டு, டோக்கன்களின் ஒரு வரிசையை உருவாக்குகிறது. இதை மேலும் செயலாக்கத்திற்காக உள்ளீட்டைத் தயாரிக்கும் ஆரம்ப வரிசைப்படுத்தல் மற்றும் லேபிளிங் செயல்முறையாகக் கருதுங்கள்.

உங்களிடம் ஒரு வாக்கியம் இருப்பதாக கற்பனை செய்து பாருங்கள்: `x = y + 5;` லெக்சிகல் அனலைசர் அதை பின்வரும் டோக்கன்களாகப் பிரிக்கும்:

லெக்சிகல் அனலைசர் நிரலாக்க மொழியின் இந்த அடிப்படைக் கட்டுமானத் தொகுதிகளை அடிப்படையில் அடையாளம் காண்கிறது.

லெக்சிகல் பகுப்பாய்வில் உள்ள முக்கிய கருத்துக்கள்

டோக்கன்கள் மற்றும் லெக்சீம்கள்

மேலே குறிப்பிட்டபடி, ஒரு டோக்கன் என்பது ஒரு லெக்சீமின் வகைப்படுத்தப்பட்ட பிரதிநிதித்துவமாகும். ஒரு லெக்சீம் என்பது மூலக் குறியீட்டில் உள்ள எழுத்துக்களின் உண்மையான வரிசையாகும், இது ஒரு டோக்கனுக்கான ஒரு வடிவத்துடன் பொருந்துகிறது. பைத்தானில் பின்வரும் குறியீட்டுத் துண்டைக் கவனியுங்கள்:

if x > 5:
    print("x is greater than 5")

இந்தத் துண்டிலிருந்து டோக்கன்கள் மற்றும் லெக்சீம்களின் சில எடுத்துக்காட்டுகள் இங்கே:

டோக்கன் லெக்சீமின் *வகையைக்* குறிக்கிறது, அதே நேரத்தில் லெக்சீம் மூலக் குறியீட்டிலிருந்து *உண்மையான சரமாகும்*. தொகுப்பின் அடுத்த கட்டமான பார்சர், நிரலின் கட்டமைப்பைப் புரிந்துகொள்ள டோக்கன்களைப் பயன்படுத்துகிறது.

ரெகுலர் எக்ஸ்பிரஷன்கள்

ரெகுலர் எக்ஸ்பிரஷன்கள் (regex) என்பது எழுத்துக்களின் வடிவங்களை விவரிப்பதற்கான ஒரு சக்திவாய்ந்த மற்றும் சுருக்கமான குறியீடாகும். லெக்சீம்கள் குறிப்பிட்ட டோக்கன்களாக அங்கீகரிக்கப்பட வேண்டிய வடிவங்களை வரையறுக்க அவை லெக்சிகல் பகுப்பாய்வில் பரவலாகப் பயன்படுத்தப்படுகின்றன. ரெகுலர் எக்ஸ்பிரஷன்கள் கம்பைலர் வடிவமைப்பில் மட்டுமல்ல, உரை செயலாக்கம் முதல் நெட்வொர்க் பாதுகாப்பு வரை கணினி அறிவியலின் பல பகுதிகளில் ஒரு அடிப்படைக் கருத்தாகும்.

சில பொதுவான ரெகுலர் எக்ஸ்பிரஷன் சின்னங்களும் அவற்றின் அர்த்தங்களும் இங்கே:

ரெகுலர் எக்ஸ்பிரஷன்கள் டோக்கன்களை வரையறுக்க எவ்வாறு பயன்படுத்தப்படலாம் என்பதற்கான சில எடுத்துக்காட்டுகளைப் பார்ப்போம்:

வெவ்வேறு நிரலாக்க மொழிகள் ஐடென்டிஃபையர்கள், முழு எண் லிட்டரல்கள் மற்றும் பிற டோக்கன்களுக்கு வெவ்வேறு விதிகளைக் கொண்டிருக்கலாம். எனவே, அதற்கேற்ப தொடர்புடைய ரெகுலர் எக்ஸ்பிரஷன்களை சரிசெய்ய வேண்டும். எடுத்துக்காட்டாக, சில மொழிகள் ஐடென்டிஃபையர்களில் யூனிகோட் எழுத்துக்களை அனுமதிக்கலாம், இதற்கு மிகவும் சிக்கலான ரெகுலர் எக்ஸ்பிரஷன் தேவைப்படுகிறது.

ஃபைனைட் ஆட்டோமேட்டா

ஃபைனைட் ஆட்டோமேட்டா (FA) என்பது ரெகுலர் எக்ஸ்பிரஷன்களால் வரையறுக்கப்பட்ட வடிவங்களை அங்கீகரிக்கப் பயன்படுத்தப்படும் சுருக்க இயந்திரங்கள் ஆகும். அவை லெக்சிகல் அனலைசர்களின் செயலாக்கத்தில் ஒரு முக்கிய கருத்தாகும். இரண்டு முக்கிய வகையான ஃபைனைட் ஆட்டோமேட்டா உள்ளன:

லெக்சிகல் பகுப்பாய்வில் வழக்கமான செயல்முறை பின்வருவனவற்றை உள்ளடக்கியது:

  1. ஒவ்வொரு டோக்கன் வகைக்கான ரெகுலர் எக்ஸ்பிரஷன்களை ஒரு NFA ஆக மாற்றுதல்.
  2. NFA ஐ ஒரு DFA ஆக மாற்றுதல்.
  3. DFA ஐ ஒரு அட்டவணை-இயக்கப்படும் ஸ்கேனராக செயல்படுத்துதல்.

பின்னர் DFA உள்ளீட்டுத் தொடரை ஸ்கேன் செய்து டோக்கன்களை அடையாளம் காணப் பயன்படுத்தப்படுகிறது. DFA ஒரு ஆரம்ப நிலையில் தொடங்கி, உள்ளீட்டை எழுத்து வாரியாகப் படிக்கிறது. தற்போதைய நிலை மற்றும் உள்ளீட்டு எழுத்தின் அடிப்படையில், அது ஒரு புதிய நிலைக்கு மாறுகிறது. எழுத்துக்களின் வரிசையைப் படித்த பிறகு DFA ஒரு ஏற்றுக்கொள்ளும் நிலையை அடைந்தால், அந்த வரிசை ஒரு லெக்சீமாக அங்கீகரிக்கப்பட்டு, அதனுடன் தொடர்புடைய டோக்கன் உருவாக்கப்படுகிறது.

லெக்சிகல் பகுப்பாய்வு எவ்வாறு செயல்படுகிறது

லெக்சிகல் அனலைசர் பின்வருமாறு செயல்படுகிறது:

  1. மூலக் குறியீட்டைப் படிக்கிறது: லெக்சர் உள்ளீட்டுக் கோப்பு அல்லது தொடரிலிருந்து மூலக் குறியீட்டை எழுத்து வாரியாகப் படிக்கிறது.
  2. லெக்சீம்களை அடையாளம் காண்கிறது: லெக்சர் ரெகுலர் எக்ஸ்பிரஷன்களை (அல்லது, இன்னும் துல்லியமாக, ரெகுலர் எக்ஸ்பிரஷன்களிலிருந்து பெறப்பட்ட ஒரு DFA) பயன்படுத்தி செல்லுபடியாகும் லெக்சீம்களை உருவாக்கும் எழுத்துக்களின் வரிசைகளை அடையாளம் காண்கிறது.
  3. டோக்கன்களை உருவாக்குகிறது: காணப்படும் ஒவ்வொரு லெக்சீமிற்கும், லெக்சர் ஒரு டோக்கனை உருவாக்குகிறது, இதில் லெக்சீம் மற்றும் அதன் டோக்கன் வகை (எ.கா., IDENTIFIER, INTEGER_LITERAL, OPERATOR) ஆகியவை அடங்கும்.
  4. பிழைகளைக் கையாளுகிறது: வரையறுக்கப்பட்ட எந்த வடிவத்துடனும் பொருந்தாத எழுத்துக்களின் வரிசையை லெக்சர் சந்தித்தால் (அதாவது, அதை டோக்கனைஸ் செய்ய முடியாது), அது ஒரு லெக்சிகல் பிழையைப் புகாரளிக்கிறது. இது ஒரு செல்லாத எழுத்து அல்லது தவறாக உருவாக்கப்பட்ட ஐடென்டிஃபையரை உள்ளடக்கியிருக்கலாம்.
  5. டோக்கன்களை பார்சருக்கு அனுப்புகிறது: லெக்சர் டோக்கன்களின் தொடரை கம்பைலரின் அடுத்த கட்டமான பார்சருக்கு அனுப்புகிறது.

இந்த எளிய C குறியீட்டுத் துண்டைக் கவனியுங்கள்:

int main() {
  int x = 10;
  return 0;
}

லெக்சிகல் அனலைசர் இந்த குறியீட்டைச் செயல்படுத்தி பின்வரும் டோக்கன்களை உருவாக்கும் (எளிமைப்படுத்தப்பட்டது):

ஒரு லெக்சிகல் அனலைசரின் நடைமுறைச் செயலாக்கம்

ஒரு லெக்சிகல் அனலைசரைச் செயல்படுத்த இரண்டு முதன்மை அணுகுமுறைகள் உள்ளன:

  1. கைமுறை செயலாக்கம்: லெக்சர் குறியீட்டை கையால் எழுதுதல். இது அதிக கட்டுப்பாடு மற்றும் மேம்படுத்தல் சாத்தியங்களை வழங்குகிறது, ஆனால் அதிக நேரம் எடுக்கும் மற்றும் பிழை ஏற்பட வாய்ப்புள்ளது.
  2. லெக்சர் ஜெனரேட்டர்களைப் பயன்படுத்துதல்: Lex (Flex), ANTLR, அல்லது JFlex போன்ற கருவிகளைப் பயன்படுத்துதல், அவை ரெகுலர் எக்ஸ்பிரஷன் விவரக்குறிப்புகளின் அடிப்படையில் லெக்சர் குறியீட்டை தானாக உருவாக்குகின்றன.

கைமுறை செயலாக்கம்

ஒரு கைமுறை செயலாக்கம் பொதுவாக ஒரு நிலை இயந்திரத்தை (DFA) உருவாக்குவதையும், உள்ளீட்டு எழுத்துக்களின் அடிப்படையில் நிலைகளுக்கு இடையில் மாறுவதற்கான குறியீட்டை எழுதுவதையும் உள்ளடக்கியது. இந்த அணுகுமுறை லெக்சிகல் பகுப்பாய்வு செயல்முறையின் மீது நுணுக்கமான கட்டுப்பாட்டை அனுமதிக்கிறது மற்றும் குறிப்பிட்ட செயல்திறன் தேவைகளுக்காக மேம்படுத்தப்படலாம். இருப்பினும், இதற்கு ரெகுலர் எக்ஸ்பிரஷன்கள் மற்றும் ஃபைனைட் ஆட்டோமேட்டா பற்றிய ஆழமான புரிதல் தேவைப்படுகிறது, மேலும் பராமரிப்பதும் பிழைதிருத்துவதும் சவாலானது.

ஒரு கைமுறை லெக்சர் பைத்தானில் முழு எண் லிட்டரல்களை எவ்வாறு கையாளக்கூடும் என்பதற்கான ஒரு கருத்தியல் (மற்றும் மிகவும் எளிமைப்படுத்தப்பட்ட) எடுத்துக்காட்டு இங்கே:

def lexer(input_string):
    tokens = []
    i = 0
    while i < len(input_string):
        if input_string[i].isdigit():
            # Found a digit, start building the integer
            num_str = ""
            while i < len(input_string) and input_string[i].isdigit():
                num_str += input_string[i]
                i += 1
            tokens.append(("INTEGER", int(num_str)))
            i -= 1 # Correct for the last increment
        elif input_string[i] == '+':
            tokens.append(("PLUS", "+"))
        elif input_string[i] == '-':
            tokens.append(("MINUS", "-"))
        # ... (handle other characters and tokens)
        i += 1
    return tokens

இது ஒரு sơ khai எடுத்துக்காட்டு, ஆனால் இது உள்ளீட்டு சரத்தை கைமுறையாகப் படித்து எழுத்து வடிவங்களின் அடிப்படையில் டோக்கன்களை அடையாளம் காணும் அடிப்படை யோசனையை விளக்குகிறது.

லெக்சர் ஜெனரேட்டர்கள்

லெக்சர் ஜெனரேட்டர்கள் என்பது லெக்சிகல் அனலைசர்களை உருவாக்கும் செயல்முறையை தானியக்கமாக்கும் கருவிகளாகும். அவை ஒரு விவரக்குறிப்புக் கோப்பை உள்ளீடாக எடுத்துக்கொள்கின்றன, இது ஒவ்வொரு டோக்கன் வகைக்கான ரெகுலர் எக்ஸ்பிரஷன்களையும் ஒரு டோக்கன் அங்கீகரிக்கப்படும்போது செய்யப்பட வேண்டிய செயல்களையும் வரையறுக்கிறது. பின்னர் ஜெனரேட்டர் ஒரு இலக்கு நிரலாக்க மொழியில் லெக்சர் குறியீட்டை உருவாக்குகிறது.

சில பிரபலமான லெக்சர் ஜெனரேட்டர்கள் இங்கே:

ஒரு லெக்சர் ஜெனரேட்டரைப் பயன்படுத்துவது பல நன்மைகளை வழங்குகிறது:

முழு எண்கள் மற்றும் ஐடென்டிஃபையர்களை அங்கீகரிப்பதற்கான ஒரு எளிய Flex விவரக்குறிப்பின் எடுத்துக்காட்டு இங்கே:

%%
[0-9]+      { printf("INTEGER: %s\n", yytext); }
[a-zA-Z_][a-zA-Z0-9_]* { printf("IDENTIFIER: %s\n", yytext); }
[ \t\n]+  ; // Ignore whitespace
.           { printf("ILLEGAL CHARACTER: %s\n", yytext); }
%%

இந்த விவரக்குறிப்பு இரண்டு விதிகளை வரையறுக்கிறது: ஒன்று முழு எண்களுக்கும் மற்றொன்று ஐடென்டிஃபையர்களுக்கும். Flex இந்த விவரக்குறிப்பைச் செயல்படுத்தும்போது, அது இந்த டோக்கன்களை அங்கீகரிக்கும் ஒரு லெக்சருக்கான C குறியீட்டை உருவாக்குகிறது. `yytext` மாறி பொருத்தப்பட்ட லெக்சீமைக் கொண்டுள்ளது.

லெக்சிகல் பகுப்பாய்வில் பிழை கையாளுதல்

பிழை கையாளுதல் என்பது லெக்சிகல் பகுப்பாய்வின் ஒரு முக்கிய அம்சமாகும். லெக்சர் ஒரு செல்லாத எழுத்து அல்லது தவறாக உருவாக்கப்பட்ட லெக்சீமை சந்திக்கும்போது, அது பயனருக்கு ஒரு பிழையைப் புகாரளிக்க வேண்டும். பொதுவான லெக்சிகல் பிழைகள் பின்வருமாறு:

ஒரு லெக்சிகல் பிழை கண்டறியப்பட்டால், லெக்சர் செய்ய வேண்டியவை:

  1. பிழையைப் புகாரளித்தல்: பிழை ஏற்பட்ட வரி எண் மற்றும் நெடுவரிசை எண், அத்துடன் பிழையின் விளக்கத்தை உள்ளடக்கிய ஒரு பிழைச் செய்தியை உருவாக்குதல்.
  2. மீட்க முயற்சித்தல்: பிழையிலிருந்து மீண்டு உள்ளீட்டைத் தொடர்ந்து ஸ்கேன் செய்ய முயற்சித்தல். இது செல்லாத எழுத்துக்களைத் தவிர்ப்பதையோ அல்லது தற்போதைய டோக்கனை முடிப்பதையோ உள்ளடக்கலாம். அடுக்கடுக்கான பிழைகளைத் தவிர்ப்பதும், பயனருக்கு முடிந்தவரை அதிக தகவல்களை வழங்குவதும் இதன் குறிக்கோள்.

பிழைச் செய்திகள் தெளிவாகவும் தகவலறிந்ததாகவும் இருக்க வேண்டும், இது நிரலாளருக்கு சிக்கலை விரைவாக அடையாளம் கண்டு சரிசெய்ய உதவுகிறது. எடுத்துக்காட்டாக, முடிக்கப்படாத சரத்திற்கான ஒரு நல்ல பிழைச் செய்தி இவ்வாறு இருக்கலாம்: `Error: Unterminated string literal at line 10, column 25`.

தொகுத்தல் செயல்பாட்டில் லெக்சிகல் பகுப்பாய்வின் பங்கு

லெக்சிகல் பகுப்பாய்வு என்பது தொகுத்தல் செயல்பாட்டில் முக்கியமான முதல் படியாகும். அதன் வெளியீடு, ஒரு டோக்கன்களின் தொடர், அடுத்த கட்டமான பார்சருக்கு (சிண்டாக்ஸ் அனலைசர்) உள்ளீடாக செயல்படுகிறது. பார்சர் டோக்கன்களைப் பயன்படுத்தி ஒரு சுருக்க தொடரியல் மரத்தை (AST) உருவாக்குகிறது, இது நிரலின் இலக்கண கட்டமைப்பைக் குறிக்கிறது. துல்லியமான மற்றும் நம்பகமான லெக்சிகல் பகுப்பாய்வு இல்லாமல், பார்சரால் மூலக் குறியீட்டைச் சரியாகப் புரிந்துகொள்ள முடியாது.

லெக்சிகல் பகுப்பாய்விற்கும் பார்சிங்கிற்கும் இடையிலான உறவை பின்வருமாறு சுருக்கமாகக் கூறலாம்:

AST பின்னர் கம்பைலரின் அடுத்தடுத்த கட்டங்களான செமாண்டிக் பகுப்பாய்வு, இடைப்பட்ட குறியீடு உருவாக்கம் மற்றும் குறியீடு மேம்படுத்தல் போன்றவற்றால் இறுதி இயக்கக்கூடிய குறியீட்டை உருவாக்கப் பயன்படுத்தப்படுகிறது.

லெக்சிகல் பகுப்பாய்வில் மேம்பட்ட தலைப்புகள்

இந்தக் கட்டுரை லெக்சிகல் பகுப்பாய்வின் அடிப்படைகளை உள்ளடக்கியிருந்தாலும், ஆராய வேண்டிய பல மேம்பட்ட தலைப்புகள் உள்ளன:

சர்வதேசமயமாக்கல் பரிசீலனைகள்

உலகளாவிய பயன்பாட்டிற்காக வடிவமைக்கப்பட்ட ஒரு மொழிக்கான கம்பைலரை வடிவமைக்கும்போது, லெக்சிகல் பகுப்பாய்விற்கான இந்த சர்வதேசமயமாக்கல் அம்சங்களைக் கவனியுங்கள்:

சர்வதேசமயமாக்கலைச் சரியாகக் கையாளத் தவறினால், வெவ்வேறு மொழிகளில் எழுதப்பட்ட அல்லது வெவ்வேறு எழுத்துத் தொகுப்புகளைப் பயன்படுத்தும் மூலக் குறியீட்டைக் கையாளும்போது தவறான டோக்கனைசேஷன் மற்றும் தொகுப்புப் பிழைகளுக்கு வழிவகுக்கும்.

முடிவுரை

லெக்சிகல் பகுப்பாய்வு என்பது கம்பைலர் வடிவமைப்பின் ஒரு அடிப்படை அம்சமாகும். இந்தக் கட்டுரையில் விவாதிக்கப்பட்ட கருத்துக்களைப் பற்றிய ஆழமான புரிதல், கம்பைலர்கள், இன்டர்பிரெட்டர்கள் அல்லது பிற மொழி செயலாக்கக் கருவிகளை உருவாக்குவதில் அல்லது வேலை செய்வதில் ஈடுபட்டுள்ள எவருக்கும் அவசியம். டோக்கன்கள் மற்றும் லெக்சீம்களைப் புரிந்துகொள்வதிலிருந்து ரெகுலர் எக்ஸ்பிரஷன்கள் மற்றும் ஃபைனைட் ஆட்டோமேட்டாவில் தேர்ச்சி பெறுவது வரை, லெக்சிகல் பகுப்பாய்வின் அறிவு கம்பைலர் கட்டுமான உலகில் மேலும் ஆராய்வதற்கான ஒரு வலுவான அடித்தளத்தை வழங்குகிறது. லெக்சர் ஜெனரேட்டர்களை ஏற்றுக்கொள்வதன் மூலமும், சர்வதேசமயமாக்கல் அம்சங்களைக் கருத்தில் கொள்வதன் மூலமும், டெவலப்பர்கள் பரந்த அளவிலான நிரலாக்க மொழிகள் மற்றும் தளங்களுக்கு வலுவான மற்றும் திறமையான லெக்சிகல் அனலைசர்களை உருவாக்க முடியும். மென்பொருள் மேம்பாடு தொடர்ந்து বিকশিত වන විට, லெக்சிகல் பகுப்பாய்வின் கோட்பாடுகள் உலகளவில் மொழி செயலாக்க தொழில்நுட்பத்தின் ஒரு மூலக்கல்லாக இருக்கும்.