Skip to content

Instantly share code, notes, and snippets.

@expalmer
Last active October 3, 2017 15:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save expalmer/c872f02d6578354c1c376824b5988734 to your computer and use it in GitHub Desktop.
Save expalmer/c872f02d6578354c1c376824b5988734 to your computer and use it in GitHub Desktop.
Analisador Léxico
a
a
int
asd
as123
99
99.
99.999
float
real a
real
double _c
double
as_asd
asd
// Tales Bitelo Viegas
-- Teste
Tales Viegas --
char
/*
COMO USAR
node index.js nomedoarquivo
*/
const fs = require('fs');
const LETTERS = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];
const NUMBERS = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
const tokens = [];
const ids = [];
const errors = [];
function isAlfaLower(v) {
return LETTERS.some(i => i === v);
}
function isNumeric(v) {
return NUMBERS.some(i => i === +v);
}
function isEndOfLine(v) {
return (v === '\n' || v === undefined);
}
function isAlfaNumInsensitive(v) {
const merged = NUMBERS.concat(LETTERS);
return merged.some(i => (i + '').toLowerCase() === `${v.toLowerCase()}`);
}
function token(line, word) {
tokens.push(`[${line + 1}] ${word}`);
}
function saveInTable(type, word) {
let index = ids.indexOf(word);
if (index === -1) {
ids.push(word);
index = ids.length - 1;
}
return `${type} ${index + 1}`;
}
// TYPES
function idType(line, word, current) {
const w = word[current];
if (isEndOfLine(w)) {
return token(line, saveInTable('IDENTIFICADOR', word));
}
if (isAlfaNumInsensitive(w)) {
return idType(line, word, current + 1);
}
return errorType(line, word);
}
function errorType(line, word, current) {
errors.push(`[${line + 1}] ${word}`);
}
function breakType(line, word, current) {
const w = word[current];
const f = breakType;
if (current === 0 && w === 'b') {
return f(line, word, current + 1);
}
if (current === 1 && w === 'r') {
return f(line, word, current + 1);
}
if (current === 2 && w === 'e') {
return f(line, word, current + 1);
}
if (current === 3 && w === 'a') {
return f(line, word, current + 1);
}
if (current === 4 && w === 'k') {
return f(line, word, current + 1);
}
if (current === 5 && isEndOfLine(w)) {
return token(line, word.slice(0, current));
}
if (isAlfaNumInsensitive(w)) {
return idType(line, word, current);
}
return errorType(line, word, current);
}
function caseType(line, word, current) {
const w = word[current];
const f = caseType;
if (current === 0 && w === 'c') {
return f(line, word, current + 1);
}
if (current === 1 && w === 'a') {
return f(line, word, current + 1);
}
if (current === 1 && w === 'h') {
return charType(line, word, current);
}
if (current === 1 && w === 'o') {
return constType(line, word, current);
}
if (current === 2 && w === 's') {
return f(line, word, current + 1);
}
if (current === 3 && w === 'e') {
return f(line, word, current + 1);
}
if (current === 4 && isEndOfLine(w)) {
return token(line, word.slice(0, current));
}
if (isAlfaNumInsensitive(w)) {
return idType(line, word, current);
}
return errorType(line, word, current);
}
function charType(line, word, current) {
const w = word[current];
const f = charType;
if (current === 1 && w === 'h') {
return f(line, word, current + 1);
}
if (current === 2 && w === 'a') {
return f(line, word, current + 1);
}
if (current === 3 && w === 'r') {
return f(line, word, current + 1);
}
if (current === 4 && isEndOfLine(w)) {
return token(line, word.slice(0, current));
}
if (isAlfaNumInsensitive(w)) {
return idType(line, word, current);
}
return errorType(line, word, current);
}
function constType(line, word, current) {
const w = word[current];
const f = constType;
if (current === 1 && w === 'o') {
return f(line, word, current + 1);
}
if (current === 2 && w === 'n') {
return f(line, word, current + 1);
}
if (current === 3 && w === 's') {
return f(line, word, current + 1);
}
if (current === 3 && w === 't') {
return continueType(line, word, current + 1);
}
if (current === 4 && w === 't') {
return f(line, word, current + 1);
}
if (current === 5 && isEndOfLine(w)) {
return token(line, word.slice(0, current));
}
if (isAlfaNumInsensitive(w)) {
return idType(line, word, current);
}
return errorType(line, word, current);
}
function continueType(line, word, current) {
const w = word[current];
const f = continueType;
if (current === 4 && w === 'i') {
return f(line, word, current + 1);
}
if (current === 5 && w === 'n') {
return f(line, word, current + 1);
}
if (current === 6 && w === 'u') {
return f(line, word, current + 1);
}
if (current === 7 && w === 'e') {
return f(line, word, current + 1);
}
if (current === 8 && isEndOfLine(w)) {
return token(line, word.slice(0, current));
}
if (isAlfaNumInsensitive(w)) {
return idType(line, word, current);
}
return errorType(line, word, current);
}
function doubleType(line, word, current) {
const w = word[current];
const f = doubleType;
if (current === 0 && w === 'd') {
return f(line, word, current + 1);
}
if (current === 1 && w === 'o') {
return f(line, word, current + 1);
}
if (current === 2 && w === 'u') {
return f(line, word, current + 1);
}
if (current === 3 && w === 'b') {
return f(line, word, current + 1);
}
if (current === 4 && w === 'l') {
return f(line, word, current + 1);
}
if (current === 5 && w === 'e') {
return f(line, word, current + 1);
}
if (current === 6 && isEndOfLine(w)) {
return token(line, word.slice(0, current).toUpperCase());
}
if (isAlfaNumInsensitive(w)) {
return idType(line, word, current);
}
return errorType(line, word, current);
}
function floatType(line, word, current) {
const w = word[current];
const f = floatType;
if (current === 0 && w === 'f') {
return f(line, word, current + 1);
}
if (current === 1 && w === 'l') {
return f(line, word, current + 1);
}
if (current === 2 && w === 'o') {
return f(line, word, current + 1);
}
if (current === 3 && w === 'a') {
return f(line, word, current + 1);
}
if (current === 4 && w === 't') {
return f(line, word, current + 1);
}
if (current === 5 && isEndOfLine(w)) {
return token(line, word.slice(0, current).toUpperCase());
}
if (isAlfaNumInsensitive(w)) {
return idType(line, word, current);
}
return errorType(line, word, current);
}
function intType(line, word, current) {
const w = word[current];
const f = intType;
if (current === 0 && w === 'i') {
return f(line, word, current + 1);
}
if (current === 1 && w === 'n') {
return f(line, word, current + 1);
}
if (current === 2 && w === 't') {
return f(line, word, current + 1);
}
if (current === 3 && isEndOfLine(w)) {
return token(line, word.slice(0, current).toUpperCase());
}
if (isAlfaNumInsensitive(w)) {
return idType(line, word, current);
}
return errorType(line, word, current);
}
function realType(line, word, current) {
const w = word[current];
const f = realType;
if (current === 0 && w === 'r') {
return f(line, word, current + 1);
}
if (current === 1 && w === 'e') {
return f(line, word, current + 1);
}
if (current === 2 && w === 'a') {
return f(line, word, current + 1);
}
if (current === 3 && w === 'l') {
return f(line, word, current + 1);
}
if (current === 4 && isEndOfLine(w)) {
return token(line, word.slice(0, current).toUpperCase());
}
if (isAlfaNumInsensitive(w)) {
return idType(line, word, current);
}
return errorType(line, word, current);
}
function commentType(line, word, current) {
const w = word[current];
const f = commentType;
if (current === 0 && w === '/') {
return f(line, word, current + 1);
}
if (current === 1 && w === '/') {
return f(line, word, current + 1);
}
if (current === 2) {
return token(line, 'COMENTÁRIO');
}
return errorType(line, word, current);
}
function realNumberType(line, word, current) {
const w = word[current];
const f = realNumberType;
if (isNumeric(w)) {
return f(line, word, current + 1);
}
if (isEndOfLine(w) && word[current - 1] !== '.') {
return token(line, saveInTable('NÚMERO REAL', word));
}
return errorType(line, word, current);
}
function integerNumberType(line, word, current) {
const w = word[current];
const f = integerNumberType;
if (isNumeric(w)) {
return f(line, word, current + 1);
}
if (w === '.') {
return realNumberType(line, word, current + 1);
}
if (isEndOfLine(w)) {
return token(line, saveInTable('NÚMERO INTEIRO', word));
}
return errorType(line, word, current);
}
function readLine(word, line) {
let current = 0;
const w = word[current];
if (w === 'b') {
return breakType(line, word, 0);
}
if (w === 'c') {
return caseType(line, word, 0);
}
if (w === 'd') {
return doubleType(line, word, 0);
}
if (w === 'f') {
return floatType(line, word, 0);
}
if (w === 'i') {
return intType(line, word, 0);
}
if (w === 'r') {
return realType(line, word, 0);
}
if (w === '/') {
return commentType(line, word, 0);
}
if (isAlfaLower(w)) {
return idType(line, word, 0);
}
if (isNumeric(w)) {
return integerNumberType(line, word, 0);
}
}
function init() {
const fileName = process.argv[2] || false;
if (!fileName) {
console.log('Informe um arquivo como: node index.js NomeDoArquivo');
return;
}
if (!fs.existsSync(fileName)) {
console.log('Arquivo não existe');
return;
}
fs.readFileSync(fileName)
.toString()
.split('\n')
.map(readLine);
console.log('\x1b[33m', 'TOKENS')
tokens
.forEach(i => console.log('\x1b[36m%s\x1b[0m', i));
console.log('\n');
console.log('\x1b[33m', 'TABELA')
ids
.forEach((i, k) => console.log('\x1b[36m%s\x1b[0m', `${k + 1}: ${i}`));
console.log('\n');
console.log('\x1b[33m', 'ERROS')
errors
.forEach(i => console.log('\x1b[31m', i));
}
init();
%%
%class ipv6
%standalone
%line
%column
%%
([0-9a-fA-F]{4})\:([0-9a-fA-F]{3,4})\:([0-9a-fA-F]{4}|[0-9a-fA-F]{1})?\:([0-9a-fA-F]{4}|[0-9a-fA-F]{1})\:([0-9a-fA-F]{4}|[0-9a-fA-F]{1})\:([0-9a-fA-F]{4}|[0-9a-fA-F]{1})?\:([0-9a-fA-F]{4})(\:([0-9a-fA-F]{4}))? {
System.out.printf("Reconheci um IPV6 [%s] na linha %d, coluna %d\n", yytext(), yyline, yycolumn);
}
\n {/* Do Nothing */}
. {/* Do Nothing */}
import java.util.regex.Matcher;
import java.util.regex.Pattern;
%%
%{
private void echo(String t) {
System.out.printf("%s\n", reverse(t));
}
String reverse(String t) {
Matcher m = Pattern.compile("(.*)(<REVERT>)([a-zA-Z ]+)(</REVERT>)(.*)").matcher(t);
if (m.find()) {
String a = m.group(1) + "<REVERTED>";
String b = new StringBuffer(m.group(3)).reverse().toString();
String c = "</REVERTED>" + m.group(5);
return a + b + c;
}
return "";
}
%}
%class revert
%standalone
%line
%column
REVERSE = .*\<REVERT\>.+\<\/REVERT\>.*
%%
{REVERSE} {
echo(yytext());
}
\n {/* Do Nothing */}
. {/* Do Nothing */}
import java.util.ArrayList;
%%
%{
ArrayList<String> ids = new ArrayList<String>();
void tabela() {
int i = 0;
System.out.printf("TABELA \n");
for (String k:ids) {
i++;
System.out.printf("%d: %s \n", i, k);
}
}
String getIdKey(String key) {
int i = 0;
for (String k:ids) {
i++;
if (k.equals(key)) {
return new Integer(i).toString();
}
}
ids.add(key);
return new Integer(i + 1).toString();
}
void reservada(int line, String w) {
System.out.printf("[%d] %s\n", line, w.toUpperCase());
}
void identificador(int line, String w) {
System.out.printf("[%d] IDENTIFICADOR %s\n", line, getIdKey(w));
}
void comentario(int line) {
System.out.printf("[%d] COMENTÁRIO\n", line);
}
void inteiro(int line, String w) {
System.out.printf("[%d] NUMERO INTEIRO %s\n", line, getIdKey(w));
}
void real(int line, String w) {
// System.out.printf("===> %s\n", w);
System.out.printf("[%d] NUMERO REAL %s\n", line, getIdKey(w));
}
%}
%eof{
tabela();
%eof}
%class trabalho
%standalone
%line
%column
%%
break|case|char|const|continue|double|float|int|real { reservada(yyline + 1, yytext()); }
^\/\/.* { comentario(yyline + 1); }
^\+|\-?[0-9]+ $ { inteiro(yyline + 1, yytext()); }
^\+|\-?[0-9]+.[0-9]+ $ { real(yyline + 1, yytext()); }
[a-z]{1}[a-zA-Z0-9]* { identificador(yyline + 1, yytext()); }
.* { }
\n {/* Do Nothing */}
. {/* Do Nothing */}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment