[Avida-SVN] r1780 - in development/source: script targets/avida-s
brysonda at myxo.css.msu.edu
brysonda at myxo.css.msu.edu
Tue Jul 10 13:46:29 PDT 2007
Author: brysonda
Date: 2007-07-10 16:46:29 -0400 (Tue, 10 Jul 2007)
New Revision: 1780
Modified:
development/source/script/AvidaScript.h
development/source/script/cLexer.l
development/source/script/cParser.cc
development/source/script/cParser.h
development/source/targets/avida-s/main.cc
Log:
Add basic call tracing (debugging purposes) to cParser. Fix a few uncaught error conditions, though there are probably many to go. Add more robust error reporting, including filename, line number, and actual token text.
Modified: development/source/script/AvidaScript.h
===================================================================
--- development/source/script/AvidaScript.h 2007-07-10 19:36:11 UTC (rev 1779)
+++ development/source/script/AvidaScript.h 2007-07-10 20:46:29 UTC (rev 1780)
@@ -30,46 +30,46 @@
ENDL,
COMMA,
- OP_BIT_NOT,
+ OP_BIT_NOT, // 4
OP_BIT_AND,
OP_BIT_OR,
- OP_LOGIC_NOT,
+ OP_LOGIC_NOT, // 7
OP_LOGIC_AND,
OP_LOGIC_OR,
- OP_ADD,
+ OP_ADD, // 10
OP_SUB,
OP_MUL,
OP_DIV,
OP_MOD,
- DOT,
+ DOT, // 15
ASSIGN,
REF,
- OP_EQ,
+ OP_EQ, // 18
OP_LE,
OP_GE,
OP_LT,
OP_GT,
OP_NEQ,
- PREC_OPEN,
+ PREC_OPEN, // 24
PREC_CLOSE,
- IDX_OPEN,
+ IDX_OPEN, // 26
IDX_CLOSE,
- ARR_OPEN,
+ ARR_OPEN, // 28
ARR_CLOSE,
ARR_RANGE,
ARR_EXPAN,
ARR_WILD,
- MAT_MODIFY,
+ MAT_MODIFY, // 33
- TYPE_ARRAY,
+ TYPE_ARRAY, // 34
TYPE_CHAR,
TYPE_FLOAT,
TYPE_INT,
@@ -77,29 +77,29 @@
TYPE_STRING,
TYPE_VOID,
- CMD_IF,
+ CMD_IF, // 41
CMD_ELSE,
CMD_ENDIF,
- CMD_WHILE,
+ CMD_WHILE, // 44
CMD_ENDWHILE,
- CMD_FOREACH,
+ CMD_FOREACH, // 46
CMD_ENDFOREACH,
- CMD_FUNCTION,
+ CMD_FUNCTION, // 48
CMD_ENDFUNCTION,
- CMD_RETURN,
+ CMD_RETURN, // 50
- ID,
+ ID, // 51
- FLOAT,
+ FLOAT, // 52
INT,
STRING,
CHAR,
- UNKNOWN,
+ UNKNOWN, // 56
INVALID
} ASToken_t;
@@ -108,6 +108,7 @@
AS_PARSE_ERR_UNTERMINATED_EXPR,
AS_PARSE_ERR_NULL_EXPR,
AS_PARSE_ERR_EOF,
+ AS_PARSE_ERR_EMPTY,
AS_PARSE_ERR_INTERNAL,
AS_PARSE_ERR_UNKNOWN
} ASParseError_t;
Modified: development/source/script/cLexer.l
===================================================================
--- development/source/script/cLexer.l 2007-07-10 19:36:11 UTC (rev 1779)
+++ development/source/script/cLexer.l 2007-07-10 20:46:29 UTC (rev 1780)
@@ -33,11 +33,12 @@
%option c++
%option noyywrap
+%option yylineno
%%
#.*\n /* ignore comments */
-\/\/ /* ignore comments */
+\/\/.*\n /* ignore comments */
[ \t]+ /* ignore whitespace */
Modified: development/source/script/cParser.cc
===================================================================
--- development/source/script/cParser.cc 2007-07-10 19:36:11 UTC (rev 1779)
+++ development/source/script/cParser.cc 2007-07-10 20:46:29 UTC (rev 1780)
@@ -189,29 +189,49 @@
*/
+
+#define PARSE_DEBUG(x) { std::cerr << x << std::endl; }
+#define PARSE_TRACE(x) { std::cerr << "trace: " << x << std::endl; }
+
#define PARSE_ERROR(x) reportError(AS_PARSE_ERR_ ## x, __LINE__)
#define PARSE_UNEXPECT() { if (currentToken()) { PARSE_ERROR(UNEXPECTED_TOKEN); } else { PARSE_ERROR(EOF); } }
cParser::cParser(cASLibrary* library)
: m_library(library)
+, m_filename("(unknown)")
, m_eof(false)
, m_success(true)
, m_cur_tok(INVALID)
, m_next_tok(INVALID)
+, m_cur_text(NULL)
, m_err_eof(false)
{
}
bool cParser::Parse(cFile& input)
{
+ m_filename = input.GetFilename();
m_lexer = new cLexer(input.GetFileStream());
- parseStatementList();
+
+ m_tree = parseStatementList();
+
+ if (!m_eof) PARSE_UNEXPECT();
+ //if (!m_tree) PARSE_ERROR(EMPTY); @todo - statement list doesn't actually return anything yet
+
delete m_lexer;
+ m_lexer = NULL;
return m_success;
}
+cParser::~cParser()
+{
+ delete m_tree;
+ delete m_lexer;
+}
+
+
void cParser::Accept(cASTVisitor& visitor)
{
@@ -225,12 +245,32 @@
} else {
m_cur_tok = (ASToken_t)m_lexer->yylex();
}
+ delete m_cur_text;
+ m_cur_text = NULL;
+ PARSE_DEBUG("nextToken: " << m_cur_tok);
return m_cur_tok;
}
+ASToken_t cParser::peekToken()
+{
+ if (m_next_tok == INVALID) {
+ delete m_cur_text;
+ m_cur_text = new cString(m_lexer->YYText());
+ m_next_tok = (ASToken_t)m_lexer->yylex();
+ }
+ return m_next_tok;
+}
+const cString& cParser::currentText()
+{
+ if (!m_cur_text) m_cur_text = new cString(m_lexer->YYText());
+ return *m_cur_text;
+}
+
+
cASTNode* cParser::parseArrayUnpack()
{
+ PARSE_TRACE("parseArrayUnpack");
cASTNode* au = NULL;
if (nextToken() != ID) {
@@ -262,6 +302,7 @@
cASTNode* cParser::parseArgumentList()
{
+ PARSE_TRACE("parseArgumentList");
cASTNode* al = NULL;
parseExpression();
@@ -274,6 +315,7 @@
cASTNode* cParser::parseAssignment()
{
+ PARSE_TRACE("parseAssignment");
cASTNode* an = NULL;
nextToken();
@@ -284,6 +326,7 @@
cASTNode* cParser::parseCallExpression()
{
+ PARSE_TRACE("parseCallExpression");
cASTNode* ce = NULL;
bool eoe = false;
@@ -296,9 +339,8 @@
}
break;
case PREC_OPEN:
- nextToken();
- parseArgumentList();
- if (nextToken() != PREC_CLOSE) {
+ if (nextToken() != PREC_CLOSE) parseArgumentList();
+ if (currentToken() != PREC_CLOSE) {
PARSE_UNEXPECT();
return ce;
}
@@ -331,6 +373,7 @@
cASTNode* cParser::parseCodeBlock(bool& loose)
{
+ PARSE_TRACE("parseCodeBlock");
cASTNode* cb = NULL;
nextToken();
@@ -349,6 +392,7 @@
cASTNode* cParser::parseExpression()
{
+ PARSE_TRACE("parseExpression");
cASTNode* expr = NULL;
expr = parseExprP0();
@@ -364,6 +408,7 @@
cASTNode* cParser::parseExprP0()
{
+ PARSE_TRACE("parseExprP0");
cASTNode* l = parseExprP1();
cASTNode* r = NULL;
@@ -374,6 +419,7 @@
ASToken_t op = currentToken();
nextToken();
r = parseExprP1();
+ if (!r) PARSE_ERROR(NULL_EXPR);
l = new cASTExpressionBinary(op, l, r);
break;
@@ -387,6 +433,7 @@
cASTNode* cParser::parseExprP1()
{
+ PARSE_TRACE("parseExprP1");
cASTNode* l = parseExprP2();
cASTNode* r = NULL;
@@ -397,6 +444,7 @@
ASToken_t op = currentToken();
nextToken();
r = parseExprP2();
+ if (!r) PARSE_ERROR(NULL_EXPR);
l = new cASTExpressionBinary(op, l, r);
break;
@@ -410,6 +458,7 @@
cASTNode* cParser::parseExprP2()
{
+ PARSE_TRACE("parseExprP2");
cASTNode* l = parseExprP3();
cASTNode* r = NULL;
@@ -420,6 +469,7 @@
ASToken_t op = currentToken();
nextToken();
r = parseExprP3();
+ if (!r) PARSE_ERROR(NULL_EXPR);
l = new cASTExpressionBinary(op, l, r);
break;
@@ -433,6 +483,7 @@
cASTNode* cParser::parseExprP3()
{
+ PARSE_TRACE("parseExprP3");
cASTNode* l = parseExprP4();
cASTNode* r = NULL;
@@ -447,6 +498,7 @@
ASToken_t op = currentToken();
nextToken();
r = parseExprP4();
+ if (!r) PARSE_ERROR(NULL_EXPR);
l = new cASTExpressionBinary(op, l, r);
break;
@@ -460,6 +512,7 @@
cASTNode* cParser::parseExprP4()
{
+ PARSE_TRACE("parseExprP4");
cASTNode* l = parseExprP5();
cASTNode* r = NULL;
@@ -470,6 +523,7 @@
ASToken_t op = currentToken();
nextToken();
r = parseExprP5();
+ if (!r) PARSE_ERROR(NULL_EXPR);
l = new cASTExpressionBinary(op, l, r);
break;
@@ -483,6 +537,7 @@
cASTNode* cParser::parseExprP5()
{
+ PARSE_TRACE("parseExprP5");
cASTNode* l = parseExprP6();
cASTNode* r = NULL;
@@ -494,6 +549,7 @@
ASToken_t op = currentToken();
nextToken();
r = parseExprP6();
+ if (!r) PARSE_ERROR(NULL_EXPR);
l = new cASTExpressionBinary(op, l, r);
break;
@@ -507,6 +563,7 @@
cASTNode* cParser::parseExprP6()
{
+ PARSE_TRACE("parseExprP6");
cASTNode* expr = NULL;
switch (currentToken()) {
@@ -519,8 +576,7 @@
case ID:
if (peekToken() == PREC_OPEN) {
nextToken();
- nextToken();
- parseArgumentList();
+ if (nextToken() != PREC_CLOSE) parseArgumentList();
if (currentToken() != PREC_CLOSE) {
PARSE_UNEXPECT();
return expr;
@@ -533,6 +589,7 @@
case PREC_OPEN:
nextToken();
expr = parseExpression();
+ if (!expr) PARSE_ERROR(NULL_EXPR);
if (currentToken() != PREC_CLOSE) {
PARSE_UNEXPECT();
return expr;
@@ -544,8 +601,7 @@
return expr;
}
case ARR_OPEN:
- nextToken();
- parseArgumentList();
+ if (nextToken() != ARR_CLOSE) parseArgumentList();
if (currentToken() != ARR_CLOSE) {
PARSE_UNEXPECT();
return expr;
@@ -557,6 +613,7 @@
case OP_SUB:
ASToken_t op = currentToken();
expr = new cASTExpressionUnary(op, parseExpression());
+ if (!expr) PARSE_ERROR(NULL_EXPR);
nextToken();
return expr;
@@ -564,12 +621,14 @@
break;
}
+ nextToken();
if (expr) expr = parseExprP6_Index(expr);
return expr;
}
cASTNode* cParser::parseExprP6_Index(cASTNode* l)
{
+ PARSE_TRACE("parseExprP6_Index");
while (currentToken() == DOT || currentToken() == IDX_OPEN) {
if (currentToken() == DOT) {
if (nextToken() != ID) {
@@ -578,8 +637,7 @@
}
if (peekToken() == PREC_OPEN) {
nextToken();
- nextToken();
- parseArgumentList();
+ if (nextToken() != PREC_CLOSE) parseArgumentList();
if (currentToken() != PREC_CLOSE) {
PARSE_UNEXPECT();
return l;
@@ -605,6 +663,7 @@
cASTNode* cParser::parseForeachStatement()
{
+ PARSE_TRACE("parseForeachStatement");
cASTNode* fs = NULL;
switch (nextToken()) {
@@ -649,6 +708,7 @@
cASTNode* cParser::parseFunctionDefine()
{
+ PARSE_TRACE("parseFunctionDefine");
cASTNode* fd = parseFunctionHeader(false);
bool loose = false;
@@ -663,6 +723,7 @@
cASTNode* cParser::parseFunctionHeader(bool declare)
{
+ PARSE_TRACE("parseFunctionHeader");
cASTNode* fd = NULL;
switch (nextToken()) {
@@ -697,14 +758,15 @@
return fd;
}
- nextToken();
- if (declare) {
- parseVarDeclareList();
- } else {
- parseArgumentList();
+ if (nextToken() != PREC_CLOSE) {
+ if (declare) {
+ parseVarDeclareList();
+ } else {
+ parseArgumentList();
+ }
}
- if (nextToken() != PREC_CLOSE) {
+ if (currentToken() != PREC_CLOSE) {
PARSE_UNEXPECT();
return fd;
}
@@ -714,6 +776,7 @@
cASTNode* cParser::parseIDStatement()
{
+ PARSE_TRACE("parseIDStatement");
cASTNode* is = NULL;
switch (nextToken()) {
@@ -739,6 +802,7 @@
cASTNode* cParser::parseIfStatement()
{
+ PARSE_TRACE("parseIfStatement");
cASTNode* is = NULL;
if (nextToken() != PREC_OPEN) {
@@ -772,6 +836,7 @@
cASTNode* cParser::parseIndexExpression()
{
+ PARSE_TRACE("parseIndexExpression");
cASTNode* ie = NULL;
nextToken();
@@ -785,6 +850,7 @@
cASTNode* cParser::parseLooseBlock()
{
+ PARSE_TRACE("parseLooseBlock");
nextToken();
cASTNode* sl = parseStatementList();
if (currentToken() != ARR_CLOSE) {
@@ -795,6 +861,7 @@
cASTNode* cParser::parseRefStatement()
{
+ PARSE_TRACE("parseRefStatement");
cASTNode* rs = NULL;
switch (nextToken()) {
@@ -813,6 +880,7 @@
cASTNode* cParser::parseReturnStatement()
{
+ PARSE_TRACE("parseReturnStatement");
cASTNode* rs = NULL;
nextToken();
@@ -823,6 +891,7 @@
cASTNode* cParser::parseStatementList()
{
+ PARSE_TRACE("parseStatementList");
cASTNode* sl = NULL;
#define CHECK_LINETERM() { if (!checkLineTerm(sl)) return sl; }
@@ -886,6 +955,7 @@
cASTNode* cParser::parseVarDeclare()
{
+ PARSE_TRACE("parseVarDeclare");
cASTNode* vd = NULL;
switch (currentToken()) {
@@ -919,8 +989,7 @@
parseExpression();
break;
case PREC_OPEN:
- nextToken();
- parseArgumentList();
+ if (nextToken() != PREC_CLOSE) parseArgumentList();
if (currentToken() != PREC_CLOSE) {
PARSE_UNEXPECT();
return vd;
@@ -936,6 +1005,7 @@
cASTNode* cParser::parseVarDeclareList()
{
+ PARSE_TRACE("parseVarDeclareList");
cASTNode* vl = NULL;
parseVarDeclare();
@@ -948,7 +1018,8 @@
cASTNode* cParser::parseWhileStatement()
{
- cASTNode* ws = NULL;
+ PARSE_TRACE("parseWhileStatement");
+ cASTNode* ws = NULL;
if (nextToken() != PREC_OPEN) {
PARSE_UNEXPECT();
@@ -976,7 +1047,7 @@
bool cParser::checkLineTerm(cASTNode* node)
{
- nextToken();
+ PARSE_TRACE("checkLineTerm");
if (currentToken() == SUPPRESS) {
// @todo - mark output as suppressed
return true;
@@ -993,23 +1064,32 @@
{
m_success = false;
- std::cerr << "error: ";
+ std::cerr << m_filename << ":";
+
+ int lineno = m_lexer ? m_lexer->lineno() : 0;
+ if (lineno) std::cerr << lineno;
+ else std::cerr << "?";
+
+ std::cerr << ": error: ";
switch (err) {
case AS_PARSE_ERR_UNEXPECTED_TOKEN:
- std::cerr << "unexpected token '" << currentToken() << "'." << std::endl;
+ std::cerr << "unexpected token '" << currentText() << "'." << std::endl;
break;
case AS_PARSE_ERR_UNTERMINATED_EXPR:
- std::cerr << "unterminated expression'" << currentToken() << "'." << std::endl;
+ std::cerr << "unterminated expression." << std::endl;
break;
case AS_PARSE_ERR_NULL_EXPR:
- std::cerr << "expected expression, found '" << currentToken() << "'." << std::endl;
+ std::cerr << "expected expression, found '" << currentText() << "'." << std::endl;
case AS_PARSE_ERR_EOF:
if (!m_err_eof) {
std::cerr << "unexpected end of file" << std::endl;
m_err_eof = true;
}
break;
+ case AS_PARSE_ERR_EMPTY:
+ std::cerr << "empty script, no valid statements found" << std::endl;
+ break;
case AS_PARSE_ERR_INTERNAL:
std::cerr << "internal parser error at cParser.cc:" << line << std::endl;
case AS_PARSE_ERR_UNKNOWN:
Modified: development/source/script/cParser.h
===================================================================
--- development/source/script/cParser.h 2007-07-10 19:36:11 UTC (rev 1779)
+++ development/source/script/cParser.h 2007-07-10 20:46:29 UTC (rev 1780)
@@ -53,6 +53,9 @@
{
private:
cASLibrary* m_library;
+
+ cString m_filename;
+
cLexer* m_lexer;
cASTNode* m_tree;
@@ -61,6 +64,7 @@
ASToken_t m_cur_tok;
ASToken_t m_next_tok;
+ cString* m_cur_text;
bool m_err_eof;
@@ -72,6 +76,7 @@
public:
cParser(cASLibrary* library);
+ ~cParser();
bool Parse(cFile& input);
void Accept(cASTVisitor& visitor);
@@ -80,8 +85,10 @@
private:
inline ASToken_t currentToken() { return m_cur_tok; }
ASToken_t nextToken();
- inline ASToken_t peekToken();
+ ASToken_t peekToken();
+ const cString& currentText();
+
cASTNode* parseArgumentList();
cASTNode* parseArrayUnpack();
cASTNode* parseAssignment();
@@ -116,11 +123,4 @@
};
-inline ASToken_t cParser::peekToken()
-{
- if (m_next_tok == INVALID) m_next_tok = (ASToken_t)m_lexer->yylex();
- return m_next_tok;
-}
-
-
#endif
Modified: development/source/targets/avida-s/main.cc
===================================================================
--- development/source/targets/avida-s/main.cc 2007-07-10 19:36:11 UTC (rev 1779)
+++ development/source/targets/avida-s/main.cc 2007-07-10 20:46:29 UTC (rev 1780)
@@ -28,7 +28,9 @@
#include "cParser.h"
#include "PlatformExpert.h"
+#include <iostream>
+
int main (int argc, char * const argv[])
{
PlatformExpert::Initialize();
@@ -37,9 +39,17 @@
cParser* parser = new cParser(lib);
cFile file;
- if (file.Open("main.asl")) parser->Parse(file);
+ if (file.Open("main.asl")) {
+ if (parser->Parse(file)) {
+ std::cout << "Parse Successful" << std::endl;
+ ExitAvida(0);
+ } else {
+ std::cout << "Parse Failed" << std::endl;
+ ExitAvida(1);
+ }
+ } else {
+ std::cerr << "error: unable to open script" << std::endl;
+ }
- ExitAvida(0);
-
- return 0;
+ return -1;
}
More information about the Avida-cvs
mailing list