Почему лимон не запускает терминалы сразу?
Я перевожу небольшой интерпретатор с использованием flex и yacc для re2c и lemon. Все работает, но буквально.
Почему действие, связанное с литералами, не запускается так же, как с 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 $@ $^ $(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
это имя редукционного значения. Другими словами, это соответствует $$
в яцк Семантическая ценность терминала LITERAL
является $1
, поскольку вы не указали символическое имя для этого значения.
Возможно, вы имели в виду:
expr ::= LITERAL(val). { /* something with val */ }
Или же
expr(e) ::= LITERAL(v). { e = v; /* some other action */ }