Skip to content

Instantly share code, notes, and snippets.

@yetimdasturchi
Last active June 28, 2022 20:01
Show Gist options
  • Save yetimdasturchi/06e92c452eca06ac46581993e91faf75 to your computer and use it in GitHub Desktop.
Save yetimdasturchi/06e92c452eca06ac46581993e91faf75 to your computer and use it in GitHub Desktop.
PHP asosida yozilgan dasturlash tili

Birnarsa dasturlash tili

Birnarsa dasturlash tili php asosida ishlab chiqilgan bo'lib ekranga matn chop etish uchun foydalaniladi. Unda atiga chopet, yangiqator funskiyalari mavjud xolos.

Kod namunasi

chopet "Salom dunyo"
yangiqator
chopet "dunyo"

Ishga tushirish

php birnarsa.php source.narsa
<?php
class Birnarsa {
private $code;
/* Ruxsat etilgan funksiyalar */
const BUILT_IN_KEYWORDS = ["chopet", "yangiqator"];
/* Kalit so'zlar (funksiya nomlar, o'zgaruvchilar) uchun ruxsat etilgan belgilar */
const ALLOWED_KEYWORD_CHARS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_';
function __construct( $code ) {
$this->code = $code;
}
public function tokenize() {
$length = strlen( $this->code );
$pos = 0;
$tokens = [];
while ( $pos < $length ) {
$currentChar = $this->code[$pos];
//Joriy indeks bo'sh belgi yoki yangi qatorga mos kelsa siklni shunchaki davom etish
if ($currentChar === " " || $currentChar === "\n") {
$pos++;
continue;
} else if ($currentChar === '"') { //agar joriy belgi " bo'lsa satr kuzatilgan
$res = "";
$pos++;
// keyingi belgi " yoki \n belgilariga mos kelmasa kod tugallanmagan
while ($pos < $length-1 && $this->code[$pos] !== '"' && $this->code[$pos] !== '\n') {
$res .= $this->code[$pos];
$pos++;
}
//Yuqoridagi sikldan so'ng " belgisi topilmasa demak tugallanmagan satr haqida xatolik qaytarish
if ($this->code[$pos] !== '"') {
return [
'error' => ( $pos+1 ) . "-pozitsiyadagi qo'shtirnoq yopilsa keyin ishga tushish haqida o'ylab ko'raman :)"
];
}
$pos++;
//Shartlar mos kelsa token massiviga satrni qo'shish
$tokens[] = [
'type' => 'string',
'value' => $res,
];
} else if ( strpos( self::ALLOWED_KEYWORD_CHARS , $currentChar ) !== FALSE) {
$res = $currentChar;
$pos++;
// satr tugallagunga qadar ruxat etilgan kalit so'z belgilariga tekshirish
while($pos < $length && strpos( self::ALLOWED_KEYWORD_CHARS, $this->code[$pos] ) !== FALSE) {
$res .= $this->code[$pos];
$pos++;
}
//Token ruxsat etilgan funksiyalar doirasida bo'lmasa
if ( ! in_array($res, self::BUILT_IN_KEYWORDS ) ) {
return [
'error' => "\"$res\" vazifasi haqida bilmayman, faqat matn chop etishdan xabarim bor"
];
}
//Shartlar mos kelsa token massiviga funksiyani qo'shish
$tokens[] = [
'type' => 'keyword',
'value' => $res,
];
} else { // kodda keraksiz belgi mavjud
return [
'error' => "$pos-pozitsiyadagi belgi ($currentChar) juda qiziqarli, lekin tushunarsiz"
];
}
}
// Tokenlarni parser uchun qaytarish
return [
'error' => FALSE,
'tokens' => $tokens
];
}
public function parse( $tokens ) {
$len = count( $tokens );
$pos = 0;
while($pos < $len) {
$token = $tokens[$pos];
// Token chopetga mos kelsa
if($token['type'] === "keyword" && $token['value'] === "chopet") {
//chopet argumenti uchun keyingi indeksdagi tokenni tekshirish
if(empty($tokens[$pos + 1])) {
exit( ($pos + 1) . "-qator uchun argumentni enamdan olamanmi?");
}
//chopet argumenti sifatida keyingi token "string"ga mos kelishini tekshirish
if($tokens[$pos + 1]['type'] != "string") {
exit( ($pos + 1) . "-qatorda ikkita qo'chqor kallasi bitta qozonda qaynamasligiga misol ko'rish mumkin");
}
//Tekshiruv o'tgan chopet argumentini o'zak til orqali ekranga chiqarish
echo $tokens[$pos + 1]['value'];
$pos += 2;
}else if($token['type'] === "keyword" && $token['value'] === "yangiqator") {
echo PHP_EOL;
$pos += 1;
}else{
//Token hech qaysi qoidalarga mos kelmasa
exit ("\"{$token['value']}\" vazifasi haqida bilmayman, faqat matn chop etishdan xabarim bor");
}
}
}
public function run() {
$result = $this->tokenize();
if ( !empty( $result['error'] ) ) {
exit( $result['error'] );
}
echo "Token: " . json_encode($result['tokens']) .PHP_EOL;
echo "Natija:".PHP_EOL;
echo str_repeat('-', 30).PHP_EOL;
$this->parse( $result['tokens'] );
echo PHP_EOL.str_repeat('-', 30).PHP_EOL;
}
}
if( !empty($argv[1]) ){
if (!file_exists($argv[1]) ) {
exit( "Ko'rsatilgan fayl topilmadi".PHP_EOL );
}
$code = file_get_contents($argv[1]);
$compiler = new Birnarsa( $code );
$compiler->run();
}else{
exit( "Kompiliyatsiya uchun dastur kodi ko'rsatilmadi".PHP_EOL );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment