Nano Hash - криптовалюты, майнинг, программирование

Парсер рекурсивного спуска для EBNF в PHP

Я пытаюсь написать анализатор рекурсивного спуска на PHP для следующего EBNF:

EXP ::= < TERM > { ( + | - ) < TERM > }
TERM ::= < FACTOR > { ( * | / ) < FACTOR > }
FACTOR ::= ( < EXP > ) | < DIGIT >
DIGIT ::= 0 | 1 | 2 | 3

Я следовал этому руководству, которое мне рекомендовали по аналогичному вопросу. (искал перед тем как написать)

По большей части я понимаю, как это работает, и понимаю грамматику. Я думаю, что проблема в моем синтаксисе. Я новичок в PHP, поэтому ссылаюсь на W3Schools. В настоящее время я получаю следующую ошибку с моим кодом:

Warning: Wrong parameter count for exp() .... on line 101

Я пытался найти эту ошибку и не очень повезло. Я читал несколько сообщений о том, что люди передают неверный тип параметра, но у меня нет никаких параметров, установленных для этой функции. Есть ли что-то в PHP, которое мне здесь не хватает?

Ниже приведен мой код, я думаю, что логика верна, поскольку я основывал его на дереве синтаксического анализа для грамматики. Ввод $ будет поступать из поля формы на HTML-странице. Я также взял функцию str_split из другого поста, когда обнаружил, что в PHP4 она не встроена.

<html>
<body>
<?php 
if(!function_exists("exp")){
  function exp(){
    term();
    while($token == "+" | $token == "-"){
        if($token == "+"){
            match("+");
            term();
        }
        if($token == "-"){
            match("-");
            term();
        }
    }
  }//end exp
}

if(!function_exists("term")){
  function term(){
    factor();
    while($token == "*" | $token == "/"){
        if($token == "*"){
            match("*");
            factor();
        }
        if($token == "/"){
            match("/");
            factor();
        }
    }
  }//end term
}

if(!function_exists("factor")){
  function factor(){
    if($token == "("){
        match("(");
        exp();
        if($token == ")")
            match(")");
    }
    else if($token == 0|1|2|3){
         if($token == 0)
            match(0);
         if($token == 1)
            match(1);
         if($token == 2)
            match(2);
         if($token == 3)
            match(3);
    }
    else
        error();
  }//end factor
}

if(!function_exists("match")){
  function match($expected){
    if($token == $expected)
        nextToken();
    else
        error();
  }//end match
}

if(!function_exists("next_Token")){
  function nextToken(){
    $next++;
    $token = $tokenStr[$next];
    if($token == "$");
        legal();
  }
}

if(!function_exists("error")){
  function error(){
    echo "Illegal token stream, try again";
  }
}

if(!function_exists("legal")){
  function legal(){
    echo "Legal token stream, congrats!";
  }
}

if(!function_exists('str_split')) {
  function str_split($string, $split_length = 1) {
    $array = explode("\r\n", chunk_split($string, $split_length));
    array_pop($array);
    return $array;
  }
}

$tokenStr = str_split($input);
$next = 0;
$token = $tokenStr[0];
exp();
?>
</body>
</html>

Итак, в основном я хочу знать, что вызывает эту ошибку и почему, и я на правильном пути с точки зрения создания этого парсера.

Я ценю любые комментарии, предложения, критику, водные шары и помидоры. Спасибо, что нашли время, чтобы прочитать мой пост. Хорошего дня/ночи.


  • Извините, дикая догадка, но не конфликтует ли это с функцией exp() из математики: php.net/manual/en/function.exp.php ? 28.03.2011
  • Спасибо, именно так и было, но теперь все компилируется корректно без вывода. Я предполагаю, что он не получает переданный ввод. Есть ли проблема с тем, как мои функции получают доступ к глобальным переменным? 28.03.2011

Ответы:


1

exp() — это встроенная функция PHP. Вы не можете определить его под этим именем.

У вас не должно быть причин использовать идиому if(!function_exists(' в обычных PHP-приложениях. (Это часто используется больше как обходной путь, когда включаемые скрипты конфликтуют или идентичные функции объявлены в разных местах.)


Еще одна проблема с синтаксисом, которую я заметил, — это использование побитового ИЛИ. Логическое ИЛИ должно быть || или просто or.

while($token == "*" | $token == "/"){
28.03.2011
  • Я чувствую себя немного глупо из-за того, что не заглянул в это. Спасибо большое. Я очистил код, использовал логическое ИЛИ и удалил существующие вызовы функций, и теперь проверяю, все ли работает. 28.03.2011

  • 2

    Я превращу свою дикую догадку в ответ. Так может в этом и заключается проблема?

    http://php.net/manual/en/function.exp.php

    28.03.2011

    3

    В PHP уже есть функция с именем exp(). Вы можете каким-то образом префиксировать имена своих функций, или лучше использовать классы, чтобы избежать конфликтов имен.

    28.03.2011
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..