موضوع مقاله: هک لکسر | مخاطب: عمومی | لحن: دانشنامه‌ای | ساختار: عنوان، مقدمه، 3 بخش، جمع‌بندی | مقاله: | # هک لکسر | مقدمه: در برنامه‌نویسی کامپیوتر ، هک لکسر (Lexer Hack) یک راه حل معمول برای مشکل تجزیه یا پارس آنسی سی است، از آنجایی که زبان اشاره شده گرامر حساس به متن است. | ## بخش 1: هک لکسر | در زبان سی، طبقه‌بندی دنباله ای از اسم متغیر یا نوع اسم نیاز به اطلاعات وابسته به متنی از ساختار عبارت است که از مستقل از متن بودن تحلیل لغوی جلوگیری می‌کند. مشکل اینجاست که در کد زیر، کلاس لغوی A بدون اطلاعات بیشتر وابسته به متن قابل تصمیم‌گیری نیست:(A)*Bاین کد می‌تواند ضرب دو متغیر باشد که در این صورت A یک متغیر است، که غیر مبهم نوشته شده:A * Bدر حالتی دیگر، می‌تواند مقدار بی مرجع B را به نوع A بدهد. که در این صورت A یک اسم typedef (ساخت نوعی جدید) است، که غیر مبهم نوشته شده:(A) (*B)اگر نیاز باشد که بیشتر توضیح دهیم، در یک کامپایلر، تحلیل لغوی یکی از اولی‌ترین مراحل تبدیل کد منبع یه برنامه است. به کلماتی مثل، "عدد"، "رشته" یا … پارسر یا فاز تحلیل نحوی دنباله ای از این توکن‌ها را تحلیل و آنالیز کرده تا با قوانین نحو (سینتکس) آن‌ها را تطابق دهد. مشکلی که اینجا می‌تواند رخ دهد این است که یک دنباله ای از توکن‌ها بتوانند به‌طور مبهم دار با بیش از یک قانون نحو تطابق پیدا کنند. این ابهام می‌تواند در زبان سی اتفاق بیفتد اگر فاز تحلیل لغوی (لکسر) نتواند بین متغیر و typedef (ساخت نوعی جدید). به عنوان مثال در زبان سی داریم:(A) * Bفاز تحلیلی امکان دارد این توکن‌ها را پیدا کند: پرانتز سمت چپ تعیین هویت 'A' پرانتز راست عملگر '*' تعیین هویت 'B' مشکل دقیقاً اینجاست که کلاس لغوی A بدون اطلاعات بیشتر از متن نمی‌تواند تصمیم‌گیری انجام دهد: فاز تحلیل نحوی می‌تواند این را به عنوان "متغیر A ضربدر متغیر B" یا به صورت "مقدار بی مرجع B به نوع A داده شده" تفسیر کند. | ## بخش 2: هک لکسر | راه حل به‌طور کلی شامل تغذیه اطلاعات از جدول نمادهای لغوی به فاز تحلیل لغوی (لکسر) است؛ یعنی به جای اینکه شبیه به یک خط لوله یک طرفه فقط از واژگان به تجزیه کننده عمل کند، یک کانال پشتی از تحلیل معنایی به فاز تحلیل لغوی (لکسر) وجود دارد. این ترکیب پارس کردن (از فاز تحلیل نحوی) و تحلیل معنایی عموماً بی‌ظرافت در نظر گرفته می‌شود، به همین دلیل به آن «هک» می‌گویند. بدون زمینه اطلاعاتی اضافه شده، تحلیل لغوی (لکسر) نمی‌تواند شناسه‌های نوع را از سایر شناسه‌ها تشخیص دهد زیرا همه شناسه‌ها قالب یکسانی دارند. با هک در مثال بالا، زمانی که تحلیل لغوی (لکسر) شناسه A را پیدا می‌کند باید بتواند نشانه را به عنوان یک شناسه نوع طبقه‌بندی کند. قواعد زبان با مشخص کردن اینکه typecastها (اختصاص دادن نوع) به یک شناسه نوع نیاز دارند و ابهام از بین می‌رود، واضح و مشخص می‌شود. این مشکل در ++C نیز وجود دارد و تجزیه کننده‌ها می‌توانند از همان هک استفاده کنند. این مشکل هنگام استفاده از تکنیک‌های تجزیه بدون lexer به وجود نمی‌آید (و از این رو برای حل کردن نیازی به «هک» نیست، زیرا اینها ذاتاً متنی هستند. | ## بخش 3: هک لکسر | با این حال، این طرح‌ها معمولاً به عنوان طرح‌های کمتر ظریف دیده می‌شوند، زیرا فاقد مدولار بودن داشتن یک lexer و تجزیه‌کننده همزمان در یک خط لوله هستند. در مشکلی که در اینجا توضیح داده شد، اگر تلاشی به دلیل اطلاعات معنایی مربوط به شناسه با شکست مواجه شود، می‌تواند به عقب برگردد و قوانین دیگری را امتحان کند. تجزیه کننده Clang وضعیت را به روشی کاملاً متفاوت مدیریت می‌کند، یعنی با استفاده از دستور زبان واژگانی غیر مرجع. لکسر Clang سعی نمی‌کند بین نام نوع و نام متغیر تمایز قائل شود: فقط نشانه فعلی را به عنوان یک شناسه گزارش می‌کند. تجزیه کننده سپس از کتابخانه تحلیل معنایی Clang برای تعیین ماهیت شناسه استفاده می‌کند. این اجازه می‌دهد تا جداسازی بسیار تمیزتر نگرانی‌ها و محصورسازی لکسر و تجزیه کننده اتفاق بیفتد، و بنابراین توسط برخی از توسعه دهندگان کامپایلر به عنوان راه حل بسیار زیباتر از هک لکسر در نظر گرفته می‌شود. | ## جمع‌بندی | این روشی است که در اکثر زبان‌های مدرن دیگر استفاده می‌شود که طبقات مختلف شناسه‌ها را در دستور زبان واژگانی متمایز نمی‌کنند، اما در عوض آن‌ها را به مرحله تجزیه یا تحلیل معنایی، زمانی که اطلاعات کافی در دسترس است، موکول می‌کنند.