開発環境
- OS X El Capitan - Apple (OS)
- Emacs(Text Editor)
- C (プログラミング言語)
- flex(字句解析)、bison(構文解析)
lex&yaccプログラミング (NUTSHELL HANDBOOKS) (John R Levine著、Doug Brown著、Tony Mason著、村上 列翻訳)の1章(lex と yacc)、1.6(演習問題)、問3を解いてみる。
問3
コード(Emacs)
lex3.l
%{ #include "parse3.tab.h" #include "symtab.h" int state; %} %% \n { state = LOOKUP;} \.\n { state = LOOKUP; return 0;} aux { state = AUXVERB;} verb { state = VERB;} adj { state = ADJECTIVE; } adv { state = ADVERB; } noun { state = NOUN; } prep {state = PREPOSITION; } pron { state = PRONOUN; } conj { state = CONJUNCTION; } nov { state = NOUN_OR_VERB; } [a-zA-Z]+ { if (state != LOOKUP) { add_word(state, yytext); } else { switch(lookup_word(yytext)) { case AUXVERB: return AUXVERB; case VERB: return VERB; case ADJECTIVE: return ADJECTIVE; case ADVERB: return ADVERB; case NOUN: return NOUN; case PREPOSITION: return PREPOSITION; case PRONOUN: return PRONOUN; case CONJUNCTION: return CONJUNCTION; default: printf("%s: don't recognize\n", yytext); } } } [ \t] %%
parse3.y
%{ #include <stdio.h> int yyerror(char *s); extern int yylex (void); %} %token LOOKUP AUXVERB VERB ADJECTIVE ADVERB NOUN PREPOSITION PRONOUN CONJUNCTION %token NOUN_OR_VERB %% sentence: simple_sentence { printf("Parsed a simple sentence.\n"); yyparse();} | compound_sentence { printf("Parsed a compound sentence.\n"); yyparse(); } ; simple_sentence: subject verb object | subject verb object prep_phrase ; compound_sentence: simple_sentence CONJUNCTION simple_sentence | compound_sentence CONJUNCTION simple_sentence ; subject: NOUN | PRONOUN | NOUN_OR_VERB | ADJECTIVE subject | ADVERB subject /* 追加 */ ; verb: VERB | ADVERB VERB | AUXVERB VERB | NOUN_OR_VERB | verb VERB ; object: NOUN | NOUN_OR_VERB | ADJECTIVE object ; prep_phrase: PREPOSITION NOUN ; %% extern FILE *yyin; int main() { while (1) { yyparse(); } } int yyerror(char *s) { fprintf(stderr, "%s\n", s); return 1; }
symtab.h
#pragma once
int add_word(int type, char *word);
int lookup_word(char *word);
symtab.c
#include "symtab.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "parse.tab.h"
typedef struct word {
char *word_name;
int word_type;
struct word *next;
} Word;
Word *word_list;
int add_word(int type, char *word) {
Word *wp;
if (lookup_word(word) != LOOKUP) {
printf("!!! warning: word %s already defined \n", word);
return 0;
}
wp = (Word*)malloc(sizeof(Word));
wp->next = word_list;
wp->word_name = (char*)malloc(strlen(word) + 1);
strcpy(wp->word_name, word);
wp->word_type = type;
word_list = wp;
return 1;
}
int lookup_word(char *word) {
Word *wp = word_list;
for (; wp; wp = wp->next) {
if (strcmp(wp->word_name, word) == 0){
return wp->word_type;
}
}
return LOOKUP;
}
入出力結果(Terminal(bash))
$ make lex lex3.l bison -d parse3.y cc -g -Wall -O0 -I/opt/local/include -L/opt/local/lib -lfl symtab.o parse3.tab.c lex.yy.c -o main lex.yy.c:1161:17: warning: unused function 'yyunput' [-Wunused-function] static void yyunput (int c, register char * yy_bp ) ^ lex.yy.c:1202:16: warning: function 'input' is not needed and will not be emitted [-Wunneeded-internal-declaration] static int input (void) ^ 2 warnings generated. $ ./main noun money nov time verb is time is money. time: don't recognize syntax error syntax error C-c C-c $ # うまくいかなかった
0 コメント:
コメントを投稿