From f9de4179eecb09e20a936ad8ffb1321bc71ae15a Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Mon, 21 Aug 2017 22:30:46 +0200 Subject: [PATCH] proper string in cli lexer and parser --- alib2cli/src/lexer/Lexer.cpp | 46 ++++++++++++++++++++++++++++------ alib2cli/src/lexer/Lexer.h | 3 +++ alib2cli/src/parser/Parser.cpp | 8 ++++-- alib2cli/src/parser/Parser.h | 8 ++++++ 4 files changed, 56 insertions(+), 9 deletions(-) diff --git a/alib2cli/src/lexer/Lexer.cpp b/alib2cli/src/lexer/Lexer.cpp index 294f51e4db..2041b330c2 100644 --- a/alib2cli/src/lexer/Lexer.cpp +++ b/alib2cli/src/lexer/Lexer.cpp @@ -7,7 +7,7 @@ namespace cli { Lexer::Token Lexer::nextToken () { Token res { "", TokenType::ERROR }; -q0: if ( m_index >= m_line.size ( ) ) { +q0: if ( m_index >= m_line.size ( ) ) { res.m_type = TokenType::END; return res; } @@ -76,6 +76,11 @@ q0: if ( m_index >= m_line.size ( ) ) { goto q2; } + if ( m_line [ m_index ] == '"' ) { + m_index ++; + goto q4; + } + if ( ( m_line [ m_index ] >= '0' && m_line [ m_index ] <= '9' ) ) { res.m_value += m_line [ m_index ]; m_index++; @@ -84,8 +89,8 @@ q0: if ( m_index >= m_line.size ( ) ) { if ( ( m_line [ m_index ] >= 'a' && m_line [ m_index ] <= 'z' ) || ( m_line [ m_index ] >= 'A' && m_line [ m_index ] <= 'Z' ) - || m_line [ m_index ] == '/' || m_line [ m_index ] == '.' - || m_line [ m_index ] == '~' || m_line [ m_index ] == '_' ) { + || m_line [ m_index ] == '/' || m_line [ m_index ] == '.' + || m_line [ m_index ] == '~' || m_line [ m_index ] == '_' ) { res.m_value += m_line [ m_index ]; m_index++; goto q3; @@ -120,8 +125,8 @@ q2: if ( m_index >= m_line.size ( ) ) { if ( ( m_line [ m_index ] >= 'a' && m_line [ m_index ] <= 'z' ) || ( m_line [ m_index ] >= 'A' && m_line [ m_index ] <= 'Z' ) - || m_line [ m_index ] == '/' || m_line [ m_index ] == '.' || m_line [ m_index ] == '-' - || m_line [ m_index ] == '~' || m_line [ m_index ] == '_' || m_line [ m_index ] == ':' ) { + || m_line [ m_index ] == '/' || m_line [ m_index ] == '.' || m_line [ m_index ] == '-' + || m_line [ m_index ] == '~' || m_line [ m_index ] == '_' || m_line [ m_index ] == ':' ) { res.m_value += m_line [ m_index ]; m_index++; goto q3; @@ -138,8 +143,8 @@ q3: if ( m_index >= m_line.size ( ) ) { if ( ( m_line [ m_index ] >= '0' && m_line [ m_index ] <= '9' ) || ( m_line [ m_index ] >= 'a' && m_line [ m_index ] <= 'z' ) || ( m_line [ m_index ] >= 'A' && m_line [ m_index ] <= 'Z' ) - || m_line [ m_index ] == '/' || m_line [ m_index ] == '.' || m_line [ m_index ] == '-' - || m_line [ m_index ] == '~' || m_line [ m_index ] == '_' || m_line [ m_index ] == ':' ) { + || m_line [ m_index ] == '/' || m_line [ m_index ] == '.' || m_line [ m_index ] == '-' + || m_line [ m_index ] == '~' || m_line [ m_index ] == '_' || m_line [ m_index ] == ':' ) { res.m_value += m_line [ m_index ]; m_index++; goto q3; @@ -147,6 +152,33 @@ q3: if ( m_index >= m_line.size ( ) ) { res.m_type = is_kw ( res.m_value ); return res; } + +q4: if ( m_index >= m_line.size ( ) ) { + res.m_type = TokenType::ERROR; + return res; + } + if ( m_line [ m_index ] == '"' ) { + res.m_type = TokenType::STRING; + m_index++; + return res; + } + if ( m_line [ m_index ] == '\\' ) { + m_index++; + goto q5; + } else { + res.m_value += m_line [ m_index ]; + m_index ++; + goto q4; + } + +q5: if ( m_index >= m_line.size ( ) ) { + res.m_type = TokenType::ERROR; + return res; + } + + res.m_value += m_line [ m_index ]; + m_index++; + goto q4; } } /* namespace cli */ diff --git a/alib2cli/src/lexer/Lexer.h b/alib2cli/src/lexer/Lexer.h index c946a5f716..7ed1d1676f 100644 --- a/alib2cli/src/lexer/Lexer.h +++ b/alib2cli/src/lexer/Lexer.h @@ -14,6 +14,7 @@ public: enum class TokenType { IDENTIFIER, INTEGER, + STRING, IN_REDIRECT, OUT_REDIRECT, LEFT_PAREN, @@ -44,6 +45,8 @@ public: return out << "identifier: " << token.m_value; case TokenType::INTEGER : return out << "number: " << token.m_value; + case TokenType::STRING : + return out << "string: \"" << token.m_value << "\""; case TokenType::IN_REDIRECT : return out << "in_redirect"; case TokenType::OUT_REDIRECT : diff --git a/alib2cli/src/parser/Parser.cpp b/alib2cli/src/parser/Parser.cpp index 3001d2a506..e8da17a9d9 100644 --- a/alib2cli/src/parser/Parser.cpp +++ b/alib2cli/src/parser/Parser.cpp @@ -131,6 +131,9 @@ std::unique_ptr < Param > Parser::value_param ( ) { } else if ( check ( cli::Lexer::TokenType::IDENTIFIER ) ) { std::string value = matchIdentifier ( ); return std::make_unique < ImmediateParam < std::string > > ( value ); + } else if ( check ( cli::Lexer::TokenType::STRING ) ) { + std::string value = matchString ( ); + return std::make_unique < ImmediateParam < std::string > > ( value ); } else if ( check ( cli::Lexer::TokenType::INTEGER ) ) { int value = matchInteger ( ); return std::make_unique < ImmediateParam < int > > ( value ); @@ -297,9 +300,10 @@ std::unique_ptr < Command > Parser::parse ( ) { return introspect_command ( ); } else if ( check_nonreserved_kw ( "set" ) ) { match_nonreserved_kw ( "set" ); - std::string param = matchIdentifier ( ); - std::string value = getTokenValue ( ); + std::string param = getTokenValue ( ); match ( cli::Lexer::TokenType::INTEGER, cli::Lexer::TokenType::IDENTIFIER ); + std::string value = getTokenValue ( ); + match ( cli::Lexer::TokenType::INTEGER, cli::Lexer::TokenType::IDENTIFIER, cli::Lexer::TokenType::STRING ); match ( cli::Lexer::TokenType::END ); return std::make_unique < SetCommand > ( std::move ( param ), std::move ( value ) ); } else { diff --git a/alib2cli/src/parser/Parser.h b/alib2cli/src/parser/Parser.h index 245b152086..79d88125e6 100644 --- a/alib2cli/src/parser/Parser.h +++ b/alib2cli/src/parser/Parser.h @@ -59,6 +59,14 @@ public: return res; } + std::string matchString ( ) { + if ( ! check ( Lexer::TokenType::STRING ) ) + throw exception::CommonException ( "Mismatched token while matching a token." ); + std::string res = m_current.m_value; + m_current = m_lexer.nextToken ( ); + return res; + } + int matchInteger ( ) { if ( ! check ( Lexer::TokenType::INTEGER ) ) throw exception::CommonException ( "Mismatched token while matching a token." ); -- GitLab