如何在不使用数组或任何正则表达式的情况下缩进包含特殊关键字的文本文件中的文本

时间:2018-06-28 01:12:10

标签: java indentation pseudocode

每当当前行包含一些特定关键字时,我的程序就必须缩进文本文件中的文本,而不能使用数组或任何正则表达式。

例如

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

我无法让我的程序正确缩进第一个“关键字”之后的内容。关键字是“何时,是否,执行,如果,结束,结束,开始等...”

我不允许使用数组或任何正则表达式

我的读取文本文件的代码的一部分:

    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块,但是如果该do块内有另一个关键字,则不会获得新的缩进级别。

那是为什么?

我尝试了许多方法来将缩进级别保存为变量,但没有成功。

3 个答案:

答案 0 :(得分:2)

  

此解决方案同时使用数组和正则表达式-我将在此处发布,以供将来可能没有此限制的编码人员使用。

这是我刚刚整理的一个快速样本。它使您可以设置要缩进的单词数组,以及哪些单词应触发缩进。

还有一些改进的余地,因为它无法满足您可能需要的所有情况。

您还需要实现将输出写入文件。

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

答案 1 :(得分:0)

所以这是答案的一个重要部分,我不明白为什么noot使用array和regex,但为什么不使用

这是您需要实现的一种代码,但是您的语言描述非常糟糕,不是LL(1),因此如果... ...您遇到的问题是处理一端与另一端之间的差异。可能没有while分隔符,而while结束对您有帮助吗?

这种实现非常繁琐, 我显然不推荐这种事情 !但是挑战很有趣^^

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);
    }
}

答案 2 :(得分:0)

如果无法使用数组或正则表达式,则必须使用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