extended flex to use custom token type
This commit is contained in:
parent
0a8cced386
commit
bb381be55f
|
@ -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"
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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; }
|
|
@ -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) {
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
|
||||||
|
struct LexerToken {
|
||||||
|
char* sval;
|
||||||
|
float fval;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define YYSTYPE LexerToken
|
||||||
|
|
Loading…
Reference in New Issue