Skip to content

Commit

Permalink
Simplify parser and rewrite error printing.
Browse files Browse the repository at this point in the history
With new parser, we can print multiple alternative errors on the same
spot.
  • Loading branch information
dmsc committed Oct 27, 2018
1 parent 300c3b5 commit 41f3293
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 70 deletions.
84 changes: 40 additions & 44 deletions src/basic.syn
Original file line number Diff line number Diff line change
Expand Up @@ -90,20 +90,20 @@ EXTERN {

# Floating point expressions
#@if FASTBASIC_FP
FP_EXPR: floating point expression
FP_EXPR:
FP_T_EXPR FP_E_EXPR_MORE FP_M_EXPR_MORE FP_EXPR_MORE

FP_EXPR_MORE:
FP_EXPR_MORE: '+', '-'
"+" FP_T_EXPR FP_E_EXPR_MORE FP_M_EXPR_MORE emit TOK_FP_ADD FP_EXPR_MORE
"-" FP_T_EXPR FP_E_EXPR_MORE FP_M_EXPR_MORE emit TOK_FP_SUB FP_EXPR_MORE
pass

FP_M_EXPR_MORE:
FP_M_EXPR_MORE: '*', '/'
"*" FP_T_EXPR FP_E_EXPR_MORE emit TOK_FP_MUL FP_M_EXPR_MORE
"/" FP_T_EXPR FP_E_EXPR_MORE emit TOK_FP_DIV FP_M_EXPR_MORE
pass

FP_E_EXPR_MORE:
FP_E_EXPR_MORE: '^'
"^" T_EXPR emit TOK_FP_IPOW FP_E_EXPR_MORE
"^" emit TOK_FP_LOG10 FP_T_EXPR emit TOK_FP_MUL emit TOK_FP_EXP10 FP_E_EXPR_MORE
pass
Expand Down Expand Up @@ -137,18 +137,18 @@ FP_PAR_EXPR: left parenthesis
INT_EXPR: integer expression
T_EXPR BIT_EXPR_MORE M_EXPR_MORE INT_EXPR_MORE

INT_EXPR_MORE:
INT_EXPR_MORE: '+', '-'
"+" T_EXPR BIT_EXPR_MORE M_EXPR_MORE emit TOK_ADD INT_EXPR_MORE
"-" T_EXPR BIT_EXPR_MORE M_EXPR_MORE emit TOK_SUB INT_EXPR_MORE
pass

M_EXPR_MORE:
M_EXPR_MORE: '*', '/', 'MOD'
"*" T_EXPR BIT_EXPR_MORE emit TOK_MUL M_EXPR_MORE
"/" T_EXPR BIT_EXPR_MORE emit TOK_DIV M_EXPR_MORE
"MOD" T_EXPR BIT_EXPR_MORE emit TOK_MOD M_EXPR_MORE
pass

BIT_EXPR_MORE:
BIT_EXPR_MORE: '&', '!', 'EXOR'
"&" T_EXPR emit TOK_BIT_AND BIT_EXPR_MORE
"!" T_EXPR emit TOK_BIT_OR BIT_EXPR_MORE
"EXOR" T_EXPR emit TOK_BIT_EXOR BIT_EXPR_MORE
Expand All @@ -168,7 +168,7 @@ ADR_EXPR: string or variable
emit TOK_VAR_LOAD E_VAR_ARRAY_STRING

USR_EXPR_MORE:
"," EXPR emit TOK_USR_PARAM USR_EXPR_MORE
C_EXPR emit TOK_USR_PARAM USR_EXPR_MORE
pass

T_EXPR: integer constant, variable or function
Expand Down Expand Up @@ -242,14 +242,14 @@ EXPR:
FORCE_BOOL_EXPR:
NOT_EXPR AND_EXPR_MORE OR_EXPR_MORE

OR_EXPR_RIGHT:
OR_EXPR_RIGHT: 'OR'
"OR" NOT_EXPR AND_EXPR_MORE emit TOK_L_OR OR_EXPR_MORE

OR_EXPR_MORE:
OR_EXPR_RIGHT
pass

AND_EXPR_RIGHT:
AND_EXPR_RIGHT: 'AND'
"AND" NOT_EXPR emit TOK_L_AND AND_EXPR_MORE

AND_EXPR_MORE:
Expand All @@ -271,7 +271,7 @@ COMP_OR_BOOL:
#@endif FASTBASIC_FP
emit TOK_COMP_0

COMP_EXPR_RIGHT:
COMP_EXPR_RIGHT: integer comparison operator
"<=" INT_EXPR emit TOK_GT emit TOK_L_NOT
">=" INT_EXPR emit TOK_LT emit TOK_L_NOT
"<>" INT_EXPR emit TOK_NEQ
Expand All @@ -281,7 +281,7 @@ COMP_EXPR_RIGHT:

#@if FASTBASIC_FP
# FP Comparisons:
COMP_FP_RIGHT: integer expression
COMP_FP_RIGHT: floating-point comparison operator
"=" FP_EXPR emit TOK_FP_CMP emit TOK_EQ
">" FP_EXPR emit TOK_FP_CMP emit TOK_GT
">=" FP_EXPR emit TOK_FP_CMP emit TOK_LT emit TOK_L_NOT
Expand All @@ -290,7 +290,7 @@ COMP_FP_RIGHT: integer expression
"<" FP_EXPR emit TOK_FP_CMP emit TOK_LT
#@endif FASTBASIC_FP

COMP_STR_RIGHT: integer expression
COMP_STR_RIGHT: comparison operator
"=" STR_EXPR emit TOK_CMP_STR emit TOK_EQ
">" STR_EXPR emit TOK_CMP_STR emit TOK_GT
">=" STR_EXPR emit TOK_CMP_STR emit TOK_LT emit TOK_L_NOT
Expand All @@ -307,7 +307,7 @@ STR_EXPR: string expression
STR_EXPR_BASE OPT_STR_INDEX

OPT_STR_INDEX:
"[" EXPR_2 "]" emit TOK_STR_IDX OPT_STR_INDEX
"[" EXPR C_EXPR "]" emit TOK_STR_IDX OPT_STR_INDEX
"[" EXPR "]" emit TOK_BYTE emit 255 emit TOK_STR_IDX OPT_STR_INDEX
pass

Expand Down Expand Up @@ -412,14 +412,14 @@ NEXT_VARNAME:

# POSITION arguments, used also in PLOT, DRAWTO, LOCATE and FILLTO
POSITION:
emit TOK_BYTE emit COLCRS EXPR "," emit TOK_DPOKE emit TOK_BYTE emit ROWCRS EXPR emit TOK_POKE
emit TOK_BYTE emit COLCRS EXPR emit TOK_DPOKE emit TOK_BYTE emit ROWCRS C_EXPR emit TOK_POKE

# SOUND arguments, three possibilities:
# SOUND voice, freq, distort, vol
# SOUND voice
# SOUND
SOUND:
EXPR emit TOK_USHL emit TOK_NUM word AUDF1 emit TOK_ADD "," EXPR "," EXPR_AB emit TOK_SHL8 emit TOK_ADD emit TOK_DPOKE emit TOK_NUM word AUDCTL emit TOK_0 emit TOK_POKE emit TOK_NUM word SKCTL emit TOK_BYTE emit 3 emit TOK_POKE
EXPR emit TOK_USHL emit TOK_NUM word AUDF1 emit TOK_ADD C_EXPR EXPR_AB emit TOK_SHL8 emit TOK_ADD emit TOK_DPOKE emit TOK_NUM word AUDCTL emit TOK_0 emit TOK_POKE emit TOK_NUM word SKCTL emit TOK_BYTE emit 3 emit TOK_POKE
EXPR emit TOK_USHL emit TOK_NUM word AUDF1 emit TOK_ADD emit TOK_0 emit TOK_DPOKE
emit TOK_SOUND_OFF

Expand All @@ -442,7 +442,7 @@ DIM_MORE: comma
# INPUT
INPUT_STR:
IO_CHAN_COMMA # I/O channel, don't print prompt
IO_CHAN "," # I/O channel, don't print prompt
"\"" emit TOK_CSTRING E_CONST_STRING emit TOK_PRINT_STR PRINT_SEP # Prints a given string
PRINT_SEP # If starts with ',' or ';', don't print anyting
emit TOK_BYTE emit 63 emit TOK_PUT # Prints a '?' by default
Expand Down Expand Up @@ -480,12 +480,8 @@ DIM_VAR: new variable name
IO_CHAN: I/O channel number
"#" emit TOK_BYTE emit IOCHN EXPR emit TOK_USHL emit TOK_USHL emit TOK_USHL emit TOK_USHL emit TOK_POKE

# Note: we need the version without comma for "CLOSE #*"
IO_CHAN_COMMA:
IO_CHAN ","

IO_CHAN_OPT:
IO_CHAN_COMMA
IO_CHAN ","
pass

# Used only for CLS
Expand All @@ -500,24 +496,24 @@ GETK_EXPR: variable name

# Get expression
GET_EXPR: variable name
VAR_BYTE_LVALUE emit TOK_GET emit TOK_POKE GET_EXPR_MORE
VAR_WORD_LVALUE emit TOK_GET emit TOK_DPOKE GET_EXPR_MORE
"," VAR_BYTE_LVALUE emit TOK_GET emit TOK_POKE GET_EXPR_MORE
"," VAR_WORD_LVALUE emit TOK_GET emit TOK_DPOKE GET_EXPR_MORE

GET_EXPR_MORE:
"," GET_EXPR
GET_EXPR
emit TOK_IOCHN0

# Get two comma separated expressions "A,B" and returns "A*16+B"
EXPR_AB:
EXPR emit TOK_USHL emit TOK_USHL emit TOK_USHL emit TOK_USHL "," EXPR emit TOK_ADD
# A comma followed by an expression
C_EXPR: comma followed by an expression
"," EXPR

# 2 expressions separated by comma
EXPR_2:
EXPR "," EXPR
# Get two comma separated expressions ",A,B" and returns "A*16+B"
EXPR_AB:
C_EXPR emit TOK_USHL emit TOK_USHL emit TOK_USHL emit TOK_USHL C_EXPR emit TOK_ADD

# Parses a XIO AUX1/AUX2/STRING expression
XIO_EXPR:
EXPR_2 emit TOK_SHL8 emit TOK_ADD "," STR_EXPR emit TOK_XIO
C_EXPR C_EXPR emit TOK_SHL8 emit TOK_ADD "," STR_EXPR emit TOK_XIO

# Parses a "DATA" expression, get's binary data in memory
DATA_WORDS: data word
Expand Down Expand Up @@ -548,14 +544,14 @@ PARSE_LINE_COMMAND:
"PRint" IO_CHAN_OPT PRINT_EXPR
"INput" INPUT_STR INPUT_VAR_LIST emit TOK_IOCHN0
"GEt" GETK_EXPR
"GEt" IO_CHAN_COMMA GET_EXPR
"GEt" IO_CHAN GET_EXPR
"PUt" IO_CHAN_OPT EXPR emit TOK_PUT
"CLS" IO_CHAN_OPT_NOCOMMA emit TOK_BYTE emit CLS emit TOK_PUT
"Poke" EXPR_2 emit TOK_POKE
"Dpoke" EXPR_2 emit TOK_DPOKE
"MSet" EXPR_2 "," EXPR emit TOK_MSET
"Move" EXPR_2 "," EXPR emit TOK_MOVE
"-move" EXPR_2 "," EXPR emit TOK_NMOVE
"Poke" EXPR C_EXPR emit TOK_POKE
"Dpoke" EXPR C_EXPR emit TOK_DPOKE
"MSet" EXPR C_EXPR C_EXPR emit TOK_MSET
"Move" EXPR C_EXPR C_EXPR emit TOK_MOVE
"-move" EXPR C_EXPR C_EXPR emit TOK_NMOVE
"DO" emit LT_DO_LOOP E_PUSH_LT
"Loop" emit TOK_JUMP E_POP_LOOP
"Repeat" emit LT_REPEAT E_PUSH_LT
Expand All @@ -576,14 +572,14 @@ PARSE_LINE_COMMAND:
"PLot" POSITION emit TOK_BYTE emit COLOR emit TOK_PEEK emit TOK_PLOT
"DRawto" POSITION emit TOK_BYTE emit DRAWLN emit TOK_DRAWTO
"FIllto" POSITION emit TOK_BYTE emit FILLIN emit TOK_DRAWTO
"SEtcolor" EXPR emit TOK_NUM word COLOR0 emit TOK_ADD "," EXPR_AB emit TOK_POKE
"SEtcolor" EXPR emit TOK_NUM word COLOR0 emit TOK_ADD EXPR_AB emit TOK_POKE
"Sound" SOUND
"DIm" DIM_VAR DIM_MORE
"CLose" IO_CHAN emit TOK_CLOSE
"Open" IO_CHAN_COMMA emit TOK_BYTE emit OPEN XIO_EXPR
"Xio" IO_CHAN_COMMA EXPR "," XIO_EXPR
"BPut" IO_CHAN_COMMA EXPR_2 emit TOK_BPUT
"BGet" IO_CHAN_COMMA EXPR_2 emit TOK_BGET
"Open" IO_CHAN emit TOK_BYTE emit OPEN XIO_EXPR
"Xio" IO_CHAN C_EXPR XIO_EXPR
"BPut" IO_CHAN C_EXPR C_EXPR emit TOK_BPUT
"BGet" IO_CHAN C_EXPR C_EXPR emit TOK_BGET
"PAuse" EXPR emit TOK_PAUSE
"INC" VAR_WORD_LVALUE emit TOK_INC
"DEc" VAR_WORD_LVALUE emit TOK_DEC
Expand All @@ -597,7 +593,7 @@ PARSE_LINE_COMMAND:
"RAd" emit TOK_BYTE emit DEGFLAG emit TOK_0 emit TOK_POKE
#@endif FASTBASIC_FP

PARSE_LINE_ASSIGN: &LOW_ERROR
PARSE_LINE_ASSIGN:
VAR_WORD_LVALUE EQUAL EXPR emit TOK_DPOKE
VAR_BYTE_LVALUE EQUAL EXPR emit TOK_POKE
VAR_STR_LVALUE EQUAL STR_EXPR emit TOK_COPY_STR
Expand Down
14 changes: 12 additions & 2 deletions src/compiler/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,18 @@ int main(int argc, char **argv)
if( !SMB_PARSE_START(s) || ( s.pos != line.length() && !s.peek(':') ) )
{
std::cerr << iname << ":" << ln << ":" << s.max_pos << ": parse error";
if( !s.saved_error.empty() )
std::cerr << ", " << s.saved_error;
if( !s.saved_errors.empty() )
{
std::cerr << ", expected: ";
bool first = true;
for(const auto &i: s.saved_errors)
{
if( !first )
std::cerr << ", ";
std::cerr << i;
first = false;
}
}
std::cerr << "\n";
size_t min = 0, max = s.str.length();
if( s.max_pos > 40 ) min = s.max_pos - 40;
Expand Down
51 changes: 27 additions & 24 deletions src/compiler/parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
// parser.cc: C++ parser

#include <string>
#include <algorithm>

#include "codew.h"

Expand All @@ -38,9 +39,7 @@ class parse {
std::string str;
size_t pos;
size_t max_pos;
bool low_error;
std::string current_error;
std::string saved_error;
std::vector<std::string> saved_errors;
int linenum;
std::map<std::string, std::vector<codew>> procs;
std::map<std::string, int> vars;
Expand All @@ -52,7 +51,7 @@ class parse {

parse():
lvl(0), maxlvl(0), pos(0),
max_pos(0), low_error(false), label_num(0),
max_pos(0), label_num(0),
finalized(false),
code(&procs[std::string()]) { }

Expand Down Expand Up @@ -117,6 +116,7 @@ class parse {
{
pos = max_pos = 0;
str = l;
saved_errors.clear();
linenum = ln;
}

Expand All @@ -127,33 +127,41 @@ class parse {

void error(std::string str)
{
if( str == "&LOW_ERROR" )
low_error = true;
else if( !str.empty() )
if( !str.empty() )
{
current_error = "expected " + str;
debug( "Set error='" + current_error + "'" );
if( pos >= max_pos )
{
debug( "Set error='" + str + "' "
"at pos='" + std::to_string(pos) + "' "
"mp='" + std::to_string(max_pos) + "'" );
if( pos > max_pos )
{
debug( "ERROR SAVED" );
saved_errors.clear();
}
else
debug( "ERROR ADDED" );
if( saved_errors.end() == std::find(saved_errors.begin(), saved_errors.end(), str) )
saved_errors.push_back(str);
max_pos = pos;
}
}
}

bool loop_error(std::string str)
{
current_error = str;
saved_error = current_error;
debug( "Set loop error='" + current_error + "'" );
// Loop error takes precedence over all other errors
saved_errors.clear();
saved_errors.push_back(str);
debug( "Set loop error='" + str + "'" );
return false;
}

void restore(saved_pos s)
{
if( pos >= max_pos )
if( pos > max_pos )
{
if( !current_error.empty() &&
( !low_error || pos > max_pos || saved_error.empty() ) )
{
debug("save error='" + current_error + "'");
saved_error = current_error;
}
debug("error, pos > max_pos ?!?!?");
max_pos = pos;
}
pos = s.pos;
Expand Down Expand Up @@ -262,11 +270,6 @@ class parse {
return true;
}
}
if( c == ',' )
{
current_error = "comma";
debug( "Set error='" + current_error + "'" );
}
return false;
}
bool eol()
Expand Down

0 comments on commit 41f3293

Please sign in to comment.