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

📄 syntax.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* GNU Emacs routines to deal with syntax tables; also word and list parsing.   Copyright (C) 1985, 1987, 1990 Free Software Foundation, Inc.This file is part of GNU Emacs.GNU Emacs is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 1, or (at your option)any later version.GNU Emacs is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU Emacs; see the file COPYING.  If not, write tothe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */#include "config.h"#include <ctype.h>#include "lisp.h"#include "commands.h"#include "buffer.h"#include "syntax.h"Lisp_Object Qsyntax_table_p;DEFUN ("syntax-table-p", Fsyntax_table_p, Ssyntax_table_p, 1, 1, 0,  "Return t if ARG is a syntax table.\n\Any vector of 256 elements will do.")  (obj)     Lisp_Object obj;{  if (XTYPE (obj) == Lisp_Vector && XVECTOR (obj)->size == 0400)    return Qt;  return Qnil;}Lisp_Objectcheck_syntax_table (obj)     Lisp_Object obj;{  register Lisp_Object tem;  while (tem = Fsyntax_table_p (obj),	 NULL (tem))    obj = wrong_type_argument (Qsyntax_table_p, obj, 0);  return obj;}   DEFUN ("syntax-table", Fsyntax_table, Ssyntax_table, 0, 0, 0,  "Return the current syntax table.\n\This is the one specified by the current buffer.")  (){  return current_buffer->syntax_table;}DEFUN ("standard-syntax-table", Fstandard_syntax_table,   Sstandard_syntax_table, 0, 0, 0,  "Return the standard syntax table.\n\This is the one used for new buffers.")  (){  return Vstandard_syntax_table;}DEFUN ("copy-syntax-table", Fcopy_syntax_table, Scopy_syntax_table, 0, 1, 0,  "Construct a new syntax table and return it.\n\It is a copy of the TABLE, which defaults to the standard syntax table.")  (table)     Lisp_Object table;{  Lisp_Object size, val;  XFASTINT (size) = 0400;  XFASTINT (val) = 0;  val = Fmake_vector (size, val);  if (!NULL (table))    table = check_syntax_table (table);  else if (NULL (Vstandard_syntax_table))    /* Can only be null during initialization */    return val;  else table = Vstandard_syntax_table;  bcopy (XVECTOR (table)->contents,	 XVECTOR (val)->contents, 0400 * sizeof (Lisp_Object));  return val;}DEFUN ("set-syntax-table", Fset_syntax_table, Sset_syntax_table, 1, 1, 0,  "Select a new syntax table for the current buffer.\n\One argument, a syntax table.")  (table)     Lisp_Object table;{  table = check_syntax_table (table);  current_buffer->syntax_table = table;  /* Indicate that this buffer now has a specified syntax table.  */  current_buffer->local_var_flags |= buffer_local_flags.syntax_table;  return table;}/* Convert a letter which signifies a syntax code into the code it signifies. This is used by modify-syntax-entry, and other things. */char syntax_spec_code[0400] =  { 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377,    0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377,    0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377,    0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377,    (char) Swhitespace, 0377, (char) Sstring, 0377,        (char) Smath, 0377, 0377, (char) Squote,    (char) Sopen, (char) Sclose, 0377, 0377,	0377, (char) Swhitespace, (char) Spunct, (char) Scharquote,    0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377,    0377, 0377, 0377, 0377,	(char) Scomment, 0377, (char) Sendcomment, 0377,    0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377,   /* @, A, ... */    0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377,    0377, 0377, 0377, 0377, 0377, 0377, 0377, (char) Sword,    0377, 0377, 0377, 0377, (char) Sescape, 0377, 0377, (char) Ssymbol,    0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377,   /* `, a, ... */    0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377,    0377, 0377, 0377, 0377, 0377, 0377, 0377, (char) Sword,    0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377  };/* Indexed by syntax code, give the letter that describes it. */char syntax_code_spec[13] =  {    ' ', '.', 'w', '_', '(', ')', '\'', '\"', '$', '\\', '/', '<', '>'  };DEFUN ("char-syntax", Fchar_syntax, Schar_syntax, 1, 1, 0,  "Return the syntax code of CHAR, described by a character.\n\For example, if CHAR is a word constituent, ?w is returned.\n\The characters that correspond to various syntax codes\n\are listed in the documentation of  modify-syntax-entry.")  (ch)     Lisp_Object ch;{  CHECK_NUMBER (ch, 0);  return make_number (syntax_code_spec[(int) SYNTAX (0xFF & XINT (ch))]);}/* This comment supplies the doc string for modify-syntax-entry,   for make-docfile to see.  We cannot put this in the real DEFUN   due to limits in the Unix cpp.DEFUN ("modify-syntax-entry", foo, bar, 0, 0, 0,  "Set syntax for character CHAR according to string S.\n\The syntax is changed only for table TABLE, which defaults to\n\ the current buffer's syntax table.\n\The first character of S should be one of the following:\n\  Space    whitespace syntax.    w   word constituent.\n\  _        symbol constituent.   .   punctuation.\n\  (        open-parenthesis.     )   close-parenthesis.\n\  \"        string quote.         \\   character-quote.\n\  $        paired delimiter.     '   expression prefix operator.\n\  <	   comment starter.	 >   comment ender.\n\Only single-character comment start and end sequences are represented thus.\n\Two-character sequences are represented as described below.\n\The second character of S is the matching parenthesis,\n\ used only if the first character is ( or ).\n\Any additional characters are flags.\n\Defined flags are the characters 1, 2, 3 and 4.\n\ 1 means C is the start of a two-char comment start sequence.\n\ 2 means C is the second character of such a sequence.\n\ 3 means C is the start of a two-char comment end sequence.\n\ 4 means C is the second character of such a sequence.")*/DEFUN ("modify-syntax-entry", Fmodify_syntax_entry, Smodify_syntax_entry, 2, 3,   /* I really don't know why this is interactive     help-form should at least be made useful whilst reading the second arg   */  "cSet syntax for character: \nsSet syntax for %s to: ",  0 /* See immediately above */)  (c, newentry, syntax_table)     Lisp_Object c, newentry, syntax_table;{  register unsigned char *p, match;  register enum syntaxcode code;  Lisp_Object val;  CHECK_NUMBER (c, 0);  CHECK_STRING (newentry, 1);  if (NULL (syntax_table))    syntax_table = current_buffer->syntax_table;  else    syntax_table = check_syntax_table (syntax_table);  p = XSTRING (newentry)->data;  code = (enum syntaxcode) syntax_spec_code[*p++];  if (((int) code & 0377) == 0377)    error ("invalid syntax description letter: %c", c);  match = *p;  if (match) p++;  if (match == ' ') match = 0;  XFASTINT (val) = (match << 8) + (int) code;  while (*p)    switch (*p++)      {      case '1':	XFASTINT (val) |= 1 << 16;	break;      case '2':	XFASTINT (val) |= 1 << 17;	break;      case '3':	XFASTINT (val) |= 1 << 18;	break;      case '4':	XFASTINT (val) |= 1 << 19;	break;      }	  XVECTOR (syntax_table)->contents[0xFF & XINT (c)] = val;  return Qnil;}/* Dump syntax table to buffer in human-readable format */describe_syntax (value)    Lisp_Object value;{  register enum syntaxcode code;  char desc, match, start1, start2, end1, end2;  char str[2];  Findent_to (make_number (16), make_number (1));  if (XTYPE (value) != Lisp_Int)    {      InsStr ("invalid");      return;    }  code = (enum syntaxcode) (XINT (value) & 0377);  match = (XINT (value) >> 8) & 0377;  start1 = (XINT (value) >> 16) & 1;  start2 = (XINT (value) >> 17) & 1;  end1 = (XINT (value) >> 18) & 1;  end2 = (XINT (value) >> 19) & 1;  if ((int) code < 0 || (int) code >= (int) Smax)    {      InsStr ("invalid");      return;    }  desc = syntax_code_spec[(int) code];  str[0] = desc, str[1] = 0;  insert (str, 1);  str[0] = match ? match : ' ';  insert (str, 1);  if (start1)    insert ("1", 1);  if (start2)    insert ("2", 1);  if (end1)    insert ("3", 1);  if (end2)    insert ("4", 1);  InsStr ("\twhich means: ");#ifdef SWITCH_ENUM_BUG  switch ((int) code)#else  switch (code)#endif    {    case Swhitespace:      InsStr ("whitespace"); break;    case Spunct:      InsStr ("punctuation"); break;    case Sword:      InsStr ("word"); break;    case Ssymbol:      InsStr ("symbol"); break;    case Sopen:      InsStr ("open"); break;    case Sclose:      InsStr ("close"); break;    case Squote:      InsStr ("quote"); break;    case Sstring:      InsStr ("string"); break;    case Smath:      InsStr ("math"); break;    case Sescape:      InsStr ("escape"); break;    case Scharquote:      InsStr ("charquote"); break;    case Scomment:      InsStr ("comment"); break;    case Sendcomment:      InsStr ("endcomment"); break;    default:      InsStr ("invalid");      return;    }  if (match)    {      InsStr (", matches ");            str[0] = match, str[1] = 0;      insert (str, 1);    }  if (start1)    InsStr (",\n\t  is the first character of a comment-start sequence");  if (start2)    InsStr (",\n\t  is the second character of a comment-start sequence");  if (end1)    InsStr (",\n\t  is the first character of a comment-end sequence");  if (end2)    InsStr (",\n\t  is the second character of a comment-end sequence");  InsStr ("\n");}Lisp_Objectdescribe_syntax_1 (vector)     Lisp_Object vector;{  struct buffer *old = current_buffer;  set_buffer_internal (XBUFFER (Vstandard_output));  describe_vector (vector, Qnil, describe_syntax, 0, Qnil);  set_buffer_internal (old);  return Qnil;}DEFUN ("describe-syntax", Fdescribe_syntax, Sdescribe_syntax, 0, 0, "",  "Describe the syntax specifications in the syntax table.\n\The descriptions are inserted in a buffer, which is selected so you can see it.")  (){  internal_with_output_to_temp_buffer     ("*Help*", describe_syntax_1, current_buffer->syntax_table);  return Qnil;}/* Return the position across `count' words from `from'.   If that many words cannot be found before the end of the buffer, return 0.   `count' negative means scan backward and stop at word beginning.  */scan_words (from, count)     register int from, count;{  register int beg = BEGV;  register int end = ZV;  immediate_quit = 1;  QUIT;  while (count > 0)    {      while (1)	{	  if (from == end)	    {	      immediate_quit = 0;	      return 0;	    }	  if (SYNTAX(FETCH_CHAR (from)) == Sword)	    break;	  from++;	}      while (1)	{	  if (from == end) break;	  if (SYNTAX(FETCH_CHAR (from)) != Sword)	    break;	  from++;	}      count--;    }  while (count < 0)    {      while (1)	{	  if (from == beg)	    {	      immediate_quit = 0;	      return 0;	    }	  if (SYNTAX(FETCH_CHAR (from - 1)) == Sword)	    break;	  from--;	}      while (1)	{	  if (from == beg) break;	  if (SYNTAX(FETCH_CHAR (from - 1)) != Sword)	    break;	  from--;	}      count++;    }  immediate_quit = 0;  return from;}DEFUN ("forward-word", Fforward_word, Sforward_word, 1, 1, "p",  "Move point forward ARG words (backward if ARG is negative).\n\Normally returns t.\n\If an edge of the buffer is reached, point is left there\n\and nil is returned.")  (count)     Lisp_Object count;{  int val;  CHECK_NUMBER (count, 0);  if (!(val = scan_words (point, XINT (count))))    {      SET_PT (XINT (count) > 0 ? ZV : BEGV);      return Qnil;    }  SET_PT (val);  return Qt;}int parse_sexp_ignore_comments;Lisp_Objectscan_lists (from, count, depth, sexpflag)     register int from;     int count, depth, sexpflag;{  Lisp_Object val;  register int stop;  register int c;  char stringterm;  int quoted;  int mathexit = 0;  register enum syntaxcode code;  int min_depth = depth;    /* Err out if depth gets less than this. */  if (depth > 0) min_depth = 0;  immediate_quit = 1;  QUIT;  while (count > 0)    {      stop = ZV;      while (from < stop)	{	  c = FETCH_CHAR (from);	  code = SYNTAX(c);	  from++;	  if (from < stop && SYNTAX_COMSTART_FIRST (c)	      && SYNTAX_COMSTART_SECOND (FETCH_CHAR (from))	      && parse_sexp_ignore_comments)	    code = Scomment, from++;#ifdef SWITCH_ENUM_BUG	  switch ((int) code)#else	  switch (code)#endif	    {	    case Sescape:	    case Scharquote:	      if (from == stop) goto lose;	      from++;	      /* treat following character as a word constituent */	    case Sword:	    case Ssymbol:	      if (depth || !sexpflag) break;	      /* This word counts as a sexp; return at end of it. */	      while (from < stop)		{#ifdef SWITCH_ENUM_BUG		  switch ((int) SYNTAX(FETCH_CHAR (from)))#else		  switch (SYNTAX(FETCH_CHAR (from)))#endif		    {		    case Scharquote:		    case Sescape:		      from++;		      if (from == stop) goto lose;		      break;		    case Sword:		    case Ssymbol:		    case Squote:		      break;		    default:		      goto done;		    }		  from++;		}	      goto done;	    case Scomment:	      if (!parse_sexp_ignore_comments) break;	      while (1)		{		  if (from == stop) goto done;		  if (SYNTAX (c = FETCH_CHAR (from)) == Sendcomment)		    break;		  from++;		  if (from < stop && SYNTAX_COMEND_FIRST (c)		       && SYNTAX_COMEND_SECOND (FETCH_CHAR (from)))		    { from++; break; }		}	      break;	    case Smath:	      if (!sexpflag)		break;	      if (from != stop && c == FETCH_CHAR (from))		from++;	      if (mathexit)		{		  mathexit = 0;		  goto close1;		}	      mathexit = 1;	    case Sopen:	      if (!++depth) goto done;	      break;	    case Sclose:	    close1:	      if (!--depth) goto done;	      if (depth < min_depth)		error ("Containing expression ends prematurely");	      break;	    case Sstring:	      stringterm = FETCH_CHAR (from - 1);	      while (1)		{		  if (from >= stop) goto lose;		  if (FETCH_CHAR (from) == stringterm) break;#ifdef SWITCH_ENUM_BUG		  switch ((int) SYNTAX(FETCH_CHAR (from)))#else		  switch (SYNTAX(FETCH_CHAR (from)))#endif

⌨️ 快捷键说明

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