1
// This file is part of PUMA.
2
// Copyright (C) 1999-2003 The PUMA developer team.
4
// This program is free software; you can redistribute it and/or
5
// modify it under the terms of the GNU General Public License as
6
// published by the Free Software Foundation; either version 2 of
7
// the License, or (at your option) any later version.
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
// GNU General Public License for more details.
14
// You should have received a copy of the GNU General Public
15
// License along with this program; if not, write to the Free
16
// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21
#include "Puma/CRecognizer.h"
22
#include "Puma/Source.h"
24
// Include token type definitions
25
#include "Puma/PreParser.h"
26
#include "Puma/CTokens.h"
27
#include "Puma/CWildcardTokens.h"
28
#include "Puma/CWhitespaceTokens.h"
29
#include "Puma/PreMacroOpTokens.h"
34
// Include generated scanner tables
35
#include "CStringTab.ot"
36
#include "PreDirectiveTab.ot"
37
#include "PreTokenTab.ot"
38
#include "CDirectiveTab.ot"
39
#include "CWhitespaceTab.ot"
40
#include "CWildcardTab.ot"
41
#include "CCoreTab.ot"
42
#include "CIdentifierTab.ot"
45
// Declaration of orange token recognizer objects
47
MappedOrangeRecognizer<CScanBuffer> CRecognizer::string_recognizer (
48
CStringTabMap, CStringTabExprMap,
49
CStringTabStart, CStringTabStates,
50
CStringTabNext, CStringTabControl,
51
sizeof (CStringTabNext) / sizeof (int));
53
MappedOrangeRecognizer<CScanBuffer> CRecognizer::pre_dir_recognizer (
54
PreDirectiveTabMap, PreDirectiveTabExprMap,
55
PreDirectiveTabStart, PreDirectiveTabStates,
56
PreDirectiveTabNext, PreDirectiveTabControl,
57
sizeof (PreDirectiveTabNext) / sizeof (int));
59
MappedOrangeRecognizer<CScanBuffer> CRecognizer::pre_token_recognizer (
60
PreTokenTabMap, PreTokenTabExprMap,
61
PreTokenTabStart, PreTokenTabStates,
62
PreTokenTabNext, PreTokenTabControl,
63
sizeof (PreTokenTabNext) / sizeof (int));
65
OrangeRecognizer<CScanBuffer> CRecognizer::dir_recognizer (
66
CDirectiveTabMap, CDirectiveTabStart,
67
CDirectiveTabStates, CDirectiveTabNext,
69
sizeof (CDirectiveTabNext) / sizeof (int));
71
MappedOrangeRecognizer<CScanBuffer> CRecognizer::whitespace_recognizer (
72
CWhitespaceTabMap, CWhitespaceTabExprMap, CWhitespaceTabStart,
73
CWhitespaceTabStates, CWhitespaceTabNext, CWhitespaceTabControl,
74
sizeof (CWhitespaceTabNext) / sizeof (int));
76
MappedOrangeRecognizer<CScanBuffer> CRecognizer::wildcard_recognizer (
77
CWildcardTabMap, CWildcardTabExprMap, CWildcardTabStart,
78
CWildcardTabStates, CWildcardTabNext, CWildcardTabControl,
79
sizeof (CWildcardTabNext) / sizeof (int));
81
MappedOrangeRecognizer<CScanBuffer> CRecognizer::core_recognizer (
82
CCoreTabMap, CCoreTabExprMap, CCoreTabStart, CCoreTabStates,
83
CCoreTabNext, CCoreTabControl, sizeof (CCoreTabNext) / sizeof (int));
85
MappedOrangeRecognizer<CScanBuffer> CRecognizer::identifier_recognizer (
86
CIdentifierTabMap, CIdentifierTabExprMap, CIdentifierTabStart,
87
CIdentifierTabStates, CIdentifierTabNext, CIdentifierTabControl,
88
sizeof (CIdentifierTabNext) / sizeof (int));
94
void CRecognizer::setup (ScanBuffer &buffer) {
95
scan_buffer.decorate (&buffer);
96
comment_recognizer.mode (CCommentRecognizer::NO_COMMENT);
97
check_directive = true;
103
int CRecognizer::recognize (Lang &lang, int &expr, int &len) {
106
if (scan_buffer.new_line ()) {
108
check_directive = true;
111
if ((result = comment_recognizer.recognize (&scan_buffer, expr, len)) != 0) {
115
scan_buffer.retry ();
117
if (check_directive && ! macro_ops) {
118
check_directive = false;
119
if ((result = pre_dir_recognizer.recognize (&scan_buffer, expr, len)) != 0) {
121
scan_mode = IN_PRE_DIR;
125
scan_buffer.retry ();
127
if ((result = dir_recognizer.recognize (&scan_buffer, expr, len)) != 0) {
129
scan_mode = IN_COMP_DIR;
133
scan_buffer.retry ();
136
if ((result = whitespace_recognizer.recognize (&scan_buffer, expr, len)) != 0) {
140
scan_buffer.retry ();
142
if ((result = string_recognizer.recognize (&scan_buffer, expr, len)) != 0) {
146
scan_buffer.retry ();
148
if (macro_ops || scan_mode == IN_PRE_DIR) {
149
if ((result = pre_token_recognizer.recognize (&scan_buffer, expr, len)) != 0) {
153
scan_buffer.retry ();
157
if ((result = wildcard_recognizer.recognize (&scan_buffer, expr, len)) != 0) {
161
scan_buffer.retry ();
164
if ((result = core_recognizer.recognize (&scan_buffer, expr, len)) != 0) {
165
if (expr <= TOK_LAST_CORE) {
169
// if it looks like a keyword we have to check if some character follows
170
// that makes it an identifier instead of a keyword
171
scan_buffer.more (len);
172
if (scan_buffer.state () == ScanBuffer::STATE_OK) {
173
char next = scan_buffer.next ();
174
if (isalnum ((int)next) || next == '_')
176
scan_buffer.more (len);
179
((expr <= TOK_LAST_AC && aspectc) ||
180
(expr <= TOK_LAST_CC && std_cplusplus) ||
181
(expr <= TOK_LAST_C && std_c))) {
186
scan_buffer.retry ();
188
long num = additional_keyword_recognizers.length ();
189
for (long i = 0; i < num; i++) {
190
if ((result = additional_keyword_recognizers[i]->recognize (&scan_buffer, expr, len)) != 0) {
194
scan_buffer.retry ();
197
if ((result = identifier_recognizer.recognize (&scan_buffer, expr, len)) != 0) {
201
scan_buffer.retry ();