Diskuze: Enumerátory
Jirka:13.10.2018 17:27
Ahoj,
co zkusit regulární výraz, jako "\b[0-9A-F]+\b".
Ahoj,
Nevím jestli jsem pochopil přesně čeho chceš docílit, ale pokud chceš
zjistit jestli řádek obsahuje 0x
a k tomu nějaké číslo a to
následně převést z hexadecimální soustavy do decimální, použil bych regex . Pokud ve tvém souboru, víš že všechny tvé
hexadecimální čísla budou začínat na 0x
tak tvůj regex by
mohl vypadat nějak tak to:
0x([0-9A-Fa-f]+)
V Javě s tím pak můžeš pracovat nějak tak to:
String mujRadek = "0x1F";
String hexRegex = "0x([0-9A-Fa-f]+)";
Pattern r = Pattern.compile(hexRegex);
Matcher m = r.matcher(mujRadek);
if(m.find()) {
String hex = m.group().substring(2);
System.out.println("HEX: " + hex);
System.out.println("DEC: " + Integer.parseInt(hex, 16));
}
Jirka:13.10.2018 19:05
Nebo co třeba něco jako:
package itn.forum;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
public class Hex {
public static void main(String[] args) {
List<String> los = new ArrayList<>();
los.add(" 0x10 ");
los.add(" 0x1f 0x16");
los.add(" 0xzf ");
los.add(" 0x0cblabla ");
los.add(" 0x0c ");
Pattern r = Pattern.compile("\\b0x([0-9A-Fa-f]{2,2})\\b");
for(String s : los) {
if(r.matcher(s).find()) { System.out.println(s + " => souhlasi"); }
}
}
}
Děkuji všem za pomoc, ale stále to není přesně to co hledám. Zkusím upřesnit svůj dotaz. Mám zadání naprogramovat lexikální analyzátor, kteýr bude zpracovávat text a pomocí tokenů vypisovat na obrazovku text.
- Musí rozeznávat klíčová slova (end,begin,if,while,...)
2 ) Musí rozeznávat identifikátory (jakékoliv slovo)
- Musí rozeznávat DEC číslo
- Musí rozeznávat HEX číslo (s prefixem 0x) a převést ho ve výpisu do DEC
- Musí umět přeskakovat mezery (pokud jich je víc po sobě) - vždy zobrazí jen jednu
- Musí načítat jen slova s malým písmenem
- Délka klíčových slov a identifikátorů nesmí přesáhnout 32 znaků
Pustil jsem se do programování a myslím, že mi funguje vše kromě bodů:
4), 6), 7)..
Matlám se s tím strašně dlouho a pořád nic, tak jsem doufal, že tady mě
to zachrání.
Main
public static void main(String[] args) {
try {
Analyzator analyzator = new Analyzator("testFile.txt");
while (!analyzator.jeVycerpano()) {
System.out.printf("%s %s\n", analyzator.currentToken(), analyzator.currentEnum());
analyzator.cteniZnaku();
}
} catch (Exception e) {
}
}
}
Analyzator
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Stream;
/**
*
* @author Radek
*/
public final class Analyzator {
private final int MAXIMALNI_DELKA = 32;
private Token token;
private String enumy;
private StringBuilder stringBuilder = new StringBuilder();
private static final Set<Character> prazdnaMista = new HashSet<Character>();
private boolean vycerpano = false;
public Analyzator(String file) {
try (Stream<String> stream = Files.lines(Paths.get(file))) {
stream.forEach(stringBuilder::append);
} catch (IOException e) {
}
cteniZnaku();
}
static {
prazdnaMista.add((char) 8);
prazdnaMista.add((char) 9);
prazdnaMista.add((char) 11);
prazdnaMista.add((char) 12);
prazdnaMista.add((char) 32);
}
private void preskakujMezery() {
int mezery = 0;
while (prazdnaMista.contains(stringBuilder.charAt(mezery))) {
mezery++;
}
if (mezery > 0) {
stringBuilder.delete(1, mezery);
}
}
public void cteniZnaku() {
if (stringBuilder.length() == 0) {
vycerpano = true;
return;
}
preskakujMezery();
dalsiZnak();
}
private boolean dalsiZnak() {
for (Token t : Token.values()) {
int end = t.konecCteni(stringBuilder.toString());
if (end != 0) {
{
token = t;
enumy = stringBuilder.substring(0, end);
stringBuilder.delete(0, end);
return true;
}
}
}
return false;
}
public Token currentToken() {
return token;
}
public String currentEnum() {
return enumy;
}
public boolean jeVycerpano() {
return vycerpano;
}
}
Tokeny
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
*
* @author Radek
*/
public enum Token {
KEYWORD_BEGIN("begin{0,33}"),
KEYWORD_END("end{0,33}"),
KEYWORD_FOR("for{0,33}"),
KEYWORD_IF("if{0,33}"),
KEYWORD_THEN("then{0,33}"),
KEYWORD_ELSE("else{0,33}"),
KEYWORD_WHILE("while{0,33}"),
KEYWORD_RETURN("return{0,33}"),
SEPARATOR_ROVNITKO("="),
SEPARATOR_CARKA(","),
SEPARATOR_DVOJTECKA(":"),
SEPARATOR_STREDNIK(";"),
NUMBER_DEC("\\d+"),
NUMBER_HEX("\\b0x[0-9A-F]"),
BLANK("\\s"),
IDENTIFIER("\\w{0,33}");
private final Pattern pattern;
Token(String regex) {
pattern = Pattern.compile("^" + regex);
}
int konecCteni(String string) {
Matcher matcher = pattern.matcher(string);
if (matcher.find()) {
return matcher.end();
}
return 0;
}
}
A ještě přiložím soubor se kterým pracuji:
testFile.txt
begin;
a,b=100;
c=0x10;
end;
Tak pokud by byl někdo ochotný mi poradit a pomoc to dotáhnout do konce, byl bych vděčný.
Unda:16.10.2018 17:47
V druháku jsem to vyřešil tím, že jsem to načítal po znaku, nikoliv řádku a zjišťoval co je za 0.
Patrik Valkovič:16.10.2018 18:25
Pokud máš napsat lexikální analyzátor, tak bych řekl že tě s regulárními výrazy pošlou někam. Lexikální analyzátor využívá zpravidla regulárních jazyků a tedy stavových automatů. I když lze každý regulární výraz převést na stavový automat, jejich použití je v lexikálním analyzátoru nevhodné, protože jsou příliš pomalé. Pouvažuj nad tím, jestli to nechceš napsat pořádně
Ale ve výsledku to vše funguje přesně podle zadání moc nerozumím jak bych to vlastně měl jinak přepsat. Koukám do toho každý den, ale bohužel jsem se moc neposunul..
Zobrazeno 8 zpráv z 8.