Author: kjs
Date: Wed Apr  4 13:08:48 2007
New Revision: 17979

Modified:
   trunk/compilers/pirc/src/pirparser.c

Log:
compilers/pirc:
* fixed long invocation syntax
* add some comments here and there, changed syntax_error() to bail out after 
first error,resulting in much better error report.

Modified: trunk/compilers/pirc/src/pirparser.c
==============================================================================
--- trunk/compilers/pirc/src/pirparser.c        (original)
+++ trunk/compilers/pirc/src/pirparser.c        Wed Apr  4 13:08:48 2007
@@ -265,23 +265,35 @@
     }
     else {
         if (p->curtoken == T_EOF) { /* no characters have been read, so 
nothing to display */
-            syntax_error(p, 3 , "expected ", find_keyword(expected), " but got 
end of file");
+            syntax_error(p, 3 , "expected '", find_keyword(expected), "' but 
got end of file");
             exit_parser(p);     /* no use to continue when having read end of 
file */
         }
         else { /* 'normal' error; not end of file yet */
-            syntax_error(p, 4, "expected ", find_keyword(expected), " but got: 
", find_keyword(p->curtoken));
+            syntax_error(p, 4, "expected '", find_keyword(expected), "' but 
got: ", find_keyword(p->curtoken));
 
-            /* Try to reduce errors; skip tokens up to ".end" and
-             * try to continue with the next subroutine, if any
+            /* XXX
+            * exiting here right away gives a much nicer error report. 
Suggestion for later: try to read tokens
+            * up to end of line where syntax_error() is called, at >that< 
point, we know what the next token should
+            * be, probably making it possible to continue without too many 
errors.
+            */
+            exit_parser(p);
+
+            /* Try to reduce errors; skip tokens up to the end of line and
+             * try to continue with the next line, if any
              */
+
+            /*
             do {
                 next(p);
             }
-            while (p->curtoken != T_END && p->curtoken != T_EOF);
+            while (p->curtoken != T_NEWLINE && p->curtoken != T_EOF);
+            */
 
             /* loop broke, see what happened: */
-            if (p->curtoken == T_END) next(p);
-            else exit_parser(p); /* we got T_EOF; clean up and go home */
+            /*
+            if (p->curtoken == T_NEWLINE) next(p);
+            else exit_parser(p); */ /* we got T_EOF; clean up and go home */
+
 
         }
     }
@@ -334,11 +346,9 @@
         case T_PASM_IREG: case T_IREG:
         case T_PASM_SREG: case T_SREG:
         case T_MACRO_IDENT:
-            exprtok = p->curtoken;
-
+            exprtok = p->curtoken; /* store current token type to return */
             /* emit the expression */
             emit_expr(p, get_current_token(p->lexer));
-
             next(p);
             break;
         default:
@@ -361,12 +371,11 @@
 */
 static void
 string_value(parser_state *p) {
-    /* also allow string registers */
+    /* also allow string registers, but /no/ identifiers! */
     switch (p->curtoken) {
         case T_SREG:
         case T_PASM_SREG:
         case T_STRING_CONSTANT:
-        /* case T_IDENTIFIER: string variable? */
             next(p);
             break;
         default:
@@ -797,7 +806,11 @@
 
 =item *
 
-  return_statement -> '.return' ( arguments | target ['->' method] arguments | 
methodcall ) '\n'
+  return_statement -> '.return' ( arguments
+                                | target ['->' method] arguments
+                                | methodcall
+                                )
+                                '\n'
 
 =cut
 
@@ -887,7 +900,9 @@
 
 =item *
 
-  local_id_list -> IDENTIFIER [':unique_reg'] { ',' IDENTIFIER [':unique_reg'] 
}
+  local_id_list -> local_id { ',' local_id }
+
+  local_id  -> IDENTIFIER [':unique_reg']
 
 =cut
 
@@ -897,7 +912,10 @@
     emit_expr(p, get_current_token(p->lexer));
     match(p, T_IDENTIFIER);
 
-    if (p->curtoken == T_UNIQUE_REG_FLAG) next(p);
+    /* process the flag, if any */
+    if (p->curtoken == T_UNIQUE_REG_FLAG) {
+        next(p);
+    }
 
     while (p->curtoken == T_COMMA) {
         next(p); /* skip comma */
@@ -995,7 +1013,7 @@
 
   conditional_expression -> expression [cond_op expression]
 
-  cond_op                -> '>' | '>=' | '<' | '<=' | '==' | '!='
+  cond_op -> '>' | '>=' | '<' | '<=' | '==' | '!='
 
 =cut
 
@@ -1240,9 +1258,36 @@
 
 =item *
 
+  invokable -> IDENTIFIER | PREG
+
+=cut
+
+*/
+static void
+invocant(parser_state *p) {
+    switch (p->curtoken) {
+        case T_IDENTIFIER:
+        case T_PREG:
+        case T_PASM_PREG:
+            emit_invokable(p, get_current_token(p->lexer));
+            next(p);
+            break;
+        default:
+            syntax_error(p, 1, "invokable object expected");
+            break;
+    }
+}
+
+/*
+
+=item *
+
   long-invocation -> '.pcc_begin' '\n'
                      { '.arg' expression arg_flags }
-                     ('.pcc_call'|'.nci_call'|'.meth_call')
+                     ( '.pcc_call'|'.nci_call') invocant '\n'
+                     | '.invocant' invocant '\n'
+                       '.meth_call' method '\n'
+                     )
                      { (local_declaration| '.result' target '\n') }
                      '.pcc_end' '\n'
 
@@ -1255,12 +1300,12 @@
 
     emit_invocation_start(p);
 
-    match(p, T_PCC_BEGIN);  /* '.pcc_begin '\n' ... */
+    match(p, T_PCC_BEGIN);               /* '.pcc_begin '\n' */
     match(p, T_NEWLINE);
 
     /* arguments */
     emit_args_start(p);
-    while (p->curtoken == T_ARG) { /* ... { '.arg' expr [flag] '\n' } ... */
+    while (p->curtoken == T_ARG) {      /* { '.arg' expr [flag] '\n' } */
         next(p);
         expression(p);
         arg_flags(p);
@@ -1270,18 +1315,18 @@
 
     /* the invocant and/or sub to be called */
     switch (p->curtoken) {
-        case T_PCC_CALL: /* ... '.pcc_call' target '\n' ... */
-        case T_NCI_CALL: /* ... '.nci_call' target '\n' ... */
+        case T_PCC_CALL:                /* '.pcc_call' invocant '\n' */
+        case T_NCI_CALL:                /* '.nci_call' invocant '\n' */
             next(p);
-            target(p);
+            invocant(p);
             match(p, T_NEWLINE);
             break;
-        case T_INVOCANT: /* '.invocant' target '\n' */
+        case T_INVOCANT:                /* '.invocant' invocant '\n' */
             next(p);
-            target(p);
+            invocant(p);
             match(p, T_NEWLINE);
-            match(p, T_METH_CALL); /* .meth_call target '\n' */
-            target(p);
+            match(p, T_METH_CALL);      /* .meth_call method '\n' */
+            method(p);
             match(p, T_NEWLINE);
             break;
         default:
@@ -1468,7 +1513,7 @@
 
 =item *
 
-  multi-result-invocation -> target_list '=' (invokable arguments | 
methodcall)) '\n'
+  multi-result-invocation -> target_list '=' (invokable arguments | 
methodcall) '\n'
 
   invokable -> IDENTIFIER | PREG | STRINGC
 
@@ -1851,13 +1896,13 @@
                 break;
             case T_OUTER_FLAG:
             case T_VTABLE_FLAG: {
-                emit_sub_flag(p, p->curtoken);
+                emit_sub_flag(p, p->curtoken); /* emit current flag */
                 next(p);
-                emit_list_start(p);
+                emit_list_start(p); /* start a list of flag arguments -- 
needed? only 1 arg.. */
                 match(p, T_LPAREN);
                 emit_expr(p, get_current_token(p->lexer));
                 match(p, T_STRING_CONSTANT);
-                emit_list_end(p);
+                emit_list_end(p); /* close list of arguments -- needed? */
                 match(p, T_RPAREN);
                 break;
             }

Reply via email to