Как я могу создать Генератор Таблицы истинности?

Полный способ указать текущую ориентацию телефона:

    public String getRotation(Context context){
    final int rotation = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getOrientation();
           switch (rotation) {
            case Surface.ROTATION_0:
                return "portrait";
            case Surface.ROTATION_90:
                return "landscape";
            case Surface.ROTATION_180:
                return "reverse portrait";
            default:
                return "reverse landscape";
            }
        }

Chear Binh Nguyen

14
задан rahul 6 July 2009 в 06:44
поделиться

5 ответов

Звучит как отличный личный проект. Вы узнаете много нового о том, как работают основные части компилятора. Я бы пропустил попытку использовать генератор парсера; если это для вашего собственного назидания, вы узнаете больше, сделав все с нуля.

То, как работают такие системы, является формализацией того, как мы понимаем естественные языки. Если я дам вам предложение: «Собака, Ровер, съел свою еду», первое, что вы сделаете, - это разбейте его на слова и знаки препинания. «The», «SPACE», «dog», «COMMA», «SPACE», «Rover», ... Это «токенизация» или «lexing».

Следующее, что вы делаете, это анализируете поток токенов, чтобы увидеть, является ли предложение грамматическим. Грамматика английского языка чрезвычайно сложна, но это предложение довольно простое. SUBJECT-APPOSITIVE-VERB-OBJECT. Это «синтаксический анализ».

Как только вы узнаете, что предложение грамматическое, вы можете проанализировать предложение, чтобы действительно понять его смысл. Например, вы можете видеть, что есть три части этого предложения - подлежащее, аппозитив и «его» в объекте - все они относятся к одной и той же сущности, а именно к собаке. Вы можете понять, что собака ест, а еда - это то, что едят. Это фаза семантического анализа.

Затем у компиляторов есть четвертая фаза, которой нет у людей, а именно: они генерируют код, который представляет действия, описанные на языке.

Итак, сделайте все это. Начните с определения токенов вашего языка, определите токен базового класса и набор производных классов для каждого из них. (IdentifierToken, OrToken, AndToken, ImpliesToken, RightParenToken ...). Затем напишите метод, который принимает строку и возвращает IEnumerable '. Это ваш лексер.

Во-вторых, выясните, что такое грамматика вашего языка, и напишите парсер рекурсивного спуска, который разбивает IEnumerable на абстрактное синтаксическое дерево, представляющее грамматические объекты на вашем языке.

Затем напишите анализатор. который смотрит на это дерево и вычисляет вещи, например, «сколько различных свободных переменных у меня есть?»

Затем напишите генератор кода, который выдаст код, необходимый для оценки таблиц истинности. Плевание ИЛ кажется излишним, но если вы действительно хотите быть баффом, вы можете. Возможно, было бы проще позволить библиотеке дерева выражений сделать это за вас; вы можете преобразовать дерево синтаксического анализа в дерево выражений, а затем превратить дерево выражения в делегат и оценить делегат.

23
ответ дан 1 December 2019 в 10:04
поделиться

Я считаю, что генератор синтаксического анализатора - это излишество. Для решения этой проблемы вы можете использовать идею преобразования выражения в постфикс и вычисления постфиксных выражений (или непосредственного построения дерева выражения из инфиксного выражения и использования его для создания таблицы истинности).

2
ответ дан 1 December 2019 в 10:04
поделиться

Как упоминает Мердад, у вас должна быть возможность вручную выполнить синтаксический анализ за то же время, которое потребуется для изучения синтаксиса лексера / анализатора. Конечным результатом, который вам нужен, является некоторое абстрактное синтаксическое дерево (AST) данного выражения.

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

Затем повторите итерацию. во входном наборе, генерируя результаты для каждой входной комбинации, учитывая правила (AST), которые вы проанализировали на первом этапе.

Как бы я это сделал:

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

1
ответ дан 1 December 2019 в 10:04
поделиться

Если ваша цель - обработка логических выражений, генератор синтаксического анализатора и весь связанный с ним механизм - пустая трата времени, если вы не хотите узнать, как они работают (тогда подойдет любое из них

Но легко создать синтаксический анализатор с рекурсивным спуском вручную для логических выражений, который вычисляет и возвращает результаты "оценки" выражения. Такой синтаксический анализатор можно использовать на первом проходе для определения количества уникальных переменных, где «оценка» означает «couunt 1 для каждого нового имени переменной». Writing a generator to produce all possible truth values for N variables is trivial; for each set of values, simply call the parser again and use it to evaluate the expression, where evaluate means "combine the values of the subexpressions according to the operator".

You need a grammar:

formula = disjunction ;
disjunction = conjunction 
              | disjunction "or" conjunction ;
conjunction = term 
              | conjunction "and" term ;
term = variable 
       | "not" term 
       |  "(" formula ")" ;

Yours can be more complicated, but for boolean expressions it can't be that much more complicated.

For each grammar rule, write 1 subroutine that uses a global "scan" index into the string being parsed:

  int disjunction()
 // returns "-1"==> "not a disjunction"
 // in mode 1:
 // returns "0" if disjunction is false
 // return  "1" if disjunction is true
 { skipblanks(); // advance scan past blanks (duh)
   temp1=conjunction();
   if (temp1==-1) return -1; // syntax error
   while (true)
     { skipblanks();
       if (matchinput("or")==false) return temp1;
       temp2= conjunction();
       if (temp2==-1) return temp1;
       temp1=temp1 or temp2;
     }
  end

  int term()
  { skipblanks();
    if (inputmatchesvariablename())
       { variablename = getvariablenamefrominput();
         if unique(variablename) then += numberofvariables;
         return lookupvariablename(variablename); // get truthtable value for name
       }
     ...
  }

Each of your parse routines will be about this complicated. Seriously.

1
ответ дан 1 December 2019 в 10:04
поделиться

Вы можете получить исходный код программы pyttgen на http://code.google.com/p/pyttgen/source/browse/#hg/src Она генерирует таблицы истинности для логических выражений. Код основан на библиотеке ply, поэтому он очень прост :)

0
ответ дан 1 December 2019 в 10:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: