diff options
| author | Shinya Sato <shinnya.sato@gmail.com> | 2024-02-16 20:33:11 +0900 |
|---|---|---|
| committer | Shinya Sato <shinnya.sato@gmail.com> | 2024-02-16 20:33:11 +0900 |
| commit | 90a52d957e96501e7eef4890e4ceb28c889ac317 (patch) | |
| tree | 950a4e629de8ad66831c20f22ce828ef8d9a4aa3 | |
| parent | e813c7b6903feb2afa106cd0cf9732fc19b363f2 (diff) | |
| download | inpla-90a52d957e96501e7eef4890e4ceb28c889ac317.tar.gz inpla-90a52d957e96501e7eef4890e4ceb28c889ac317.zip | |
v0.11.2
| -rw-r--r-- | Changelog.md | 8 | ||||
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | sample/TuringMachine.in | 131 | ||||
| -rw-r--r-- | src/inpla.y | 237 | ||||
| -rw-r--r-- | src/lex.l | 38 |
5 files changed, 289 insertions, 127 deletions
diff --git a/Changelog.md b/Changelog.md index 4ea452f..db8b8ac 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,13 @@ # Change log +### v0.11.2 (released on 16 Feb 2024) + +#### Polished + +- **Kindly error messages**: Error messages have column number. Other helpful clues can be included. + + + ### v0.11.1 (released on 14 Feb 2024) #### Bug Fix @@ -6,7 +6,7 @@ Inpla is a multi-threaded parallel interpreter of interaction nets. Once you write programs for sequential execution, it works also in multi-threaded parallel execution. Each thread is managed on each CPU-core with POSIX-thread library. -* The current version is 0.11.1, released on **14 Feb 2024**. (See [Changelog.md](Changelog.md) for details.) +* The current version is 0.11.2, released on **16 Feb 2024**. (See [Changelog.md](Changelog.md) for details.) * The below graph shows speed-up ratio to threads numbers for programs in the following benchmark table.  diff --git a/sample/TuringMachine.in b/sample/TuringMachine.in new file mode 100644 index 0000000..2819d19 --- /dev/null +++ b/sample/TuringMachine.in @@ -0,0 +1,131 @@ +// ------------------------------------------------------------- +// Turing Machine +// ------------------------------------------------------------- +// Every 1 on tapes becomes 0. +// It finishes when the head reads a tape cell whose value is 0. +// +// Rule +// (state, sym) => command +// (0 , 1) => Write(0, 1) // write 0 and change state into 1 +// (1 , 0) => GoRight(2) // headPos+1 and change state into 2 +// (2 , 1) => Write(0, 1) // write 0 and change state into 1 +// otherwise => Halt +// +// Example: +// (tape, state, headPos) +// ([0,1,1,1,1,0], 1, 0) -->* ([0,0,0,0,0,0,0],2,5) +// + + + +// ----------------------------------------- +// getRule +// rule << getRule( (int state, int sym) ) +// NOTE: getRule needs a pair (state, sym). +// So it should be called such as +// ret << getRule( (state, sym) ); +// ----------------------------------------- + +getRule(r) >< (int state, int sym) +| (state==0) && (sym==1) => r~Write(0, 1) +| (state==1) && (sym==0) => r~GoRight(2) +| (state==2) && (sym==1) => r~Write(0, 1) +| _ => r~Halt; + + + + +// ----------------------------------------- +// changeSym +// resultTape << changeSym(headPos, sym, tape) +// ----------------------------------------- + +changeSym(resultTape, headPos, sym) >< t:ts => // <-- t:ts is tape + resultTape << changeSym_sub([], headPos, sym, t:ts); + +changeSym_sub(r, done, int headPos, int sym) >< (int t):ts + | headPos == 0 => r << Append(done, sym:ts) + | _ => done_new << Append(done, [t]), + r << changeSym_sub(done_new, headPos-1, sym, ts); + +changeSym_sub(r, done, headPos, sym) >< [] => + r~Error(done, headPos, sym); + + + + +// ----------------------------------------- +// do +// configure << do(tape, int state, int headPos, Command) +// ----------------------------------------- + +do(r, tape, int state, int headPos) >< Write(sym, new_state) => + changeSym(doneTape, headPos, sym) ~ tape, + r ~ Configure(doneTape, new_state, headPos); + +do(r, tape, int state, int head) >< GoRight(int new_state) => + r ~ Configure(tape, new_state, head+1); + +do(r, tape, int state, int head) >< Halt => + r ~ STOP_Configure(tape, state, head); + + + +// ----------------------------------------- +// getSym +// tapeDone << getSym(sym, int headPos, tape) +// ----------------------------------------- + +getSym(tapeDone, sym, int headPos) >< t:ts => // <- t:ts is tape + tapeDone << getSym_sub([], sym, headPos, t:ts); + + +getSym_sub(r, done, sym, int headPos) >< (int t):ts + | headPos == 0 => r << Append(done, t:ts), sym~t + | _ => cnt << Append(done,[t]), + r << getSym_sub(cnt, sym, headPos-1, ts); + +getSym_sub(r, done, sym, int headPos) >< [] + | headPos == 0 => r << Append(done, [0]), sym~0 + | _ => new_done << Append(done, [0]), + r << getSym_sub(new_done, sym, headPos-1, []); + + + +// ----------------------------------------- +// oneCycle +// configure << Configure(tape, int state, int headPos) +// ----------------------------------------- + +oneCycle(r) >< Configure(tape, int state, int headPos) => + tapeDone, sym << getSym(headPos, tape), + r << oneCycle_sub(tapeDone, state, headPos, sym); + +oneCycle_sub(r, tapeDone, int state, int headPos)><(int sym) => + rule << getRule( (state, sym) ), + r << do(tapeDone, state, headPos, rule); + + + +// ----------------------------------------- +// allCycle +// result << allCycle(Configure(tape, state, headPos)) +// ----------------------------------------- + +allCycle(r) >< Configure(tape, state, headPos) => + r1 << oneCycle(Configure(tape, state, headPos)), + r << allCycle(r1); + +allCycle(r) >< STOP_Configure(tape, state, headPos) => + r ~ Configure(tape, state, headPos); + + + + +// ----------------------------------------- +// main +// ----------------------------------------- + +configure ~ Configure([1,1,1,1,1,0], 0, 0), //(tape, state, headPos) +r << allCycle(configure); +r; // -->* Configure([0,0,0,0,0,0,0],2,5) diff --git a/src/inpla.y b/src/inpla.y index 00a3a9a..26ffe63 100644 --- a/src/inpla.y +++ b/src/inpla.y @@ -22,8 +22,8 @@ // ---------------------------------------------- -#define VERSION "0.11.1" -#define BUILT_DATE "14 Feb 2024" +#define VERSION "0.11.2" +#define BUILT_DATE "16 Feb 2024" // ------------------------------------------------------------------ @@ -95,7 +95,7 @@ extern FILE *yyin; extern int yylex(); int yyerror(); #define YY_NO_INPUT -extern int yylineno; +extern int yylineno, yycolumn; // For error message when nested source files are specified. #define MY_YYLINENO @@ -157,18 +157,27 @@ static char *Errormsg = NULL; Ast *ast; } -%token <chval> NAME AGENT +%token <chval> NAME "NAME_LITERAL" +%token <chval> AGENT "AGENT_LITERAL" %token <longval> NUMERAL_LITERAL %token <chval> STRING_LITERAL -%token LP RP LC RC LB RB COMMA CROSS DELIMITER ABR -%token COLON -%token TO CNCT -%token ANNOTATE_L ANNOTATE_R +%token CROSS "><" +%token ABR "<<" +%token ARROW "=>" +%token PIPE "|" -%token PIPE -%token NOT AND OR LD EQUAL NE GT GE LT LE -%token ADD SUB MUL DIV MOD INT LET IN END IF THEN ELSE ANY WHERE RAND DEF +%token ANNOTATE_L "(*L)" +%token ANNOTATE_R "(*R)" + +%token NE "!=" +%token LD "=" +%token EQUAL "==" +%token LE "<=" +%token GE ">=" + +%token NOT AND OR +%token INT LET IN END IF THEN ELSE WHERE RAND DEF %token INTERFACE IFCE PRNAT FREE EXIT %token END_OF_FILE USE @@ -190,39 +199,47 @@ abr_annotate //body %nonassoc REDUCE -%nonassoc RP +%nonassoc ')' -%right COLON +%right ':' //%right LD //%right EQ //%left NE GE GT LT //%left ADD SUB //%left MULT DIV + // For error message information + %define parse.error verbose + %locations + + %% s -: error DELIMITER { +: error ';' { yyclearin; yyerrok; puts(Errormsg); free(Errormsg); ast_heapReInit(); if (yyin == stdin) yylineno=0; + yycolumn=1; // YYACCEPT; YYABORT; } -| DELIMITER { +| ';' { if (yyin == stdin) yylineno=0; + yycolumn=1; YYACCEPT; } -| body DELIMITER +| body ';' { exec($1); // $1 is a list such as [stmlist, aplist] ast_heapReInit(); if (yyin == stdin) yylineno=0; + yycolumn=1; YYACCEPT; } -| rule DELIMITER { +| rule ';' { if (make_rule($1)) { if (yyin == stdin) yylineno=0; YYACCEPT; @@ -230,9 +247,11 @@ s if (yyin == stdin) yylineno=0; YYABORT; } + yycolumn=1; } | command { if (yyin == stdin) yylineno=0; + yycolumn=1; YYACCEPT; } ; @@ -246,10 +265,10 @@ body | aplist WHERE stmlist_nondelimiter { $$ = ast_makeAST(AST_BODY, $3, $1);} | aplist WHERE { $$ = ast_makeAST(AST_BODY, NULL, $1);} | LET stmlist IN aplist END { $$ = ast_makeAST(AST_BODY, $2, $4);} -| LET stmlist DELIMITER IN aplist END { $$ = ast_makeAST(AST_BODY, $2, $5);} +| LET stmlist ';' IN aplist END { $$ = ast_makeAST(AST_BODY, $2, $5);} | LET IN aplist END { $$ = ast_makeAST(AST_BODY, NULL, $3);} -| LC stmlist RC aplist { $$ = ast_makeAST(AST_BODY, $2, $4);} -| LC stmlist DELIMITER RC aplist { $$ = ast_makeAST(AST_BODY, $2, $5);} +| '{' stmlist '}' aplist { $$ = ast_makeAST(AST_BODY, $2, $4);} +| '{' stmlist ';' '}' aplist { $$ = ast_makeAST(AST_BODY, $2, $5);} ; // rule is changed as follows: @@ -265,16 +284,16 @@ body rule -: astterm CROSS astterm TO +: astterm CROSS astterm ARROW { $$ = ast_makeAST(AST_RULE, ast_makeAST(AST_CNCT, $1, $3), NULL); } -| astterm CROSS astterm TO body +| astterm CROSS astterm ARROW body { $$ = ast_makeAST(AST_RULE, ast_makeAST(AST_CNCT, $1, $3), $5); } -| astterm CROSS astterm TO if_sentence +| astterm CROSS astterm ARROW if_sentence { $$ = ast_makeAST(AST_RULE, ast_makeAST(AST_CNCT, $1, $3), $5); } @@ -293,38 +312,38 @@ name_params ; command: -| FREE name_params DELIMITER +| FREE name_params ';' { free_Names_ast($2); } -| FREE DELIMITER -| FREE IFCE DELIMITER +| FREE ';' +| FREE IFCE ';' { NameTable_free_all(); } -| FREE INTERFACE DELIMITER +| FREE INTERFACE ';' { NameTable_free_all(); } -| name_params DELIMITER +| name_params ';' { puts_Names_ast($1); } -| PRNAT NAME DELIMITER +| PRNAT NAME ';' { puts_Name_port0_nat($2); } -| INTERFACE DELIMITER +| INTERFACE ';' { NameTable_puts_all(); } -| IFCE DELIMITER +| IFCE ';' { NameTable_puts_all(); } -| EXIT DELIMITER {destroy(); exit(0);} -| USE STRING_LITERAL DELIMITER { +| EXIT ';' {destroy(); exit(0);} +| USE STRING_LITERAL ';' { // http://flex.sourceforge.net/manual/Multiple-Input-Buffers.html yyin = fopen($2, "r"); if (!yyin) { @@ -354,7 +373,7 @@ command: } -| DEF AGENT LD NUMERAL_LITERAL DELIMITER { +| DEF AGENT LD NUMERAL_LITERAL ';' { int entry=ast_recordConst($2,$4); if (!entry) { @@ -363,7 +382,7 @@ command: fflush(stdout); } } -| DEF AGENT LD SUB NUMERAL_LITERAL DELIMITER { +| DEF AGENT LD '-' NUMERAL_LITERAL ';' { int entry=ast_recordConst($2,$5*(-1)); if (!entry) { @@ -376,7 +395,7 @@ command: bodyguard -: PIPE expr TO bd_compound bd_elif +: PIPE expr ARROW bd_compound bd_elif { $$ = ast_makeAST(AST_IF, $2, ast_makeAST(AST_THEN_ELSE, $4, $5));} ; @@ -387,12 +406,12 @@ bd_compound bd_elif : bd_else -| PIPE expr TO bd_compound bd_elif +| PIPE expr ARROW bd_compound bd_elif { $$ = ast_makeAST(AST_IF, $2, ast_makeAST(AST_THEN_ELSE, $4, $5));} ; bd_else -: PIPE ANY TO bd_compound +: PIPE '_' ARROW bd_compound { $$ = $4; } ; @@ -413,12 +432,12 @@ if_compound // AST ----------------- astterm -: LP ANNOTATE_L RP astterm_item +: '(' ANNOTATE_L ')' astterm_item { $$=ast_makeAST(AST_ANNOTATION_L, $4, NULL); } -| LP ANNOTATE_R RP astterm_item +| '(' ANNOTATE_R ')' astterm_item { $$=ast_makeAST(AST_ANNOTATION_R, $4, NULL); } -//| astterm_item COLON astterm_item -| astterm_item COLON astterm // h:t +//| astterm_item ':' astterm_item +| astterm_item ':' astterm // h:t {$$ = ast_makeAST(AST_OPCONS, NULL, ast_makeList2($1, $3)); } | astterm_item ; @@ -435,9 +454,9 @@ astterm_item ; agent_percent -: MOD AGENT +: '%' AGENT { $$=ast_makeAST(AST_PERCENT, ast_makeSymbol($2), NULL); } -| MOD NAME +| '%' NAME { $$=ast_makeAST(AST_PERCENT, ast_makeSymbol($2), NULL); } ; @@ -446,13 +465,13 @@ val_declare ; agent_cons -: LB astterm PIPE astterm RB +: '[' astterm PIPE astterm ']' { $$ = ast_makeAST(AST_OPCONS, NULL, ast_makeList2($2, $4)); } ; agent_list -: LB RB { $$ = ast_makeAST(AST_NIL, NULL, NULL); } -| LB astparams RB { $$ = ast_paramToCons($2); } +: '[' ']' { $$ = ast_makeAST(AST_NIL, NULL, NULL); } +| '[' astparams ']' { $$ = ast_paramToCons($2); } ; agent_tuple @@ -471,34 +490,34 @@ agentterm astparam -: LP RP { $$ = NULL; } -| LP astparams RP { $$ = $2; } +: '(' ')' { $$ = NULL; } +| '(' astparams ')' { $$ = $2; } ; astparams : astterm { $$ = ast_makeList1($1); } -| astparams COMMA astterm { $$ = ast_addLast($1, $3); } +| astparams ',' astterm { $$ = ast_addLast($1, $3); } ; ap -: astterm CNCT astterm { $$ = ast_makeAST(AST_CNCT, $1, $3); } +: astterm '~' astterm { $$ = ast_makeAST(AST_CNCT, $1, $3); } // // param << A(...) -| astparams ABR abr_agent_name LP astparams RP +| astparams ABR abr_agent_name '(' astparams ')' { $$ = ast_unfoldABR($1, $3, $5, NULL); } // << A(...) -| ABR abr_agent_name LP astparams RP +| ABR abr_agent_name '(' astparams ')' { $$ = ast_unfoldABR(NULL, $2, $4, NULL); } // param << (*L)A(...) -| astparams ABR abr_annotate abr_agent_name LP astparams RP +| astparams ABR abr_annotate abr_agent_name '(' astparams ')' { $$ = ast_unfoldABR($1, $4, $6, $3); } // << (*L)A(...) -| ABR abr_annotate abr_agent_name LP astparams RP +| ABR abr_annotate abr_agent_name '(' astparams ')' { $$ = ast_unfoldABR(NULL, $3, $5, $2); } // -//| astparams ABR NAME LP astparams RP +//| astparams ABR NAME '(' astparams ')' //{ $$ = ast_unfoldABR($1, $3, $5, NULL); } -//| ABR NAME LP astparams RP +//| ABR NAME '(' astparams ')' //{ $$ = ast_unfoldABR(NULL, $2, $4, NULL); } ; @@ -508,14 +527,14 @@ abr_agent_name ; abr_annotate -: LP ANNOTATE_L RP { $$ = ast_makeAST(AST_ANNOTATION_L, NULL, NULL); } -| LP ANNOTATE_R RP { $$ = ast_makeAST(AST_ANNOTATION_R, NULL, NULL); } +: '(' ANNOTATE_L ')' { $$ = ast_makeAST(AST_ANNOTATION_L, NULL, NULL); } +| '(' ANNOTATE_R ')' { $$ = ast_makeAST(AST_ANNOTATION_R, NULL, NULL); } ; aplist : ap { $$ = ast_makeList1($1); } -| aplist COMMA ap { $$ = ast_addLast($1, $3); } +| aplist ',' ap { $$ = ast_addLast($1, $3); } ; stm @@ -523,7 +542,7 @@ stm stmlist : stm { $$ = ast_makeList1($1); } -| stmlist DELIMITER stm { $$ = ast_addLast($1, $3); } +| stmlist ';' stm { $$ = ast_addLast($1, $3); } stmlist_nondelimiter : stm { $$ = ast_makeList1($1); } @@ -548,36 +567,36 @@ logical_expr relational_expr : additive_expr -| relational_expr LT additive_expr { $$ = ast_makeAST(AST_LT, $1, $3); } +| relational_expr '<' additive_expr { $$ = ast_makeAST(AST_LT, $1, $3); } | relational_expr LE additive_expr { $$ = ast_makeAST(AST_LE, $1, $3); } -| relational_expr GT additive_expr { $$ = ast_makeAST(AST_LT, $3, $1); } +| relational_expr '>' additive_expr { $$ = ast_makeAST(AST_LT, $3, $1); } | relational_expr GE additive_expr { $$ = ast_makeAST(AST_LE, $3, $1); } ; additive_expr : multiplicative_expr -| additive_expr ADD multiplicative_expr { $$ = ast_makeAST(AST_PLUS, $1, $3); } -| additive_expr SUB multiplicative_expr { $$ = ast_makeAST(AST_SUB, $1, $3); } +| additive_expr '+' multiplicative_expr { $$ = ast_makeAST(AST_PLUS, $1, $3); } +| additive_expr '-' multiplicative_expr { $$ = ast_makeAST(AST_SUB, $1, $3); } ; multiplicative_expr : unary_expr -| multiplicative_expr MUL primary_expr { $$ = ast_makeAST(AST_MUL, $1, $3); } -| multiplicative_expr DIV primary_expr { $$ = ast_makeAST(AST_DIV, $1, $3); } -| multiplicative_expr MOD primary_expr { $$ = ast_makeAST(AST_MOD, $1, $3); } +| multiplicative_expr '*' primary_expr { $$ = ast_makeAST(AST_MUL, $1, $3); } +| multiplicative_expr '/' primary_expr { $$ = ast_makeAST(AST_DIV, $1, $3); } +| multiplicative_expr '%' primary_expr { $$ = ast_makeAST(AST_MOD, $1, $3); } unary_expr : primary_expr -| SUB primary_expr { $$ = ast_makeAST(AST_UNM, $2, NULL); } -| RAND LP primary_expr RP { $$ = ast_makeAST(AST_RAND, $3, NULL); } +| '-' primary_expr { $$ = ast_makeAST(AST_UNM, $2, NULL); } +| RAND '(' primary_expr ')' { $$ = ast_makeAST(AST_RAND, $3, NULL); } ; primary_expr : nameterm { $$ = $1;} | NUMERAL_LITERAL { $$ = ast_makeInt($1); } | AGENT { $$=ast_makeAST(AST_AGENT, ast_makeSymbol($1), NULL); } -| LP expr RP { $$ = $2; } +| '(' expr ')' { $$ = $2; } ; @@ -588,14 +607,14 @@ primary_expr int yyerror(char *s) { extern char *yytext; char msg[256]; - + #ifdef MY_YYLINENO if (InfoLineno != NULL) { - sprintf(msg, "%s:%d: %s near token `%s'.\n", - InfoLineno->fname, yylineno+1, s, yytext); + sprintf(msg, "%s:%d:%d: %s near token `%s'.\n", + InfoLineno->fname, yylineno+1, yycolumn, s, yytext); } else { - sprintf(msg, "%d: %s near token `%s'.\n", - yylineno, s, yytext); + sprintf(msg, "%d:%d: %s near token `%s'.\n", + yylineno, yycolumn, s, yytext); } #else sprintf(msg, "%d: %s near token `%s'.\n", yylineno, s, yytext); @@ -1776,7 +1795,7 @@ void puts_Name_port0_nat(char *sym) { } else if (IS_NAMEID(BASIC(a1)->id)) { a1=NAME(a1)->port; } else { - puts("ERROR: puts_Name_port0_nat"); + puts("ERROR: it is not unary number."); exit(-1); } } @@ -3649,13 +3668,15 @@ int CmEnv_check_linearity_in_rule(void) { if ((CmEnv.bind[i].type == NB_META_L) || (CmEnv.bind[i].type == NB_META_R)) { if (CmEnv.bind[i].refnum != 1) { // Be just once! - printf("ERROR: `%s' is referred not once in the right-hand side ", CmEnv.bind[i].name); + printf("%d:ERROR: `%s' is referred not once in the right-hand side ", + yylineno, CmEnv.bind[i].name); return 0; } } else if (CmEnv.bind[i].type == NB_NAME) { if (CmEnv.bind[i].refnum != 1) { // Be just once in the RHS. - printf("ERROR: `%s' is referred not twice in the right-hand side ", CmEnv.bind[i].name); + printf("%d:ERROR: `%s' is referred not twice in the right-hand side ", + yylineno, CmEnv.bind[i].name); return 0; } } @@ -3671,8 +3692,8 @@ int CmEnv_check_name_reference_times(void) { for (i=0; i<CmEnv.bindPtr; i++) { if (CmEnv.bind[i].type == NB_NAME) { if (CmEnv.bind[i].refnum > 2) { - printf("ERROR: The name `%s' occurs more than twice.\n", - CmEnv.bind[i].name); + printf("%d:ERROR: The name `%s' occurs more than twice.\n", + yylineno, CmEnv.bind[i].name); return 0; } } @@ -6123,8 +6144,8 @@ int Compile_expr_on_ast(Ast *ptr, int target) { // Increase the counter of compilation errors CmEnv.count_compilation_errors++; - printf("ERROR: `%s' is referred to as a property variable in an expression, although it has not yet been declared (as so).\n", - ptr->left->sym); + printf("%d:ERROR: `%s' is referred to as a property variable in an expression, although it has not yet been declared (as so).\n", + yylineno, ptr->left->sym); return 0; } @@ -6134,8 +6155,9 @@ int Compile_expr_on_ast(Ast *ptr, int target) { int get_result; get_result = CmEnv_gettype_forname((ptr)->left->sym, &type); if ((get_result) && (type != NB_INTVAR)) { - printf("Warning: `%s' is used as a property variable, although is is not declared as so.\n", - (ptr)->left->sym); + printf("%d:Warning: `%s' is used as a property variable, although is is not declared as so.\n", + yylineno, + (ptr)->left->sym); } } @@ -6310,7 +6332,8 @@ int Compile_expr_on_ast(Ast *ptr, int target) { } default: - puts("ERROR: Wrong AST was given to CompileExpr.\n"); + printf("%d:ERROR: Wrong AST was given to CompileExpr.\n\n", + yylineno); return 0; } @@ -6558,7 +6581,7 @@ int Compile_term_on_ast(Ast *ptr, int target) { char *sym = (char *)ptr->left->sym; id = NameTable_get_id(sym); if (id == -1) { - printf("Warning: `%s' is given to %%, although it hasn't yet been defined.\n", sym); + printf("%d:Warning: `%s' is given to %%, although it hasn't yet been defined.\n", yylineno, sym); id=NameTable_get_set_id_with_IdTable_forAgent(sym); } @@ -6750,7 +6773,8 @@ int Compile_term_on_ast(Ast *ptr, int target) { #else int compile_expr_result = Compile_expr_on_ast(ptr, result); if (compile_expr_result == 0) { - puts("ERROR: Something strange in Compile_term_on_ast."); + printf("%d:ERROR: Something strange in Compile_term_on_ast.\n", + yylineno); ast_puts(ptr); puts(""); // exit(1); } @@ -6819,8 +6843,9 @@ int check_invalid_occurrence(Ast *ast) { count = keynode_exists_in_another_term(aheap, NULL); if (count == 2) { // already twice - printf("ERROR: `%s' occurs twice already. \n", ast->left->sym); - printf(" Use `ifce' command to see the occurrence.\n"); + printf("%d:ERROR: `%s' occurs twice already. \n", + yylineno, ast->left->sym); + printf("Use `ifce' command to see the occurrence.\n"); return 0; } @@ -6894,13 +6919,15 @@ int Compile_eqlist_on_ast_in_rulebody(Ast *at) { // the left term is a variable on property if (Ast_is_expr(eq->right)) { - printf("Warning: The variable `%s' is connected to an expression. It may cause runtime error.\n", + printf("%d:Warning: The variable `%s' is connected to an expression. It may cause runtime error.\n", + yylineno, (eq->left)->left->sym); } else if ((eq->right)->id == AST_NAME) { result = CmEnv_gettype_forname((eq->right)->left->sym, &type); if ((result !=0) && (type == NB_INTVAR)) { - printf("Warning: The variable `%s' is connected to a variable %s. It may cause runtime error.\n", + printf("%d:Warning: The variable `%s' is connected to a variable %s. It may cause runtime error.\n", + yylineno, (eq->left)->left->sym, (eq->right)->left->sym); } } @@ -6914,14 +6941,16 @@ int Compile_eqlist_on_ast_in_rulebody(Ast *at) { // the right term is a variable on property if (Ast_is_expr(eq->left)) { - printf("Warning: The variable `%s' is connected to an expression. It may cause runtime error.\n", - (eq->right)->left->sym); + printf("%d:Warning: The variable `%s' is connected to an expression. It may cause runtime error.\n", + yylineno, + (eq->right)->left->sym); } else { if ((eq->left)->id == AST_NAME) { result = CmEnv_gettype_forname((eq->left)->left->sym, &type); if ((result !=0) && (type == NB_INTVAR)) { - printf("Warning: The variable `%s' is connected to a variable %s. It may cause runtime error.\n", + printf("%d:Warning: The variable `%s' is connected to a variable %s. It may cause runtime error.\n", + yylineno, (eq->right)->left->sym, (eq->left)->left->sym); } @@ -7257,7 +7286,7 @@ int Compile_stmlist_on_ast(Ast *at) { // (AST_LD (AST_NAME sym NULL) some) if (ptr->id != AST_LD) { - puts("System ERROR: The given StmList contains something besides statements."); + printf("%d:System ERROR: The given StmList contains something besides statements.", yylineno); exit(-1); } // operation of x=y: @@ -7267,7 +7296,8 @@ int Compile_stmlist_on_ast(Ast *at) { // the sym is new toRegLeft = CmEnv_set_as_INTVAR(ptr->left->left->sym); } else { - printf("Warning: `%s' has been already defined.\n", ptr->left->left->sym); + printf("%d:Warning: `%s' has been already defined.\n", + yylineno, ptr->left->left->sym); } // for the y @@ -7316,7 +7346,8 @@ int Compile_body_on_ast(Ast *body) { if (!Compile_stmlist_on_ast(stms)) return 0; if (!Compile_eqlist_on_ast_in_rulebody(eqs)) { - printf("ERROR: Compilation failure for %s >< %s.\n", + printf("%d:ERROR: Compilation failure for %s >< %s.\n", + yylineno, IdTable_get_name(CmEnv.idL), IdTable_get_name(CmEnv.idR)); return 0; @@ -7936,7 +7967,8 @@ int make_rule_oneway(Ast *ast) { arity = get_arity_on_ast(ruleAgent_L); } if (arity > MAX_PORT) { - printf("ERROR: Too many arguments of `%s'. It should be MAX_PORT(=%d) or less.\n", + printf("%d:ERROR: Too many arguments of `%s'. It should be MAX_PORT(=%d) or less.\n", + yylineno, ruleAgent_L->left->sym, MAX_PORT); return 0; } @@ -7949,7 +7981,8 @@ int make_rule_oneway(Ast *ast) { arity = get_arity_on_ast(ruleAgent_R); } if (arity > MAX_PORT) { - printf("ERROR: Too many arguments of `%s'. It should be MAX_PORT(=%d) or less.\n", + printf("%d:ERROR: Too many arguments of `%s'. It should be MAX_PORT(=%d) or less.\n", + yylineno, ruleAgent_R->left->sym, MAX_PORT); return 0; } @@ -8133,11 +8166,11 @@ int make_rule(Ast *ast) { Ast *ruleAgent_R = ast->left->right; if (ruleAgent_L->id == AST_NAME) { - printf("ERROR: The name `%s' was specified as the left-hand side of rule agents. It should be an agent.\n", ruleAgent_L->left->sym); + printf("%d:ERROR: The name `%s' was specified as the left-hand side of rule agents. It should be an agent.\n", yylineno, ruleAgent_L->left->sym); return 0; } if (ruleAgent_R->id == AST_NAME) { - printf("ERROR: The name `%s' was specified as the right-hand side of rule agents. It should be an agent.\n", ruleAgent_R->left->sym); + printf("%d:ERROR: The name `%s' was specified as the right-hand side of rule agents. It should be an agent.\n", yylineno, ruleAgent_R->left->sym); return 0; } @@ -67,47 +67,37 @@ char *Parse_closeStringBuffer() { return ret; } +// https://stackoverflow.com/questions/26854374/how-do-i-use-yy-bs-lineno-and-yy-bs-column-in-flex +int yycolumn = 1; +#define YY_USER_ACTION \ + yylloc.first_line = yylloc.last_line = yylineno; \ + yylloc.first_column = yycolumn; \ + yylloc.last_column = yycolumn + yyleng - 1; \ + yycolumn += yyleng; \ + //yylval.str = strdup(yytext); %} %option nounput -%option yylineno %option noyywrap +%option yylineno %x STRING_STATE COM_STATE %% -<INITIAL>";" return (DELIMITER); -<INITIAL>":" return (COLON); -<INITIAL>"(" return (LP); -<INITIAL>")" return (RP); -<INITIAL>"{" return LC; -<INITIAL>"}" return RC; -<INITIAL>"[" return LB; -<INITIAL>"]" return RB; -<INITIAL>"," return (COMMA); <INITIAL>"><" return (CROSS); -<INITIAL>"=>" return (TO); -<INITIAL>"~" return (CNCT); -<INITIAL>"-" return (SUB); +<INITIAL>"=>" return (ARROW); +<INITIAL>"|" return(PIPE); <INITIAL>"&&" return(AND); <INITIAL>"and" return(AND); <INITIAL>"||" return(OR); <INITIAL>"or" return(OR); <INITIAL>"!" return(NOT); <INITIAL>"not" return(NOT); -<INITIAL>"|" return(PIPE); <INITIAL>"=" return(LD); <INITIAL>"==" return(EQUAL); <INITIAL>"!=" return(NE); -<INITIAL>">" return(GT); <INITIAL>">=" return(GE); -<INITIAL>"<" return(LT); <INITIAL>"<=" return(LE); -<INITIAL>"+" return (ADD); -<INITIAL>"*" return (MUL); -<INITIAL>"/" return (DIV); -<INITIAL>"%" return (MOD); -<INITIAL>"_" return (ANY); <INITIAL>"<<" return (ABR); <INITIAL>"int" return(INT); @@ -150,8 +140,8 @@ char *Parse_closeStringBuffer() { <COM_STATE>\n ; <COM_STATE>"*/" BEGIN INITIAL; //comment -<INITIAL>\r\n ; -<INITIAL>[\n|\r] ; +<INITIAL>\r\n { yycolumn=1; }; +<INITIAL>[\n|\r] { yycolumn=1; }; <INITIAL>[ \t]+ ; <INITIAL><<EOF>> {return END_OF_FILE;} <INITIAL>\" { @@ -173,7 +163,7 @@ char *Parse_closeStringBuffer() { // Parse_addString('\n'); yyerror("Unterminated string"); BEGIN(INITIAL); -return DELIMITER; +return ';'; } <STRING_STATE>\\\" Parse_addString('"'); <STRING_STATE>\\n Parse_addString('\n'); |
