aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/LexErlang.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/LexErlang.cxx')
-rw-r--r--src/LexErlang.cxx993
1 files changed, 543 insertions, 450 deletions
diff --git a/src/LexErlang.cxx b/src/LexErlang.cxx
index 809dcefe9..45577bda4 100644
--- a/src/LexErlang.cxx
+++ b/src/LexErlang.cxx
@@ -1,10 +1,12 @@
// Scintilla source code edit control
+// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
/** @file LexErlang.cxx
** Lexer for Erlang.
- ** Written by Peter-Henry Mander, based on Matlab lexer by José Fonseca
+ ** Enhanced by Etienne 'Lenain' Girondel (lenaing@gmail.com)
+ ** Originally wrote by Peter-Henry Mander,
+ ** based on Matlab lexer by José Fonseca.
**/
-// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
-// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
@@ -13,7 +15,6 @@
#include <stdarg.h>
#include "Platform.h"
-
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
@@ -25,502 +26,594 @@
using namespace Scintilla;
#endif
-/*
- TODO:
- o _Param should be a new lexical type
-*/
-
static int is_radix(int radix, int ch) {
- int digit;
- if ( 16 < radix || 2 > radix ) {
- return 0;
- }
- if ( isdigit(ch) ) {
- digit = ch - '0';
- } else if ( isxdigit(ch) ) {
- digit = toupper(ch) - 'A' + 10;
- } else {
- return 0;
- }
- if ( digit < radix ) {
- return 1;
- } else {
- return 0;
- }
+ int digit;
+
+ if (36 < radix || 2 > radix)
+ return 0;
+
+ if (isdigit(ch)) {
+ digit = ch - '0';
+ } else if (isalnum(ch)) {
+ digit = toupper(ch) - 'A' + 10;
+ } else {
+ return 0;
+ }
+
+ return (digit < radix);
}
typedef enum {
- STATE_NULL,
- ATOM_UNQUOTED,
- ATOM_QUOTED,
- ATOM_FUN_NAME,
- NODE_NAME_UNQUOTED,
- NODE_NAME_QUOTED,
- MACRO_START,
- MACRO_UNQUOTED,
- MACRO_QUOTED,
- RECORD_START,
- RECORD_UNQUOTED,
- RECORD_QUOTED,
- NUMERAL_START,
- NUMERAL_SIGNED,
- NUMERAL_RADIX_LITERAL,
- NUMERAL_SPECULATIVE_MANTISSA,
- NUMERAL_FLOAT_MANTISSA,
- NUMERAL_FLOAT_EXPONENT,
- NUMERAL_FLOAT_SIGNED_EXPONENT,
- PARSE_ERROR
+ STATE_NULL,
+ COMMENT,
+ COMMENT_FUNCTION,
+ COMMENT_MODULE,
+ COMMENT_DOC,
+ COMMENT_DOC_MACRO,
+ ATOM_UNQUOTED,
+ ATOM_QUOTED,
+ NODE_NAME_UNQUOTED,
+ NODE_NAME_QUOTED,
+ MACRO_START,
+ MACRO_UNQUOTED,
+ MACRO_QUOTED,
+ RECORD_START,
+ RECORD_UNQUOTED,
+ RECORD_QUOTED,
+ NUMERAL_START,
+ NUMERAL_BASE_VALUE,
+ NUMERAL_FLOAT,
+ NUMERAL_EXPONENT,
+ PREPROCESSOR
} atom_parse_state_t;
+static inline bool IsAWordChar(const int ch) {
+ return (ch < 0x80) && (ch != ' ') && (isalnum(ch) || ch == '_');
+}
+
static void ColouriseErlangDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler) {
+ WordList *keywordlists[], Accessor &styler) {
- WordList &keywords = *keywordlists[0];
+ StyleContext sc(startPos, length, initStyle, styler);
+ WordList &reservedWords = *keywordlists[0];
+ WordList &erlangBIFs = *keywordlists[1];
+ WordList &erlangPreproc = *keywordlists[2];
+ WordList &erlangModulesAtt = *keywordlists[3];
+ WordList &erlangDoc = *keywordlists[4];
+ WordList &erlangDocMacro = *keywordlists[5];
+ int radix_digits = 0;
+ int exponent_digits = 0;
+ atom_parse_state_t parse_state = STATE_NULL;
+ atom_parse_state_t old_parse_state = STATE_NULL;
+ bool to_late_to_comment = false;
+ char cur[100];
+ int old_style = SCE_ERLANG_DEFAULT;
styler.StartAt(startPos);
- StyleContext sc(startPos, length, initStyle, styler);
- atom_parse_state_t parse_state = STATE_NULL;
- int radix_digits = 0;
- int exponent_digits = 0;
for (; sc.More(); sc.Forward()) {
- if ( STATE_NULL != parse_state ) {
- switch (parse_state) {
- case STATE_NULL:
- sc.SetState(SCE_ERLANG_DEFAULT);
- break;
- case ATOM_UNQUOTED:
- if ( '@' == sc.ch ){
- parse_state = NODE_NAME_UNQUOTED;
- } else if ( !isalnum(sc.ch) && sc.ch != '_' ) {
- char s[100];
- sc.GetCurrent(s, sizeof(s));
- if (keywords.InList(s)) {
- sc.ChangeState(SCE_ERLANG_KEYWORD);
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- } else {
- if ( '/' == sc.ch ) {
- parse_state = ATOM_FUN_NAME;
- } else {
- sc.ChangeState(SCE_ERLANG_ATOM);
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- }
- }
- }
- break;
- case ATOM_QUOTED:
- if ( '@' == sc.ch ){
- parse_state = NODE_NAME_QUOTED;
- } else if ( '\'' == sc.ch && '\\' != sc.chPrev ) {
- sc.ChangeState(SCE_ERLANG_ATOM);
- sc.ForwardSetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- }
- break;
- case ATOM_FUN_NAME:
- if ( !isdigit(sc.ch) ) {
- sc.ChangeState(SCE_ERLANG_FUNCTION_NAME);
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- }
- break;
- case NODE_NAME_QUOTED:
- if ( '@' == sc.ch ) {
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- } else if ( '\'' == sc.ch && '\\' != sc.chPrev ) {
- sc.ChangeState(SCE_ERLANG_NODE_NAME);
- sc.ForwardSetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- }
- break;
- case NODE_NAME_UNQUOTED:
- if ( '@' == sc.ch ) {
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- } else if ( !isalnum(sc.ch) && sc.ch != '_' ) {
- sc.ChangeState(SCE_ERLANG_NODE_NAME);
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- }
- break;
- case RECORD_START:
- if ( '\'' == sc.ch ) {
- parse_state = RECORD_QUOTED;
- } else if (isalpha(sc.ch) && islower(sc.ch)) {
- parse_state = RECORD_UNQUOTED;
- } else { // error
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- }
- break;
- case RECORD_QUOTED:
- if ( '\'' == sc.ch && '\\' != sc.chPrev ) {
- sc.ChangeState(SCE_ERLANG_RECORD);
- sc.ForwardSetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- }
- break;
- case RECORD_UNQUOTED:
- if ( !isalpha(sc.ch) && '_' != sc.ch ) {
- sc.ChangeState(SCE_ERLANG_RECORD);
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- }
- break;
- case MACRO_START:
- if ( '\'' == sc.ch ) {
- parse_state = MACRO_QUOTED;
- } else if (isalpha(sc.ch)) {
- parse_state = MACRO_UNQUOTED;
- } else { // error
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- }
- break;
- case MACRO_UNQUOTED:
- if ( !isalpha(sc.ch) && '_' != sc.ch ) {
- sc.ChangeState(SCE_ERLANG_MACRO);
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- }
- break;
- case MACRO_QUOTED:
- if ( '\'' == sc.ch && '\\' != sc.chPrev ) {
- sc.ChangeState(SCE_ERLANG_MACRO);
- sc.ForwardSetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- }
- break;
- case NUMERAL_START:
- if ( isdigit(sc.ch) ) {
- radix_digits *= 10;
- radix_digits += sc.ch - '0'; // Assuming ASCII here!
- } else if ( '#' == sc.ch ) {
- if ( 2 > radix_digits || 16 < radix_digits) {
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- } else {
- parse_state = NUMERAL_RADIX_LITERAL;
- }
- } else if ( '.' == sc.ch && isdigit(sc.chNext)) {
- radix_digits = 0;
- parse_state = NUMERAL_FLOAT_MANTISSA;
- } else if ( 'e' == sc.ch || 'E' == sc.ch ) {
- exponent_digits = 0;
- parse_state = NUMERAL_FLOAT_EXPONENT;
- } else {
- radix_digits = 0;
- sc.ChangeState(SCE_ERLANG_NUMBER);
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- }
- break;
- case NUMERAL_RADIX_LITERAL:
- if ( !is_radix(radix_digits,sc.ch) ) {
- radix_digits = 0;
- if ( !isalnum(sc.ch) ) {
- sc.ChangeState(SCE_ERLANG_NUMBER);
- }
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- }
- break;
- case NUMERAL_FLOAT_MANTISSA:
- if ( 'e' == sc.ch || 'E' == sc.ch ) {
- exponent_digits = 0;
- parse_state = NUMERAL_FLOAT_EXPONENT;
- } else if ( !isdigit(sc.ch) ) {
- sc.ChangeState(SCE_ERLANG_NUMBER);
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- }
- break;
- case NUMERAL_FLOAT_EXPONENT:
- if ( '-' == sc.ch || '+' == sc.ch ) {
- parse_state = NUMERAL_FLOAT_SIGNED_EXPONENT;
- } else if ( !isdigit(sc.ch) ) {
- if ( 0 < exponent_digits ) {
- sc.ChangeState(SCE_ERLANG_NUMBER);
- }
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- } else {
- ++exponent_digits;
- }
- break;
- case NUMERAL_FLOAT_SIGNED_EXPONENT:
- if ( !isdigit(sc.ch) ) {
- if ( 0 < exponent_digits ) {
- sc.ChangeState(SCE_ERLANG_NUMBER);
- }
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- } else {
- ++exponent_digits;
- }
- break;
- case NUMERAL_SIGNED:
- if ( !isdigit(sc.ch) ) {
- sc.ChangeState(SCE_ERLANG_NUMBER);
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- } else if ( '.' == sc.ch ) {
- parse_state = NUMERAL_FLOAT_MANTISSA;
- }
- break;
- case NUMERAL_SPECULATIVE_MANTISSA:
- if ( !isdigit(sc.ch) ) {
- sc.ChangeState(SCE_ERLANG_OPERATOR);
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- } else {
- parse_state = NUMERAL_FLOAT_MANTISSA;
- }
- break;
- case PARSE_ERROR:
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- break;
- }
- } else if (sc.state == SCE_ERLANG_OPERATOR) {
- if (sc.chPrev == '.') {
- if (sc.ch == '*' || sc.ch == '/' || sc.ch == '\\' || sc.ch == '^') {
- sc.ForwardSetState(SCE_ERLANG_DEFAULT);
- } else if (sc.ch == '\'') {
- sc.ForwardSetState(SCE_ERLANG_DEFAULT);
- } else {
- sc.SetState(SCE_ERLANG_DEFAULT);
+ int style = SCE_ERLANG_DEFAULT;
+ if (STATE_NULL != parse_state) {
+
+ switch (parse_state) {
+
+ case STATE_NULL : sc.SetState(SCE_ERLANG_DEFAULT); break;
+
+ /* COMMENTS ------------------------------------------------------*/
+ case COMMENT : {
+ if (sc.ch != '%') {
+ to_late_to_comment = true;
+ } else if (!to_late_to_comment && sc.ch == '%') {
+ // Switch to comment level 2 (Function)
+ sc.ChangeState(SCE_ERLANG_COMMENT_FUNCTION);
+ old_style = SCE_ERLANG_COMMENT_FUNCTION;
+ parse_state = COMMENT_FUNCTION;
+ sc.Forward();
+ }
}
- } else {
- sc.SetState(SCE_ERLANG_DEFAULT);
- }
- } else if (sc.state == SCE_ERLANG_VARIABLE) {
- if (!isalnum(sc.ch) && sc.ch != '_') {
- sc.SetState(SCE_ERLANG_DEFAULT);
- }
- } else if (sc.state == SCE_ERLANG_STRING) {
- if (sc.ch == '\"' && sc.chPrev != '\\') {
- sc.ForwardSetState(SCE_ERLANG_DEFAULT);
+ // V--- Falling through!
+ case COMMENT_FUNCTION : {
+ if (sc.ch != '%') {
+ to_late_to_comment = true;
+ } else if (!to_late_to_comment && sc.ch == '%') {
+ // Switch to comment level 3 (Module)
+ sc.ChangeState(SCE_ERLANG_COMMENT_MODULE);
+ old_style = SCE_ERLANG_COMMENT_MODULE;
+ parse_state = COMMENT_MODULE;
+ sc.Forward();
+ }
+ }
+ // V--- Falling through!
+ case COMMENT_MODULE : {
+ if (parse_state != COMMENT) {
+ // Search for comment documentation
+ if (sc.chNext == '@') {
+ old_parse_state = parse_state;
+ parse_state = ('{' == sc.ch)
+ ? COMMENT_DOC_MACRO
+ : COMMENT_DOC;
+ sc.ForwardSetState(sc.state);
+ }
+ }
+
+ // All comments types fall here.
+ if (sc.atLineEnd) {
+ to_late_to_comment = false;
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+ } break;
+
+ case COMMENT_DOC :
+ // V--- Falling through!
+ case COMMENT_DOC_MACRO : {
+
+ if (!isalnum(sc.ch)) {
+ // Try to match documentation comment
+ sc.GetCurrent(cur, sizeof(cur));
+
+ if (parse_state == COMMENT_DOC_MACRO
+ && erlangDocMacro.InList(cur)) {
+ sc.ChangeState(SCE_ERLANG_COMMENT_DOC_MACRO);
+ while (sc.ch != '}' && !sc.atLineEnd)
+ sc.Forward();
+ } else if (erlangDoc.InList(cur)) {
+ sc.ChangeState(SCE_ERLANG_COMMENT_DOC);
+ } else {
+ sc.ChangeState(old_style);
+ }
+
+ // Switch back to old state
+ sc.SetState(old_style);
+ parse_state = old_parse_state;
+ }
+
+ if (sc.atLineEnd) {
+ to_late_to_comment = false;
+ sc.ChangeState(old_style);
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+ } break;
+
+ /* -------------------------------------------------------------- */
+ /* Atoms ---------------------------------------------------------*/
+ case ATOM_UNQUOTED : {
+ if ('@' == sc.ch){
+ parse_state = NODE_NAME_UNQUOTED;
+ } else if (sc.ch == ':') {
+ // Searching for module name
+ if (sc.chNext == ' ') {
+ // error
+ sc.ChangeState(SCE_ERLANG_UNKNOWN);
+ parse_state = STATE_NULL;
+ } else {
+ sc.Forward();
+ if (isalnum(sc.ch)) {
+ sc.GetCurrent(cur, sizeof(cur));
+ sc.ChangeState(SCE_ERLANG_MODULES);
+ sc.SetState(SCE_ERLANG_MODULES);
+ }
+ }
+ } else if (!IsAWordChar(sc.ch)) {
+
+ sc.GetCurrent(cur, sizeof(cur));
+ if (reservedWords.InList(cur)) {
+ style = SCE_ERLANG_KEYWORD;
+ } else if (erlangBIFs.InList(cur)
+ && strcmp(cur,"erlang:")){
+ style = SCE_ERLANG_BIFS;
+ } else if (sc.ch == '(' || '/' == sc.ch){
+ style = SCE_ERLANG_FUNCTION_NAME;
+ } else {
+ style = SCE_ERLANG_ATOM;
+ }
+
+ sc.ChangeState(style);
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+
+ } break;
+
+ case ATOM_QUOTED : {
+ if ( '@' == sc.ch ){
+ parse_state = NODE_NAME_QUOTED;
+ } else if ('\'' == sc.ch && '\\' != sc.chPrev) {
+ sc.ChangeState(SCE_ERLANG_ATOM);
+ sc.ForwardSetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+ } break;
+
+ /* -------------------------------------------------------------- */
+ /* Node names ----------------------------------------------------*/
+ case NODE_NAME_UNQUOTED : {
+ if ('@' == sc.ch) {
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ } else if (!IsAWordChar(sc.ch)) {
+ sc.ChangeState(SCE_ERLANG_NODE_NAME);
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+ } break;
+
+ case NODE_NAME_QUOTED : {
+ if ('@' == sc.ch) {
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ } else if ('\'' == sc.ch && '\\' != sc.chPrev) {
+ sc.ChangeState(SCE_ERLANG_NODE_NAME_QUOTED);
+ sc.ForwardSetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+ } break;
+
+ /* -------------------------------------------------------------- */
+ /* Records -------------------------------------------------------*/
+ case RECORD_START : {
+ if ('\'' == sc.ch) {
+ parse_state = RECORD_QUOTED;
+ } else if (isalpha(sc.ch) && islower(sc.ch)) {
+ parse_state = RECORD_UNQUOTED;
+ } else { // error
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+ } break;
+
+ case RECORD_UNQUOTED : {
+ if (!IsAWordChar(sc.ch)) {
+ sc.ChangeState(SCE_ERLANG_RECORD);
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+ } break;
+
+ case RECORD_QUOTED : {
+ if ('\'' == sc.ch && '\\' != sc.chPrev) {
+ sc.ChangeState(SCE_ERLANG_RECORD_QUOTED);
+ sc.ForwardSetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+ } break;
+
+ /* -------------------------------------------------------------- */
+ /* Macros --------------------------------------------------------*/
+ case MACRO_START : {
+ if ('\'' == sc.ch) {
+ parse_state = MACRO_QUOTED;
+ } else if (isalpha(sc.ch)) {
+ parse_state = MACRO_UNQUOTED;
+ } else { // error
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+ } break;
+
+ case MACRO_UNQUOTED : {
+ if (!IsAWordChar(sc.ch)) {
+ sc.ChangeState(SCE_ERLANG_MACRO);
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+ } break;
+
+ case MACRO_QUOTED : {
+ if ('\'' == sc.ch && '\\' != sc.chPrev) {
+ sc.ChangeState(SCE_ERLANG_MACRO_QUOTED);
+ sc.ForwardSetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+ } break;
+
+ /* -------------------------------------------------------------- */
+ /* Numerics ------------------------------------------------------*/
+ /* Simple integer */
+ case NUMERAL_START : {
+ if (isdigit(sc.ch)) {
+ radix_digits *= 10;
+ radix_digits += sc.ch - '0'; // Assuming ASCII here!
+ } else if ('#' == sc.ch) {
+ if (2 > radix_digits || 36 < radix_digits) {
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ } else {
+ parse_state = NUMERAL_BASE_VALUE;
+ }
+ } else if ('.' == sc.ch && isdigit(sc.chNext)) {
+ radix_digits = 0;
+ parse_state = NUMERAL_FLOAT;
+ } else if ('e' == sc.ch || 'E' == sc.ch) {
+ exponent_digits = 0;
+ parse_state = NUMERAL_EXPONENT;
+ } else {
+ radix_digits = 0;
+ sc.ChangeState(SCE_ERLANG_NUMBER);
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+ } break;
+
+ /* Integer in other base than 10 (x#yyy) */
+ case NUMERAL_BASE_VALUE : {
+ if (!is_radix(radix_digits,sc.ch)) {
+ radix_digits = 0;
+
+ if (!isalnum(sc.ch))
+ sc.ChangeState(SCE_ERLANG_NUMBER);
+
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+ } break;
+
+ /* Float (x.yyy) */
+ case NUMERAL_FLOAT : {
+ if ('e' == sc.ch || 'E' == sc.ch) {
+ exponent_digits = 0;
+ parse_state = NUMERAL_EXPONENT;
+ } else if (!isdigit(sc.ch)) {
+ sc.ChangeState(SCE_ERLANG_NUMBER);
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+ } break;
+
+ /* Exponent, either integer or float (xEyy, x.yyEzzz) */
+ case NUMERAL_EXPONENT : {
+ if (('-' == sc.ch || '+' == sc.ch)
+ && (isdigit(sc.chNext))) {
+ sc.Forward();
+ } else if (!isdigit(sc.ch)) {
+ if (0 < exponent_digits)
+ sc.ChangeState(SCE_ERLANG_NUMBER);
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ } else {
+ ++exponent_digits;
+ }
+ } break;
+
+ /* -------------------------------------------------------------- */
+ /* Preprocessor --------------------------------------------------*/
+ case PREPROCESSOR : {
+ if (!IsAWordChar(sc.ch)) {
+
+ sc.GetCurrent(cur, sizeof(cur));
+ if (erlangPreproc.InList(cur)) {
+ style = SCE_ERLANG_PREPROC;
+ } else if (erlangModulesAtt.InList(cur)) {
+ style = SCE_ERLANG_MODULES_ATT;
+ }
+
+ sc.ChangeState(style);
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+ } break;
+
}
- } else if (sc.state == SCE_ERLANG_COMMENT ) {
- if (sc.atLineEnd) {
- sc.SetState(SCE_ERLANG_DEFAULT);
+
+ } /* End of : STATE_NULL != parse_state */
+ else
+ {
+ switch (sc.state) {
+ case SCE_ERLANG_VARIABLE : {
+ if (!IsAWordChar(sc.ch))
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ } break;
+ case SCE_ERLANG_STRING : {
+ if (sc.ch == '\"' && sc.chPrev != '\\')
+ sc.ForwardSetState(SCE_ERLANG_DEFAULT);
+ } break;
+ case SCE_ERLANG_COMMENT : {
+ if (sc.atLineEnd)
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ } break;
+ case SCE_ERLANG_CHARACTER : {
+ if (sc.chPrev == '\\') {
+ sc.ForwardSetState(SCE_ERLANG_DEFAULT);
+ } else if (sc.ch != '\\') {
+ sc.ForwardSetState(SCE_ERLANG_DEFAULT);
+ }
+ } break;
+ case SCE_ERLANG_OPERATOR : {
+ if (sc.chPrev == '.') {
+ if (sc.ch == '*' || sc.ch == '/' || sc.ch == '\\'
+ || sc.ch == '^') {
+ sc.ForwardSetState(SCE_ERLANG_DEFAULT);
+ } else if (sc.ch == '\'') {
+ sc.ForwardSetState(SCE_ERLANG_DEFAULT);
+ } else {
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ }
+ } else {
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ }
+ } break;
}
- } else if (sc.state == SCE_ERLANG_CHARACTER ) {
- if ( sc.chPrev == '\\' ) {
- sc.ForwardSetState(SCE_ERLANG_DEFAULT);
- } else if ( sc.ch != '\\' ) {
- sc.ForwardSetState(SCE_ERLANG_DEFAULT);
- }
- }
+ }
if (sc.state == SCE_ERLANG_DEFAULT) {
- if (sc.ch == '%') {
- sc.SetState(SCE_ERLANG_COMMENT);
- } else if (sc.ch == '\"') {
- sc.SetState(SCE_ERLANG_STRING);
- } else if (sc.ch == '#') {
- parse_state = RECORD_START;
- sc.SetState(SCE_ERLANG_UNKNOWN);
- } else if (sc.ch == '?') {
- parse_state = MACRO_START;
- sc.SetState(SCE_ERLANG_UNKNOWN);
- } else if (sc.ch == '$') {
- sc.SetState(SCE_ERLANG_CHARACTER);
- } else if (sc.ch == '\'') {
- parse_state = ATOM_QUOTED;
- sc.SetState(SCE_ERLANG_UNKNOWN);
- } else if ( isdigit(sc.ch) ) {
- parse_state = NUMERAL_START;
- radix_digits = sc.ch - '0';
- sc.SetState(SCE_ERLANG_UNKNOWN);
- } else if ( '.' == sc.ch ) {
- parse_state = NUMERAL_SPECULATIVE_MANTISSA;
- sc.SetState(SCE_ERLANG_UNKNOWN);
- } else if (isalpha(sc.ch) && isupper(sc.ch)) {
- sc.SetState(SCE_ERLANG_VARIABLE);
- } else if (isalpha(sc.ch)) {
- parse_state = ATOM_UNQUOTED;
- sc.SetState(SCE_ERLANG_UNKNOWN);
- } else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '\\') {
- sc.SetState(SCE_ERLANG_OPERATOR);
+ bool no_new_state = false;
+
+ switch (sc.ch) {
+ case '\"' : sc.SetState(SCE_ERLANG_STRING); break;
+ case '$' : sc.SetState(SCE_ERLANG_CHARACTER); break;
+ case '%' : {
+ parse_state = COMMENT;
+ sc.SetState(SCE_ERLANG_COMMENT);
+ } break;
+ case '#' : {
+ parse_state = RECORD_START;
+ sc.SetState(SCE_ERLANG_UNKNOWN);
+ } break;
+ case '?' : {
+ parse_state = MACRO_START;
+ sc.SetState(SCE_ERLANG_UNKNOWN);
+ } break;
+ case '\'' : {
+ parse_state = ATOM_QUOTED;
+ sc.SetState(SCE_ERLANG_UNKNOWN);
+ } break;
+ case '+' :
+ case '-' : {
+ if (IsADigit(sc.chNext)) {
+ parse_state = NUMERAL_START;
+ radix_digits = 0;
+ sc.SetState(SCE_ERLANG_UNKNOWN);
+ } else if (sc.ch != '+') {
+ parse_state = PREPROCESSOR;
+ sc.SetState(SCE_ERLANG_UNKNOWN);
+ }
+ } break;
+ default : no_new_state = true;
+ }
+
+ if (no_new_state) {
+ if (isdigit(sc.ch)) {
+ parse_state = NUMERAL_START;
+ radix_digits = sc.ch - '0';
+ sc.SetState(SCE_ERLANG_UNKNOWN);
+ } else if (isupper(sc.ch) || '_' == sc.ch) {
+ sc.SetState(SCE_ERLANG_VARIABLE);
+ } else if (isalpha(sc.ch)) {
+ parse_state = ATOM_UNQUOTED;
+ sc.SetState(SCE_ERLANG_UNKNOWN);
+ } else if (isoperator(static_cast<char>(sc.ch))
+ || sc.ch == '\\') {
+ sc.SetState(SCE_ERLANG_OPERATOR);
+ }
}
}
+
}
sc.Complete();
}
-static int ClassifyFoldPointErlang(
- Accessor &styler,
- int styleNext,
- int keyword_start
+static int ClassifyErlangFoldPoint(
+ Accessor &styler,
+ int styleNext,
+ int keyword_start
) {
int lev = 0;
- if ( styler.Match(keyword_start,"case")
- || (
- styler.Match(keyword_start,"fun")
- && SCE_ERLANG_FUNCTION_NAME != styleNext)
- || styler.Match(keyword_start,"if")
- || styler.Match(keyword_start,"query")
- || styler.Match(keyword_start,"receive")
- ) {
- ++lev;
- } else if ( styler.Match(keyword_start,"end") ) {
- --lev;
- }
+ if (styler.Match(keyword_start,"case")
+ || (
+ styler.Match(keyword_start,"fun")
+ && (SCE_ERLANG_FUNCTION_NAME != styleNext)
+ )
+ || styler.Match(keyword_start,"if")
+ || styler.Match(keyword_start,"query")
+ || styler.Match(keyword_start,"receive")
+ ) {
+ ++lev;
+ } else if (styler.Match(keyword_start,"end")) {
+ --lev;
+ }
+
return lev;
}
-
static void FoldErlangDoc(
- unsigned int startPos, int length, int initStyle,
- WordList** /*keywordlists*/, Accessor &styler
+ unsigned int startPos, int length, int initStyle,
+ WordList** /*keywordlists*/, Accessor &styler
) {
unsigned int endPos = startPos + length;
- //~ int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
- int levelCurrent = levelPrev;
- char chNext = styler.SafeGetCharAt(startPos);
+ int currentLine = styler.GetLine(startPos);
+ int lev;
+ int previousLevel = styler.LevelAt(currentLine) & SC_FOLDLEVELNUMBERMASK;
+ int currentLevel = previousLevel;
int styleNext = styler.StyleAt(startPos);
int style = initStyle;
+ int stylePrev;
int keyword_start = 0;
-
- bool fold_keywords = true;
- bool fold_comments = true;
- bool fold_braces = true;
- bool fold_function_clauses = false;
- bool fold_clauses = false;
-
- //int clause_level = 0;
+ char ch;
+ char chNext = styler.SafeGetCharAt(startPos);
+ bool atEOL;
for (unsigned int i = startPos; i < endPos; i++) {
- char ch = chNext;
+ ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
- int stylePrev = style;
+
+ // Get styles
+ stylePrev = style;
style = styleNext;
styleNext = styler.StyleAt(i + 1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
-
- if ( (stylePrev != SCE_ERLANG_KEYWORD) && (style == SCE_ERLANG_KEYWORD) ) {
- keyword_start = i;
- }
- if ( fold_keywords ) {
- if ( (stylePrev == SCE_ERLANG_KEYWORD)
- && (style != SCE_ERLANG_KEYWORD)
- && (style != SCE_ERLANG_ATOM)
- ) {
- levelCurrent += ClassifyFoldPointErlang(styler,styleNext,keyword_start);
- }
- }
-
- if ( fold_comments ) {
- if (style == SCE_ERLANG_COMMENT) {
- if ((ch == '%') && (chNext == '{')) {
- levelCurrent++;
- } else if ((ch == '%') && (chNext == '}')) {
- levelCurrent--;
- }
- }
- }
-
- if ( fold_function_clauses ) {
- if ( (SC_FOLDLEVELBASE == levelCurrent) /*&& (style == SCE_ERLANG_OPERATOR)*/ ) {
- if ( (ch == '-') && (chNext == '>')) {
- //~ fprintf(stderr,"levelCurrent=%d\n", levelCurrent);
- //++clause_level;
- //~ if ( 0 < clause_level )
- ++levelCurrent;
- }
- }
- //~ if ( (stylePrev != SCE_ERLANG_RECORD)
- //~ && (style != SCE_ERLANG_NUMBER)
- //~ && (style != SCE_ERLANG_STRING)
- //~ && (style != SCE_ERLANG_COMMENT)
- //~ ) {
- if ( (SC_FOLDLEVELBASE+1 == levelCurrent) && (ch == '.') ) {
- //--clause_level;
- //~ if ( 0 == clause_level )
- --levelCurrent;
- }
- //~ }
- }
-
- if ( fold_clauses ) {
- if ( (0 < levelCurrent) && (style == SCE_ERLANG_OPERATOR) ) {
- if ((ch == '-') && (chNext == '>')) {
- levelCurrent++;
- }
- if ( (ch == ';') ) {
- levelCurrent--;
- }
- }
- if ( (stylePrev != SCE_ERLANG_RECORD)
- && (style != SCE_ERLANG_NUMBER)
- && (style != SCE_ERLANG_STRING)
- && (style != SCE_ERLANG_COMMENT)
- ) {
- if ( (ch == '.') ) {
- levelCurrent--;
- }
- }
- if ( (stylePrev == SCE_ERLANG_KEYWORD)
- && (style != SCE_ERLANG_KEYWORD)
- && (style != SCE_ERLANG_ATOM)
- && (
- styler.Match(keyword_start,"end") // 'end' counted twice if fold_keywords too
- || styler.Match(keyword_start,"after") )
- ) {
- levelCurrent--;
- }
- }
-
- if ( fold_braces ) {
- if (style == SCE_ERLANG_OPERATOR) {
- if ( (ch == '{') || (ch == '(') || (ch == '[') ) {
- levelCurrent++;
- } else if ( (ch == '}') || (ch == ')') || (ch == ']') ) {
- levelCurrent--;
- }
- }
- }
+ atEOL = ((ch == '\r') && (chNext != '\n')) || (ch == '\n');
+
+ if (stylePrev != SCE_ERLANG_KEYWORD
+ && style == SCE_ERLANG_KEYWORD) {
+ keyword_start = i;
+ }
+
+ // Fold on keywords
+ if (stylePrev == SCE_ERLANG_KEYWORD
+ && style != SCE_ERLANG_KEYWORD
+ && style != SCE_ERLANG_ATOM
+ ) {
+ currentLevel += ClassifyErlangFoldPoint(styler,
+ styleNext,
+ keyword_start);
+ }
+
+ // Fold on comments
+ if (style == SCE_ERLANG_COMMENT
+ || style == SCE_ERLANG_COMMENT_MODULE
+ || style == SCE_ERLANG_COMMENT_FUNCTION) {
+
+ if (ch == '%' && chNext == '{') {
+ currentLevel++;
+ } else if (ch == '%' && chNext == '}') {
+ currentLevel--;
+ }
+ }
+
+ // Fold on braces
+ if (style == SCE_ERLANG_OPERATOR) {
+ if (ch == '{' || ch == '(' || ch == '[') {
+ currentLevel++;
+ } else if (ch == '}' || ch == ')' || ch == ']') {
+ currentLevel--;
+ }
+ }
+
if (atEOL) {
- int lev = levelPrev;
- //~ if (visibleChars == 0 && foldCompact)
- //~ lev |= SC_FOLDLEVELWHITEFLAG;
- //~ if ((levelCurrent > levelPrev) && (visibleChars > 0))
- if ((levelCurrent > levelPrev)) {
+ lev = previousLevel;
+
+ if (currentLevel > previousLevel)
lev |= SC_FOLDLEVELHEADERFLAG;
- }
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelPrev = levelCurrent;
- //~ visibleChars = 0;
+
+ if (lev != styler.LevelAt(currentLine))
+ styler.SetLevel(currentLine, lev);
+
+ currentLine++;
+ previousLevel = currentLevel;
}
- //~ if (!isspacechar(ch))
- //~ visibleChars++;
}
+
// Fill in the real level of the next line, keeping the current flags as they will be filled in later
- int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
- styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+ styler.SetLevel(currentLine,
+ previousLevel
+ | (styler.LevelAt(currentLine) & ~SC_FOLDLEVELNUMBERMASK));
}
static const char * const erlangWordListDesc[] = {
- "Keywords",
+ "Erlang Reserved words",
+ "Erlang BIFs",
+ "Erlang Preprocessor",
+ "Erlang Module Attributes",
+ "Erlang Documentation",
+ "Erlang Documentation Macro",
0
};
LexerModule lmErlang(
- SCLEX_ERLANG,
- ColouriseErlangDoc,
- "erlang",
- FoldErlangDoc,
- erlangWordListDesc);
-
+ SCLEX_ERLANG,
+ ColouriseErlangDoc,
+ "erlang",
+ FoldErlangDoc,
+ erlangWordListDesc);