⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mix_scanner.l

📁 汇编语言编程源代码
💻 L
字号:
/* -*-c-*- -------------- mix_scanner.l : * Lexical scanner used by mix_parser_t * ------------------------------------------------------------------ * Copyright (C) 2000 Free Software Foundation, Inc. *   * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. *   * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. *   * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *   */%{#include <string.h>#include "mix.h"#include "xmix_parser.h"#define YY_DECL mix_parser_err_t mix_flex_scan (mix_parser_t *parser)#define RESET()					\  do {						\    mix_ins_fill_from_id (ins, mix_NOP);	\    ins.address = 0;				\    ins.index = 0;				\    nof = FALSE;				\    lsf = FALSE;				\    if (symbol != NULL )			\     {						\       g_free (symbol);				\       symbol = NULL;				\     }						\    if (lsymbol != NULL)			\     {						\       g_free (lsymbol);			\       lsymbol = NULL;				\     }                       			\  } while (FALSE)#define NEXT()						\  do {							\    if (lsymbol != NULL)				\       mix_parser_manage_local_symbol (parser,lsymbol,  \				       loc);    	\    parser->loc_count++;				\    RESET ();						\    ++lineno;						\    BEGIN (INITIAL);					\  } while (FALSE)#define ADD_INS()				\  do {						\    mix_parser_add_ins (parser, &ins, lineno);	\    NEXT ();					\  } while (FALSE)#define ADD_RAW(value)				\  do {						\    mix_parser_add_raw (parser, value, lineno);	\    NEXT ();	               			\  } while (FALSE)#define ENTER_EVAL()				\  do {						\    if (yytext[0] != '*')                       \      {                                         \        expr_val = MIX_WORD_ZERO;		\        yyless (0);				\      }                                         \    else                                        \      {                                         \        expr_val = mix_short_to_word_fast (parser->loc_count); \	yyless (1);                             \      }                                         \    yy_push_state (EVAL);			\  } while (FALSE)#define ENTER_WEVAL()				\  do {						\    wexpr_val = MIX_WORD_ZERO;			\    wexpr_val_tmp = MIX_WORD_ZERO;		\    is_fp = FALSE;                              \    yyless (0);					\    yy_push_state (WEVAL);			\  } while (FALSE)#define RETURN_ERROR(error, comment)				\  do {								\    char c;							\    mix_parser_log_error (parser,error,lineno,comment,FALSE);	\    while ( (c = input ()) != '\n' && c != EOF ) ;		\    if ( c == EOF ) return error; else ++lineno;		\    RESET ();							\    BEGIN (INITIAL);						\  } while (FALSE) static mix_word_t  eval_binop_ (const gchar *op, mix_word_t x, mix_word_t y); static void  unput_word_ (mix_word_t word); %}%option nomain%option caseless%option pointer%option stack%option noyywrap%option noyy_top_state%option noreject%option outfile="lex.yy.c"%s  LOC%s  OP%s  ADDRESS%s  INDEX%s  FSPEC%s  EVAL%s  WEVAL%s  ORIG%s  CON%s  EQU%s  ENDws	[ \t]+digit	[0-9]letter	[A-Z]number	[+-]?{digit}+mixchar [0-9A-Z .,'')(+*/=$<>@;:\-]locsymbol   {digit}Hflocsymbol  {digit}Fblocsymbol  {digit}Bsymbol	{digit}*{letter}+[A-Z0-9]*binop	"+"|"-"|"*"|"/"|"//"|":"atexpr	{digit}+|{symbol}|\*expr	[+-]?{atexpr}({binop}{1}{atexpr})*fpart   \({expr}\)wexpr   {expr}({fpart})?(,{expr}({fpart})?)*  %%%{  mix_ins_t ins;  gboolean nof = FALSE, is_fp = FALSE, end = FALSE, lsf = FALSE;  mix_word_t expr_val = MIX_WORD_ZERO, wexpr_val = MIX_WORD_ZERO,  wexpr_val_tmp = MIX_WORD_ZERO;  gchar *symbol = NULL, *lsymbol = NULL;  mix_address_t loc = MIX_SHORT_ZERO;  guint lineno = 1;  mix_ins_fill_from_id (ins, mix_NOP);		  ins.address = 0;				  ins.index = 0;				  parser->err_line = 0;  yyin = mix_file_to_FILE (parser->in_file);  %}  <*><<EOF>> {  mix_parser_log_error (parser, MIX_PERR_UNEX_EOF, lineno, NULL, FALSE);  return MIX_PERR_UNEX_EOF;}<INITIAL>{  ^\*.*	/* eat comments */  .	{    if ( end ) return parser->status;    yyless (0);    BEGIN (LOC);  }  \n {     ++lineno;    if ( end ) return parser->status;   }}			<LOC>{  {ws}+	BEGIN (OP); /* LOC field is empty */  {locsymbol} { /* manage local symbol */    loc = get_ploc_ (parser);    lsymbol = g_strdup (yytext);    if ( lsymbol == NULL ) {      mix_parser_log_error (parser, MIX_PERR_INTERNAL, lineno, NULL, FALSE);      return MIX_PERR_INTERNAL;    }    BEGIN (OP);  }  {locsymbol}/({ws}+EQU) {/* local symbol with value */    loc = get_ploc_ (parser);    symbol = g_strdup (yytext);    lsymbol = g_strdup (yytext);    if ( symbol == NULL || lsymbol == NULL) {      mix_parser_log_error (parser, MIX_PERR_INTERNAL, lineno, NULL, FALSE);      return MIX_PERR_INTERNAL;    }    symbol[1] = 'B'; /* this will be referred as nB afterwards */    BEGIN (OP);  }      {flocsymbol}|{blocsymbol} RETURN_ERROR (MIX_PERR_UNEX_LOC, yytext);  {symbol}/({ws}+EQU) { /* store symbol name for future definition */    symbol = g_strdup (yytext);    if ( symbol == NULL ) {      mix_parser_log_error (parser, MIX_PERR_INTERNAL, lineno, NULL, FALSE);      return MIX_PERR_INTERNAL;    }    BEGIN (OP);  }  {symbol} { /* define a new symbol */    mix_parser_err_t err;    if ( mix_get_id_from_string (yytext) != mix_INVALID_INS )      mix_parser_log_error (parser, MIX_PERR_SYM_INS, lineno, yytext, TRUE);    if ( (err = mix_parser_define_symbol_here (parser,yytext)) != MIX_PERR_OK )      mix_parser_log_error (parser, err, lineno, yytext, FALSE);    BEGIN (OP);  }  .	RETURN_ERROR (MIX_PERR_INV_LOC, yytext);  \n 	++lineno; /* empty line */}<OP>{  {ws} /* eat leading whitespace */  \n    RETURN_ERROR (MIX_PERR_NOOP, NULL);  ORIG{ws}+  BEGIN (ORIG);  CON{ws}+   BEGIN (CON);  EQU{ws}+   BEGIN (EQU);  END{ws}+   BEGIN (END);  ALF{ws}+\"{mixchar}{5,}\"{ws}+.*\n |  ALF{ws}+\"{mixchar}{5,}\"{ws}*\n {    mix_byte_t bytes[5];    mix_word_t value;    guint k, j = 4;    while ( yytext[j++] != '\"' ) ;    for ( k = j; k < 5+j && yytext[k] != '\"'; ++k )      bytes[k-j] = mix_ascii_to_char (yytext[k]);    if ( k-j < 5 )      mix_parser_log_error (parser, MIX_PERR_SHORT_ALF, lineno, NULL, TRUE);    else if ( yytext[k] != '\"' )      mix_parser_log_error (parser, MIX_PERR_LONG_ALF, lineno, NULL, TRUE);    value = mix_bytes_to_word (bytes, 5);        ADD_RAW (value);   }  [A-Z0-9]+{ws}*/\n |      [A-Z0-9]+{ws}+ {    mix_ins_id_t id = mix_get_id_from_string (g_strchomp (yytext));    if ( id == mix_INVALID_INS )      mix_parser_log_error (parser, MIX_PERR_INV_OP, lineno, yytext, FALSE);    else {      mix_ins_fill_from_id (ins, id);      nof = mix_ins_id_is_extended (id);    }    BEGIN (ADDRESS);  }  {expr} RETURN_ERROR (MIX_PERR_INV_OP, yytext);  .  RETURN_ERROR (MIX_PERR_INV_OP, yytext);		}<ORIG>{  {number}{ws}*\n   |  {number}{ws}+.*\n {    mix_word_t value = mix_word_new (atol (yytext));    parser->loc_count = mix_word_to_short_fast (value);    ++lineno;    BEGIN (INITIAL);  }}<CON>{  {number}{ws}*\n |  {number}{ws}+.*\n  {    mix_word_t value = mix_word_new (atol (yytext));    ADD_RAW (value);  }}<EQU>{  {number}{ws}*\n   |  {number}{ws}+.*\n {    mix_word_t value;    gint def;    if ( symbol == NULL ) RETURN_ERROR (MIX_PERR_MIS_SYM, NULL);    value = mix_word_new (atol (yytext));    def = mix_parser_define_symbol_value (parser, symbol, value);    if ( def == MIX_SYM_DUP )  RETURN_ERROR (MIX_PERR_DUP_SYMBOL, symbol);    if ( def == MIX_SYM_LONG )  RETURN_ERROR (MIX_PERR_LONG_SYMBOL, symbol);    ++lineno;    BEGIN (INITIAL);  }}<END>{  {number}{ws}*\n   |  {number}{ws}+.*\n {    parser->start = mix_short_new (atol (yytext));    end = TRUE;    if ( parser->status == MIX_PERR_NOCOMP ) parser->status = MIX_PERR_OK;    return parser->status;  }}<ORIG,CON,EQU,END>{  {wexpr} ENTER_WEVAL ();  . RETURN_ERROR (MIX_PERR_INV_OP, yytext);}<ADDRESS,INDEX,FSPEC>{locsymbol}  RETURN_ERROR (MIX_PERR_UNEX_LOC, yytext);<ADDRESS>{  =/[+-]?{number}=  lsf = TRUE;  =/{expr}=     lsf = TRUE;  [+-]?{number}={ws}*\n   |  [+-]?{number}={ws}+.*\n {    if (!lsf) RETURN_ERROR (MIX_PERR_INV_ADDRESS, yytext);    mix_parser_define_ls (parser, mix_word_new (atol (yytext)));    ADD_INS ();  }  [+-]?{number}{ws}+.*\n |  [+-]?{number}[(,\n] {    ins.address = mix_short_new (atol (yytext));    switch ( yytext[yyleng-1] ) {    case '(' : BEGIN (FSPEC); break;     case ',' : BEGIN (INDEX); break;    case '\n' : ADD_INS (); break;    default: g_assert_not_reached ();    }  }  ([+-]?{symbol})/[(,\n\t ] {    gboolean neg = (yytext[0] == '-');    const gchar *s = (neg || yytext[0] == '+')? yytext+1 : yytext;    if ( !mix_symbol_table_is_defined (parser->symbol_table, s) )      {	mix_parser_set_future_ref (parser, s);	if (neg)	  mix_parser_log_error (parser, MIX_PERR_UNDEF_SYM, lineno, s, TRUE);	unput (neg? '1':'0');      }    else      {	mix_word_t v = mix_symbol_table_value (parser->symbol_table, s);	if ( neg ) mix_word_reverse_sign (v);	unput_word_ (v);      }  }  {expr}/[(,=\n\t ] ENTER_EVAL ();  \n    ADD_INS ();  .	RETURN_ERROR (MIX_PERR_INV_ADDRESS, yytext);}	<INDEX>{  {number}[\n(\t ] {    int end = yytext[yyleng-1];    ins.index = mix_byte_new (atol (yytext));    if ( end == '\n' )      ADD_INS ();    else if ( end == '(' )      BEGIN (FSPEC);    else      { /* eat rest of line (comment) */	while ( (end = input()) != '\n' && end != EOF ) ;	if ( end == '\n' ) ADD_INS ();	else RETURN_ERROR (MIX_PERR_UNEX_EOF, NULL);      }  }  {expr}/[\n(\t ]  ENTER_EVAL ();  \n	{    mix_parser_log_error (parser, MIX_PERR_INV_IDX, lineno++, NULL, FALSE);    RESET ();     BEGIN (INITIAL);  }  .	RETURN_ERROR (MIX_PERR_INV_IDX, yytext);}<FSPEC>{  {number}")"(({ws}+.*\n)|\n) {    glong val  = atol (yytext);    if ( val < 0 || val > MIX_BYTE_MAX )       RETURN_ERROR (MIX_PERR_INV_FSPEC, NULL);    if ( ins.opcode != mix_opMOVE          && ( ins.opcode < mix_opJBUS || ins.opcode > mix_opJXx )         && !mix_fspec_is_valid (mix_byte_new (val)) )      RETURN_ERROR (MIX_PERR_INV_FSPEC, NULL);    if ( nof )       mix_parser_log_error (parser, MIX_PERR_INV_FSPEC,			    lineno, _("ignored"), TRUE);    else      {	ins.fspec = mix_byte_new (val);	ADD_INS ();      }  }  {expr}/")"  {    ENTER_EVAL ();  }  .	RETURN_ERROR (MIX_PERR_INV_FSPEC, yytext);}<EVAL>{  {binop}{digit}+ {    const gchar *s = ( yytext[1] == '/' ) ? yytext+2 : yytext+1;    mix_word_t value = mix_word_new (atol (s));    expr_val = eval_binop_ (yytext, expr_val, value);  }  {binop}{symbol} {    const gchar *s = ( yytext[1] == '/' ) ? yytext+2 : yytext+1;    if ( !mix_symbol_table_is_defined (parser->symbol_table, s) ) {      mix_parser_log_error (parser, MIX_PERR_UNDEF_SYM, lineno, s, FALSE);      yy_pop_state ();    }    expr_val = eval_binop_ (yytext, expr_val, 			    mix_symbol_table_value (parser->symbol_table, s));  }  {binop}"*" {    expr_val = eval_binop_ (yytext, expr_val, 			    mix_short_to_word_fast (parser->loc_count));  }  "*"         unput_word_ (mix_short_to_word_fast (parser->loc_count));  {number}    expr_val = mix_word_new (atol (yytext));  {symbol} {    if ( !mix_symbol_table_is_defined (parser->symbol_table, yytext) ) {      mix_parser_log_error (parser, MIX_PERR_UNDEF_SYM, lineno, yytext, FALSE);      yy_pop_state ();    }    expr_val = mix_symbol_table_value (parser->symbol_table, yytext);  }  [,)(=\n\t ]   unput (yytext[0]); unput_word_ (expr_val); yy_pop_state ();  .   RETURN_ERROR (MIX_PERR_INV_EXPR, yytext);}<WEVAL>{  {number}"(" {    is_fp = TRUE;    wexpr_val_tmp = mix_word_new (atol (yytext));  }  {number}")"  {    glong val  = atol (yytext);    if ( !is_fp ) {      mix_parser_log_error (parser, MIX_PERR_MIS_PAREN, lineno, NULL, FALSE);      yy_pop_state ();    }    if ( val < 0 || val > MIX_BYTE_MAX          || !mix_fspec_is_valid (mix_byte_new (val)) ) {      mix_parser_log_error (parser, MIX_PERR_INV_FSPEC, lineno, NULL, FALSE);      yy_pop_state ();    }    is_fp = FALSE;    wexpr_val = mix_word_store_field (mix_byte_new (val), wexpr_val_tmp, 				      wexpr_val);  }  {number}/[,()\n\t ] wexpr_val = mix_word_new (atol (yytext));  {expr}/[,()\n\t ]  ENTER_EVAL ();  ,/{expr} /* eat comma if followed by expression */  [\n\t ] { /* ok if not inside an f-part */    if ( is_fp ) {      mix_parser_log_error (parser, MIX_PERR_MIS_PAREN, lineno, NULL, FALSE);      yy_pop_state ();     }    unput (yytext[yyleng-1]);    unput_word_ (wexpr_val);    yy_pop_state ();  }  .  RETURN_ERROR (MIX_PERR_INV_EXPR, NULL);}%%static mix_word_teval_binop_ (const gchar *op, mix_word_t x, mix_word_t y){  mix_word_t result = MIX_WORD_ZERO;  switch (op[0])    {    case '+':       result = mix_word_add (x,y);       break;    case '-':      result = mix_word_sub (x,y);      break;    case '*':      mix_word_mul (x, y, NULL, &result);      break;    case ':':      {	mix_word_t a;	mix_word_mul (x, 8, NULL, &a);	result = mix_word_add (a, y);	break;      }    case '/':      if ( strlen (op) > 1 && op[1] == '/' ) {	mix_word_div (x,MIX_WORD_ZERO,y, &result, NULL);      } else {	mix_word_div (MIX_WORD_ZERO, x, y, &result, NULL);      }      break;    default:      g_assert_not_reached ();    }  return result;}static voidunput_word_ (mix_word_t word)					{								  gchar *value;						  gint k;							  value = g_strdup_printf ("%s%ld",							   mix_word_is_negative (word)? "-":"+",			   mix_word_magnitude (word));		  for (k = strlen (value) - 1; k >= 0; --k)			    unput (value[k]);						  g_free (value);						}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -