質問
私形成のための試みが行われているLisp文法を学びます。す。そうです。
私は現在これらの入力を受ける誤りの...
( 1 1)
23 23 23
ui ui
この文法...
%%
sexpr: atom {printf("matched sexpr\n");}
| list
;
list: '(' members ')' {printf("matched list\n");}
| '('')' {printf("matched empty list\n");}
;
members: sexpr {printf("members 1\n");}
| sexpr members {printf("members 2\n");}
;
atom: ID {printf("ID\n");}
| NUM {printf("NUM\n");}
| STR {printf("STR\n");}
;
%%
ときといながらプレーする必要がありま一つの単一端として定義されてプログラムでできており、全体の構文木(parse tree)が掛かります。はかるととされているようには思えない。
編集-この"トップターミナル"アプローチ:
program: slist;
slist: slist sexpr | sexpr;
することができなどの問題:
( 1 1
Edit2:フレックスコードが---
%{
#include <stdio.h>
#include "a.yacc.tab.h"
int linenumber;
extern int yylval;
%}
%%
\n { linenumber++; }
[0-9]+ { yylval = atoi(yytext); return NUM; }
\"[^\"\n]*\" { return STR; }
[a-zA-Z][a-zA-Z0-9]* { return ID; }
.
%%
たとえば、マッチング...
(1 1 1)
NUM
matched sexpr
NUM
matched sexpr
NUM
matched sexpr
(1 1
NUM
matched sexpr
NUM
matched sexpr
何のエラー。
編集:のエラーはレクサー.
解決
エラーはレクサーに実際にあります。あなたの括弧は最後として終わります「」レクサーで、パーサの括弧として表示されません。
タグのようなルールを追加します。
\) { return RPAREN; }
\( { return LPAREN; }
字句解析および構文解析器でそれぞれLPARENとRPARENに「(」「)」のすべての発生を変更します。 (また、あなたがあなたのトークンリストを定義LPARENとRPARENを#defineしする必要があります)。
注:私は、バックスラッシュが間違っている可能性があり、構文についてはよく分からない。
。他のヒント
Lispの文法は文脈自由文法で表現できない、およびyaccは、すべてのLispコードを解析できません。 これは、理由は、このようなリード評価およびプログラマブル・リーダーなどのlispの機能です。だから、任意のLispコードを読み込むだけのために、あなたは完全なLispの実行を持っている必要があります。これは、いくつかのあいまいな、未使用の機能ではありませんが、それは実際に使用されます。例えば、CL-インターポール、CL-SQLます。
目標は舌足らずのサブセットを解析する場合には、その後、プログラムのテキストはsexprsのシーケンスです。
しかしその定義する必要があり非端子です。この集合として定義されsexpr.くなったのYACC文法です。私は一部を AOETOOLS のためのパーサーや発電機の構文することはできない。
program: sexpr*
ことを示す0以sexpr.
更新YACC文法:
program : /* empty */
| program sexpr
;
なYACCなものか、全文のAOETOOLS v3製品の場合の記載を除く文字列をその手段としては、できない重要なこの例では、も使用してC#コンソール出力でありがとうございまし験す):
program: (sexpr)*;
sexpr: list
| atom {Console.WriteLine("matched sexpr");}
;
list:
'('')' {Console.WriteLine("matched empty list");}
| '(' members ')' {Console.WriteLine("matched list");}
;
members: (sexpr)+ {Console.WriteLine("members 1");};
atom: Id {Console.WriteLine("ID");}
| Num {Console.WriteLine("NUM");}
;
Num: ( '0' .. '9')+;
Id: ('a' .. 'z' | 'A' .. 'Z')+;
Whitespace : ( ' ' | '\r' '\n' | '\n' | '\t' ) {Skip();};
こんどはYACCがYACCが発生しLALRパーサがAOETOOLSは再帰降下します。あるC/C++の出力を目標AOETOOLSは含まれておりませんがくることができてうれしいです。
あなたはneccesarilyのyacc / bisonのパーサが必要ですか? 「Lispの構文のサブセットを読み込み、」読者はあなたが「(」、 'まで順番に含まれるsexprsのリストを構築することを見たときにCで実装するのは難しい(、read_sexpr機能をread_listへの発送を開始するということではありません)」見られ、そうでない場合、)原子を収集し、それはもはや原子構成文字を読み取ることができるときにそれを返さないread_atomを呼び出す
。あなたはarbritary Common Lispのを読むことができるようにしたい場合は、CLは、読者が、実行時間(さらに別の読み取りテーブルを切り替える変更することができるよう、Common Lispのを実装(最悪の場合)する必要があります実行時にプログラム制御の下で、非常に便利あなたは)lispの他の言語や方言で書かれたコードをロードしたいしているときに
。私はYACCで働いていたので、長い時間がかかったが、あなたはトップレベルの非ターミナルが必要です。あなたは「それを試してみました」と「動作していないようでした」について、より具体的なのだろうか?または、そのことについては、エラーが何であるか?
私はまた、YACCは、このような構文光の言語のやり過ぎかもしれないと思われると思います。 (再帰下降のような)単純な何かがよりよく働くかもしれない。
現在のページのこの文法試みることができます。
私はちょうどそれを試してみました、私の "のyacc lispの文法は、" 正常に動作します:
%start exprs
exprs:
| exprs expr
/// if you prefer right recursion :
/// | expr exprs
;
list:
'(' exprs ')'
;
expr:
atom
| list
;
atom:
IDENTIFIER
| CONSTANT
| NIL
| '+'
| '-'
| '*'
| '^'
| '/'
;