開発環境
- 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(演習問題)、問1を解いてみる。
問1
コード(Emacs)
lex.l
%{
#include "parse2.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; }
[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]
%%
parse.y
%{
#include <stdio.h>
int yyerror(char *s);
extern int yylex (void);
%}
%token LOOKUP AUXVERB VERB ADJECTIVE ADVERB NOUN PREPOSITION PRONOUN CONJUNCTION
%%
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
| ADJECTIVE subject
| ADVERB subject /* 追加 */
;
verb: VERB
| ADVERB VERB
| AUXVERB VERB
| verb VERB
;
object: NOUN
| 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 bison -d parse2.y flex lex2.l cc -g -Wall -O0 -I/opt/local/include -L/opt/local/lib -lfl symtab.o parse2.tab.c lex.yy.c -o main lex.yy.c:1156:17: warning: unused function 'yyunput' [-Wunused-function] static void yyunput (int c, register char * yy_bp ) ^ lex.yy.c:1197:16: warning: function 'input' is not needed and will not be emitted [-Wunneeded-internal-declaration] static int input (void) ^ 2 warnings generated. $ ./main noun i dogs aux have verb seen i have seen dogs. Parsed a simple sentence. C-c C-c $
0 コメント:
コメントを投稿