Merge branch 'main' of gitlab.cs.wallawalla.edu:cptr354/student354
This commit is contained in:
commit
a8c39591de
|
|
@ -1 +1,14 @@
|
|||
---
|
||||
lab_3_tests:
|
||||
stage: test
|
||||
image: gitlab.cs.wallawalla.edu:5050/cs_department/docker-images/cpp
|
||||
script:
|
||||
- apt update
|
||||
- apt install -y flex bison
|
||||
- bison --version
|
||||
- cd lab-3
|
||||
- echo "Lab 3 - Flex"
|
||||
- flex -o scanner.c scanner.flex
|
||||
- echo "Lab 3 - Compile Tests"
|
||||
- gcc main_test.c scanner.c -o scanner_test.out
|
||||
- echo "Lab 3 - Run Tests"
|
||||
- ./scanner_test.out
|
||||
|
|
|
|||
|
|
@ -0,0 +1,73 @@
|
|||
# Flex Scanner
|
||||
|
||||
Create a scanner for your sample programs.
|
||||
See the [example lab for Python](https://gitlab.cs.wallawalla.edu/cptr354/language-interpreter-lab-python).
|
||||
|
||||
## Language Scanner
|
||||
|
||||
Add the tokens needed to scan your sample code files.
|
||||
|
||||
In addition include the following:
|
||||
|
||||
* All the math operations (+,-,/,* etc.)
|
||||
* All boolean expression (==,>,< etc.)
|
||||
* All relational operators (not,and,or)
|
||||
* ...
|
||||
|
||||
## Testing the Language Scanner
|
||||
|
||||
Write unit test for your sample code.
|
||||
The sample program uses `utest.h` which is a simple c unit test framework.
|
||||
The documentation can be found at <https://github.com/sheredom/utest.h>.
|
||||
|
||||
The `main.c` has been replaced with unit test code.
|
||||
Your task is to create one unit test for each sample file.
|
||||
|
||||
When you submit the code to GitLab, the CI should automatically compile and run your test code.
|
||||
To recieve full credit, the tests must pass when run through GitLab CI.
|
||||
|
||||
## Build Process
|
||||
|
||||
To build the `scanner.c` run the following **flex** command.
|
||||
|
||||
```sh
|
||||
flex -o scanner.c scanner.flex
|
||||
```
|
||||
|
||||
Then build the `main.c` and `scanner.c` using **gcc**.
|
||||
|
||||
```sh
|
||||
gcc main_test.c scanner.c -o scanner_test.out
|
||||
```
|
||||
|
||||
Then execute the test suite using `./scanner_test.out`.
|
||||
|
||||
```sh
|
||||
./scanner_test.out
|
||||
```
|
||||
|
||||
## Scanner Only
|
||||
|
||||
```sh
|
||||
flex -o scanner.c scanner.flex
|
||||
gcc main.c scanner.c -o scanner.out
|
||||
./scanner.out
|
||||
```
|
||||
|
||||
|
||||
## Grading Rubric
|
||||
|
||||
The grading will be over the following categories.
|
||||
|
||||
Points Description
|
||||
----------- ------------------------------------
|
||||
30 points Tests for individual language tokens
|
||||
10 points Ability to scan — Hello world
|
||||
20 points Ability to scan — Quadratic equation
|
||||
20 points Ability to scan — Integer sorting
|
||||
20 points Passes continuous integration
|
||||
|
||||
## Turn In
|
||||
|
||||
Please submit the URL of your gitlab project to D2L's Brightspace with your report.
|
||||
On gitlab update the `lab-3` folder to have your report and code snippets before the due date.
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
#include "token.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
extern FILE *yyin;
|
||||
extern int yylex();
|
||||
extern char *yytext;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
FILE *file;
|
||||
const char *filename = "samples/hello.py"; // Default filename
|
||||
|
||||
// Check if a filename is provided as a command-line argument
|
||||
if (argc > 1) {
|
||||
filename = argv[1];
|
||||
}
|
||||
|
||||
// Open the file
|
||||
yyin = fopen(filename, "r");
|
||||
if (!yyin) {
|
||||
printf("could not open file!\n");
|
||||
return 1;
|
||||
}
|
||||
while (1) {
|
||||
token_t t = yylex();
|
||||
if (t == TOKEN_EOF)
|
||||
break;
|
||||
printf("token: %d text: %s\n", t, yytext);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
#include "token.h"
|
||||
// https://github.com/sheredom/utest.h/blob/master/utest.h
|
||||
#include "utest.h"
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct yy_buffer_state *YY_BUFFER_STATE;
|
||||
extern void yyrestart(FILE * input_file);
|
||||
extern YY_BUFFER_STATE yy_scan_buffer(char *str, int i);
|
||||
extern void yy_delete_buffer(YY_BUFFER_STATE buffer);
|
||||
extern FILE *yyin;
|
||||
extern int yylex();
|
||||
extern char *yytext;
|
||||
|
||||
UTEST_MAIN();
|
||||
|
||||
struct token_st {
|
||||
token_t t;
|
||||
char *p;
|
||||
};
|
||||
|
||||
UTEST(scanner, identifier) {
|
||||
token_t t;
|
||||
// Must include the null character to terminate input
|
||||
char string[] = "test\0";
|
||||
YY_BUFFER_STATE buffer = yy_scan_buffer(string, sizeof(string));
|
||||
|
||||
ASSERT_EQ(TOKEN_IDENT, (t = yylex()));
|
||||
ASSERT_STREQ("test", yytext);
|
||||
|
||||
ASSERT_EQ(TOKEN_EOF, (t = yylex()));
|
||||
ASSERT_STREQ("", yytext);
|
||||
|
||||
yy_delete_buffer(buffer);
|
||||
}
|
||||
|
||||
UTEST(scanner, assignment) {
|
||||
token_t t;
|
||||
// Must include the null character to terminate input
|
||||
char string[] = "=\0";
|
||||
YY_BUFFER_STATE buffer = yy_scan_buffer(string, sizeof(string));
|
||||
|
||||
ASSERT_EQ(TOKEN_ASSIGNMENT, (t = yylex()));
|
||||
ASSERT_STREQ("=", yytext);
|
||||
|
||||
ASSERT_EQ(TOKEN_EOF, (t = yylex()));
|
||||
ASSERT_STREQ("", yytext);
|
||||
|
||||
yy_delete_buffer(buffer);
|
||||
}
|
||||
|
||||
UTEST(scanner, sample) {
|
||||
struct token_st tokens[] = {
|
||||
{TOKEN_IDENT, "answer"},
|
||||
{TOKEN_ASSIGNMENT, "="},
|
||||
{TOKEN_NUMBER, "2020"},
|
||||
{TOKEN_ADD, "+"},
|
||||
{TOKEN_NUMBER, "4"},
|
||||
{TOKEN_EOF, ""}
|
||||
};
|
||||
|
||||
yyin = fopen("samples/program.c", "r");
|
||||
yyrestart(yyin);
|
||||
ASSERT_TRUE(yyin);
|
||||
|
||||
int index = 0;
|
||||
token_t t;
|
||||
do {
|
||||
ASSERT_EQ(tokens[index].t, (t = yylex()));
|
||||
ASSERT_STREQ(tokens[index].p, yytext);
|
||||
++index;
|
||||
} while (t != TOKEN_EOF);
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
answer = 2020+4
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
%{
|
||||
#include "token.h"
|
||||
%}
|
||||
DIGIT [0-9]
|
||||
LETTER [a-zA-Z]
|
||||
%%
|
||||
(" "|\t|\n) /* skip whitespace */
|
||||
\+ { return TOKEN_ADD; }
|
||||
"=" { return TOKEN_ASSIGNMENT; }
|
||||
while { return TOKEN_WHILE; }
|
||||
{LETTER}+ { return TOKEN_IDENT; }
|
||||
{DIGIT}+ { return TOKEN_NUMBER; }
|
||||
. { return TOKEN_ERROR; }
|
||||
%%
|
||||
int yywrap() { return 1; }
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
typedef enum {
|
||||
TOKEN_EOF = 0,
|
||||
TOKEN_WHILE,
|
||||
TOKEN_ADD,
|
||||
TOKEN_ASSIGNMENT,
|
||||
TOKEN_IDENT,
|
||||
TOKEN_NUMBER,
|
||||
TOKEN_ERROR
|
||||
} token_t;
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue