ベストアンサー lexとyaccでのプログラミング 2005/12/16 16:39 lexとyaccを使って関数電卓を作っているのですが、どうしても2進数や8進数での計算のプログラミングができません。 あと分数計算も入れたいと思っているのですが、参考になるものがありましたら教えて下さい。 みんなの回答 (1) 専門家の回答 質問者が選んだベストアンサー ベストアンサー namacya ベストアンサー率8% (21/243) 2005/12/16 16:51 回答No.1 http://kmaebashi.com/programmer/devlang/yacclex.html 参考URL: http://kmaebashi.com/programmer/devlang/yacclex.html 通報する ありがとう 0 カテゴリ [技術者向] コンピュータープログラミング・開発その他(プログラミング・開発) 関連するQ&A yaccとlex macのターミナルでyaccのみのプログラムは実行できますが、yaccとlexのプログラムはコンパイルできても実行できません。xcodeもインストールしてあります。どうしてでしょうか? YaccとLex macのターミナルでYaccとLexのプログラムを実行しようと思っています。Yaccプログラム(ren.y)は bison -y ren.y の後 gcc y.tab.c -ly -o a.exe の後更に ./a.exe でしっかり実行できます。しかし、YaccとLexのプログラム(Yaccプログラムはren1.y、Lexプログラムはren2.l)において、bison -dv -y ren1.y の後、flex -l ren2.l までのコンパイルはできるのですが、gcc y.tab.c lex.yy.c -ly -lfl -lm -o a でコンパイルリンクしようとすると、 ld: library not found for -lfl clang: error: linker command failed with exit code 1 (use -v to see invocation) と表示されエラーが生じてしまいます。 macにはXcodeもインストールしてあります。 どうしてy.tab.cとlex.yy.cのコンパイルリンクと実行プログラムaの作成に失敗するのでしょうか? Lex,Yaccについて。 最近LexとYaccの勉強を始めたのですが、 本を買うと高いので、インターネット上でわかりやすく 解説されてるHPなどを知っている方がいたら教えてほしいです。検索エンジンで探してみたものの、なかなかわかりやすいサイトが見つからないので。。。 yacc&lexの実行の仕方がよくわかりません。 いま、yaccとlexのプログラムを作ってみたんですが、実行方法がわかりません。yacc hogehoge.yとcygwinで打っても「コマンド ノット ファウンド」って表示されます。 初歩的な質問で申し訳ありませんが、回答よろしくお願いします。 yacc,lexで作ったプログラムが正しく動きません。 加減乗除ができ、平方根や常用対数を計算でき、PIが円周率3.14159265に変換される、負の数、浮動小数点数を扱える電卓のインタプリタ(数式を入力すると計算結果を表示して終了するプログラム)をyacc構文解析とlex字句解析を用いて以下のようにしました。 yacc %{ #include<stdio.h> #include<math.h> int yyerror(char* s); %} %union{ double num; } %type<num> E T F %token<num> NUM SQRT LOG10 PI %% program: E {printf("%lf\n", $1); } E : E'+'T {$$=$1+$3; } |E'-'T {$$=$1-$3; } |T {$$=$1; } ; T : T'*'F {$$=$1*$3; } |T'/'F {$$=$1/$3; } |F {$$=$1; } ; F : '('E')' {$$=$2; } |SQRT'('E')' {$$=sqrt($3); } |LOG10'('E')' {$$=log10($3); } |PI {$$=3.14159265; } |NUM {$$=$1; } |'-'F {$$=$2*(-1); } ; %% main(){ yyparse(); } yyerror(char* s){ fprintf(stderr, "%s\n", s); } lex %{ #include "j5_13y.h" %} D 0|1|2|3|4|5|6|7|8|9 DEZ 1|2|3|4|5|6|7|8|9 %% "+" {return *yytext; } "-" {return *yytext; } "*" {return *yytext; } "/" {return *yytext; } "(" {return *yytext; } ")" {return *yytext; } "sqrt" {return SQRT; } "log10" {return LOG10; } "PI" {return PI; } ({DEZ}{D}*|0)|({DEZ}{D}*|0).{D}* {yylval.num=atof(yytext); return NUM; } . {yyerror("invalid character"); exit(1); } %% int yywrap(){return 1; } コンパイルは通り、実行時エラーも出ません。 しかし、数式を入力してエンターキーを押すと、何も表示せず入力待ち状態が続き、ここでの入力は前の入力に連結されて処理されます。 (例)入力1.0+2.0(Enter) ↓ 改行して入力待ち状態 ↓ 入力-log10(100.0)(Enter) ↓ 改行して入力待ち ↓ 入力+sqrt(4.0)(Enter) ↓ 改行して入力待ち ↓ 入力-2.0*PI(Enter) ↓ 改行して入力待ち ↓ 入力2.0-1.0 ↓ syntax error表示し終了 上記コードのどこが悪いのでしょうか。よろしくお願いします。 yaccのコンパイル法 Bisonを実行して出力されたPekePeke_Tab.c をコンパイル(ボーランドを使用)すると、_yyerrorが未解決です のコメントが出てうまく行きません。 コマンドは bcc32 PekePeke_Tab.c libmain.obj です。 ライブラリの不足でしょうか? ちなみに Flex のコンパイルはうまく行きました。 bcc32 lex.yy.c libmain.obj libwrap.obj でOKでした。 yacc関連の書物やWEBなどは、yacc lex 本体の説明だけで、コンパイルの説明が皆無なので困っています。 lex、yaccファイルのコンパイラができません。このような警告がでます。足りないライブラリはなんでしょうか。 lexとyaccを復習しているのですがこのサイトhttp://cis.k.hosei.ac.jp/~nakata/lectureCompiler/YaccLex/6.2.htmlの説明にあるサンプルを実行しようとしているのですがうまくいきません。 以下の作業で何が問題だと考えられるでしょうか。 sample.y sample.l のふたつのファイルを http://cis.k.hosei.ac.jp/~nakata/lectureCompiler/YaccLex/6.htmlのような手順でコンパイルしようとした結果 こうなってしまいます。 ----------------------実行結果-------------------------- ken@ubuntu-vm:~/ken/1$ yacc -d sample.y ken@ubuntu-vm:~/ken/1$ lex sample.l ken@ubuntu-vm:~/ken/1$ cc y.tab.c -ly -ll -o executablesample.y: In function ‘yyparse’: sample.y:8: 警告: incompatible implicit declaration of built-in function ‘printf’ ken@ubuntu-vm:~/ken/1$ -------------------------------------------------------- ------------------sample.yの内容---------------------- %token NL %token NUMBER %left ADDOP %% list: /* Empty */ | list expression NL {printf("%d\n",$2);} ; expression: expression ADDOP expression {$$=$1+$3;} | NUMBER {$$=$1;} ; %% #include "lex.yy.c" #include <stdio.h> /*追加してみましたが変わりませんでした。"stdio.h"にしてもダメでした*/ ----------------------------------------------------- -------------------sample.lの内容---------------------- %{ #include "y.tab.h" #include <stdio.h> /*追加してみましたが変わりませんでした"stdio.h"にしてもダメでした */ %} %% "+" return(ADDOP); [0-9]+ {sscanf(yytext,"%d",&yylval); return(NUMBER);} [ \t] ; \n|\r|\r\n return(NL); . return(yytext[0]); %% -------------------------------------------------------- #include が入ってないせいだと思い、上記のように追加してみたのですが見当違いなことをしているように思えます。ちなみにCでprintfを使うと普通にコンパイルできます。 必要なライブラリが入ってないのだとしたら何かわからず困っています。 最近VMwareでUbuntuは始めたばかりです。 パッケージは build-essentials yum liby-dev bison などをインストールしました。 何が足りないでしょうか。。すいません、お願いします。 yaccとlexで、logや三角関数を含む電卓を作るプログラムの組み方 今、yaccとlexで、logや三角関数を含む電卓を作るプログラムを作成しています。四則演算は実装できました。パイも実装できました。しかしlogや三角関数sin,cos,tanやabs,expなどがどうしても実装できません。以下のプログラムをlinux上のターミナルで実行しsin(90)やlog(90)どと入力しても、sintax errorと返されてしまいます。ちなみに実行時は-lmオプションは付けています。どうしたらこれらが実装できるのでしょうか。ご教授願えると幸いです。 ■yaccの.yファイル■ %{ #define YYSTYPE double #define PAICONST 3.14159265358979 #include <stdio.h> #include <math.h> double mcon=PAICONST/180.0; %} %token NL NUM LP RP END %left ADD SUB %left MUL DIV %left Pai Abs Sqrt Sin Cos Tan Log Exp NEG %% s : list ; list : /* empty */ | list expr NL { printf ("result: %lf\n", $2);} | list END { return;} ; expr : expr ADD expr {$$ = $1 + $3;} | expr SUB expr {$$ = $1 - $3;} | expr MUL expr {$$ = $1 * $3;} | expr DIV expr {$$ = $1 / $3;} | SUB expr %prec NEG {$$ = -$2;} | LP expr RP {$$ = $2;} | NUM {$$ = $1;} | Pai {$$=PAICONST;} | Abs "(" expr ")" {$$=abs($3);} | Sqrt "(" expr ")" {$$=sqrt($3);} | Sin "(" expr ")" {$$=sin($3*mcon);} | Cos "(" expr ")" {$$=cos($3*mcon);} | Tan "(" expr ")" {$$=tan($3*mcon);} | Log "(" expr ")" {$$=log($3);} | Exp "(" expr ")" {$$=exp($3);} ; %% yyerror(s) char *s; { printf ("%s\n",s);} main() { yyparse(); } #include "lex.yy.c" ■lexの.lファイル■ %{ #include <math.h> #include <ctype.h> %} %% "+" return (ADD); "-" return (SUB); "*" return (MUL); "/" return (DIV); "(" return (LP); ")" return (RP); "." return (END); (pai|PAI) return(Pai); (abs|ABS) return(Abs); (sqrt|SQRT) return(Sqrt); (sin|SIN) return(Sin); (cos|COS) return(Cos); (tan|TAN) return(Tan); (log|LOG) return(Log); (exp|EXP) return(Exp); [0-9]+\.[0-9]*|[0-9]+ { sscanf (yytext, "%lf", &yylval); return (NUM); } [ \t] ; ^\n return (END); \n return (NL); . return (yytext[0]); %% Pythonのプログラミングです。 【Pythonのプログラミング】 TkinterでGUIを組んでいるのですが、mathモジュールには、階乗計算がないようです。 式入力型電卓を作っているのですが、「3!」とうち込むと、「6」が出るようなものは、どのようにして作るのでしょうか? ちなみに、 http://www.geocities.jp/m_hiroi/light/pytk02.html を参考に作っています。 HTML構文解析 はじめまして。 早速ですが、HTMLの構文解析ルーチンを作成しようと考えております。構文解析といえば、lex/yaccというのがあると思うのですが、HTMLを解析する場合、lex/yaccの特性を生かして作成することができるのでしょうか?それとも、自分でゴリゴリ作ったほうがよいのでしょうか。皆さんの意見をお聞かせいただければと思います。 lex,yaccについて いま授業で使おうとしているのですが、windows上でこれらのソフト(機能?)を使うことはできるのでしょうか? VC++にはできるような記述がネット上であったのですが、コマンドプロンプト上で(Borland 無償版)使用したいと思います。 標準でできる物なのでしょうか? ご存じの方は教えて下さい。 よろしくお願いします。 windowsとlinuxでのlexの実行結果の差 プログラミング初心者です。 lexでプログラムを作成しています。 centOSでlexのプログラムを作製し、コンパイルして実行したら、全て理想通りに動作しました。 Makefileと実行結果を以下に示します。 **Makefile** CC = cc y.tab.c lex.yy.c YACC = yacc -d LEX = lex all : parser y.tab.c y.tab.h : parser.y $(YACC) parser.y lex.yy.c : scanner.l $(LEX) scanner.l parser : y.tab.c lex.yy.c $(CC) -lfl -o parser clean : rm y.tab.c rm y.tab.h rm lex.yy.c rm parser **実行結果** program is inputted. ***initial call*** PL0A var is inputted. n ***insert call*** =name= =address= =kind= n 10 global sum ***insert call*** =name= =address= =kind= n 10 global sum 10 global ***lookup call*** ==look== =name= =kind= n n global ***lookup call*** ==look== =name= =kind= sum sum global ***lookup call*** ==look== =name= =kind= n n global ***lookup call*** ==look== =name= =kind= sum sum global ***lookup call*** ==look== =name= =kind= n n global ***lookup call*** ==look== =name= =kind= sum sum global ***lookup call*** ==look== =name= =kind= n n global ***lookup call*** ==look== =name= =kind= n n global このプログラムを、windows7のcygwin(フルインストール)下で、コンパイルして実行しました。 Makefileの中身は変更していません。 **実行結果** $ ./parser pl0a.p program is inputted. ***initial call*** PL0A var is inputted. n ***insert call*** n 10 global sum ***insert call*** sum 10 global ***lookup call*** ==look== sum global Error n sum global ***lookup call*** ==look== sum global Error sum sum global ***lookup call*** ==look== sum global Error n sum global ***lookup call*** ==look== sum global Error sum sum global ***lookup call*** ==look== sum global Error n sum global ***lookup call*** ==look== sum global Error sum sum global ***lookup call*** ==look== sum global Error n sum global ***lookup call*** ==look== sum global Error n sum global 全然違う結果になってしまいました。lexをflexに、ccをgccに修正などしても変化はありませんでした。 同じように出力するにはどうすれば良いのでしょうか? 台形則のプログラミング http://www.sist.ac.jp/~suganuma/cpp/2-bu/7-sho/C++/daikei.txt このサイトのプログラミングを参考にして、いろいろいじっているのですが、分割数、積分範囲の指定、積分する関数の変更 がよくわかりません。 具体的には、 分割数、範囲は改めて数を宣言するのか?それともこのプログラミングにある、x1、x2などにそのまま代入するのか? 関数は真ん中にあるreturn ~の部分だけ変更すればいいのか? ということがわかりません。 回答、アドバイス等ありましたらお願いします! 少数などのまたは整数をルート表示にするには 関数電卓でルート計算をして応えが少数ででました。 これをルート表記または分数での表記にするにはどうしたらよろしいでしょうか? 関数電卓が欲しい 仕事柄、16進数の計算・10進数への変換等をする必要があります。 普段はWindowsのアクセサリの関数電卓で計算しています(これがまた便利なようで不便で)。 PC上の電卓ではなく普通の簡単に持ち運べる電卓があればいいなと思います。 16進数の計算(+,/,*,-,XOR,AND,OR程度が計算できるとありがたい)及び10進数及び2進数への変換ができる機能を持った電卓ってご存じないでしょうか? 市販の関数電卓は上記機能を有しているのでしょうか? できれば数千円ぐらいで購入したいです。 教えてください。 関数電卓のlogについて 関数電卓のlogで10を底とした対数を計算できるのは知っているんですが、 2や3など他の数を底とした対数を関数電卓では計算できないのでしょうか? もしできるのなら、是非知りたいです。 C言語プログラミングについて質問です 2つの実数のそれぞれの平方根を計算した後にその差を計算し、それを二乗した結果を表示するプログラミングを作り、そしてその関数reverseがmain関数のなかで正しく昨日するか確かめるプログラミングを作る 上のプログラムを教えてください プログラミング関係で プログラミングで次の問題をどうすればいいのかわかりません。 教えてください 1.配列に次のデータが格納されており、 2,-8,5,-4,6,5,7,-3,-9,-1 奇数、偶数、負の数がそれぞれいくつあるかを数え、表示するプログラムを作成してください。 2.任意の整数Xを入力し、Xの階乗の結果を表示するプログラムを作成しなさい。ただし、Xの階乗の計算は別関数で行い、入力と結果の表示はmain関数で行うようにすること。 建築関係の就職試験での関数電卓 建築関係の就職試験で関数電卓(ただし、プログラミングでの計算機能のないもの)を 持ってくるように言われました。 記述式の問題が出るそうです。 関数電卓ということは、sin,cos,tanをつかったり、ルートを使ったりすると思われますが、 具体的にはどのような問題が出るのでしょうか? 正規表現・lexによる字句解析器 lexソースの中に次のようなコードが出てるんですが、左側の正規表現の意味がわからなくて困っています。文字列の解釈のコードだと思います。 \はバックスラッシュだと思ってください。 \"[^"]*\" { yytext[yyleng - 1] = '\0'; yylval.str = strdup(&yytext[ 1]); return(STRING); } (yaccのソースの中に&token <str> STRINGという記述が入っている) 文字列はダブルクォーテーション「"」で囲み、間に改行が入っても構わないそうです。 yytextは次の入力を処理するときに破壊されるので、ヒープ上に確保した領域に文字列を格納し、そのアドレスをyylval.strに渡す。初めと終わりの「"」は取り除く・・ のだそうです。おそらくstrdupの説明だと思うのですが、C言語のマニュアルには載ってなかったですね・・・。