Mikroprocesorowa ośla łączka, część 28
Dziedziczenie pozwala na realizację różnorodnych rozwiązań. Tu można wskazać na funkcjonalność typu HAL, która pozwala na adaptację obsługi sprzętu do konkretnych uwarunkowań sprzętowych. Inną możliwością jest rozszerzenie funkcjonalności istniejących komponentów.
W poprzedniej części została opisana możliwość adaptacji obsługi odpowiedniego sprzętu elektronicznego do określonego środowiska. Warto oddzielić logikę sterowania dołączanych komponentów od rzeczywistego rozwiązania samego przyłączenia. Teraz zostanie przedstawiona koncepcja rozbudowy funkcjonalności komponentu o nowe możliwości. Tłem do rozważań jest analiza składniowa. Wiele urządzeń jest sterowanych poleceniami tekstowymi przesyłanymi z zewnątrz. To może być kanał transmisji szeregowej, poprzez który dostarczane są polecenia. Bardziej nowoczesne jest zastosowanie sieci ethernetowej. Różnica związana jest jedynie z „nośnikiem danych”. Wspólną częścią jest analizator tych poleceń wbudowany w mikrokontroler. Składa się on z kilku warstw, gdzie podstawową jest analiza leksykalna.
Analizator leksykalny
Analiza leksykalna (ang. lexical analysis) to proces wstępnego przetwarzania tekstu, polegający na podziale ciągu znaków na mniejsze, logiczne jednostki zwane tokenami (np. wyrazy, liczby, znaki przestankowe). Proces ten obejmuje też odrzucenie elementów bez znaczenia, jak przykładowo spacje. Wyodrębniając podstawowe elementy (tokeny), analizator sprawdza poprawność ich zapisu i może zgłosić błąd formatu zapisu. Przykładowo jako napis (ciąg znaków zapisany między znakami apostrofów lub cudzysłowu) musi mieć znak zamknięcia łańcucha, identyczny jak znak otwierający (apostrof lub cudzysłów). Podobnie wymagane jest, by liczba z ułamkiem dziesiętnym po znaku oddzielającym część całkowitą od ułamkowej (w tej roli występuje znak kropki), zawierała cyfry.
Do analizy leksykalnej zdefiniowana jest klasa TLexicalAnalyzer zawarta w (LexicalModule.h oraz LexicalModule.cpp). Postać komponentu pokazuje listing 1:
class TLexicalAnalyzer {
public :
TLexicalAnalyzer ( ) ;
void AnalError ( uint16_t ErrorNo ) ;
void AnalCardError ( uint16_t ErrorCode ,
uint32_t LCValue ) ;
void AnalStrError ( uint16_t ErrorCode ,
uint8_t * StrValue ) ;
uint8_t ReadSymbol ( ) ;
uint32_t ReadCardinal ( ) { return CardInpValue ; } ;
float ReadReal ( ) { return RealInpValue ; } ;
uint8_t * ReadString ( ) { return StrInpValue ; } ;
void SetRealEnable ( uint8_t Enable ) { RealEnable = Enable ; } ;
void OpenLineAnalyser ( uint8_t * LineBuffer ) ;
void CheckEndOfLine ( uint16_t ErrorCode ) ;
uint8_t ErrorsPresent ( ) { return ErrorPresent ; } ;
void PrintAllErrors ( ) ;
virtual void StartPrintErrors ( ) ;
virtual void StopPrintErrors ( ) ;
virtual void PrintError ( uint16_t ErrorCodes ,
uint8_t * ErrorSpelling ) ;
virtual void PrintLine ( uint8_t * Buffer ) ;
public :
SpellingType InpSpelling ;
private :
uint8_t GetNextChar ( ) ;
void PutSpellCh ( uint8_t PCh ) ;
void ReadString ( uint8_t Terminator ) ;
private :
LineBuffType SourceLine ;
uint8_t RealEnable ;
uint8_t * CurrChar ;
uint32_t CardInpValue ;
float RealInpValue ;
uint8_t LineChar ;
uint8_t LineChar2 ;
uint16_t SpeelCt ;
InpStringType StrInpValue ;
uint16_t ErrCodes [ MaxErr ] ;
SpellingType ErrSpell [ MaxErr ] ;
uint8_t ErrIndex ;
uint8_t EndOfLReached ;
uint8_t ErrorPresent ;
} ;
Publicznie dostępne elementy pełnią następujące funkcje:
• TLexicalAnalyzer – konstruktor obiektu, inicjuje wartości początkowe zmiennych obiektu, między innymi „włącza” rozpoznawanie liczb ułamkowych (aby umożliwić analizę adresów IP jako czterech liczb rozdzielonych znakiem kropki, należy „wyłączyć” analizę liczb ułamkowych),
• OpenLineAnalyser – metoda przyłączająca do analizatora bufor zawierający tekst do analizy, podany parametr wywołania jest tablicą znakową w rozumieniu języka C/C++ (zakończony znakiem o kodzie 0),
• SetRealEnable – metoda do włączania/wyłączania rozpoznawania liczb ułamkowych (aby analiza adresu IP zapisanego w konwencjonalnym formacie nie kolidowała z rozpoznawaniem liczb ułamkowych należy ją wyłączyć),
• ReadSymbol – podstawowa metoda do wczytania kolejnego tokena, jego treść zawsze jest zawarta w InpSpelling, przy zgłaszaniu błędów treść tokena jest zapamiętana, by umożliwić lokalizację błędnych zapisów, wynikiem funkcji jest liczba 8-bitowa pozwalająca na rozpoznanie wczytanego tokena, przykładowo LexicNoSy oznacza, że wczytany token nie jest rozpoznany, LexicIdentSy sygnalizuje, że został wczytany wyraz, LexicEndLineSy informuje, że w analizie został osiągnięty koniec wiersza (dalsze czytanie „na siłę” zawsze zwróci tę wartość), listing 2 przedstawia rozpoznawane tokeny,
• ReadCardinal – metoda do pobrania wartości całkowitej w postaci binarnej (po konwersji) jeżeli wywołanie ReadSymbol zgłosiło wartość LexicCardConstSy,
• ReadReal – metoda do pobrania wartości liczby typu float w postaci binarnej (po konwersji) jeżeli wywołanie ReadSymbol zgłosiło wartość LexicRealConstSy,
• ReadString – metoda do pobrania tekstu napisu jako wskazanie na pierwszy jego znak (łańcuch znaków w kategorii języka C/C++) jeżeli wywołanie ReadSymbol zgłosiło wartość LexicStrConstSy,
• AnalError – metoda przeznaczona do zgłaszania błędów analizy leksykalnej oraz syntaktycznej (warstwy wyższej) pozwalająca użytkownikowi na lokalizację błędnych zapisów,
• AnalCardError – metoda przewidziana do zgłaszania błędnych wartości liczbowych,
• AnalStrError – metoda przeznaczona do zgłaszania błędnych wartości zapisanych jako łańcuch znaków,
• CheckEndOfLine – metoda do zgłaszania błędów dla wszystkich tokenów zapisanych na końcu wiersza,
• ErrorsPresent – pozwala zapytać analizator, czy w trakcie przetwarzania bieżącego wiersza zostały stwierdzone jakiekolwiek błędy,
• PrintAllErrors – metoda do „pokazania” wszystkich błędów zgłoszonych w trakcie analizy bieżącego wiersza, wewnątrz posiłkuje się wirtualnymi metodami: StartPrintErrors, StopPrintErrors oraz PrintError,
• StartPrintErrors – wirtualna metoda do realizacji działań przed wyświetleniem listy zgłoszonych błędów,
• StopPrintErrors – wirtualna metoda do realizacji działań po wyświetleniu listy zgłoszonych błędów,
• PrintError – wirtualna metoda do realizacji wyświetlenia komunikatu pojedynczego błędu,
• PrintLine – wirtualna metoda wyświetlenia analizowanego wiersza polecenia,
• pole InpSpelling zawiera treść wczytanego tokena, ma zastosowanie do rozpoznania wczytanego wyrazu (jeżeli ReadSymbol zwróci wartość LexicIdentSy).
Listing 2:
#define LexicNoSy 0 // symbol nierozpoznany #define LexicEndLineSy 1 // napotkano koniec wiersza #define LexicEqSy 2 // napotkano znak ’=’ #define LexicPlusSy 3 // napotkano znak ’+’ #define LexicMinusSy 4 // napotkano znak ’-’ #define LexicMultSy 5 // napotkano ’*’ #define LexicDivSy 6 // napotkano ’/’ #define LexicLTSy 7 // napotkano ’<’ #define LexicGTSy 8 // napotkano ’>’ #define LexicLESy 9 // napotkano ’<=’ #define LexicGESy 10 // napotkano ’>=’ #define LexicAndSy 11 // napotkano ’&’ #define LexicLParentSy 12 // napotkano ’(’ #define LexicRParentSy 13 // napotkano ’)’ #define LexicLBrackSy 14 // napotkano ’[’ #define LexicRBrackSy 15 // napotkano ’]’ #define LexicCommaSy 16 // napotkano ’,’ #define LexicPointSy 17 // napotkano ’.’ #define LexicColonSy 18 // napotkano ’:’ #define LexicSemiColonSy 19 // napotkano ’;’ #define LexicHashSy 20 // napotkano ’#’ #define LexicCardConstSy 21 // napotkano stala calkowita #define LexicRealConstSy 22 // napotkano stala reczywista #define LexicStrConstSy 23 // napotkano stala tekstowa #define LexicIdentSy 24 // napotkano identyfikator
W komponencie występuje kilka metod wirtualnych (ich postać w komponencie bazowym jest pusta). Istnieje możliwość utworzenia w klasie pochodnej ich realizacji przystosowanych do konkretnej potrzeby.
(…)
——– ciach! ——–
To jest tylko fragment artykułu, którego pełna wersja ukazała się we wrześniowym numerze czasopisma Zrozumieć Elektronikę (ZE 9/2026). Pełną wersję czasopisma znajdziesz pod tym linkiem. Natomiast niepełna, okrojona wersja, pozwalająca zapoznać się z zawartością numeru ZE 9/2026 znajduje się tutaj.
Andrzej Pawluczuk
apawluczuk@vp.pl
Uwaga! Wskazówki, jak nabyć pełne wersje dowolnych numerów ZE znajdują się na stronie:
https://piotr-gorecki.pl/n11.