Как сделать отступ в текстовом файле, содержащем специальные ключевые слова, без использования массивов или регулярных выражений - PullRequest
0 голосов
/ 28 июня 2018

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

пример;

start
write "enter your name
read name
write "enter your age"
read age
if age==100 then
do
print "you stink"
while age !=100
end if
while something
if something
do something
while something
end if
end 

должно быть:

start

   write "enter your name"
   read name

   write "enter your age"
   read age

   if age==100 then
          do
          print "you stink"
          while age !=100
   end if
    while something
        if something
            do something
            while something
        end if
end

Я не могу заставить свою программу правильно делать отступы после первого «ключевого слова». ключевые слова: "while, if, do, end if, end, start и т.д ..."

Мне запрещено использовать массивы или регулярные выражения

часть моего кода, которая читает текстовый файл:

    String corrIndent (String pseudocode2) {
    String sTrim = ""; //pseudocode to return
    String sTmp;

    int debut = 0; //current line start index
    int fin; //current line end index

    fin = pseudocode2.indexOf("\n", debut);//read lines

    do {
         //extracts current line 
         sTmp = pseudocode2.substring(debut, fin);
         //opens the do..while loop indent level

         if(sTmp.contains("do")){//opens do indent(indents 1 level)

             for (int i=1;i<=999;i++){

                 sTmp =pseudocode2.substring(debut, fin);
                 //sTrim="\t";
                 if (sTmp.contains("while")){//close do indent (reduce indentation 1 level)
                    i=999;//supposes that the text file is never that long

                 } 
                 //add current line to string to return
                 //with a newline.
                 sTrim = sTrim + sTmp+ ""+"   ";
                 //ajuster le debut de la ligne courante suivante
                 debut =  fin + 1;
                 //trouver la fin de la ligne courante suivante
                 fin = pseudocode2.indexOf("\n", debut);
             }
         } 


         {//when no more indentation is needed
             sTrim = sTrim + sTmp + "\n";

             debut = fin + 1;

             fin = pseudocode2.indexOf("\n", debut);
         }

    }while (fin != -1);
    return sTrim;
  }

С помощью этого кода я могу правильно сделать отступ для блока do, но если в этом блоке есть другое ключевое слово, он не получит новый уровень отступа.

Почему это?

Я пробовал многочисленные методы для сохранения уровня отступа как переменной без успеха.

Ответы [ 3 ]

0 голосов
/ 28 июня 2018

Итак, вот потенциальная часть ответа. Я не понимаю, почему не используют массив и регулярные выражения, но почему бы и нет

вот код, который вам нужно реализовать, но описание вашего языка довольно плохое, это не LL (1), поэтому у вас есть проблема для обработки разницы между концом и концом, если ... другая проблема заключается в том, что вы нет конечного разделителя для инструкции while, может быть, и end в то время как вам поможет?

Этот вид реализации очень тяжелый и Я явно не рекомендую такие вещи !! но это было забавно принять вызов ^^

public class MainIndent {

    public static enum Tokens {
        start("start", 1), end("end", -1), write("write", 0), end_if("end if", -1), read("read", 0), _if("if", 1),
        _do("do", 1), _while("while", 1);
        private final String keyword;
        private final int policy;

        Tokens(String keyword, int policy) {
            this.keyword = keyword;
            this.policy = policy;
        }

        public int getPolicy() {
            return policy;
        }

        public String getKeyword() {
            return keyword;
        }
    }

    public static String parse(String input, String indent) {
        String remaining = input;
        String parsed = "";
        int nbIndent = 0;
        int doCount = 0;
        while (!remaining.isEmpty()) {
            Tokens tokens = getNextToken(remaining);
            Tokens nextTokens = getNextToken(remaining.substring(tokens.getKeyword().length()));
            int indexOf;
            if (nextTokens == null) {
                parsed += createIndent(indent, nbIndent+tokens.getPolicy()) + remaining + "\n";
                remaining = "";
            } else {
                if (tokens == Tokens.end_if && (nextTokens == Tokens.end || nextTokens == Tokens.end_if)) {
                    indexOf = tokens.getKeyword().length()
                            + remaining.substring(tokens.getKeyword().length()).indexOf(nextTokens.getKeyword());
                } else {
                    indexOf = remaining.indexOf(nextTokens.getKeyword());
                }
                int lastIndent = nbIndent;
                if (tokens == Tokens._do) {
                    doCount++;
                    nbIndent++;
                } else if (tokens == Tokens._while && doCount > 0) {
                    doCount--;
                    nbIndent--;
                    lastIndent--;
                } else {
                    if (tokens.getPolicy() < 0) {
                        lastIndent--;
                    }
                    nbIndent += tokens.getPolicy();

                }
                parsed += createIndent(indent, lastIndent) + remaining.substring(0, indexOf) + "\n";
                remaining = remaining.substring(indexOf).trim();
            }
            System.out.println(parsed);
            System.out.println(remaining);
        }

        return parsed;
    }

    private static String createIndent(String indent, int nbIndent) {
        String output = "";
        for (int i = 0; i < nbIndent; i++) {
            output += indent;
        }
        return output;
    }

    public static void main(String[] args) {
        System.out.println(corrIndent(
                "   start write \"enter your name\" read name\n write \"enter your age\" read age if age==100 then do write \"you stink\" while age!=100 end if while something if something do something while something end if end     "));
    }

    public static String corrIndent(String pseudocode2) {
        return corrIndent(pseudocode2, "    ");
    }

    public static String corrIndent(String pseudocode2, String indent) {
        String remainingStringtoParse = clearwhiteSpace(pseudocode2); // this will remove all current indentation
        return parse(remainingStringtoParse, indent);
    }

    private static Tokens getNextToken(String input2) {
        int startIndex = input2.indexOf(Tokens.start.getKeyword());
        startIndex = startIndex == -1 ? input2.length() : startIndex;
        int writeIndex = input2.indexOf(Tokens.write.getKeyword());
        writeIndex = writeIndex == -1 ? input2.length() : writeIndex;
        int readIndex = input2.indexOf(Tokens.read.getKeyword());
        readIndex = readIndex == -1 ? input2.length() : readIndex;
        int ifIndex = input2.indexOf(Tokens._if.getKeyword());
        ifIndex = ifIndex == -1 ? input2.length() : ifIndex;
        int doIndex = input2.indexOf(Tokens._do.getKeyword());
        doIndex = doIndex == -1 ? input2.length() : doIndex;
        int whileIndex = input2.indexOf(Tokens._while.getKeyword());
        whileIndex = whileIndex == -1 ? input2.length() : whileIndex;
        int endIndex = input2.indexOf(Tokens.end.getKeyword());
        endIndex = endIndex == -1 ? input2.length() : endIndex;
        int endifIndex = input2.indexOf(Tokens.end_if.getKeyword());
        endifIndex = endifIndex == -1 ? input2.length() : endifIndex;
        if (startIndex < endIndex && startIndex < endifIndex && startIndex < writeIndex && startIndex < readIndex
                && startIndex < ifIndex && startIndex < doIndex && startIndex < whileIndex) {
            return Tokens.start;
        } else if (writeIndex < readIndex && writeIndex < ifIndex && writeIndex < doIndex && writeIndex < whileIndex
                && writeIndex < endIndex && writeIndex < endifIndex) {
            return Tokens.write;
        } else if (readIndex < ifIndex && readIndex < doIndex && readIndex < whileIndex && readIndex < endIndex
                && readIndex < endifIndex) {
            return Tokens.read;
        } else if (ifIndex < doIndex && ifIndex < whileIndex && ifIndex < endIndex && ifIndex < endifIndex) {
            return Tokens._if;
        } else if (doIndex < whileIndex && doIndex < endIndex && doIndex < endifIndex) {
            return Tokens._do;
        } else if (whileIndex < endIndex && whileIndex < endifIndex) {
            return Tokens._while;
        } else if (endIndex < endifIndex) {
            return Tokens.end;
        } else if (endifIndex != input2.length()) {
            return Tokens.end_if;
        } else {
            return null;
        }
    }

    private static String clearwhiteSpace(String pseudocode) {
        String remainingStringtoParse = pseudocode;
        String parsedString = "";
        while (remainingStringtoParse.length() > 0) {
            remainingStringtoParse = removeHeadWhiteSpace(remainingStringtoParse);
            int nextWhiteSpaceIndex = getNextWhiteSpaceIndex(remainingStringtoParse);
            parsedString += remainingStringtoParse.substring(0,
                    nextWhiteSpaceIndex == -1 ? remainingStringtoParse.length() : nextWhiteSpaceIndex)
                    + (nextWhiteSpaceIndex == -1 ? "" : " ");
            remainingStringtoParse = nextWhiteSpaceIndex == -1 ? ""
                    : remainingStringtoParse.substring(nextWhiteSpaceIndex);
        }
        return parsedString;
    }

    private static int getNextWhiteSpaceIndex(String remainingStringtoParse) {
        int whitespace = 0;
        while (remainingStringtoParse.length() > whitespace
                && !isWhiteSpace(remainingStringtoParse.charAt(whitespace))) {
            whitespace++;
        }
        return remainingStringtoParse.length() == whitespace ? -1 : whitespace;
    }

    private static String removeHeadWhiteSpace(String pseudocode) {
        int whitespace = 0;
        while (pseudocode.length() > whitespace && isWhiteSpace(pseudocode.charAt(whitespace))) {
            whitespace++;
        }
        return pseudocode.length() == whitespace ? "" : pseudocode.substring(whitespace);
    }

    private static boolean isWhiteSpace(char charAt) {
        return Character.isWhitespace(charAt);
    }
}
0 голосов
/ 05 июля 2018

если вы не можете сделать это с массивами или регулярными выражениями, вам придется использовать операторы if.

Вы можете сделать что-то вроде

$document = (openfile c:\test\document)
$indentVariable = 0
foreach $line in $document; do
    if $line starts with "if" OR "end if" OR "while" OR "end while";
        if $line starts with "if"
            $indentVariable = $indentVariable + 1
            indent $line $indentVariable tabs
            $indentVariable = $indentVariable + 1
        elseif $line starts with "end if"
            $indentVariable = $indentVariable - 2
            indent $line $indentVariable tabs
        elseif $line starts with "while"
            $indentVariable = $indentVariable + 1
            indent $line $indentVariable tabs
            $indentVariable = $indentVariable + 1
        elseif $line starts with "end while"
            indentVariable = $indentVariable - 2
            indent $line $indentVariable tabs
        end if
    else
        indent $line $indentVariable tabs
    end if
end foreach

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

Этот ответ основан на "псевдокоде", а не на java.

также вы можете минимизировать это как первый оператор if. используя ненастоящий "массив" в проверке if что-то вроде

$document = (openfile c:\test\document)
$indentVariable = 0
foreach $line in $document; do
    if $line starts with "if" OR "while"
        $indentVariable = $indentVariable + 1
        indent $line $indentVariable tabs
        $indentVariable = $indentVariable + 1
    elseif $line starts with "end if" OR "end while"
        $indentVariable = $indentVariable - 2
        indent $line $indentVariable tabs
    else
        indent $line $indentVariable tabs
    end if
end foreach
0 голосов
/ 28 июня 2018

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

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

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

Вам также необходимо реализовать запись вывода в файл.

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class Main {

    public static void main(String[] args) {

        final String IN_FILE = "test.txt";
        final String OUT_FILE = "sample/indent/result.txt";
        final int INDENT_SPACES = 4;    // Number of spaces to indent

        StringBuilder output = new StringBuilder();
        int currentIndentLevel = 0;

        // Increase indent level on these keywords
        String[] keywordsIn = {"start", "if", "do"};

        // Decrease indent level on these keywords
        String[] keywordsOut = {"while", "end"};

        // Read the file, line by line
        try {
            BufferedReader reader = new BufferedReader(new FileReader(IN_FILE));

            String line = reader.readLine();

            while (line != null) {

                // Indent the line based on current level
                for (int i = 0; i < INDENT_SPACES * currentIndentLevel; i++) {
                    output.append(" ");
                }
                output.append(line).append("\n");

                // Check if it contains a keyword
                for (int i = 0; i < keywordsIn.length; i++) {
                    // Line begins with a keyword to increase the indent
                    if (line.matches(keywordsIn[i] + "\\b.*")) {
                        currentIndentLevel += 1; // Increase the indent level
                    }
                }
                for (int i = 0; i < keywordsOut.length; i++) {
                    // Line begins with a keyword to decrease the indent
                    if (line.matches(keywordsOut[i] + "\\b.*")) {
                        currentIndentLevel -= 1; // Decrease the indent level
                    }
                }


                // Get next line
                line = reader.readLine();

            }

        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println(output.toString());
    }
}

Принимая ваш исходный входной файл, вот что выводит эта программа:

start
    write "enter your name
    read name
    write "enter your age"
    read age
    if age==100 then
        do
            print "you stink"
            while age !=100
        end if
    while something
if something
    do something
        while something
    end if
end
...