質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

Q&A

1回答

1100閲覧

文字列の挿入の複数回実行

tosakasimon

総合スコア8

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

0グッド

0クリップ

投稿2019/11/13 05:36

javaによるpascal風言語の字句解析

pascal風言語のソースコードをmark[]文字列や数字、’’で囲まれた文字列や定義された文字列ごとに分けて[本文の単語 分類 分類ID 行]ごとに出力するようなプログラムを作成しています。行に於いて、単語に区切る際に前後に空白文字を挿入してから、split関数で分割していくという方式をとっているのですが、",""-""+"などの一行の中に複数回出てくる可能性のある文字列に対して繰り返しを用いようとしているのですが、メモリーエラーなどが起きてしまいます。

Lexer.java

java

1package enshud.s1.lexer; 2 3import java.io.IOException; 4import java.io.BufferedReader; 5import java.io.BufferedWriter; 6import java.io.File; 7import java.io.FileReader; 8import java.io.FileWriter; 9import java.nio.file.Files; 10import java.nio.file.Paths; 11import java.util.List; 12import java.util.ArrayList; 13import java.util.Arrays; 14import java.util.Collection; 15import java.text.MessageFormat; 16import java.util.HashMap; 17import java.util.Map.Entry; 18class data{ 19 String[] word; 20 String[] sword; 21 String[] tline; 22 int lineNumber; 23 boolean[] flag; 24 int[] ID; 25} 26public class Lexer { 27 28 /** 29 * サンプルmainメソッド. 30 * 単体テストの対象ではないので自由に改変しても良い. 31 */ 32 public static void main(final String[] args) { 33 // normalの確認 34 new Lexer().run("data/pas/normal01.pas", "tmp/out1.ts"); 35 new Lexer().run("data/pas/normal02.pas", "tmp/out2.ts"); 36 new Lexer().run("data/pas/normal03.pas", "tmp/out3.ts"); 37 } 38 public void run(final String inputFileName, final String outputFileName) { 39 String mark[]= {"and","array","begin","boolean","char","div", 40 "do","else","end","false","if","integer","mod","not", 41 "of","or","procedure","program","readln","then","true","var", 42 "while","writeln","=","<>","<","<=",">=",">","+","-","*","(",")","[", 43 "]",";",":","..",":=",",",".","/" 44 }; 45 String smark[]= { 46 "SAND","SARRAY","SBEGIN","SBOOLEAN","SCHAR","SDIVD","SDO", 47 "SELSE","SEND","SFALSE","SIF","SINTEGER","SMOD","SNOT", 48 "SOF","SOR","SPROCEDURE","SPROGRAM","SREADLN","STHEN","STRUE","SVAR", 49 "SWHILE","SWRITELN","SEQUAL","SNOTEQUAL","SLESS","SLESSEQUAL", 50 "SGREATEQUAL","SGREAT","SPLUS","SMINUS","SSTAR","SLPAREN","SRPAREN", 51 "SLBRACKET","SRBRACKET","SSEMICOLON","SCOLON","SRANGE","SASSIGN", 52 "SCOMMA","SDOT","SDIV" 53 }; 54 int LineNum=0; 55 String sstr="'"; 56 int qoat; 57 int lsqoat,ssqoat; 58 // TODO 59 60 try { 61 final List<String> buffer=Files.readAllLines(Paths.get(inputFileName)); 62 LineNum=buffer.size(); 63 String[] stringArr = buffer.toArray(new String[0]); 64 data[] arr_data=new data[LineNum]; 65 for(int i=0;i<LineNum;i++) { 66 arr_data[i]=new data(); 67 68 } 69 for(int i=0;i<LineNum;i++) { 70 71 72 arr_data[i].lineNumber=i+1 ; 73 ssqoat=stringArr[i].indexOf(sstr); 74 lsqoat=stringArr[i].lastIndexOf(sstr); 75 76 for(int j=0;j<44;j++) { 77 int mpoint=stringArr[i].indexOf(mark[j]); 78 if((mpoint!=-1&&(ssqoat==-1&&lsqoat==-1))|| 79 (mpoint!=-1&&(ssqoat!=-1&&lsqoat!=-1)&&((mpoint<ssqoat)||(mpoint>lsqoat))) 80 ) { 81 int mlength=mark[j].length(); 82 int h=stringArr[i].indexOf(mark[j]); 83 int l=stringArr[i].length(); 84 StringBuilder sb = new StringBuilder(); 85 if(j==26||j==29||j==38){ 86 if(h<l-1) { 87 if(stringArr[i].charAt(h+1)==61) { 88 sb.append(stringArr[i]); 89 sb.insert(sb.indexOf(mark[j])," "); 90 sb.insert(sb.indexOf(mark[j])+mlength+1," "); 91 stringArr[i]=new String(sb); 92 }else { 93 sb.append(stringArr[i]); 94 sb.insert(sb.indexOf(mark[j])," "); 95 sb.insert(sb.indexOf(mark[j])+mlength," "); 96 stringArr[i]=new String(sb); 97 } 98 }else { 99 sb.append(stringArr[i]); 100 sb.insert(sb.indexOf(mark[j])," "); 101 stringArr[i]=new String(sb); 102 } 103 }else if(j==24){ 104 if(stringArr[i].charAt(h-1)==58|| 105 stringArr[i].charAt(h-1)==60|| 106 stringArr[i].charAt(h-1)==62) { 107 sb.append(stringArr[i]); 108 sb.insert(sb.indexOf(mark[j])-1," "); 109 sb.insert(sb.indexOf(mark[j])+mlength," "); 110 stringArr[i]=new String(sb); 111 }else { 112 sb.append(stringArr[i]); 113 sb.insert(sb.indexOf(mark[j])," "); 114 sb.insert(sb.indexOf(mark[j])+mlength," "); 115 stringArr[i]=new String(sb); 116 } 117 }else if(j==42) { 118 if(h<l-1) { 119 if(stringArr[i].charAt(h+1)==46) { 120 sb.append(stringArr[i]); 121 sb.insert(sb.indexOf(mark[j])," "); 122 sb.insert(sb.indexOf(mark[j])+mlength+1," "); 123 stringArr[i]=new String(sb); 124 } 125 }else { 126 sb.append(stringArr[i]); 127 sb.insert(sb.indexOf(mark[j])," "); 128 stringArr[i]=new String(sb); 129 } 130 }else{ 131 int result=0; 132 for(int m=0;m<stringArr[i].length();m++) { 133 if(stringArr[i].indexOf(mark[j],m)!=-1) { 134 result++;m=stringArr[i].indexOf(mark[j],m); 135 } 136 } 137 int space=0; 138 for(int m=0;m<result;m++) { 139 sb.append(stringArr[i]); 140 sb.insert(sb.indexOf(mark[j],space)," "); 141 sb.insert(sb.indexOf(mark[j],space)+mlength," "); 142 space=sb.indexOf(mark[j],space)+1; 143 stringArr[i]=new String(sb); 144 sb.toString(); 145 } 146 } 147 } 148 } 149 ssqoat=stringArr[i].indexOf(sstr); 150 lsqoat=stringArr[i].lastIndexOf(sstr); 151 if(ssqoat!=-1&&lsqoat!=-1) { 152 StringBuilder sb = new StringBuilder(); 153 sb.append(stringArr[i]); 154 sb.insert(ssqoat," "); 155 sb.insert(lsqoat+2," "); 156 stringArr[i]=new String(sb); 157 } 158 159 } 160 for(int i=0;i<LineNum;i++) { 161 arr_data[i].word=stringArr[i].split(" +"); 162 List<String> list = new ArrayList<String>(Arrays.asList(arr_data[i].word)); 163 list.remove(arr_data[i].word[0]); 164 String[] arr = (String[]) list.toArray(new String[list.size()]); 165 arr_data[i].word=arr; 166 int wlength=arr_data[i].word.length; 167 arr_data[i].ID=new int[wlength]; 168 arr_data[i].flag=new boolean[wlength]; 169 arr_data[i].sword=new String[wlength]; 170 arr_data[i].tline=new String[wlength]; 171 } 172 for(int i=0;i<LineNum;i++) { 173 174 int wlength=arr_data[i].word.length; 175 for(int k=0;k<wlength;k++) { 176 arr_data[i].flag[k]=true; 177 for(int j=0;j<44;j++) { 178 if(arr_data[i].word[k].equals(mark[j])) { 179 arr_data[i].flag[k]=false; 180 arr_data[i].ID[k]=j; 181 arr_data[i].sword[k]=smark[j]; 182 if(j==43)arr_data[i].ID[k]=5; 183 } 184 } 185 186 } 187 } 188 String tab="\t"; 189 for(int i=0;i<LineNum;i++) { 190 191 if(arr_data[i].word!=null) { 192 int wlength=arr_data[i].word.length; 193 for (int k=0;k<wlength;k++) { 194 if(arr_data[i].flag[k]==true) { 195 if(arr_data[i].word[k].charAt(0)>=48&&arr_data[i].word[k].charAt(0)<=57) { 196 arr_data[i].ID[k]=44; 197 arr_data[i].sword[k]="SCONSTANT"; 198 }else if(arr_data[i].word[k].charAt(0)==39) { 199 int Length; 200 Length=arr_data[i].word[k].length(); 201 //arr_data[i].word[k]=arr_data[i].word[k].substring(0,Length-1); 202 arr_data[i].sword[k]="SSTRING"; 203 arr_data[i].ID[k]=45; 204 }else { 205 arr_data[i].sword[k]="SIDENTIFIER"; 206 arr_data[i].ID[k]=43; 207 } 208 } 209 210 } 211 } 212 } 213 for(int i=0;i<LineNum;i++) { 214 215 int wlength=arr_data[i].word.length; 216 for (int k=0;k<wlength;k++) { 217 arr_data[i].tline[k]=""; 218 arr_data[i].tline[k] += arr_data[i].word[k]; 219 arr_data[i].tline[k]+=(tab); 220 arr_data[i].tline[k]+=(arr_data[i].sword[k]); 221 arr_data[i].tline[k]+=(tab); 222 String pstr=String.valueOf(arr_data[i].ID[k]); 223 arr_data[i].tline[k]+=(pstr); 224 arr_data[i].tline[k]+=(tab); 225 pstr=String.valueOf(arr_data[i].lineNumber); 226 arr_data[i].tline[k]+=(pstr); 227 228 229 } 230 } 231 try{ 232 File f=new File(outputFileName); 233 BufferedWriter bw = new BufferedWriter(new FileWriter(f)); 234 for(int i=0;i<LineNum;i++) { 235 int wlength=arr_data[i].word.length; 236 for(int k=0;k<wlength;k++) { 237 bw.write(arr_data[i].tline[k]); 238 if(i!=LineNum-1||k!=wlength-1) { 239 bw.newLine(); 240 } 241 } 242 } 243 bw.close(); 244 }catch(IOException e){ 245 System.err.println("File not found"); 246 } 247 System.out.println("OK"); 248 }catch(final IOException e){ 249 System.err.println("File not found"); 250 } 251 252 } 253}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

やろうとしていることが今ひとつわかりませんが、メモリに関して言うならとりあえず、

java

1 final List<String> buffer=Files.readAllLines(Paths.get(inputFileName)); 2 LineNum=buffer.size(); 3 String[] stringArr = buffer.toArray(new String[0]);

これ以降bufferという変数が登場しません。ファイルの文字列をListと配列で二重に持っており、無駄です。
そもそもこの処理は、ファイルの内容を全部文字列としてメモリに乗せることになりますから、ファイル自体が大きい場合はその対処を行ったとしてもメモリエラーになるかもしれません。Listで全部一気に取り出すのではなく、行ごとに処理したほうが賢明かと思います。

そもそもコードが非常に読みづらいです。ネストは深いし、マジックナンバーが多数登場するし、無駄な記述が多いし、変数名の意味が分かりにくいし、他多数のツッコミどころにより何をしたいのかが本当に読みづらいです。
とりあえずメソッド最初の変数宣言は全部消したいです。配列で定義されているものはLexerクラスのstatic定数にして、他の変数はスコープを狭くしたいので、最初から書いてみると

java

1 public void run(final String inputFileName, final String outputFileName) { 2 try { 3 // ファイル読み込み部分省略 4 for(int i=0;i<lineNum;i++) { //変数は小文字始まりのものにしたほうが良い 5 arr_data[i] = new Data(); //クラス名は大文字始まりで定義したほうが良い 6 arr_data[i].lineNumber = i + 1;; 7 //44というマジックナンバーは避け、mark配列の要素を回すということを明示化 8 for(int j = 0; j < mark.length; j++) { 9 int mPoint=stringArr[i].indexOf(mark[j]); 10 if (mPoint == -1) { 11 continue; //見つからないならさっさと次に行く 12 } 13 int lQuote = stringArr[i].indexOf("'"); 14 int rQuore = stringArr[i].lastIndexOf("'"); 15 //同じ文字を、indexOfで見つかって、lastIndexOfで見つからない、ということは絶対にない。 16 //そのため、両方が-1であるかどうか、などの判定は不要 17 if (lQuote != -1 && (lQuote <= mPoint && mPoint <= rQuote)) { 18 continue; //クォーテーションマークで囲われてたら次に行く 19 } 20 /* ここからは何をしたいのか本当に読み取れません。正直上の変更も正しいのか微妙です。 21       ifとかforとかがどこまでの括りなのかわからないので。 */ 22 } 23 } 24 } 25 }

投稿2019/11/13 06:52

編集2019/11/14 17:19
swordone

総合スコア20651

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問