Skip to content

Commit

Permalink
Parse in terms of lines and slash separators
Browse files Browse the repository at this point in the history
The grammar rules for LF and `/` are inconsistent:

* The first instruction can have slashes before it and the last line can
  end with a slash.
* Multiple slashes are treated as a single slash. Spaces or comments
  cannot be between slashes, except at the start of the file or after a
  label definition.
* Lines containing only whitespace or comments are not allowed, except
  at the start of the file or after label definitions.
* The last line must be terminated with LF.

Simplify the rules to be line-based:

* A line cannot start or end with a slash.
* A single slash separates adjacent instructions on the same line, but
  is optional after a label definition.
  • Loading branch information
thaliaarchi committed Aug 20, 2024
1 parent f3e6a72 commit 4cfc5f7
Show file tree
Hide file tree
Showing 12 changed files with 40 additions and 13 deletions.
4 changes: 2 additions & 2 deletions asm.l
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@
-?[01]+[bB] { yylval->string = strdup(yytext); return NUMBER; }
-?[0-9][0-9A-Fa-f]*[hH] { yylval->string = strdup(yytext); return NUMBER; }
-?[0-9]+ { yylval->string = strdup(yytext); return NUMBER; }
\n+ { return LF; }
"/"+ { return LF; }
\n { return LF; }
"/" { return SLASH; }
[\t\r\f ] { ; }
. { fprintf(stderr, "wsi: unrecognized token at line %d: `%c'", yylineno, *yytext); }

Expand Down
37 changes: 26 additions & 11 deletions asm.y
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

#define node(type, param) (struct node_t) { type, param, imm_none(), imm_none(), yyloc.first_line, yyloc.first_column }
#define node2(type, param1, param2) (struct node_t) { type, param1, param2, imm_none(), yyloc.first_line, yyloc.first_column }

vector(struct node_t) insn = NULL;
}

%code requires {
Expand All @@ -26,7 +28,6 @@
%union {
char * string;
struct node_t ins;
vector(struct node_t) insn;
struct immediate_t imm;
}

Expand All @@ -37,33 +38,47 @@

%token END 0 "end of file"

%type<insn> ToplevelScope
%type<ins> Construct
%type<imm> NumericalConstant
%token I_GETC I_GETN I_PUTC I_PUTN
%token I_PSH I_DUP I_XCHG I_DROP I_COPY I_SLIDE
%token I_ADD I_SUB I_MUL I_DIV I_MOD
%token I_STO I_RCL
%token I_CALL I_JMP I_JZ I_JLTZ I_RET I_END
%token I_REP COMMA LF
%token I_REP COMMA SLASH LF

%token<string> CHAR STRING NUMBER G_LBL G_REF

%start Start
%%
Start
: MaybeLF ToplevelScope { asm_gen(stdout, $2, optlevel); }
: Lines Line { asm_gen(stdout, insn, optlevel); }
;

Lines
: Lines Line LF
| %empty
;

Line
: Instructions LastInstruction
| %empty
;

Instructions
: Instructions G_LBL OptionalSLASH { vector_push_back(insn, node(LBL, imm_lbl($2))); }
| Instructions Construct SLASH { vector_push_back(insn, $2); }
| %empty
;

MaybeLF
: %empty
| LF MaybeLF
LastInstruction
: G_LBL { vector_push_back(insn, node(LBL, imm_lbl($1))); }
| Construct { vector_push_back(insn, $1); }
;

ToplevelScope
: ToplevelScope Construct LF { vector_push_back($1, $2); $$ = $1; }
| ToplevelScope G_LBL MaybeLF { vector_push_back($1, node(LBL, imm_lbl($2))); $$ = $1; }
| %empty { $$ = NULL; }
OptionalSLASH
: SLASH
| %empty
;

Construct
Expand Down
1 change: 1 addition & 0 deletions tests/parsing/fail/slash/inst_slash_space_slash.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
push 1 / / push 2
1 change: 1 addition & 0 deletions tests/parsing/fail/slash/label_slash_space_slash.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@lbl / / push 1
2 changes: 2 additions & 0 deletions tests/parsing/fail/slash/lf_slash.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
push 1
/ push 2
1 change: 1 addition & 0 deletions tests/parsing/fail/slash/slash_eof.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
push 1 /
2 changes: 2 additions & 0 deletions tests/parsing/fail/slash/slash_lf.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
push 1 /
push 2
1 change: 1 addition & 0 deletions tests/parsing/fail/slash/slash_lf_eof.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
push 1 /
1 change: 1 addition & 0 deletions tests/parsing/fail/slash/slash_slash.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
push 1 // push 2
1 change: 1 addition & 0 deletions tests/parsing/fail/slash/sof_slash.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/ push 1
1 change: 1 addition & 0 deletions tests/parsing/regress/pass/no_final_lf.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
push 1
1 change: 1 addition & 0 deletions tests/parsing/regress/pass/no_final_lf.ws
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

0 comments on commit 4cfc5f7

Please sign in to comment.