28. oktober 2007 - 20:00Der er
14 kommentarer og 1 løsning
Konstruere et simpelt programmeringssprog
Hej
Jeg er ved at konstruere og implementere mit eget lille programmeringssprog. Jeg har fået lavet en del af det, men jeg mangler lige det sidste. Da det kniber lidt med mit overblik over situationen lige p.t., så ville jeg meget gerne, hvis de manglende stykker kode kan identificeres.
Det lavede arbejde er:
token.cs: using System; using System.Collections.Generic; using System.Text;
namespace cmc { public class Token { public byte kind; public String spelling;
public Token(byte kind, String spelling) { this.kind=kind; this.spelling=spelling; //if kind is IDENTIFIER and SPELLING matches one //of the keywords, change the tokens kind accordingly: if(kind==IDENTIFIER){ for (int k = BEGIN; k<=WHILE; k++) { if (spelling.Equals(spellings[k])) { this.kind = k; break; } } } }
private bool isDigit(char c) { //if(c.Equals('0')); if (c == '0') return true; else if (c == '1') return true; else if (c == '2') return true; else if (c == '3') return true; else if ( c == '4') return true; else if (c == '5') return true; else if ( c == '6') return true; else if ( c == '7') return true; else if ( c == '8') return true; else if (c == '9') return true; else return false; }
private bool isLetter(char c) { switch(c){ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'x': case 'y': case 'z': return true; } return false; }
private byte scanToken() { switch(currentChar) { case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'x': case 'y': case 'z': takeIt(); return Token.IDENTIFIER; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': takeIt(); while(isDigit(currentChar)) takeIt(); return Token.INTEGERLITERAL; case '+': case '-': case '*': case '/': case '%': case '=': takeIt(); return Token.OPERATOR; case ';': takeIt(); return Token.SEMICOLON; case ':': takeIt(); if(currentChar=='='){ takeIt(); return Token.BECOMES; }else return Token.COLON; case '(': takeIt(); return Token.LEFTPARAN; case ')': takeIt(); return Token.RIGHTPARAN; case "\000": return Token.EOT; default: Console.Out.WriteLine("lecical error"); } }
private void scanSeperator() { switch(currentChar) { case ' ': case '\n': takeIt(); default: Console.Out.WriteLine("Error in seperators"); } }
public Token scan() { while(currentChar==' '||currentChar=='\n') scanSeperator(); currentSpelling=new StringBuffer(); currentKind=scanToken(); return new Token(currentKind, currentSpelling.toString()); } } }
parser.cs: using System; using System.Collections.Generic; using System.Text;
namespace cmc { public class Parser { private Scanner scan; private Token currentTerminal;
public void parseLine() { //* the subroutines are called in this order: parseProgram(); parseClass(); parseDeclarations(); parseOneDeclaration(); parseMultipleDeclaration(); parseImplementation(); parseMultipleImplementationStatement(); parseOneImplementationStatement(); parseExpression(); parsePrimary(); *// if(parseProgram().Equals(true)) accept( Token.DOT ); }
public bool parseProgram() { if(currentTerminal.kind == Token.CLASS) return parseClass(); else Console.Out.WriteLine("Does not contain class"); if(currentTerminal.kind != Token.EOT ) Console.Out.WriteLine("Tokens found after end of program"); return false; }
Denne side indeholder artikler med forskellige perspektiver på Identity & Access Management i private og offentlige organisationer. Artiklerne behandler aktuelle IAM-emner og leveres af producenter, rådgivere og implementeringspartnere.
Jeg kender ikke så meget til generatorer. Egentlig vil jeg meget gerne se selve koden for sproget, og det ved jeg ikke, og man får ved brug af en generator? Men ellers er det vel logisk opbygget mht. kald og procedurer m.m. (som jeg har forsøgt at skrive i koden), jeg mangler blot overblikket og den rigtige tilgang.
Jeg vil selvfølgelig gerne, at koden kan afvikles op mod en tekstfil, så det bliver så "kompileringsagtigt" som muligt. Hertil her jeg hørt om en "fil-dialog"-boks i Visual Studio, men den ved jeg heller ikke, hvordan fungerer i praksis.
Nu har jeg arbejdet en del videre med projektet. Jeg ha lavet lidt om påkoden, så den er opbygget efter mine kendte principper (ikke teori, men hvad jeg ved, der fungerer). Til det formål har jeg lavet en undermappe i projektet. Her har jeg lavet en almindelig ".cs"-fil, som indehlder alle classer og metoder. Så vil jeg gerne teste koden. Men når jeg trykker på "run"-knappen, så kommer der blot en tom form frem.Hvorfor sker dette?
I den sammenhæng har jeg så prøvet at køre programet fra prompten på denne måde: java fil(argument) men så skriver den bl.a., at der ikke findes nogen Main. Er det fordi, Main står inde i classen? Jeg har også prøvet at skrive Main'en udenfr klassen, men det hjælper ikke.
Ahh, ja selvfølgelig. Min handling var vist et godt udtryk for, at jeg mangler lidt overblik over projektet. Jeg har nemlig fundet ud af, at der vist primært bliver lavet programmeringssprog i java - derfor prøvede jeg nok ubevidst med java-compileren. I java findes der en masse klasser, som kan afhjælpe konstruktionen. Findes der nogle eksempler (gerne avancerede) i java, som representerer et programmeringssprog? (altså hvor man blot skal rette nogle linier i koden, så man får det ønskede output med egne begrænsninger/ønkser)
Nu har jeg downloaded nogle af de generatorer. Umiddelbart ser Coco fin ud. Dog tror jeg, at den giver nogle lidt for avancerede muligheder. Jeg ville egentlig godt prøve ANTLR, men hver dén, eller umiddelbart nogle af de andre, kan jeg betjene korrekt. Ved du bl.a. hordan jeg laver f.eks. grammar'en i ANTLR?
(jeg har ikke set så meget på "hvordan" i de andre)
Jeg har lavet en masse med "den første version". Nu er der kun nogle få kompileringsfejl. Er det noget, som arne_v eller andre eventuelt vil kompilere og finde fejlene ved? (du/i har garanteret bedre og større indsigt i programmeringshalløjet end mig)
public void parseLine() { if(parseProgram()) accept( Token.DOT ); }
public boolean parseProgram() { if(currentTerminal.kind == Token.CLASS) return parseClass(); else System.out.println("Does not contain class"); if(currentTerminal.kind != Token.EOT ) System.out.println("Tokens found after end of program"); return false; }
private boolean isDigit(int c) { switch(c) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: return true; } return false; }
private boolean isLetter(char c) { switch(c){ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'x': case 'y': case 'z': return true; } return false; }
private byte scanToken() { switch(currentChar) { case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'x': case 'y': case 'z': takeIt(); return Token.IDENTIFIER; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': takeIt(); while(isDigit(currentChar)) takeIt(); return Token.INTEGERLITERAL; case '+': case '-': case '*': case '/': case '%': case '=': takeIt(); return Token.OPERATOR; case ';': takeIt(); return Token.SEMICOLON; case ':': takeIt(); if(currentChar=='='){ takeIt(); return Token.BECOMES; }else return Token.COLON; case '(': takeIt(); return Token.LEFTPARAN; case ')': takeIt(); return Token.RIGHTPARAN; default:{ System.out.println("lecical error"); return 1; } } }
private void scanSeperator() { switch(currentChar) { case ' ': case '\n': takeIt(); } }
public Token scan() { currentSpelling=new StringBuffer(); currentKind=scanToken(); return new Token(currentKind, currentSpelling.toString()); } //***********FOUND ONLINE******ARE ONLY CODING FROM HERE AND DOWNWARDS****** private static void readFile(String fileName) { try { Scanner scanner = new Scanner(new File(fileName)); scanner.useDelimiter (System.getProperty("line.separator")); while (scanner.hasNext()) { parseLine(scanner.next()); } Token.EOT;//for at slutte af fra scanner før System.out.println("\nScanning completed\n"); scanner.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } }
private static void parseLine(String line)//static //check for beginning of line and process accordingly {//is called pr line try{ Scanner lineScanner = new Scanner(line); while(lineScanner.hasNext()) { word=lineScanner.next(); if(word=="class")//check if word is "class" { endingBuffer.append(word.toString()); if(lineScanner.hasNext()){ word=lineScanner.next(); endingBuffer.append(word.toString());//append name of class } if(lineScanner.hasNext()){ System.out.println("Too many words after name of class"); System.exit(1); } else{ return; } System.out.println("Missing name of class"); System.exit(1); } if(word=="{"){ //finalBuffer.append(word.toString()); numberBeginingBrachets++; return;//return to linechecker } if(word=="}"){ //finalBuffer.append(word.toString()); numberEndingBrachets++; return;//return to linechecker } if(word=="declaration:") { endingBuffer.append(word.toString()); declaration=true; if(lineScanner.hasNext()){ System.out.println("Not allowed to type after DECLARATION"); System.exit(1); } } if(declaration=true){//the last runthrough stated a declaration begun if(word==Token.Int||word==Token.Bool){ if(word==Token.Int) numberInt++; if(word==Token.Bool) numberBoolean++; endingBuffer.append(word.toString());//found an identifier/type word=lineScanner.next();//search for name, =, value, ; endingBuffer.append(word.toString());//found a VARname word=lineScanner.next(); //check if word contains '='(word.contains('=')) char[] charArray=word.toCharArray(); boolean hasEqual=false; for(int count=0; count<charArray.length(); count++) { if(charArray[count]=='=') hasEqual=true; } if(hasEqual) { if(lineScanner.hasNext()){ word=lineScanner.next(); if(numberBoolean>0) { endingBuffer.append(word);//if 'true' or 'false' numberBoolean--; } if(numberInt>0) { endingBuffer.append(word);//if number numberInt--; } } else { System.out.println("Variable MUST be initialized to a value!"); System.exit(1); } } else{ System.out.println("Variable MUST be initialized with a '='!"); System.exit(1); } } declaration=false;//going out of declaration } if(word=="implementation:") { implementation=true; endingBuffer.append(word.toString()); if(lineScanner.hasNext()){ System.out.println("Not allowed to type after Implementation"); System.exit(1); } } if(implementation=true) { word=lineScanner.next(); //check if variables are initialized!!!! //check if word contains '='(word.contains('=')) char[] charArray=word.toCharArray(); boolean hasEqual=false; for(int count=0; count<charArray.length(); count++) { if(charArray[count]=='=') hasEqual=true; } if(hasEqual==true)//if a variable is handled { if(lineScanner.hasNext()){ word=lineScanner.next(); if(exists())//check if variable exists! { endingBuffer.append(word); if(lineScanner.hasNext()){ //do the operation according to Token.Operator }else System.out.println("Error in handling the variables in implementation!"); } if(word.equals("out")) { endingBuffer.append(word); //and print out the value } } else { System.out.println("Variable MUST be initialized to a value!"); System.exit(1); } } else{ System.out.println("Variable MUST be initialized with a '='!"); System.exit(1); } implementation=false; } //check if the number of '{' and '}' are even! System.exit(1); }
}catch(Exception e) { System.out.println("ERROR in try-method\n"+e.toString()); } }
Så fik jeg kringlet den med egen opbygning af koden. Det var nu ikke så omfattende, som først antaget.
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.