summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2019-06-15 09:19:06 +0800
committerruki <[email protected]>2019-06-15 09:19:06 +0800
commit115665bd7ad421d448b7dda421303096a677dd72 (patch)
treee10ec94c419814c6822cf6f051f98ed337bcbd53
parent42ddca8c330acd5928a553fbd562f3a3d2a4700b (diff)
add lex/yacc test project
-rw-r--r--tests/projects/lex_yacc/src/calc.l27
-rw-r--r--tests/projects/lex_yacc/src/calc.y81
-rw-r--r--tests/projects/lex_yacc/xmake.lua7
-rw-r--r--xmake/rules/lex_yacc/lex/xmake.lua29
-rw-r--r--xmake/rules/lex_yacc/yacc/xmake.lua29
5 files changed, 173 insertions, 0 deletions
diff --git a/tests/projects/lex_yacc/src/calc.l b/tests/projects/lex_yacc/src/calc.l
new file mode 100644
index 000000000..37d44dd27
--- /dev/null
+++ b/tests/projects/lex_yacc/src/calc.l
@@ -0,0 +1,27 @@
+%option noyywrap
+
+%{
+#include <stdio.h>
+
+#define YY_DECL int yylex()
+
+#include "calc.tab.h"
+
+%}
+
+%%
+
+[ \t] ; // ignore all whitespace
+[0-9]+\.[0-9]+ {yylval.fval = atof(yytext); return T_FLOAT;}
+[0-9]+ {yylval.ival = atoi(yytext); return T_INT;}
+\n {return T_NEWLINE;}
+"+" {return T_PLUS;}
+"-" {return T_MINUS;}
+"*" {return T_MULTIPLY;}
+"/" {return T_DIVIDE;}
+"(" {return T_LEFT;}
+")" {return T_RIGHT;}
+"exit" {return T_QUIT;}
+"quit" {return T_QUIT;}
+
+%%
diff --git a/tests/projects/lex_yacc/src/calc.y b/tests/projects/lex_yacc/src/calc.y
new file mode 100644
index 000000000..d7af910dd
--- /dev/null
+++ b/tests/projects/lex_yacc/src/calc.y
@@ -0,0 +1,81 @@
+%{
+
+#include <stdio.h>
+#include <stdlib.h>
+
+extern int yylex();
+extern int yyparse();
+extern FILE* yyin;
+
+void yyerror(const char* s);
+%}
+
+%union {
+ int ival;
+ float fval;
+}
+
+%token<ival> T_INT
+%token<fval> T_FLOAT
+%token T_PLUS T_MINUS T_MULTIPLY T_DIVIDE T_LEFT T_RIGHT
+%token T_NEWLINE T_QUIT
+%left T_PLUS T_MINUS
+%left T_MULTIPLY T_DIVIDE
+
+%type<ival> expression
+%type<fval> mixed_expression
+
+%start calculation
+
+%%
+
+calculation:
+ | calculation line
+;
+
+line: T_NEWLINE
+ | mixed_expression T_NEWLINE { printf("\tResult: %f\n", $1);}
+ | expression T_NEWLINE { printf("\tResult: %i\n", $1); }
+ | T_QUIT T_NEWLINE { printf("bye!\n"); exit(0); }
+;
+
+mixed_expression: T_FLOAT { $$ = $1; }
+ | mixed_expression T_PLUS mixed_expression { $$ = $1 + $3; }
+ | mixed_expression T_MINUS mixed_expression { $$ = $1 - $3; }
+ | mixed_expression T_MULTIPLY mixed_expression { $$ = $1 * $3; }
+ | mixed_expression T_DIVIDE mixed_expression { $$ = $1 / $3; }
+ | T_LEFT mixed_expression T_RIGHT { $$ = $2; }
+ | expression T_PLUS mixed_expression { $$ = $1 + $3; }
+ | expression T_MINUS mixed_expression { $$ = $1 - $3; }
+ | expression T_MULTIPLY mixed_expression { $$ = $1 * $3; }
+ | expression T_DIVIDE mixed_expression { $$ = $1 / $3; }
+ | mixed_expression T_PLUS expression { $$ = $1 + $3; }
+ | mixed_expression T_MINUS expression { $$ = $1 - $3; }
+ | mixed_expression T_MULTIPLY expression { $$ = $1 * $3; }
+ | mixed_expression T_DIVIDE expression { $$ = $1 / $3; }
+ | expression T_DIVIDE expression { $$ = $1 / (float)$3; }
+;
+
+expression: T_INT { $$ = $1; }
+ | expression T_PLUS expression { $$ = $1 + $3; }
+ | expression T_MINUS expression { $$ = $1 - $3; }
+ | expression T_MULTIPLY expression { $$ = $1 * $3; }
+ | T_LEFT expression T_RIGHT { $$ = $2; }
+;
+
+%%
+
+int main() {
+ yyin = stdin;
+
+ do {
+ yyparse();
+ } while(!feof(yyin));
+
+ return 0;
+}
+
+void yyerror(const char* s) {
+ fprintf(stderr, "Parse error: %s\n", s);
+ exit(1);
+}
diff --git a/tests/projects/lex_yacc/xmake.lua b/tests/projects/lex_yacc/xmake.lua
new file mode 100644
index 000000000..21e1fa611
--- /dev/null
+++ b/tests/projects/lex_yacc/xmake.lua
@@ -0,0 +1,7 @@
+
+add_rules("mode.debug", "mode.release")
+
+target("calc")
+ set_kind("binary")
+ add_rules("lex", "yacc")
+ add_files("src/*.l", "src/*.y")
diff --git a/xmake/rules/lex_yacc/lex/xmake.lua b/xmake/rules/lex_yacc/lex/xmake.lua
new file mode 100644
index 000000000..1f49731c1
--- /dev/null
+++ b/xmake/rules/lex_yacc/lex/xmake.lua
@@ -0,0 +1,29 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015 - 2019, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file xmake.lua
+--
+
+-- define rule: lex
+rule("lex")
+
+ -- set externsion
+ set_extensions(".l", ".ll")
+
+ -- load lex/flex
+ before_load(function (target)
+ end)
diff --git a/xmake/rules/lex_yacc/yacc/xmake.lua b/xmake/rules/lex_yacc/yacc/xmake.lua
new file mode 100644
index 000000000..5a7e3ae76
--- /dev/null
+++ b/xmake/rules/lex_yacc/yacc/xmake.lua
@@ -0,0 +1,29 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015 - 2019, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file xmake.lua
+--
+
+-- define rule: yacc
+rule("yacc")
+
+ -- set externsion
+ set_extensions(".y", ".yy")
+
+ -- load yacc/bison
+ before_load(function (target)
+ end)