Как посчитать количество if-операторов в отдельном файле кода - PullRequest
1 голос
/ 06 мая 2019

Я пытаюсь написать программу-схему, которая подсчитывает количество операторов if в файле, содержащем код.Я знаю, как читать в файле, но не знаю, как подсчитать количество операторов if.

Ответы [ 2 ]

0 голосов
/ 07 мая 2019

Это очень сложно без фактической реализации приведения языка к более примитивной форме. В качестве примера представим следующее:

(count-ifs '(let ((if +))
              (if 1 2 3)))
; ==> 0

0 - правильное значение, поскольку if - это теневое связывание if, а схема поддерживает теневое копирование, поэтому результатом этого выражения является 6, а не 2. let можно переписать так, чтобы вы могли проверить это вместо:

(count-ifs '((lambda (if) 
               (if 1 2 3)) 
             +))
; ==> 0

Возможно, это не похоже на улучшение, но здесь вы можете исправить это:

(define (count-ifs expr)
  (let helper ((expr expr) (count 0))
    (if (or (not (list? expr))
            (and (eq? (car expr) 'lambda)
                 (memq 'if (cadr expr))))
        count
        (foldl helper
               (if (eq? (car expr) 'if)
                   (add1 count)
                   count)
               expr))))



(count-ifs '((lambda (if) 
               (if 1 2 3)) 
             (if #t + (if if if))))
; ==> 2

Задача состоит в том, чтобы расширить макросы. На самом деле вам нужно сделать макроэкспандер, чтобы переписать код так, чтобы единственными привязками, создающими форму, был lambda. Это тот же объем работы, что и создание 80% компилятора Scheme, поскольку, как только вы его отключите, все остальное легко.

0 голосов
/ 06 мая 2019

Простым способом сделать это может быть структура рекурсии, подобная этой:

(define (count-ifs exp)
  (+ (if-expression? exp 1 0)))
     (if (pair? exp)
         (+ (count-ifs (car exp)) (count-ifs (cdr exp))))
         0)))

Но это может быть слишком много.

Более правильный способ сделать это - обработать код, проверив каждый тип выражения, которое вы видите - и когда вы вводите лямбду, вам нужно добавить переменные, которые она связывает, со списком затененных символов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...