2015-09-01 2 views
0

Я перемещаю небольшой интерпретатор с резьбой, используя flex и yacc для re2c и лимона. Все работает, но литералы.Почему лимон не запускает терминалы сразу?

Почему действие, связанное с литералами, не работает, как с yacc? Я ожидаю, что "1.0 конец", но получить "0.0 конец"

dspgrammar.y

%include {#include <assert.h>} 
%name dsp 
%token_type {float} 
program ::= expr. {printf("end\n");} 
expr(val) ::= LITERAL. {printf("%f ", val);} 

main.c

#include <stdio.h> 
#include <stdlib.h> 
#include "dspgrammar.h" 

void *dspAlloc(void *(*)(size_t)); 
void dsp(void *, int, float); 
void dspFree(void *, void (*)(void *)); 
void dspTrace(FILE *, char *); 

int main(int argc, char *argv[]) 
{ 
     void *parser = dspAlloc(malloc); 
     dspTrace(stderr, "TRACE: "); 
     dsp(parser, LITERAL, 1.0f); 
     dsp(parser,  0, 0.0f); 
     dspFree(parser, free); 
     return EXIT_SUCCESS; 
} 

Makefile

CC  = gcc 
CFLAGS = -O0 -g -Wall -Wextra -pedantic -std=gnu99 
LD  = gcc 
LDFLAGS = -lm 

dsp: main.o dspgrammar.o 
     $(LD) $(CFLAGS) -o [email protected] $^ $(LDFLAGS) 

main.o: main.c 
     $(CC) $(CFLAGS) -c main.c 

dspgrammar.o: dspgrammar.c 
     $(CC) -c $(CFLAGS) -c dspgrammar.c 

dspgrammar.c: dspgrammar.y 
     lemon dspgrammar.y 

ответ

1

В

expr(val) ::= LITERAL. { /* something with val */ } 

val - это название значения уменьшения. Другими словами, он соответствует $$ в yacc. Семантическое значение терминала LITERAL равно $1, так как вы не указали символическое имя для этого значения.

Возможно, вы имели в виду:

expr ::= LITERAL(val). { /* something with val */ } 

Или

expr(e) ::= LITERAL(v). { e = v; /* some other action */ }