extended flex to use custom token type

This commit is contained in:
Pedro 2014-10-17 17:43:57 +02:00
parent 0a8cced386
commit bb381be55f
5 changed files with 39 additions and 19 deletions

View File

@ -1,4 +1,4 @@
rm -f lemon_test lemon_parser.c flex_scanner.c rm -f lemon_test lemon_parser.c lemon_parser.h flex_scanner.c flex_scanner.h
echo "Lemon" echo "Lemon"
lemon lemon_parser.y lemon lemon_parser.y
echo "Flex" echo "Flex"

View File

@ -1,15 +1,20 @@
%{ %{
#include "lemon_parser.h" #include "lemon_parser.h"
#include <stdlib.h> #include <stdlib.h>
#include "token_def.h"
%} %}
%option reentrant %option reentrant
%option noyywrap %option noyywrap
%option bison-bridge
%% %%
[0-9]+|[0-9]+.[0-9]+ return NUMBER; [0-9]+|[0-9]+.[0-9]+ { yylval->fval = atof(yytext); return NUMBER; }
[+] return PLUS; [+] return PLUS;
[\n] return NL; [\n] return NL;
[ \t] ; /* skip whitespace */ [ \t] ; /* skip whitespace */

View File

@ -1,16 +1,16 @@
%include { %include {
#include <assert.h> #include <assert.h>
#include <cstdlib> #include <cstdlib>
#include "token_def.h"
} }
%syntax_error { printf("Lemon syntax error\n"); } %syntax_error { printf("Lemon syntax error\n"); }
%token_type {const char*} %token_type {LexerToken*}
%type expr {float}
%left PLUS MINUS .
%extra_argument { float* result } %extra_argument { float* result }
%type expr {float}
%left PLUS MINUS .
start ::= prog. start ::= prog.
prog ::= prog print NL . prog ::= prog print NL .
@ -19,5 +19,5 @@ prog ::= .
print ::= expr(a) . { *result = a; } print ::= expr(a) . { *result = a; }
expr(a) ::= NUMBER(b) . { a = atof(b); } expr(a) ::= NUMBER(b) . { a = b->fval; }
expr(a) ::= expr(b) PLUS expr(c) . { a = b + c; } expr(a) ::= expr(b) PLUS expr(c) . { a = b + c; }

View File

@ -1,8 +1,9 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <thread> #include <thread>
#include "flex_scanner.h" #include "token_def.h"
#include "lemon_parser.h" #include "lemon_parser.h"
#include "flex_scanner.h"
// Based on https://github.com/theory/flex-lemon-example // Based on https://github.com/theory/flex-lemon-example
// and http://stackoverflow.com/questions/24833465/bison-yacc-vs-lemon-vs-standard-input // and http://stackoverflow.com/questions/24833465/bison-yacc-vs-lemon-vs-standard-input
@ -10,10 +11,10 @@ typedef float ResultType;
void *ParseAlloc(void *(*mallocProc)(size_t)); void *ParseAlloc(void *(*mallocProc)(size_t));
void ParseFree(void *p, void (*freeProc)(void*)); void ParseFree(void *p, void (*freeProc)(void*));
void Parse(void *yyp, int yymajor, const char* text, ResultType*); void Parse(void *yyp, int yymajor, LexerToken* token, ResultType*);
int yylex(void); // int yylex(void);
int yylval; // int yylval;
float parseString(const char* string) { float parseString(const char* string) {
@ -27,15 +28,16 @@ float parseString(const char* string) {
int tokenCode; int tokenCode;
ResultType result; ResultType result;
do { do {
tokenCode = yylex(scanner); LexerToken token;
Parse(lemonParser, tokenCode, yyget_text(scanner), &result); tokenCode = yylex(&token, scanner);
Parse(lemonParser, tokenCode, &token, &result);
// printf("Token %d\n", tokenCode); // printf("Token %d\n", tokenCode);
} while (tokenCode > 0); } while (tokenCode > 0);
return result; return result;
} }
int parse_count = 0;
void multithreadTest(int numOfParses, int id) { void multithreadTest(int numOfParses, int id) {
for (int n = 0; n < numOfParses; ++n) { for (int n = 0; n < numOfParses; ++n) {
int a = rand() % 1000 + 1; int a = rand() % 1000 + 1;
@ -44,14 +46,18 @@ void multithreadTest(int numOfParses, int id) {
char string[32]; char string[32];
sprintf(string, "%d + %d", a, b); sprintf(string, "%d + %d", a, b);
parse_count++;
int result = parseString(string); int result = parseString(string);
if (parse_count != 1) printf("+");
parse_count--;
if (result != c) printf("Error[%d]! %s != %d\n", id, string, result); if (result != c) printf("Error[%d]! %s != %d\n", id, string, result);
} }
} }
int main(void) { int main(void) {
const int numThreads = 10; const int numThreads = 20;
int numRuns = 5000; int numRuns = 300;
std::thread threads[numThreads]; std::thread threads[numThreads];
for (int n = 0; n < numThreads; ++n) { for (int n = 0; n < numThreads; ++n) {

View File

@ -0,0 +1,9 @@
struct LexerToken {
char* sval;
float fval;
};
#define YYSTYPE LexerToken