#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define BUFFERSIZE 1024
char Buffer[BUFFERSIZE];
int Index;
int ParseError;
int getE(void);
void parseError(FILE *out, char msg[]) {
ParseError = 1;
fprintf(out, "%s\n", msg);
fprintf(out, "%s\n", Buffer);
for (int i = 0; i < Index; i++) fprintf(out, " ");
fprintf(out, "^\n");
}
void removeWhite(void) {
int j = 0, c;
for (int i = 0; (c = Buffer[i]) != '\0'; i++) {
if (c == ' ' || c == '\t' || c == '\n') continue;
Buffer[j++] = c;
}
Buffer[j] = '\0';
}
int getD(void) {
int value = 0;
while (isdigit(Buffer[Index])) {
value = 10*value + Buffer[Index] - '0';
Index++;
}
return value;
}
int getF(void) {
int value;
if (isdigit(Buffer[Index])) { // 数値表現
value = getD(); if (ParseError) return 0;
} else if (Buffer[Index] == '(') { // ( E )
++Index;
value = getE(); if (ParseError) return 0;
if (Buffer[Index] == ')') {
++Index;
} else {
parseError(stderr, "閉じ括弧')'がありません."); return 0;
}
} else {
parseError(stderr, "数字または開き括弧'('がありません."); return 0;
}
return value;
}
int getT(void) {
int v, value;
value = getF(); if (ParseError) return 0;
while (Buffer[Index] == '*' || Buffer[Index] == '/') {
char op = Buffer[Index++];
v = getF(); if (ParseError) return 0;
if (op == '*') value *= v; else value /= v;
}
return value;
}
int getE(void) {
int v, value;
if (Buffer[Index] == '-') {
++Index;
v = getT(); if (ParseError) return 0;
value = -v;
} else {
value = getT(); if (ParseError) return 0;
}
while (Buffer[Index] == '+' || Buffer[Index] == '-') {
char op = Buffer[Index++];
v = getT(); if (ParseError) return 0;
if (op == '+') value += v; else value -= v;
}
return value;
}
int getExpression(void) {
int value;
value = getE(); if (ParseError) return 0;
if (Buffer[Index] != '\0') {
parseError(stderr, "余分な表現があります.");
}
return value;
}
int mygets(char *s, int n) {
fgets(s, n, stdin);
int lg = strlen(s);
if (lg > 0 && s[lg-1] == '\n') s[--lg] = '\0';
return lg;
}
int main(void) {
int value;
while (1) {
ParseError = 0;
fprintf(stderr, "\n算術式:=");
if (mygets(Buffer, BUFFERSIZE) <= 0) break;
removeWhite();
Index = 0;
value = getExpression();
if (ParseError) {
fprintf(stderr, "正しくない算術式です.\n");
} else {
fprintf(stderr, "正しい算術式です. 値は%dです.\n", value);
}
}
return 0;
}
この構文解析プログラムを実行すると
邂苓。灘シ・=(1+2+3)*3
豁」縺励>邂苓。灘シ上〒縺・ 蛟、縺ッ18縺ァ縺・
のように文字化けしてしまうのですがなぜでしょうか?
A 回答 (2件)
- 最新から表示
- 回答順に表示
No.2
- 回答日時:
[1] (0) → 0
[2] (1) → 1
[3] ¬0 → 1
[4] ¬1 → 0
[5] 0∧0 → 0
[6] 0∧1 → 0
[7] 1∧0 → 0
[8] 1∧1 → 1
[9] 0∨0 → 0
[10] 0∨1 → 1
[11] 1∨0 → 1
[12] 1∨1 → 1
という書き換えを一度に一つだけ、[1]〜[12]の順番で適用する。(つまり[1]が適用できない場合にのみ[2]をチェックするという風にして、以下同様。)この書き換えを繰り返すと、書き換えるたびに文の長さは減少し、(文が文法に従っていれば)長さ1の文、つまり0か1になって終わる。
要するに「→の左と一致する部分文字列を見つけて、その部分を→の右の文字列に差し替える」というだけだから、書き換え規則を(if文なんか使わずに)表(配列)にしておけば、ごく短く簡明に書ける。
しかし、形式文法理論を学ぶ一環としての演習問題なら:この文脈自由文法に従う文を左から順に1文字ずつ処理して受理するpush down automatonを構成する(値の評価はツイデにできちゃう)ために、まずは文法を、例えばGreibach標準形(どの規則も
P → xQ (x∈Σ)
という格好になってる形)で表しておく。
No.1
- 回答日時:
文字コードを変更。
VSCode右「UTF-8」「エンコード付きで保存」「Shift-JIS」
(parseErroは?)
ありがとうございます。それにしたら解決できました。
ちなみになんですが、
Σ ={0, 1, (, ), ⋀, ⋁,¬}とする.
以下の生成規則をもつ拡張文脈自由文法により
開始記号 E から導出される Σ 上の記号列を論理式とよぶ.
論理式の定義
B → 0 | 1
F → {¬} B | {¬}(E)
T → F { ⋀ F }
E → T { ⋁ T
この定義において、論理式の値の評価を行うプログラムを作りたいのですが上のプログラムをどう改良すればいいでしょうか?
記号「⋀」「⋁」「¬」は,それぞれ,「&」「+」「!」で代用したいです。
もしよければ返信お願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# プログラムの時、フローチャートはどうなりますか?図でお願いします。 int main(void) { 1 2022/10/01 22:45
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- C言語・C++・C# プログラミングのペーパーテスト 実行結果を表示せよ #include <stdio.h> int h 1 2022/07/09 15:27
- PHP imageフォルダに、画像をリサイズして保存する時のファイル名を変更したい 1 2023/05/30 11:39
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# C言語で再起関数とポインタを用いて文字列反転をする方法がわかりません。 4 2023/04/29 20:32
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・「みんな教えて! 選手権!!」開催のお知らせ
- ・漫画をレンタルでお得に読める!
- ・【選手権お題その2】この漫画の2コマ目を考えてください
- ・2024年に成し遂げたこと
- ・3分あったら何をしますか?
- ・何歳が一番楽しかった?
- ・治せない「クセ」を教えてください
- ・【大喜利】看板の文字を埋めてください
- ・【大喜利】【投稿~12/17】 ありそうだけど絶対に無いことわざ
- ・【選手権お題その1】これってもしかして自分だけかもしれないな…と思うあるあるを教えてください
- ・【穴埋めお題】恐竜の新説
- ・我がまちの「給食」自慢を聞かせてっ!
- ・冬の健康法を教えて!
- ・一番好きな「クリスマスソング」は?
- ・集合写真、どこに映る?
- ・自分の通っていた小学校のあるある
- ・フォントについて教えてください!
- ・これが怖いの自分だけ?というものありますか?
- ・スマホに会話を聞かれているな!?と思ったことありますか?
- ・それもChatGPT!?と驚いた使用方法を教えてください
- ・見学に行くとしたら【天国】と【地獄】どっち?
- ・これまでで一番「情けなかったとき」はいつですか?
- ・この人頭いいなと思ったエピソード
- ・あなたの「必」の書き順を教えてください
- ・10代と話して驚いたこと
- ・14歳の自分に衝撃の事実を告げてください
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
シェルピンスキーのギャスケット
-
C言語 エラーの原因がわからな...
-
【C++】関数ポインタの使い方
-
acceptをalarmでタイムアウトさ...
-
因数分解を行うプログラムについて
-
(マルチスレッド)_beginthrea...
-
std::set<int> で、ある値が何...
-
C言語での引数の省略方法
-
異なる文字列のマッチングを、D...
-
構造体のメンバ変数が途中で変...
-
ファイルから読みこむ方法
-
毎回違う乱数を生成するにはど...
-
「指定されたキャストは有効で...
-
ヒープ木の格納 【プログラミ...
-
C言語 巡回セールスマン問題 2-...
-
プログラミング
-
ColorをRGBで指定する方法
-
フィボナッチ数列のプログラム
-
商と剰余を同時に求める(C言語)
-
C言語でif文が予想と違う動きを...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「指定されたキャストは有効で...
-
C言語での引数の省略方法
-
複数桁10進数の*桁目だけを抽出...
-
C言語 エラーの原因がわからな...
-
#define _CRT_SECURE_NO_WARNIN...
-
ラップ関数とはどんなものですか?
-
【C++】関数ポインタの使い方
-
if と配列の組み合わせ
-
(int *)の意味
-
実数の整数部,小数部の取得
-
acceptをalarmでタイムアウトさ...
-
C言語
-
std::set<int> で、ある値が何...
-
因数分解を行うプログラムについて
-
数字列を3桁ごとにカンマで区切...
-
(マルチスレッド)_beginthrea...
-
比較回数と交換回数表示について
-
式は定数値が必要です」という...
-
int型の変数値をバイト列として...
-
c言語の配列を使ってサイコロを...
おすすめ情報