Лексический анализатор не получает следующий символ - PullRequest
0 голосов
/ 05 ноября 2018

Итак, я работаю над проектом, в котором мы создаем небольшую программу компиляции, но, прежде чем я могу перейти к другим частям, у меня возникают проблемы с получением лексического анализатора для вывода чего-либо после того, как '\ BEGIN' впоследствии я отладил и кажется, что значение застряло в цикле, где условие говорит, что следующий символ всегда является новой строкой. Это потому, что я еще не добавил соответствие шаблону к определенным токенам?

Вот код

import java.util

//import com.sun.javafx.fxml.expression.Expression.Parser.Token
/*Lexical analyzer will be responsible for the following:
- finds the lexemes
- Checks each given character determining the tokens
* */
class MyLexicalAnalyzer extends LexicalAnalyzer {
  //Array full of the keywords
//val SpecialCharacters = List(']', '#', '*', '+', '\\', '[', '(',')', "![", '=')

  val TEXT = "[a-z] | _ | 0-9 | [A-Z]:"
  private var sourceLine: String = null
  private val lexeme: Array[Char] = new Array[Char](999)
  private var nextChar: Char = 0
  private var lexLength: Int = 0
  private var position: Int = 0
  private val lexems: util.List[String] = new util.ArrayList[String]

  def start(line: String): Unit = {
    initializeLexems()
    sourceLine = line
    position = 0
    getChar()
    getNextToken()
  }
  // A helper method to determine if the current character is a space.

  private def isSpace(c: Char) = c == ' '

  //Defined and intialized tokens
    def initializeLexems(): Any =  {
   lexems.add("\\BEGIN")
    lexems.add("\\END")
   lexems.add("\\PARAB")
  lexems.add("\\DEF[")
    lexems.add("\\USE[")
  lexems.add("\\PARAE")
   lexems.add("\\TITLE[")
    lexems.add("]")
   lexems.add("[")
   lexems.add("\\")
   lexems.add("(")
  lexems.add(")")
    lexems.add("![")
   lexems.add("=")
    lexems.add("+")
  lexems.add("#")
  }
//val pattern = new regex("''").r
  def getNextToken() ={
    lexLength = 0
    // Ignore spaces and add the first character to the token
    getNonBlank()
    addChar()
    getChar()
    // Continue gathering characters for the token
    while ( {
      (nextChar != '\n') && (nextChar != ' ')
    }) {
      addChar()
      getChar()
    }
    // Convert the gathered character array token into a String
    val newToken: String = new String(lexeme)
    if (lookup(newToken.substring(0, lexLength)))
      MyCompiler.setCurrentToken(newToken.substring(0,lexLength))
  }
  // A helper method to get the next non-blank character.
  private def getNonBlank(): Unit = {
    while ( {
      isSpace(nextChar)
    }) getChar()
  }

  /*
    Method of function that adds the current character to the token
    after checking to make sure that length of the token isn't too
    long, a lexical error in this case.
   */
  def addChar(){

      if (lexLength <= 998) {
        lexeme({
          lexLength += 1; lexLength - 1
        }) = nextChar
        lexeme(lexLength) = 0
      }
    else
        System.out.println("LEXICAL ERROR - The found lexeme is too long!")
    if (!isSpace(nextChar))
      while ( {
      !isSpace(nextChar)
    })
        getChar()
    lexLength = 0
    getNonBlank()
    addChar()
  }

  //Reading from the file its obtaining the tokens
  def getChar() {
    if (position < sourceLine.length)
      nextChar = sourceLine.charAt ( {
        position += 1;
        position - 1
      })
    else nextChar = '\n'

  def lookup(candidateToken: String): Boolean ={
    if (!(lexems.contains(candidateToken))) {
      System.out.println("LEXICAL ERROR - '" + candidateToken + "' is not recognized.")
      return false
    }
    return true
  }
}
 else nextChar = '\n'<- this is where the condition goes after rendering the first character '\BEGIN' then just keeps outputting in the debug console as listed below.

enter image description here Это то, что выводит консоль отладки после '\ BEGIN' Может кто-нибудь, пожалуйста, дайте мне знать, почему это так? Это происходит и после того, как я много раз вхожу в это.

Вот класс драйверов, использующий лексический анализатор

import scala.io.Source

object MyCompiler {
  //check the arguments
  //check file extensions
  //initialization
  //get first token
  //call start state
  var currentToken : String = ""

  def main(args: Array[String]): Unit = {
      val filename = args(0)
    //check if an input file provided
    if(args.length == 0) {
      //usage error
      println("USAGE ERROR:  Must provide an input file. ")
      System.exit(0)
    }
    if(!checkFileExtension(args(0))) {
      println("USAGE ERROR: Extension name is invalid make sure its .gtx ")
      System.exit(0)
    }

    val Scanner = new MyLexicalAnalyzer
    val Parser = new MySyntaxAnalyzer

    //getCurrentToken(Scanner.getNextToken())
    //Parser.gittex()
    for (line <- Source.fromFile(filename).getLines()){
      Scanner.start(line)
      println()
    }


    //.......
    //If it gets here, it is compiled
    //post processing

  }
  //checks the file extension if valid and ends with .gtx
  def checkFileExtension(filename : String) : Boolean =  filename.endsWith(".gtx")

  def getCurrentToken() : String = this.currentToken
  def setCurrentToken(t : String ) : Unit = this.currentToken = t
}

1 Ответ

0 голосов
/ 06 ноября 2018

Код работает как положено. Первая строка содержит только строку \BEGIN, поэтому лексический анализатор обрабатывает конец первой строки как '\ n', как показано в этом методе:

def getChar() {
  if (position < sourceLine.length)
    nextChar = sourceLine.charAt ( {
      position += 1;
      position - 1
    })
  else nextChar = '\n'

Однако комментарий непосредственно над этим методом не описывает то, что на самом деле делает метод. Это может быть намек на то, где находится ваше замешательство. Если в комментарии говорится, что его следует читать из файла, но он не читает из файла, возможно, это то, что вы забыли реализовать.

...